diff options
author | Amenadiel <amenadiel@gmail.com> | 2016-08-25 01:12:11 +0300 |
---|---|---|
committer | Amenadiel <amenadiel@gmail.com> | 2016-08-25 01:12:11 +0300 |
commit | 7f9b6c0512e67d5cd029779bbb70442e4e495c4b (patch) | |
tree | 12c75d4c1ab7cbcbccff8551d21d8a351db3484f | |
parent | b025530c258425c5b4d1a30cdfbd8df5729a25b7 (diff) | |
parent | d56eafd4a47e2eda1d9793f6db11170775c670df (diff) |
Merge branch 'release/v6.0.0-alpha2'vv6.0.0-alpha2
82 files changed, 14975 insertions, 15450 deletions
@@ -3,8 +3,25 @@ the premier web-based administration tool for postgresql This is a fork of [phpPgAdmin](https://github.com/phppgadmin/phppgadmin) that implements **a lot of changes** -- the app was fully refactored adding namespaces, proper folder hierarchy, separating each class in its own file and stripping the use of require and include to the bare minimum -dropping support for PHP < 5.4. -- it provides full composer compatibility -- it has PSR-4 autoloading -- it makes requirement checks so you can't go wrong +### v6.0.0-alpha1 + +- the app was fully refactored adding: + - namespaces + - proper (yet arbitrary :sad:) folder hierarchy + - separate files for separate classes +- stripes the use of require and include to the bare minimum +- drops support for PHP < 5.4. +- provides full composer compatibility +- PSR-4 autoloading +- makes requirement checks for PHP version and ext-pgsql + + +### v6.0.0-alpha2 + +- most entrypoints were moved to `src/views` and do now instance a controller, then call one of its methods depending on the `action` parameter +- due to this, entrypoint logic was moved into controller classes in `src/controllers` +- usage of global variables is being replaced by member properties and usage of `use` where is due. +- usage of global functions is being replaced by anonymous fuctions +- usage of explicit includes/requires is being replaced by composer's autoloader (except for `src/lib.inc.php`) +- global decorator functions are being replaced by static methods of the Decorator class. +- `doTree` and `doSubtree` functions of each entrypoint are now at `src/tree` mostly because they are a different, self contained family of routes that reference each other
\ No newline at end of file diff --git a/composer.json b/composer.json index c557063f..a053d060 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "huasofoundries/phppgadmin", - "version": "6.0.0-alpha1", + "version": "6.0.0-alpha2", "description": "Like phpmyadmin but for postgres", "type": "project", "license": "MIT", @@ -12,6 +12,7 @@ "autoload": { "psr-4": { "PHPPgAdmin\\": "src/classes", + "PHPPgAdmin\\Controller\\": "src/controllers", "PHPPgAdmin\\Database\\": "src/classes/database", "PHPPgAdmin\\XHtml\\": "src/classes/xhtml", "PHPPgAdmin\\Decorators\\": "src/classes/decorators" diff --git a/composer.lock b/composer.lock index 9773504a..cc5fff32 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7bd85b0232d3f90e00090049eb808aff", + "hash": "95f57a2ebe79ac38abaf9ddf5aa10968", "content-hash": "4c894ea7295f7f51cce76ca342f6b6b2", "packages": [ { @@ -10,10 +10,6 @@ $_no_db_connection = true; require_once './src/lib.inc.php'; -if (!isset($msg)) { - $msg = ''; -} - $app->post('/redirect[/{subject}]', function ($request, $response, $args) use ($msg) { $body = $response->getBody(); @@ -39,10 +35,17 @@ $app->post('/redirect[/{subject}]', function ($request, $response, $args) use ($ $_SESSION['sharedPassword'] = $_POST['loginPassword_' . md5($_POST['loginServer'])]; } - $this->misc->setReloadBrowser(true); $data = $misc->getDatabaseAccessor(); - include './src/views/all_db.php'; + $all_db_controller = new \PHPPgAdmin\Controller\AllDBController($this); + + $misc->printHeader($this->lang['strdatabases']); + $misc->printBody(); + + return $all_db_controller->doDefault(); + + $misc->setReloadBrowser(true); + $misc->printFooter(); //$body->write($this->misc->printFooter(false)); diff --git a/src/classes/Misc.php b/src/classes/Misc.php index 7a3c1304..50f06d26 100644 --- a/src/classes/Misc.php +++ b/src/classes/Misc.php @@ -11,23 +11,22 @@ use \PHPPgAdmin\Decorators\Decorator; */ class Misc { - // Tracking string to include in HREFs - var $href; - // Tracking string to include in forms - var $form; - - var $lang = []; - private $data = null; - private $app = null; - private $_connection = null; - private $server_id = null; - private $database = null; - public $appName = ''; - public $appVersion = ''; - public $appLangFiles = []; - private $_reload_browser = false; - - private $_no_db_connection = false; + + private $_connection = null; + private $_no_db_connection = false; + private $_reload_drop_database = false; + private $_reload_browser = false; + private $app = null; + private $data = null; + private $database = null; + private $server_id = null; + public $appLangFiles = []; + public $appName = ''; + public $appVersion = ''; + public $form = ''; + public $href = ''; + public $lang = []; + private $_no_output = false; /* Constructor */ function __construct(\Slim\App $app) { @@ -102,6 +101,13 @@ class Misc { return $this; } + function setNoOutput($flag) { + global $_no_output; + $this->_no_output = boolval($flag); + $_no_output = $this->_no_output; + return $this; + } + function getNoDBConnection() { return $this->_no_db_connection; } @@ -140,6 +146,16 @@ class Misc { $this->_reload_browser = boolval($flag); return $this; } + /** + * [setReloadBrowser description] + * @param boolean $flag sets internal $_reload_browser var which will be passed to the footer methods + */ + function setReloadDropDatabase($flag) { + global $_reload_drop_database; + $_reload_drop_database = $flag; + $this->_reload_drop_database = boolval($flag); + return $this; + } /** * Creates a database accessor @@ -387,6 +403,11 @@ class Misc { if (!isset($vars['url'])) { $vars['url'] = '/redirect'; } + \PC::debug($vars, 'getSubjectParams'); + if ($vars['url'] == '/redirect' && isset($vars['params']['subject'])) { + $vars['url'] = '/redirect/' . $vars['params']['subject']; + unset($vars['params']['subject']); + } return $vars; } @@ -709,8 +730,6 @@ class Misc { $lang = $this->lang; $plugin_manager = $this->plugin_manager; - global $_no_output; - $viewVars = $this->lang; $viewVars['dir'] = (strcasecmp($lang['applangdir'], 'ltr') != 0) ? ' dir="' . htmlspecialchars($lang['applangdir']) . '"' : ''; @@ -733,7 +752,7 @@ class Misc { $header_html .= "</head>\n"; - if (!isset($_no_output) && $do_print) { + if (!$this->_no_output && $do_print) { header("Content-Type: text/html; charset=utf-8"); echo $header_html; @@ -748,20 +767,17 @@ class Misc { * @param $doBody True to output body tag, false to return the html */ function printFooter($doBody = true) { - global $_reload_drop_database, $_no_bottom_link; $lang = $this->lang; $footer_html = ''; \PC::debug($this->_reload_browser, '$_reload_browser'); if ($this->_reload_browser) { $footer_html .= $this->printReload(false, false); - } elseif (isset($_reload_drop_database)) { + } elseif ($this->_reload_drop_database) { $footer_html .= $this->printReload(true, false); } - if (!isset($_no_bottom_link)) { - $footer_html .= "<a href=\"#\" class=\"bottom_link\">" . $lang['strgotoppage'] . "</a>"; - } + $footer_html .= "<a href=\"#\" class=\"bottom_link\">" . $lang['strgotoppage'] . "</a>"; $footer_html .= "</body>\n"; $footer_html .= "</html>\n"; @@ -780,12 +796,11 @@ class Misc { * @param $bodyClass - name of body class */ function printBody($doBody = true, $bodyClass = '') { - global $_no_output; $bodyClass = htmlspecialchars($bodyClass); $bodyHtml = "<body " . ($bodyClass == '' ? '' : " class=\"{$bodyClass}\"") . ">\n"; - if (!isset($_no_output) && $doBody) { + if (!$this->_no_output && $doBody) { echo $bodyHtml; } else { return $bodyHtml; @@ -2038,7 +2053,7 @@ class Misc { * @param $do_print true to echo, false to return */ function printHelp($str, $help = null, $do_print = true) { - \PC::debug(['str' => $str, 'help' => $help], 'printHelp'); + //\PC::debug(['str' => $str, 'help' => $help], 'printHelp'); if ($help !== null) { $helplink = $this->getHelpLink($help); $str .= '<a class="help" href="' . $helplink . '" title="' . $this->lang['strhelp'] . '" target="phppgadminhelp">' . $this->lang['strhelpicon'] . '</a>'; @@ -3039,7 +3054,7 @@ class Misc { $fksprops['code'] .= '<div id="fkbg"></div>'; $fksprops['code'] .= '<div id="fklist"></div>'; - $fksprops['code'] .= '<script src="js/ac_insert_row.js" type="text/javascript"></script>'; + $fksprops['code'] .= '<script src="/js/ac_insert_row.js" type="text/javascript"></script>'; } else /* we have no foreign keys on this table */ { return false; diff --git a/src/classes/database/Postgres.php b/src/classes/database/Postgres.php index a4ac02db..2bf3ba59 100755 --- a/src/classes/database/Postgres.php +++ b/src/classes/database/Postgres.php @@ -17,7 +17,7 @@ class Postgres extends ADODB_base { // Map of database encoding names to HTTP encoding names. If a // database encoding does not appear in this list, then its HTTP // encoding name is the same as its database encoding name. - var $codemap = array( + var $codemap = [ 'BIG5' => 'BIG5', 'EUC_CN' => 'GB2312', 'EUC_JP' => 'EUC-JP', @@ -52,19 +52,19 @@ class Postgres extends ADODB_base { 'WIN1252' => 'CP1252', 'WIN1256' => 'CP1256', 'WIN1258' => 'CP1258', - ); - var $defaultprops = array('', '', ''); + ]; + var $defaultprops = ['', '', '']; // Extra "magic" types. BIGSERIAL was added in PostgreSQL 7.2. - var $extraTypes = array('SERIAL', 'BIGSERIAL'); + var $extraTypes = ['SERIAL', 'BIGSERIAL']; // Foreign key stuff. First element MUST be the default. - var $fkactions = array('NO ACTION', 'RESTRICT', 'CASCADE', 'SET NULL', 'SET DEFAULT'); - var $fkdeferrable = array('NOT DEFERRABLE', 'DEFERRABLE'); - var $fkinitial = array('INITIALLY IMMEDIATE', 'INITIALLY DEFERRED'); - var $fkmatches = array('MATCH SIMPLE', 'MATCH FULL'); + var $fkactions = ['NO ACTION', 'RESTRICT', 'CASCADE', 'SET NULL', 'SET DEFAULT']; + var $fkdeferrable = ['NOT DEFERRABLE', 'DEFERRABLE']; + var $fkinitial = ['INITIALLY IMMEDIATE', 'INITIALLY DEFERRED']; + var $fkmatches = ['MATCH SIMPLE', 'MATCH FULL']; // Function properties - var $funcprops = array(array('', 'VOLATILE', 'IMMUTABLE', 'STABLE'), - array('', 'CALLED ON NULL INPUT', 'RETURNS NULL ON NULL INPUT'), - array('', 'SECURITY INVOKER', 'SECURITY DEFINER')); + var $funcprops = [['', 'VOLATILE', 'IMMUTABLE', 'STABLE'], + ['', 'CALLED ON NULL INPUT', 'RETURNS NULL ON NULL INPUT'], + ['', 'SECURITY INVOKER', 'SECURITY DEFINER']]; // Default help URL var $help_base; // Help sub pages @@ -72,9 +72,9 @@ class Postgres extends ADODB_base { // Name of id column var $id = 'oid'; // Supported join operations for use with view wizard - var $joinOps = array('INNER JOIN' => 'INNER JOIN', 'LEFT JOIN' => 'LEFT JOIN', 'RIGHT JOIN' => 'RIGHT JOIN', 'FULL JOIN' => 'FULL JOIN'); + var $joinOps = ['INNER JOIN' => 'INNER JOIN', 'LEFT JOIN' => 'LEFT JOIN', 'RIGHT JOIN' => 'RIGHT JOIN', 'FULL JOIN' => 'FULL JOIN']; // Map of internal language name to syntax highlighting name - var $langmap = array( + var $langmap = [ 'sql' => 'SQL', 'plpgsql' => 'SQL', 'php' => 'PHP', @@ -99,25 +99,25 @@ class Postgres extends ADODB_base { 'rubyu' => 'Ruby', 'plruby' => 'Ruby', 'plrubyu' => 'Ruby', - ); + ]; // Predefined size types - var $predefined_size_types = array('abstime', 'aclitem', 'bigserial', 'boolean', 'bytea', 'cid', 'cidr', 'circle', 'date', 'float4', 'float8', 'gtsvector', 'inet', 'int2', 'int4', 'int8', 'macaddr', 'money', 'oid', 'path', 'polygon', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'reltime', 'serial', 'smgr', 'text', 'tid', 'tinterval', 'tsquery', 'tsvector', 'varbit', 'void', 'xid'); + var $predefined_size_types = ['abstime', 'aclitem', 'bigserial', 'boolean', 'bytea', 'cid', 'cidr', 'circle', 'date', 'float4', 'float8', 'gtsvector', 'inet', 'int2', 'int4', 'int8', 'macaddr', 'money', 'oid', 'path', 'polygon', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'reltime', 'serial', 'smgr', 'text', 'tid', 'tinterval', 'tsquery', 'tsvector', 'varbit', 'void', 'xid']; // List of all legal privileges that can be applied to different types // of objects. - var $privlist = array( - 'table' => array('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'), - 'view' => array('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'), - 'sequence' => array('SELECT', 'UPDATE', 'ALL PRIVILEGES'), - 'database' => array('CREATE', 'TEMPORARY', 'CONNECT', 'ALL PRIVILEGES'), - 'function' => array('EXECUTE', 'ALL PRIVILEGES'), - 'language' => array('USAGE', 'ALL PRIVILEGES'), - 'schema' => array('CREATE', 'USAGE', 'ALL PRIVILEGES'), - 'tablespace' => array('CREATE', 'ALL PRIVILEGES'), - 'column' => array('SELECT', 'INSERT', 'UPDATE', 'REFERENCES', 'ALL PRIVILEGES'), - ); + var $privlist = [ + 'table' => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'], + 'view' => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'], + 'sequence' => ['SELECT', 'UPDATE', 'ALL PRIVILEGES'], + 'database' => ['CREATE', 'TEMPORARY', 'CONNECT', 'ALL PRIVILEGES'], + 'function' => ['EXECUTE', 'ALL PRIVILEGES'], + 'language' => ['USAGE', 'ALL PRIVILEGES'], + 'schema' => ['CREATE', 'USAGE', 'ALL PRIVILEGES'], + 'tablespace' => ['CREATE', 'ALL PRIVILEGES'], + 'column' => ['SELECT', 'INSERT', 'UPDATE', 'REFERENCES', 'ALL PRIVILEGES'], + ]; // List of characters in acl lists and the privileges they // refer to. - var $privmap = array( + var $privmap = [ 'r' => 'SELECT', 'w' => 'UPDATE', 'a' => 'INSERT', @@ -131,35 +131,35 @@ class Postgres extends ADODB_base { 'C' => 'CREATE', 'T' => 'TEMPORARY', 'c' => 'CONNECT', - ); + ]; // Rule action types - var $rule_events = array('SELECT', 'INSERT', 'UPDATE', 'DELETE'); + var $rule_events = ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; // Select operators - var $selectOps = array('=' => 'i', '!=' => 'i', '<' => 'i', '>' => 'i', '<=' => 'i', '>=' => 'i', + var $selectOps = ['=' => 'i', '!=' => 'i', '<' => 'i', '>' => 'i', '<=' => 'i', '>=' => 'i', '<<' => 'i', '>>' => 'i', '<<=' => 'i', '>>=' => 'i', 'LIKE' => 'i', 'NOT LIKE' => 'i', 'ILIKE' => 'i', 'NOT ILIKE' => 'i', 'SIMILAR TO' => 'i', 'NOT SIMILAR TO' => 'i', '~' => 'i', '!~' => 'i', '~*' => 'i', '!~*' => 'i', 'IS NULL' => 'p', 'IS NOT NULL' => 'p', 'IN' => 'x', 'NOT IN' => 'x', '@@' => 'i', '@@@' => 'i', '@>' => 'i', '<@' => 'i', '@@ to_tsquery' => 't', '@@@ to_tsquery' => 't', '@> to_tsquery' => 't', '<@ to_tsquery' => 't', - '@@ plainto_tsquery' => 't', '@@@ plainto_tsquery' => 't', '@> plainto_tsquery' => 't', '<@ plainto_tsquery' => 't'); + '@@ plainto_tsquery' => 't', '@@@ plainto_tsquery' => 't', '@> plainto_tsquery' => 't', '<@ plainto_tsquery' => 't']; // Array of allowed trigger events - var $triggerEvents = array('INSERT', 'UPDATE', 'DELETE', 'INSERT OR UPDATE', 'INSERT OR DELETE', - 'DELETE OR UPDATE', 'INSERT OR DELETE OR UPDATE'); + var $triggerEvents = ['INSERT', 'UPDATE', 'DELETE', 'INSERT OR UPDATE', 'INSERT OR DELETE', + 'DELETE OR UPDATE', 'INSERT OR DELETE OR UPDATE']; // When to execute the trigger - var $triggerExecTimes = array('BEFORE', 'AFTER'); + var $triggerExecTimes = ['BEFORE', 'AFTER']; // How often to execute the trigger - var $triggerFrequency = array('ROW', 'STATEMENT'); + var $triggerFrequency = ['ROW', 'STATEMENT']; // Array of allowed type alignments - var $typAligns = array('char', 'int2', 'int4', 'double'); + var $typAligns = ['char', 'int2', 'int4', 'double']; // The default type alignment var $typAlignDef = 'int4'; // Default index type var $typIndexDef = 'BTREE'; // Array of allowed index types - var $typIndexes = array('BTREE', 'RTREE', 'GIST', 'GIN', 'HASH'); + var $typIndexes = ['BTREE', 'RTREE', 'GIST', 'GIN', 'HASH']; // Array of allowed type storage attributes - var $typStorages = array('plain', 'external', 'extended', 'main'); + var $typStorages = ['plain', 'external', 'extended', 'main']; // The default type storage var $typStorageDef = 'plain'; @@ -242,7 +242,7 @@ class Postgres extends ADODB_base { * @param $type The database type of the field * @param $extras An array of attributes name as key and attributes' values as value */ - function printField($name, $value, $type, $extras = array()) { + function printField($name, $value, $type, $extras = []) { global $lang; // Determine actions string @@ -252,57 +252,57 @@ class Postgres extends ADODB_base { } switch (substr($type, 0, 9)) { - case 'bool': - case 'boolean': - if ($value !== null && $value == '') { - $value = null; - } elseif ($value == 'true') { - $value = 't'; - } elseif ($value == 'false') { - $value = 'f'; - } - - // If value is null, 't' or 'f'... - if ($value === null || $value == 't' || $value == 'f') { - echo "<select name=\"", htmlspecialchars($name), "\"{$extra_str}>\n"; - echo "<option value=\"\"", ($value === null) ? ' selected="selected"' : '', "></option>\n"; - echo "<option value=\"t\"", ($value == 't') ? ' selected="selected"' : '', ">{$lang['strtrue']}</option>\n"; - echo "<option value=\"f\"", ($value == 'f') ? ' selected="selected"' : '', ">{$lang['strfalse']}</option>\n"; - echo "</select>\n"; - } else { + case 'bool': + case 'boolean': + if ($value !== null && $value == '') { + $value = null; + } elseif ($value == 'true') { + $value = 't'; + } elseif ($value == 'false') { + $value = 'f'; + } + + // If value is null, 't' or 'f'... + if ($value === null || $value == 't' || $value == 'f') { + echo "<select name=\"", htmlspecialchars($name), "\"{$extra_str}>\n"; + echo "<option value=\"\"", ($value === null) ? ' selected="selected"' : '', "></option>\n"; + echo "<option value=\"t\"", ($value == 't') ? ' selected="selected"' : '', ">{$lang['strtrue']}</option>\n"; + echo "<option value=\"f\"", ($value == 'f') ? ' selected="selected"' : '', ">{$lang['strfalse']}</option>\n"; + echo "</select>\n"; + } else { + echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$extra_str} />\n"; + } + break; + case 'bytea': + case 'bytea[]': + if (!is_null($value)) { + $value = $this->escapeBytea($value); + } + case 'text': + case 'text[]': + case 'json': + case 'jsonb': + case 'xml': + case 'xml[]': + $n = substr_count($value, "\n"); + $n = $n < 5 ? 5 : $n; + $n = $n > 20 ? 20 : $n; + echo "<textarea name=\"", htmlspecialchars($name), "\" rows=\"{$n}\" cols=\"75\"{$extra_str}>\n"; + echo htmlspecialchars($value); + echo "</textarea>\n"; + break; + case 'character': + case 'character[]': + $n = substr_count($value, "\n"); + $n = $n < 5 ? 5 : $n; + $n = $n > 20 ? 20 : $n; + echo "<textarea name=\"", htmlspecialchars($name), "\" rows=\"{$n}\" cols=\"35\"{$extra_str}>\n"; + echo htmlspecialchars($value); + echo "</textarea>\n"; + break; + default: echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$extra_str} />\n"; - } - break; - case 'bytea': - case 'bytea[]': - if (!is_null($value)) { - $value = $this->escapeBytea($value); - } - case 'text': - case 'text[]': - case 'json': - case 'jsonb': - case 'xml': - case 'xml[]': - $n = substr_count($value, "\n"); - $n = $n < 5 ? 5 : $n; - $n = $n > 20 ? 20 : $n; - echo "<textarea name=\"", htmlspecialchars($name), "\" rows=\"{$n}\" cols=\"75\"{$extra_str}>\n"; - echo htmlspecialchars($value); - echo "</textarea>\n"; - break; - case 'character': - case 'character[]': - $n = substr_count($value, "\n"); - $n = $n < 5 ? 5 : $n; - $n = $n > 20 ? 20 : $n; - echo "<textarea name=\"", htmlspecialchars($name), "\" rows=\"{$n}\" cols=\"35\"{$extra_str}>\n"; - echo htmlspecialchars($value); - echo "</textarea>\n"; - break; - default: - echo "<input name=\"", htmlspecialchars($name), "\" value=\"", htmlspecialchars($value), "\" size=\"35\"{$extra_str} />\n"; - break; + break; } } @@ -315,45 +315,45 @@ class Postgres extends ADODB_base { */ function formatValue($type, $format, $value) { switch ($type) { - case 'bool': - case 'boolean': - if ($value == 't') { - return 'TRUE'; - } elseif ($value == 'f') { - return 'FALSE'; - } elseif ($value == '') { - return 'NULL'; - } else { - return $value; - } - - break; - default: - // Checking variable fields is difficult as there might be a size - // attribute... - if (strpos($type, 'time') === 0) { - // Assume it's one of the time types... - if ($value == '') { - return "''"; - } elseif (strcasecmp($value, 'CURRENT_TIMESTAMP') == 0 - || strcasecmp($value, 'CURRENT_TIME') == 0 - || strcasecmp($value, 'CURRENT_DATE') == 0 - || strcasecmp($value, 'LOCALTIME') == 0 - || strcasecmp($value, 'LOCALTIMESTAMP') == 0) { - return $value; - } elseif ($format == 'EXPRESSION') { - return $value; + case 'bool': + case 'boolean': + if ($value == 't') { + return 'TRUE'; + } elseif ($value == 'f') { + return 'FALSE'; + } elseif ($value == '') { + return 'NULL'; } else { - $this->clean($value); - return "'{$value}'"; + return $value; } - } else { - if ($format == 'VALUE') { - $this->clean($value); - return "'{$value}'"; + + break; + default: + // Checking variable fields is difficult as there might be a size + // attribute... + if (strpos($type, 'time') === 0) { + // Assume it's one of the time types... + if ($value == '') { + return "''"; + } elseif (strcasecmp($value, 'CURRENT_TIMESTAMP') == 0 + || strcasecmp($value, 'CURRENT_TIME') == 0 + || strcasecmp($value, 'CURRENT_DATE') == 0 + || strcasecmp($value, 'LOCALTIME') == 0 + || strcasecmp($value, 'LOCALTIMESTAMP') == 0) { + return $value; + } elseif ($format == 'EXPRESSION') { + return $value; + } else { + $this->clean($value); + return "'{$value}'"; + } + } else { + if ($format == 'VALUE') { + $this->clean($value); + return "'{$value}'"; + } + return $value; } - return $value; - } } } @@ -371,12 +371,12 @@ class Postgres extends ADODB_base { $is_array = false; if (substr($typname, 0, 1) == '_') { $is_array = true; - $typname = substr($typname, 1); + $typname = substr($typname, 1); } // Show lengths on bpchar and varchar if ($typname == 'bpchar') { - $len = $typmod - $varhdrsz; + $len = $typmod - $varhdrsz; $temp = 'character'; if ($len > 1) { $temp .= "({$len})"; @@ -392,8 +392,8 @@ class Postgres extends ADODB_base { $temp = 'numeric'; if ($typmod != -1) { $tmp_typmod = $typmod - $varhdrsz; - $precision = ($tmp_typmod >> 16) & 0xffff; - $scale = $tmp_typmod & 0xffff; + $precision = ($tmp_typmod >> 16) & 0xffff; + $scale = $tmp_typmod & 0xffff; $temp .= "({$precision}, {$scale})"; } } else { @@ -418,7 +418,7 @@ class Postgres extends ADODB_base { if (isset($this->help_page[$help])) { if (is_array($this->help_page[$help])) { - $urls = array(); + $urls = []; foreach ($this->help_page[$help] as $link) { $urls[] = $this->help_base . $link; } @@ -735,10 +735,10 @@ class Postgres extends ADODB_base { if (!$conf['show_system']) { // XXX: The mention of information_schema here is in the wrong place, but // it's the quickest fix to exclude the info schema from 7.4 - $where = " AND pn.nspname NOT LIKE \$_PATERN_\$pg\_%\$_PATERN_\$ AND pn.nspname != 'information_schema'"; + $where = " AND pn.nspname NOT LIKE \$_PATERN_\$pg\_%\$_PATERN_\$ AND pn.nspname != 'information_schema'"; $lan_where = "AND pl.lanispl"; } else { - $where = ''; + $where = ''; $lan_where = ''; } @@ -948,7 +948,7 @@ class Postgres extends ADODB_base { } // Loop over all the paths to check that none are empty - $temp = array(); + $temp = []; foreach ($paths as $schema) { if ($schema != '') { $temp[] = $schema; @@ -1034,7 +1034,7 @@ class Postgres extends ADODB_base { $schema_rs = $this->getSchemaByName($schemaname); /* Only if the owner change */ if ($schema_rs->fields['ownername'] != $owner) { - $sql = "ALTER SCHEMA \"{$schemaname}\" OWNER TO \"{$owner}\""; + $sql = "ALTER SCHEMA \"{$schemaname}\" OWNER TO \"{$owner}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -1044,7 +1044,7 @@ class Postgres extends ADODB_base { // Only if the name has changed if ($name != $schemaname) { - $sql = "ALTER SCHEMA \"{$schemaname}\" RENAME TO \"{$name}\""; + $sql = "ALTER SCHEMA \"{$schemaname}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -1336,8 +1336,8 @@ class Postgres extends ADODB_base { // Output all table columns $col_comments_sql = ''; // Accumulate comments on columns - $num = $atts->recordCount() + $cons->recordCount(); - $i = 1; + $num = $atts->recordCount() + $cons->recordCount(); + $i = 1; while (!$atts->EOF) { $this->fieldClean($atts->fields['attname']); $sql .= " \"{$atts->fields['attname']}\""; @@ -1390,18 +1390,18 @@ class Postgres extends ADODB_base { $sql .= $cons->fields['consrc']; } else { switch ($cons->fields['contype']) { - case 'p': - $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); - $sql .= "PRIMARY KEY (" . join(',', $keys) . ")"; - break; - case 'u': - $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); - $sql .= "UNIQUE (" . join(',', $keys) . ")"; - break; - default: - // Unrecognised constraint - $this->rollbackTransaction(); - return null; + case 'p': + $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); + $sql .= "PRIMARY KEY (" . join(',', $keys) . ")"; + break; + case 'u': + $keys = $this->getAttributeNames($table, explode(' ', $cons->fields['indkey'])); + $sql .= "UNIQUE (" . join(',', $keys) . ")"; + break; + default: + // Unrecognised constraint + $this->rollbackTransaction(); + return null; } } @@ -1470,22 +1470,22 @@ class Postgres extends ADODB_base { // Then storage if ($atts->fields['attstorage'] != $atts->fields['typstorage']) { switch ($atts->fields['attstorage']) { - case 'p': - $storage = 'PLAIN'; - break; - case 'e': - $storage = 'EXTERNAL'; - break; - case 'm': - $storage = 'MAIN'; - break; - case 'x': - $storage = 'EXTENDED'; - break; - default: - // Unknown storage type - $this->rollbackTransaction(); - return null; + case 'p': + $storage = 'PLAIN'; + break; + case 'e': + $storage = 'EXTERNAL'; + break; + case 'm': + $storage = 'MAIN'; + break; + case 'x': + $storage = 'EXTENDED'; + break; + default: + // Unknown storage type + $this->rollbackTransaction(); + return null; } $sql .= "ALTER TABLE ONLY \"{$t->fields['nspname']}\".\"{$t->fields['relname']}\" ALTER COLUMN \"{$atts->fields['attname']}\" SET STORAGE {$storage};\n"; } @@ -1539,21 +1539,21 @@ class Postgres extends ADODB_base { // Output privileges with no GRANT OPTION $sql .= "GRANT " . join(', ', $nongrant) . " ON TABLE \"{$t->fields['relname']}\" TO "; switch ($v[0]) { - case 'public': - $sql .= "PUBLIC;\n"; - break; - case 'user': - $this->fieldClean($v[1]); - $sql .= "\"{$v[1]}\";\n"; - break; - case 'group': - $this->fieldClean($v[1]); - $sql .= "GROUP \"{$v[1]}\";\n"; - break; - default: - // Unknown privilege type - fail - $this->rollbackTransaction(); - return null; + case 'public': + $sql .= "PUBLIC;\n"; + break; + case 'user': + $this->fieldClean($v[1]); + $sql .= "\"{$v[1]}\";\n"; + break; + case 'group': + $this->fieldClean($v[1]); + $sql .= "GROUP \"{$v[1]}\";\n"; + break; + default: + // Unknown privilege type - fail + $this->rollbackTransaction(); + return null; } // Reset user if necessary @@ -1577,20 +1577,20 @@ class Postgres extends ADODB_base { $sql .= "GRANT " . join(', ', $v[4]) . " ON \"{$t->fields['relname']}\" TO "; switch ($v[0]) { - case 'public': - $sql .= "PUBLIC"; - break; - case 'user': - $this->fieldClean($v[1]); - $sql .= "\"{$v[1]}\""; - break; - case 'group': - $this->fieldClean($v[1]); - $sql .= "GROUP \"{$v[1]}\""; - break; - default: - // Unknown privilege type - fail - return null; + case 'public': + $sql .= "PUBLIC"; + break; + case 'user': + $this->fieldClean($v[1]); + $sql .= "\"{$v[1]}\""; + break; + case 'group': + $this->fieldClean($v[1]); + $sql .= "GROUP \"{$v[1]}\""; + break; + default: + // Unknown privilege type - fail + return null; } $sql .= " WITH GRANT OPTION;\n"; @@ -1702,10 +1702,10 @@ class Postgres extends ADODB_base { return -1; } - $found = false; - $first = true; + $found = false; + $first = true; $comment_sql = ''; //Accumulate comments for the columns - $sql = "CREATE TABLE \"{$f_schema}\".\"{$name}\" ("; + $sql = "CREATE TABLE \"{$f_schema}\".\"{$name}\" ("; for ($i = 0; $i < $fields; $i++) { $this->fieldClean($field[$i]); $this->clean($type[$i]); @@ -1725,33 +1725,33 @@ class Postgres extends ADODB_base { } switch ($type[$i]) { - // Have to account for weird placing of length for with/without - // time zone types - case 'timestamp with time zone': - case 'timestamp without time zone': - $qual = substr($type[$i], 9); - $sql .= "\"{$field[$i]}\" timestamp"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + // Have to account for weird placing of length for with/without + // time zone types + case 'timestamp with time zone': + case 'timestamp without time zone': + $qual = substr($type[$i], 9); + $sql .= "\"{$field[$i]}\" timestamp"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } - $sql .= $qual; - break; - case 'time with time zone': - case 'time without time zone': - $qual = substr($type[$i], 4); - $sql .= "\"{$field[$i]}\" time"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + $sql .= $qual; + break; + case 'time with time zone': + case 'time without time zone': + $qual = substr($type[$i], 4); + $sql .= "\"{$field[$i]}\" time"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } - $sql .= $qual; - break; - default: - $sql .= "\"{$field[$i]}\" {$type[$i]}"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + $sql .= $qual; + break; + default: + $sql .= "\"{$field[$i]}\" {$type[$i]}"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } } // Add array qualifier if necessary @@ -1786,7 +1786,7 @@ class Postgres extends ADODB_base { } // PRIMARY KEY - $primarykeycolumns = array(); + $primarykeycolumns = []; for ($i = 0; $i < $fields; $i++) { if (isset($primarykey[$i])) { $primarykeycolumns[] = "\"{$field[$i]}\""; @@ -1905,7 +1905,7 @@ class Postgres extends ADODB_base { $f_schema = $this->_schema; $this->fieldClean($f_schema); - $sql = "ALTER TABLE \"{$f_schema}\".\"{$tblrs->fields['relname']}\" RENAME TO \"{$name}\""; + $sql = "ALTER TABLE \"{$f_schema}\".\"{$tblrs->fields['relname']}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status == 0) { $tblrs->fields['relname'] = $name; @@ -2107,7 +2107,7 @@ class Postgres extends ADODB_base { } if (sizeof($atts) == 0) { - return array(); + return []; } $sql = "SELECT attnum, attname FROM pg_catalog.pg_attribute WHERE @@ -2119,7 +2119,7 @@ class Postgres extends ADODB_base { if ($rs->recordCount() != sizeof($atts)) { return -2; } else { - $temp = array(); + $temp = []; while (!$rs->EOF) { $temp[$rs->fields['attnum']] = $rs->fields['attname']; $rs->moveNext(); @@ -2185,20 +2185,20 @@ class Postgres extends ADODB_base { $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" {$type}"; } else { switch ($type) { - // Have to account for weird placing of length for with/without - // time zone types - case 'timestamp with time zone': - case 'timestamp without time zone': - $qual = substr($type, 9); - $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" timestamp({$length}){$qual}"; - break; - case 'time with time zone': - case 'time without time zone': - $qual = substr($type, 4); - $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" time({$length}){$qual}"; - break; - default: - $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" {$type}({$length})"; + // Have to account for weird placing of length for with/without + // time zone types + case 'timestamp with time zone': + case 'timestamp without time zone': + $qual = substr($type, 9); + $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" timestamp({$length}){$qual}"; + break; + case 'time with time zone': + case 'time without time zone': + $qual = substr($type, 4); + $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" time({$length}){$qual}"; + break; + default: + $sql = "ALTER TABLE \"{$f_schema}\".\"{$table}\" ADD COLUMN \"{$column}\" {$type}({$length})"; } } @@ -2285,7 +2285,7 @@ class Postgres extends ADODB_base { $this->fieldClean($table); $this->fieldClean($column); - $toAlter = array(); + $toAlter = []; // Create the command for changing nullability if ($notnull != $oldnotnull) { $toAlter[] = "ALTER COLUMN \"{$name}\" " . (($notnull) ? 'SET' : 'DROP') . " NOT NULL"; @@ -2305,20 +2305,20 @@ class Postgres extends ADODB_base { $ftype = $type; } else { switch ($type) { - // Have to account for weird placing of length for with/without - // time zone types - case 'timestamp with time zone': - case 'timestamp without time zone': - $qual = substr($type, 9); - $ftype = "timestamp({$length}){$qual}"; - break; - case 'time with time zone': - case 'time without time zone': - $qual = substr($type, 4); - $ftype = "time({$length}){$qual}"; - break; - default: - $ftype = "{$type}({$length})"; + // Have to account for weird placing of length for with/without + // time zone types + case 'timestamp with time zone': + case 'timestamp without time zone': + $qual = substr($type, 9); + $ftype = "timestamp({$length}){$qual}"; + break; + case 'time with time zone': + case 'time without time zone': + $qual = substr($type, 4); + $ftype = "time({$length}){$qual}"; + break; + default: + $ftype = "{$type}({$length})"; } } @@ -2460,7 +2460,7 @@ class Postgres extends ADODB_base { } // Set serializable - $sql = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"; + $sql = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -2468,7 +2468,7 @@ class Postgres extends ADODB_base { } // Set datestyle to ISO - $sql = "SET DATESTYLE = ISO"; + $sql = "SET DATESTYLE = ISO"; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -2476,7 +2476,7 @@ class Postgres extends ADODB_base { } // Set extra_float_digits to 2 - $sql = "SET extra_float_digits TO 2"; + $sql = "SET extra_float_digits TO 2"; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -2552,16 +2552,16 @@ class Postgres extends ADODB_base { $_autovacs = $this->selectSet($sql); /* result aray to return as RS */ - $autovacs = array(); + $autovacs = []; while (!$_autovacs->EOF) { - $_ = array( + $_ = [ 'nspname' => $_autovacs->fields['nspname'], 'relname' => $_autovacs->fields['relname'], - ); + ]; foreach (explode(',', $_autovacs->fields['reloptions']) as $var) { list($o, $v) = explode('=', $var); - $_[$o] = $v; + $_[$o] = $v; } $autovacs[] = $_; @@ -2610,9 +2610,9 @@ class Postgres extends ADODB_base { // functions check that they're only modiying a single row. Otherwise, return empty array. if ($rs->recordCount() == 0) { // Check for OID column - $temp = array(); + $temp = []; if ($this->hasObjectID($table)) { - $temp = array('oid'); + $temp = ['oid']; } $this->endTransaction(); return $temp; @@ -2652,7 +2652,7 @@ class Postgres extends ADODB_base { // Build clause if (count($values) > 0) { // Escape all field names - $fields = array_map(array('Postgres', 'fieldClean'), $fields); + $fields = array_map(['\PHPPgAdmin\Database\Postgres', 'fieldClean'], $fields); $f_schema = $this->_schema; $this->fieldClean($table); $this->fieldClean($f_schema); @@ -2985,7 +2985,7 @@ class Postgres extends ADODB_base { if (!empty($name) && ($seqrs->fields['seqname'] != $name)) { $f_schema = $this->_schema; $this->fieldClean($f_schema); - $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" RENAME TO \"{$name}\""; + $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status == 0) { $seqrs->fields['seqname'] = $name; @@ -3336,7 +3336,7 @@ class Postgres extends ADODB_base { if (!empty($name) && ($name != $vwrs->fields['relname'])) { $f_schema = $this->_schema; $this->fieldClean($f_schema); - $sql = "ALTER VIEW \"{$f_schema}\".\"{$vwrs->fields['relname']}\" RENAME TO \"{$name}\""; + $sql = "ALTER VIEW \"{$f_schema}\".\"{$vwrs->fields['relname']}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status == 0) { $vwrs->fields['relname'] = $name; @@ -3625,23 +3625,23 @@ class Postgres extends ADODB_base { $this->fieldClean($f_schema); $this->fieldClean($name); switch ($type) { - case 'DATABASE': - $sql = "REINDEX {$type} \"{$name}\""; - if ($force) { - $sql .= ' FORCE'; - } + case 'DATABASE': + $sql = "REINDEX {$type} \"{$name}\""; + if ($force) { + $sql .= ' FORCE'; + } - break; - case 'TABLE': - case 'INDEX': - $sql = "REINDEX {$type} \"{$f_schema}\".\"{$name}\""; - if ($force) { - $sql .= ' FORCE'; - } + break; + case 'TABLE': + case 'INDEX': + $sql = "REINDEX {$type} \"{$f_schema}\".\"{$name}\""; + if ($force) { + $sql .= ' FORCE'; + } - break; - default: - return -1; + break; + default: + return -1; } return $this->execute($sql); @@ -3904,7 +3904,7 @@ class Postgres extends ADODB_base { } // Properly lock the table - $sql = "LOCK TABLE \"{$f_schema}\".\"{$table}\" IN ACCESS EXCLUSIVE MODE"; + $sql = "LOCK TABLE \"{$f_schema}\".\"{$table}\" IN ACCESS EXCLUSIVE MODE"; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -4035,8 +4035,8 @@ class Postgres extends ADODB_base { $this->clean($tables[0]['tablename']); $this->clean($tables[0]['schemaname']); - $tables_list = "'{$tables[0]['tablename']}'"; - $schema_list = "'{$tables[0]['schemaname']}'"; + $tables_list = "'{$tables[0]['tablename']}'"; + $schema_list = "'{$tables[0]['schemaname']}'"; $schema_tables_list = "'{$tables[0]['schemaname']}.{$tables[0]['tablename']}'"; for ($i = 1; $i < sizeof($tables); $i++) { @@ -4065,7 +4065,7 @@ class Postgres extends ADODB_base { //parse our output to find the highest dimension of foreign keys since pc.conkey is stored in an array $rs = $this->selectSet($sql); while (!$rs->EOF) { - $arrData = explode(':', $rs->fields['arr_dim']); + $arrData = explode(':', $rs->fields['arr_dim']); $tmpDimension = intval(substr($arrData[1], 0, strlen($arrData[1] - 1))); $maxDimension = $tmpDimension > $maxDimension ? $tmpDimension : $maxDimension; $rs->MoveNext(); @@ -4258,20 +4258,20 @@ class Postgres extends ADODB_base { $sql .= $type; } else { switch ($type) { - // Have to account for weird placing of length for with/without - // time zone types - case 'timestamp with time zone': - case 'timestamp without time zone': - $qual = substr($type, 9); - $sql .= "timestamp({$length}){$qual}"; - break; - case 'time with time zone': - case 'time without time zone': - $qual = substr($type, 4); - $sql .= "time({$length}){$qual}"; - break; - default: - $sql .= "{$type}({$length})"; + // Have to account for weird placing of length for with/without + // time zone types + case 'timestamp with time zone': + case 'timestamp without time zone': + $qual = substr($type, 9); + $sql .= "timestamp({$length}){$qual}"; + break; + case 'time with time zone': + case 'time without time zone': + $qual = substr($type, 4); + $sql .= "time({$length}){$qual}"; + break; + default: + $sql .= "{$type}({$length})"; } } @@ -4465,7 +4465,7 @@ class Postgres extends ADODB_base { */ function getFunctions($all = false, $type = null) { if ($all) { - $where = 'pg_catalog.pg_function_is_visible(p.oid)'; + $where = 'pg_catalog.pg_function_is_visible(p.oid)'; $distinct = 'DISTINCT ON (p.proname)'; if ($type) { @@ -4474,7 +4474,7 @@ class Postgres extends ADODB_base { } else { $c_schema = $this->_schema; $this->clean($c_schema); - $where = "n.nspname = '{$c_schema}'"; + $where = "n.nspname = '{$c_schema}'"; $distinct = ''; } @@ -4509,7 +4509,7 @@ class Postgres extends ADODB_base { * @return An array containing the properties */ function getFunctionProperties($f) { - $temp = array(); + $temp = []; // Volatility if ($f['provolatile'] == 'v') { @@ -4583,7 +4583,7 @@ class Postgres extends ADODB_base { $this->fieldClean($newname); /* $funcname is escaped in createFunction */ if ($funcname != $newname) { - $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) RENAME TO \"{$newname}\""; + $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) RENAME TO \"{$newname}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -4597,7 +4597,7 @@ class Postgres extends ADODB_base { if ($this->hasFunctionAlterOwner()) { $this->fieldClean($newown); if ($funcown != $newown) { - $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) OWNER TO \"{$newown}\""; + $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) OWNER TO \"{$newown}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -4612,7 +4612,7 @@ class Postgres extends ADODB_base { $this->fieldClean($newschema); /* $funcschema is escaped in createFunction */ if ($funcschema != $newschema) { - $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) SET SCHEMA \"{$newschema}\""; + $sql = "ALTER FUNCTION \"{$f_schema}\".\"{$funcname}\"({$args}) SET SCHEMA \"{$newschema}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -4735,7 +4735,7 @@ class Postgres extends ADODB_base { */ function dropFunction($function_oid, $cascade) { // Function comes in with $object as function OID - $fn = $this->getFunction($function_oid); + $fn = $this->getFunction($function_oid); $f_schema = $this->_schema; $this->fieldClean($f_schema); $this->fieldClean($fn->fields['proname']); @@ -4966,10 +4966,10 @@ class Postgres extends ADODB_base { return -1; } - $found = false; - $first = true; + $found = false; + $first = true; $comment_sql = ''; // Accumulate comments for the columns - $sql = "CREATE TYPE \"{$f_schema}\".\"{$name}\" AS ("; + $sql = "CREATE TYPE \"{$f_schema}\".\"{$name}\" AS ("; for ($i = 0; $i < $fields; $i++) { $this->fieldClean($field[$i]); $this->clean($type[$i]); @@ -4989,33 +4989,33 @@ class Postgres extends ADODB_base { } switch ($type[$i]) { - // Have to account for weird placing of length for with/without - // time zone types - case 'timestamp with time zone': - case 'timestamp without time zone': - $qual = substr($type[$i], 9); - $sql .= "\"{$field[$i]}\" timestamp"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + // Have to account for weird placing of length for with/without + // time zone types + case 'timestamp with time zone': + case 'timestamp without time zone': + $qual = substr($type[$i], 9); + $sql .= "\"{$field[$i]}\" timestamp"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } - $sql .= $qual; - break; - case 'time with time zone': - case 'time without time zone': - $qual = substr($type[$i], 4); - $sql .= "\"{$field[$i]}\" time"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + $sql .= $qual; + break; + case 'time with time zone': + case 'time without time zone': + $qual = substr($type[$i], 4); + $sql .= "\"{$field[$i]}\" time"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } - $sql .= $qual; - break; - default: - $sql .= "\"{$field[$i]}\" {$type[$i]}"; - if ($length[$i] != '') { - $sql .= "({$length[$i]})"; - } + $sql .= $qual; + break; + default: + $sql .= "\"{$field[$i]}\" {$type[$i]}"; + if ($length[$i] != '') { + $sql .= "({$length[$i]})"; + } } // Add array qualifier if necessary @@ -5317,7 +5317,7 @@ class Postgres extends ADODB_base { } $trigger['tgisconstraint'] = $this->phpBool($trigger['tgisconstraint']); - $trigger['tgdeferrable'] = $this->phpBool($trigger['tgdeferrable']); + $trigger['tgdeferrable'] = $this->phpBool($trigger['tgdeferrable']); $trigger['tginitdeferred'] = $this->phpBool($trigger['tginitdeferred']); // Constraint trigger or normal trigger @@ -5584,7 +5584,7 @@ class Postgres extends ADODB_base { */ function dropOperator($operator_oid, $cascade) { // Function comes in with $object as operator OID - $opr = $this->getOperator($operator_oid); + $opr = $this->getOperator($operator_oid); $f_schema = $this->_schema; $this->fieldClean($f_schema); $this->fieldClean($opr->fields['oprname']); @@ -5947,7 +5947,7 @@ class Postgres extends ADODB_base { $this->fieldClean($f_schema); $this->fieldClean($name); - $sql = "ALTER TEXT SEARCH CONFIGURATION \"{$f_schema}\".\"{$cfgname}\" RENAME TO \"{$name}\""; + $sql = "ALTER TEXT SEARCH CONFIGURATION \"{$f_schema}\".\"{$cfgname}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -6069,7 +6069,7 @@ class Postgres extends ADODB_base { $this->fieldClean($f_schema); $this->fieldClean($name); - $sql = "ALTER TEXT SEARCH DICTIONARY \"{$f_schema}\".\"{$dictname}\" RENAME TO \"{$name}\""; + $sql = "ALTER TEXT SEARCH DICTIONARY \"{$f_schema}\".\"{$dictname}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -6130,15 +6130,15 @@ class Postgres extends ADODB_base { $this->arrayClean($mapping); switch ($action) { - case 'alter': - $whatToDo = "ALTER"; - break; - case 'drop': - $whatToDo = "DROP"; - break; - default: - $whatToDo = "ADD"; - break; + case 'alter': + $whatToDo = "ALTER"; + break; + case 'drop': + $whatToDo = "DROP"; + break; + default: + $whatToDo = "ADD"; + break; } $sql = "ALTER TEXT SEARCH CONFIGURATION \"{$f_schema}\".\"{$ftscfg}\" {$whatToDo} MAPPING FOR "; @@ -6172,7 +6172,7 @@ class Postgres extends ADODB_base { WHERE c.cfgname = '{$ftscfg}' AND n.nspname='{$c_schema}'"); - $oid = $oidSet->fields['oid']; + $oid = $oidSet->fields['oid']; $cfgparser = $oidSet->fields['cfgparser']; $tokenIdSet = $this->selectSet("SELECT tokid @@ -7167,8 +7167,8 @@ class Postgres extends ADODB_base { // Pick out individual ACE's by carefully parsing. This is necessary in order // to cope with usernames and stuff that contain commas - $aces = array(); - $i = $j = 0; + $aces = []; + $i = $j = 0; $in_quotes = false; while ($i < strlen($acl)) { // If current char is a double quote and it's not escaped, then @@ -7179,7 +7179,7 @@ class Postgres extends ADODB_base { } elseif ($char == ',' && !$in_quotes) { // Add text so far to the array $aces[] = substr($acl, $j, $i - $j); - $j = $i + 1; + $j = $i + 1; } $i++; } @@ -7187,7 +7187,7 @@ class Postgres extends ADODB_base { $aces[] = substr($acl, $j); // Create the array to be returned - $temp = array(); + $temp = []; // For each ACE, generate an entry in $temp foreach ($aces as $v) { @@ -7215,14 +7215,14 @@ class Postgres extends ADODB_base { } // Break on unquoted equals sign... - $i = 0; + $i = 0; $in_quotes = false; - $entity = null; - $chars = null; + $entity = null; + $chars = null; while ($i < strlen($v)) { // If current char is a double quote and it's not escaped, then // enter quoted bit - $char = substr($v, $i, 1); + $char = substr($v, $i, 1); $next_char = substr($v, $i + 1, 1); if ($char == '"' && ($i == 0 || $next_char != '"')) { $in_quotes = !$in_quotes; @@ -7233,7 +7233,7 @@ class Postgres extends ADODB_base { } elseif ($char == '=' && !$in_quotes) { // Split on current equals sign $entity = substr($v, 0, $i); - $chars = substr($v, $i + 1); + $chars = substr($v, $i + 1); break; } $i++; @@ -7247,7 +7247,7 @@ class Postgres extends ADODB_base { // New row to be added to $temp // (type, grantee, privileges, grantor, grant option? - $row = array($atype, $entity, array(), '', array()); + $row = [$atype, $entity, [], '', []]; // Loop over chars and add privs to $row for ($i = 0; $i < strlen($chars); $i++) { @@ -7299,9 +7299,9 @@ class Postgres extends ADODB_base { $this->clean($object); switch ($type) { - case 'column': - $this->clean($table); - $sql = " + case 'column': + $this->clean($table); + $sql = " SELECT E'{' || pg_catalog.array_to_string(attacl, E',') || E'}' as acl FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_class c ON (a.attrelid = c.oid) @@ -7309,35 +7309,35 @@ class Postgres extends ADODB_base { WHERE n.nspname='{$c_schema}' AND c.relname='{$table}' AND a.attname='{$object}'"; - break; - case 'table': - case 'view': - case 'sequence': - $sql = " + break; + case 'table': + case 'view': + case 'sequence': + $sql = " SELECT relacl AS acl FROM pg_catalog.pg_class WHERE relname='{$object}' AND relnamespace=(SELECT oid FROM pg_catalog.pg_namespace WHERE nspname='{$c_schema}')"; - break; - case 'database': - $sql = "SELECT datacl AS acl FROM pg_catalog.pg_database WHERE datname='{$object}'"; - break; - case 'function': - // Since we fetch functions by oid, they are already constrained to - // the current schema. - $sql = "SELECT proacl AS acl FROM pg_catalog.pg_proc WHERE oid='{$object}'"; - break; - case 'language': - $sql = "SELECT lanacl AS acl FROM pg_catalog.pg_language WHERE lanname='{$object}'"; - break; - case 'schema': - $sql = "SELECT nspacl AS acl FROM pg_catalog.pg_namespace WHERE nspname='{$object}'"; - break; - case 'tablespace': - $sql = "SELECT spcacl AS acl FROM pg_catalog.pg_tablespace WHERE spcname='{$object}'"; - break; - default: - return -1; + break; + case 'database': + $sql = "SELECT datacl AS acl FROM pg_catalog.pg_database WHERE datname='{$object}'"; + break; + case 'function': + // Since we fetch functions by oid, they are already constrained to + // the current schema. + $sql = "SELECT proacl AS acl FROM pg_catalog.pg_proc WHERE oid='{$object}'"; + break; + case 'language': + $sql = "SELECT lanacl AS acl FROM pg_catalog.pg_language WHERE lanname='{$object}'"; + break; + case 'schema': + $sql = "SELECT nspacl AS acl FROM pg_catalog.pg_namespace WHERE nspname='{$object}'"; + break; + case 'tablespace': + $sql = "SELECT spcacl AS acl FROM pg_catalog.pg_tablespace WHERE spcname='{$object}'"; + break; + default: + return -1; } // Fetch the ACL for object @@ -7345,7 +7345,7 @@ class Postgres extends ADODB_base { if ($acl == -1) { return -2; } elseif ($acl == '' || $acl == null) { - return array(); + return []; } else { return $this->_parseACL($acl); } @@ -7412,39 +7412,39 @@ class Postgres extends ADODB_base { } switch ($type) { - case 'column': - $sql .= " (\"{$object}\")"; - $object = $table; - case 'table': - case 'view': - case 'sequence': - $this->fieldClean($object); - $sql .= " ON \"{$f_schema}\".\"{$object}\""; - break; - case 'database': - $this->fieldClean($object); - $sql .= " ON DATABASE \"{$object}\""; - break; - case 'function': - // Function comes in with $object as function OID - $fn = $this->getFunction($object); - $this->fieldClean($fn->fields['proname']); - $sql .= " ON FUNCTION \"{$f_schema}\".\"{$fn->fields['proname']}\"({$fn->fields['proarguments']})"; - break; - case 'language': - $this->fieldClean($object); - $sql .= " ON LANGUAGE \"{$object}\""; - break; - case 'schema': - $this->fieldClean($object); - $sql .= " ON SCHEMA \"{$object}\""; - break; - case 'tablespace': - $this->fieldClean($object); - $sql .= " ON TABLESPACE \"{$object}\""; - break; - default: - return -1; + case 'column': + $sql .= " (\"{$object}\")"; + $object = $table; + case 'table': + case 'view': + case 'sequence': + $this->fieldClean($object); + $sql .= " ON \"{$f_schema}\".\"{$object}\""; + break; + case 'database': + $this->fieldClean($object); + $sql .= " ON DATABASE \"{$object}\""; + break; + case 'function': + // Function comes in with $object as function OID + $fn = $this->getFunction($object); + $this->fieldClean($fn->fields['proname']); + $sql .= " ON FUNCTION \"{$f_schema}\".\"{$fn->fields['proname']}\"({$fn->fields['proarguments']})"; + break; + case 'language': + $this->fieldClean($object); + $sql .= " ON LANGUAGE \"{$object}\""; + break; + case 'schema': + $this->fieldClean($object); + $sql .= " ON SCHEMA \"{$object}\""; + break; + case 'tablespace': + $this->fieldClean($object); + $sql .= " ON TABLESPACE \"{$object}\""; + break; + default: + return -1; } // Dump PUBLIC @@ -7591,7 +7591,7 @@ class Postgres extends ADODB_base { } // Owner - $sql = "ALTER TABLESPACE \"{$spcname}\" OWNER TO \"{$owner}\""; + $sql = "ALTER TABLESPACE \"{$spcname}\" OWNER TO \"{$owner}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -7600,7 +7600,7 @@ class Postgres extends ADODB_base { // Rename (only if name has changed) if ($name != $spcname) { - $sql = "ALTER TABLESPACE \"{$spcname}\" RENAME TO \"{$name}\""; + $sql = "ALTER TABLESPACE \"{$spcname}\" RENAME TO \"{$name}\""; $status = $this->execute($sql); if ($status != 0) { $this->rollbackTransaction(); @@ -7708,7 +7708,7 @@ class Postgres extends ADODB_base { " ); - $ret = array(); + $ret = []; while (!$_defaults->EOF) { $ret[$_defaults->fields['name']] = $_defaults->fields['setting']; $_defaults->moveNext(); @@ -7874,7 +7874,7 @@ class Postgres extends ADODB_base { * @return 0 success */ function setComment($obj_type, $obj_name, $table, $comment, $basetype = NULL) { - $sql = "COMMENT ON {$obj_type} "; + $sql = "COMMENT ON {$obj_type} "; $f_schema = $this->_schema; $this->fieldClean($f_schema); $this->clean($comment); // Passing in an already cleaned comment will lead to double escaped data @@ -7886,35 +7886,35 @@ class Postgres extends ADODB_base { */ switch ($obj_type) { - case 'TABLE': - $sql .= "\"{$f_schema}\".\"{$table}\" IS "; - break; - case 'COLUMN': - $sql .= "\"{$f_schema}\".\"{$table}\".\"{$obj_name}\" IS "; - break; - case 'SEQUENCE': - case 'VIEW': - case 'TEXT SEARCH CONFIGURATION': - case 'TEXT SEARCH DICTIONARY': - case 'TEXT SEARCH TEMPLATE': - case 'TEXT SEARCH PARSER': - case 'TYPE': - $sql .= "\"{$f_schema}\"."; - case 'DATABASE': - case 'ROLE': - case 'SCHEMA': - case 'TABLESPACE': - $sql .= "\"{$obj_name}\" IS "; - break; - case 'FUNCTION': - $sql .= "\"{$f_schema}\".{$obj_name} IS "; - break; - case 'AGGREGATE': - $sql .= "\"{$f_schema}\".\"{$obj_name}\" (\"{$basetype}\") IS "; - break; - default: - // Unknown object type - return -1; + case 'TABLE': + $sql .= "\"{$f_schema}\".\"{$table}\" IS "; + break; + case 'COLUMN': + $sql .= "\"{$f_schema}\".\"{$table}\".\"{$obj_name}\" IS "; + break; + case 'SEQUENCE': + case 'VIEW': + case 'TEXT SEARCH CONFIGURATION': + case 'TEXT SEARCH DICTIONARY': + case 'TEXT SEARCH TEMPLATE': + case 'TEXT SEARCH PARSER': + case 'TYPE': + $sql .= "\"{$f_schema}\"."; + case 'DATABASE': + case 'ROLE': + case 'SCHEMA': + case 'TABLESPACE': + $sql .= "\"{$obj_name}\" IS "; + break; + case 'FUNCTION': + $sql .= "\"{$f_schema}\".{$obj_name} IS "; + break; + case 'AGGREGATE': + $sql .= "\"{$f_schema}\".\"{$obj_name}\" (\"{$basetype}\") IS "; + break; + default: + // Unknown object type + return -1; } if ($comment != '') { @@ -7980,18 +7980,18 @@ class Postgres extends ADODB_base { } // Build up each SQL statement, they can be multiline - $query_buf = null; - $query_start = 0; - $in_quote = 0; - $in_xcomment = 0; + $query_buf = null; + $query_start = 0; + $in_quote = 0; + $in_xcomment = 0; $bslash_count = 0; - $dol_quote = null; - $paren_level = 0; - $len = 0; - $i = 0; - $prevlen = 0; - $thislen = 0; - $lineno = 0; + $dol_quote = null; + $paren_level = 0; + $len = 0; + $i = 0; + $prevlen = 0; + $thislen = 0; + $lineno = 0; // Loop over each line in the file while (!feof($fd)) { @@ -8003,7 +8003,7 @@ class Postgres extends ADODB_base { continue; } - $len = strlen($line); + $len = strlen($line); $query_start = 0; /* @@ -8081,7 +8081,7 @@ class Postgres extends ADODB_base { * start of $foo$ type quote? */ else if (!$dol_quote && $this->valid_dolquote(substr($line, $i))) { - $dol_end = strpos(substr($line, $i + 1), '$'); + $dol_end = strpos(substr($line, $i + 1), '$'); $dol_quote = substr($line, $i, $dol_end + 1); $this->advance_1($i, $prevlen, $thislen); while (substr($line, $i, 1) != '$') { @@ -8144,7 +8144,7 @@ class Postgres extends ADODB_base { } } - $query_buf = null; + $query_buf = null; $query_start = $i + $thislen; } @@ -8225,7 +8225,7 @@ class Postgres extends ADODB_base { * mapped to sort direction (asc or desc or '' or null) to order by * @return The SQL query */ - function getSelectSQL($table, $show, $values, $ops, $orderby = array()) { + function getSelectSQL($table, $show, $values, $ops, $orderby = []) { $this->fieldArrayClean($show); // If an empty array is passed in, then show all columns @@ -8270,24 +8270,24 @@ class Postgres extends ADODB_base { } // Different query format depending on operator type switch ($this->selectOps[$ops[$k]]) { - case 'i': - // Only clean the field for the inline case - // this is because (x), subqueries need to - // to allow 'a','b' as input. - $this->clean($v); - $sql .= "\"{$k}\" {$ops[$k]} '{$v}'"; - break; - case 'p': - $sql .= "\"{$k}\" {$ops[$k]}"; - break; - case 'x': - $sql .= "\"{$k}\" {$ops[$k]} ({$v})"; - break; - case 't': - $sql .= "\"{$k}\" {$ops[$k]}('{$v}')"; - break; - default: - // Shouldn't happen + case 'i': + // Only clean the field for the inline case + // this is because (x), subqueries need to + // to allow 'a','b' as input. + $this->clean($v); + $sql .= "\"{$k}\" {$ops[$k]} '{$v}'"; + break; + case 'p': + $sql .= "\"{$k}\" {$ops[$k]}"; + break; + case 'x': + $sql .= "\"{$k}\" {$ops[$k]} ({$v})"; + break; + case 't': + $sql .= "\"{$k}\" {$ops[$k]}('{$v}')"; + break; + default: + // Shouldn't happen } } } @@ -8346,27 +8346,27 @@ class Postgres extends ADODB_base { // If $type is TABLE, then generate the query switch ($type) { - case 'TABLE': - if (preg_match('/^[0-9]+$/', $sortkey) && $sortkey > 0) { - $orderby = array($sortkey => $sortdir); - } else { - $orderby = array(); - } + case 'TABLE': + if (preg_match('/^[0-9]+$/', $sortkey) && $sortkey > 0) { + $orderby = [$sortkey => $sortdir]; + } else { + $orderby = []; + } - $query = $this->getSelectSQL($table, array(), array(), array(), $orderby); - break; - case 'QUERY': - case 'SELECT': - // Trim query - $query = trim($query); - // Trim off trailing semi-colon if there is one - if (substr($query, strlen($query) - 1, 1) == ';') { - $query = substr($query, 0, strlen($query) - 1); - } + $query = $this->getSelectSQL($table, [], [], [], $orderby); + break; + case 'QUERY': + case 'SELECT': + // Trim query + $query = trim($query); + // Trim off trailing semi-colon if there is one + if (substr($query, strlen($query) - 1, 1) == ';') { + $query = substr($query, 0, strlen($query) - 1); + } - break; - default: - return -4; + break; + default: + return -4; } // Generate count query @@ -8427,7 +8427,7 @@ class Postgres extends ADODB_base { } // Actually retrieve the rows, with offset and limit - $rs = $this->selectSet("SELECT * FROM ({$query}) AS sub {$orderby} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); + $rs = $this->selectSet("SELECT * FROM ({$query}) AS sub {$orderby} LIMIT {$page_size} OFFSET " . ($page - 1) * $page_size); $status = $this->endTransaction(); if ($status != 0) { $this->rollbackTransaction(); diff --git a/src/controllers/AdminTrait.php b/src/controllers/AdminTrait.php new file mode 100644 index 00000000..b9cbf1b0 --- /dev/null +++ b/src/controllers/AdminTrait.php @@ -0,0 +1,845 @@ +<?php +namespace PHPPgAdmin\Controller; + +trait AdminTrait { + +/** + * Show confirmation of cluster and perform cluster + */ + public function doCluster($type, $confirm = false) { + + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + + $script = $this->script; + $misc = $this->misc; + $lang = $this->lang; + $data = $this->getDatabaseAccessor(); + + if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifytabletocluster']); + return; + } + + if ($confirm) { + if (isset($_REQUEST['ma'])) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfclustertable'], $misc->printVal($a['table'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; + } + } // END if multi cluster + else { + $misc->printTrail($type); + $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + + if ($type == 'table') { + echo "<p>", sprintf($lang['strconfclustertable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + } else { + echo "<p>", sprintf($lang['strconfclusterdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; + } + } + echo "<input type=\"hidden\" name=\"action\" value=\"cluster\" />\n"; + + echo $misc->form; + + echo "<input type=\"submit\" name=\"cluster\" value=\"{$lang['strcluster']}\" />\n"; //TODO + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END single cluster + else { + //If multi table cluster + if ($type == 'table') { + // cluster one or more table + if (is_array($_REQUEST['table'])) { + $msg = ''; + foreach ($_REQUEST['table'] as $o) { + $status = $data->clusterIndex($o); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strclusteredgood']); + } else { + $this->doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strclusteredbad'])); + return; + } + } + // Everything went fine, back to the Default page.... + $this->doDefault($msg); + } else { + $status = $data->clusterIndex($_REQUEST['object']); + if ($status == 0) { + $this->doAdmin($type, $lang['strclusteredgood']); + } else { + $this->doAdmin($type, $lang['strclusteredbad']); + } + + } + } else { + // Cluster all tables in database + $status = $data->clusterIndex(); + if ($status == 0) { + $this->doAdmin($type, $lang['strclusteredgood']); + } else { + $this->doAdmin($type, $lang['strclusteredbad']); + } + + } + } + } + +/** + * Show confirmation of reindex and perform reindex + */ + public function doReindex($type, $confirm = false) { + + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + $script = $this->script; + $misc = $this->misc; + $lang = $this->lang; + $data = $this->getDatabaseAccessor(); + + if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifytabletoreindex']); + return; + } + + if ($confirm) { + if (isset($_REQUEST['ma'])) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strreindex'], 'pg.reindex'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfreindextable'], $misc->printVal($a['table'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; + } + } // END if multi reindex + else { + $misc->printTrail($type); + $misc->printTitle($lang['strreindex'], 'pg.reindex'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + + if ($type == 'table') { + echo "<p>", sprintf($lang['strconfreindextable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + } else { + echo "<p>", sprintf($lang['strconfreindexdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; + } + } + echo "<input type=\"hidden\" name=\"action\" value=\"reindex\" />\n"; + + if ($data->hasForceReindex()) { + echo "<p><input type=\"checkbox\" id=\"reindex_force\" name=\"reindex_force\" /><label for=\"reindex_force\">{$lang['strforce']}</label></p>\n"; + } + + echo $misc->form; + + echo "<input type=\"submit\" name=\"reindex\" value=\"{$lang['strreindex']}\" />\n"; //TODO + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END single reindex + else { + //If multi table reindex + if (($type == 'table') && is_array($_REQUEST['table'])) { + $msg = ''; + foreach ($_REQUEST['table'] as $o) { + $status = $data->reindex(strtoupper($type), $o, isset($_REQUEST['reindex_force'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strreindexgood']); + } else { + $this->doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strreindexbad'])); + return; + } + } + // Everything went fine, back to the Default page.... + $misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + $status = $data->reindex(strtoupper($type), $_REQUEST['object'], isset($_REQUEST['reindex_force'])); + if ($status == 0) { + $misc->setReloadBrowser(true); + $this->doAdmin($type, $lang['strreindexgood']); + } else { + $this->doAdmin($type, $lang['strreindexbad']); + } + + } + } + } + +/** + * Show confirmation of analyze and perform analyze + */ + public function doAnalyze($type, $confirm = false) { + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + $script = $this->script; + $data = $this->data; + $misc = $this->misc; + $lang = $this->lang; + + if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifytabletoanalyze']); + return; + } + + if ($confirm) { + if (isset($_REQUEST['ma'])) { + $misc->printTrail('schema'); + $misc->printTitle($lang['stranalyze'], 'pg.analyze'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfanalyzetable'], $misc->printVal($a['table'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; + } + } // END if multi analyze + else { + $misc->printTrail($type); + $misc->printTitle($lang['stranalyze'], 'pg.analyze'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + + if ($type == 'table') { + echo "<p>", sprintf($lang['strconfanalyzetable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + } else { + echo "<p>", sprintf($lang['strconfanalyzedatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; + } + } + echo "<input type=\"hidden\" name=\"action\" value=\"analyze\" />\n"; + echo $misc->form; + + echo "<input type=\"submit\" name=\"analyze\" value=\"{$lang['stranalyze']}\" />\n"; //TODO + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END single analyze + else { + //If multi table analyze + if (($type == 'table') && is_array($_REQUEST['table'])) { + $msg = ''; + foreach ($_REQUEST['table'] as $o) { + $status = $data->analyzeDB($o); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['stranalyzegood']); + } else { + $this->doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['stranalyzebad'])); + return; + } + } + // Everything went fine, back to the Default page.... + $misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + //we must pass table here. When empty, analyze the whole db + $status = $data->analyzeDB($_REQUEST['table']); + if ($status == 0) { + $misc->setReloadBrowser(true); + $this->doAdmin($type, $lang['stranalyzegood']); + } else { + $this->doAdmin($type, $lang['stranalyzebad']); + } + + } + } + } + +/** + * Show confirmation of vacuum and perform actual vacuum + */ + public function doVacuum($type, $confirm = false) { + + $script = ($type == 'database') ? 'database.php' : 'tables.php'; + + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifytabletovacuum']); + return; + } + + if ($confirm) { + if (isset($_REQUEST['ma'])) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strvacuum'], 'pg.vacuum'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfvacuumtable'], $misc->printVal($a['table'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; + } + } else { + // END if multi vacuum + $misc->printTrail($type); + $misc->printTitle($lang['strvacuum'], 'pg.vacuum'); + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + + if ($type == 'table') { + echo "<p>", sprintf($lang['strconfvacuumtable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + } else { + echo "<p>", sprintf($lang['strconfvacuumdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; + } + } + echo "<input type=\"hidden\" name=\"action\" value=\"vacuum\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"vacuum_full\" name=\"vacuum_full\" /> <label for=\"vacuum_full\">{$lang['strfull']}</label></p>\n"; + echo "<p><input type=\"checkbox\" id=\"vacuum_analyze\" name=\"vacuum_analyze\" /> <label for=\"vacuum_analyze\">{$lang['stranalyze']}</label></p>\n"; + echo "<p><input type=\"checkbox\" id=\"vacuum_freeze\" name=\"vacuum_freeze\" /> <label for=\"vacuum_freeze\">{$lang['strfreeze']}</label></p>\n"; + echo "<input type=\"submit\" name=\"vacuum\" value=\"{$lang['strvacuum']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END single vacuum + else { + //If multi drop + if (is_array($_REQUEST['table'])) { + $msg = ''; + foreach ($_REQUEST['table'] as $t) { + $status = $data->vacuumDB($t, isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strvacuumgood']); + } else { + $this->doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strvacuumbad'])); + return; + } + } + // Everything went fine, back to the Default page.... + $misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + //we must pass table here. When empty, vacuum the whole db + $status = $data->vacuumDB($_REQUEST['table'], isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze'])); + if ($status == 0) { + $misc->setReloadBrowser(true); + $this->doAdmin($type, $lang['strvacuumgood']); + } else { + $this->doAdmin($type, $lang['strvacuumbad']); + } + + } + } + } + +/** + * Add or Edit autovacuum params and save them + */ + public function doEditAutovacuum($type, $confirm, $msg = '') { + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + $script = $this->script; + + $misc = $this->misc; + $lang = $this->lang; + $data = $this->getDatabaseAccessor(); + + if (empty($_REQUEST['table'])) { + $this->doAdmin($type, '', $lang['strspecifyeditvacuumtable']); + return; + } + + $script = ($type == 'database') ? 'database.php' : 'tables.php'; + + if ($confirm) { + $misc->printTrail($type); + $misc->printTitle(sprintf($lang['streditvacuumtable'], $misc->printVal($_REQUEST['table']))); + $misc->printMsg(sprintf($msg, $misc->printVal($_REQUEST['table']))); + + if (empty($_REQUEST['table'])) { + $this->doAdmin($type, '', $lang['strspecifyeditvacuumtable']); + return; + } + + $old_val = $data->getTableAutovacuum($_REQUEST['table']); + $defaults = $data->getAutovacuum(); + $old_val = $old_val->fields; + + if (isset($old_val['autovacuum_enabled']) and ($old_val['autovacuum_enabled'] == 'off')) { + $enabled = ''; + $disabled = 'checked="checked"'; + } else { + $enabled = 'checked="checked"'; + $disabled = ''; + } + + if (!isset($old_val['autovacuum_vacuum_threshold'])) { + $old_val['autovacuum_vacuum_threshold'] = ''; + } + + if (!isset($old_val['autovacuum_vacuum_scale_factor'])) { + $old_val['autovacuum_vacuum_scale_factor'] = ''; + } + + if (!isset($old_val['autovacuum_analyze_threshold'])) { + $old_val['autovacuum_analyze_threshold'] = ''; + } + + if (!isset($old_val['autovacuum_analyze_scale_factor'])) { + $old_val['autovacuum_analyze_scale_factor'] = ''; + } + + if (!isset($old_val['autovacuum_vacuum_cost_delay'])) { + $old_val['autovacuum_vacuum_cost_delay'] = ''; + } + + if (!isset($old_val['autovacuum_vacuum_cost_limit'])) { + $old_val['autovacuum_vacuum_cost_limit'] = ''; + } + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"action\" value=\"editautovac\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + + echo "<br />\n<br />\n<table>\n"; + echo "\t<tr><td> </td>\n"; + echo "<th class=\"data\">{$lang['strnewvalues']}</th><th class=\"data\">{$lang['strdefaultvalues']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['strenable']}</th>\n"; + echo "<td class=\"data1\">\n"; + echo "<label for=\"on\">on</label><input type=\"radio\" name=\"autovacuum_enabled\" id=\"on\" value=\"on\" {$enabled} />\n"; + echo "<label for=\"off\">off</label><input type=\"radio\" name=\"autovacuum_enabled\" id=\"off\" value=\"off\" {$disabled} /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['strvacuumbasethreshold']}</th>\n"; + echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_threshold\" value=\"{$old_val['autovacuum_vacuum_threshold']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_threshold']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['strvacuumscalefactor']}</th>\n"; + echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_scale_factor\" value=\"{$old_val['autovacuum_vacuum_scale_factor']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_scale_factor']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['stranalybasethreshold']}</th>\n"; + echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_analyze_threshold\" value=\"{$old_val['autovacuum_analyze_threshold']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_analyze_threshold']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['stranalyzescalefactor']}</th>\n"; + echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_analyze_scale_factor\" value=\"{$old_val['autovacuum_analyze_scale_factor']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_analyze_scale_factor']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['strvacuumcostdelay']}</th>\n"; + echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_cost_delay\" value=\"{$old_val['autovacuum_vacuum_cost_delay']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_cost_delay']}</th></tr>\n"; + echo "\t<tr><th class=\"data left\">{$lang['strvacuumcostlimit']}</th>\n"; + echo "<td class=\"datat1\"><input type=\"text\" name=\"autovacuum_vacuum_cost_limit\" value=\"{$old_val['autovacuum_vacuum_cost_limit']}\" /></td>\n"; + echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_cost_limit']}</th></tr>\n"; + echo "</table>\n"; + echo "<br />"; + echo "<br />"; + echo "<input type=\"submit\" name=\"save\" value=\"{$lang['strsave']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + + echo "</form>\n"; + } else { + $status = $data->saveAutovacuum($_REQUEST['table'], $_POST['autovacuum_enabled'], $_POST['autovacuum_vacuum_threshold'], + $_POST['autovacuum_vacuum_scale_factor'], $_POST['autovacuum_analyze_threshold'], $_POST['autovacuum_analyze_scale_factor'], + $_POST['autovacuum_vacuum_cost_delay'], $_POST['autovacuum_vacuum_cost_limit']); + + if ($status == 0) { + $this->doAdmin($type, '', sprintf($lang['strsetvacuumtablesaved'], $_REQUEST['table'])); + } else { + $this->doEditAutovacuum($type, true, $lang['strsetvacuumtablefail']); + } + + } + } + +/** + * confirm drop autovacuum params for a table and drop it + */ + public function doDropAutovacuum($type, $confirm) { + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + $script = $this->script; + + $misc = $this->misc; + $lang = $this->lang; + $data = $this->getDatabaseAccessor(); + + if (empty($_REQUEST['table'])) { + $this->doAdmin($type, '', $lang['strspecifydelvacuumtable']); + return; + } + + if ($confirm) { + $misc->printTrail($type); + $misc->printTabs($type, 'admin'); + + $script = ($type == 'database') ? 'database.php' : 'tables.php'; + + printf("<p>{$lang['strdelvacuumtable']}</p>\n", + $misc->printVal("\"{$_GET['schema']}\".\"{$_GET['table']}\"")); + + echo "<form style=\"float: left\" action=\"{$script}\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"delautovac\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"rel\" value=\"", htmlspecialchars(serialize([$_REQUEST['schema'], $_REQUEST['table']])), "\" />\n"; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "</form>\n"; + + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"admin\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + + $status = $data->dropAutovacuum($_POST['table']); + + if ($status == 0) { + $this->doAdmin($type, '', sprintf($lang['strvacuumtablereset'], $misc->printVal($_POST['table']))); + } else { + $this->doAdmin($type, '', sprintf($lang['strdelvacuumtablefail'], $misc->printVal($_POST['table']))); + } + + } + } + +/** + * database/table administration and tuning tasks + * + * $Id: admin.php + */ + + public function doAdmin($type, $msg = '') { + $this->script = ($type == 'database') ? 'database.php' : 'tables.php'; + + $script = $this->script; + + $misc = $this->misc; + $lang = $this->lang; + + $data = $this->getDatabaseAccessor(); + + $misc->printTrail($type); + $misc->printTabs($type, 'admin'); + $misc->printMsg($msg); + + if ($type == 'database') { + printf("<p>{$lang['stradminondatabase']}</p>\n", $misc->printVal($_REQUEST['object'])); + } else { + printf("<p>{$lang['stradminontable']}</p>\n", $misc->printVal($_REQUEST['object'])); + } + + echo "<table style=\"width: 50%\">\n"; + echo "<tr>\n"; + echo "<th class=\"data\">"; + $misc->printHelp($lang['strvacuum'], 'pg.admin.vacuum') . "</th>\n"; + echo "</th>"; + echo "<th class=\"data\">"; + $misc->printHelp($lang['stranalyze'], 'pg.admin.analyze'); + echo "</th>"; + if ($data->hasRecluster()) { + echo "<th class=\"data\">"; + $misc->printHelp($lang['strclusterindex'], 'pg.index.cluster'); + echo "</th>"; + } + echo "<th class=\"data\">"; + $misc->printHelp($lang['strreindex'], 'pg.index.reindex'); + echo "</th>"; + echo "</tr>"; + + // Vacuum + echo "<tr class=\"row1\">\n"; + echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_vacuum\" />\n"; + echo $misc->form; + if ($type == 'table') { + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['strvacuum']}\" /></p>\n"; + echo "</form>\n"; + echo "</td>\n"; + + // Analyze + echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_analyze\" />\n"; + echo $misc->form; + if ($type == 'table') { + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['stranalyze']}\" /></p>\n"; + echo "</form>\n"; + echo "</td>\n"; + + // Cluster + if ($data->hasRecluster()) { + $disabled = ''; + echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + echo $misc->form; + if ($type == 'table') { + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + if (!$data->alreadyClustered($_REQUEST['object'])) { + $disabled = 'disabled="disabled" '; + echo "{$lang['strnoclusteravailable']}<br />"; + } + } + echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_cluster\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strclusterindex']}\" $disabled/></p>\n"; + echo "</form>\n"; + echo "</td>\n"; + } + + // Reindex + echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; + echo "<form action=\"/src/views/{$script}\" method=\"post\">\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_reindex\" />\n"; + echo $misc->form; + if ($type == 'table') { + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['strreindex']}\" /></p>\n"; + echo "</form>\n"; + echo "</td>\n"; + echo "</tr>\n"; + echo "</table>\n"; + + // Autovacuum + if ($data->hasAutovacuum()) { + // get defaults values for autovacuum + $defaults = $data->getAutovacuum(); + // Fetch the autovacuum properties from the database or table if != '' + if ($type == 'table') { + $autovac = $data->getTableAutovacuum($_REQUEST['table']); + } else { + $autovac = $data->getTableAutovacuum(); + } + + echo "<br /><br /><h2>{$lang['strvacuumpertable']}</h2>"; + echo '<p>' . (($defaults['autovacuum'] == 'on') ? $lang['strturnedon'] : $lang['strturnedoff']) . '</p>'; + echo "<p class=\"message\">{$lang['strnotdefaultinred']}</p>"; + + function enlight($f, $p) { + if (isset($f[$p[0]]) and ($f[$p[0]] != $p[1])) { + return "<span style=\"color:#F33;font-weight:bold\">" . htmlspecialchars($f[$p[0]]) . "</span>"; + } + + return htmlspecialchars($p[1]); + } + + $columns = [ + 'namespace' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + 'url' => "/redirect/schema?{$misc->href}&", + 'vars' => ['schema' => 'nspname'], + ], + 'relname' => [ + 'title' => $lang['strtable'], + 'field' => Decorator::field('relname'), + 'url' => "/redirect/table?{$misc->href}&", + 'vars' => ['table' => 'relname', 'schema' => 'nspname'], + ], + 'autovacuum_enabled' => [ + 'title' => $lang['strenabled'], + 'field' => callback('enlight', ['autovacuum_enabled', $defaults['autovacuum']]), + 'type' => 'verbatim', + ], + 'autovacuum_vacuum_threshold' => [ + 'title' => $lang['strvacuumbasethreshold'], + 'field' => callback('enlight', ['autovacuum_vacuum_threshold', $defaults['autovacuum_vacuum_threshold']]), + 'type' => 'verbatim', + ], + 'autovacuum_vacuum_scale_factor' => [ + 'title' => $lang['strvacuumscalefactor'], + 'field' => callback('enlight', ['autovacuum_vacuum_scale_factor', $defaults['autovacuum_vacuum_scale_factor']]), + 'type' => 'verbatim', + ], + 'autovacuum_analyze_threshold' => [ + 'title' => $lang['stranalybasethreshold'], + 'field' => callback('enlight', ['autovacuum_analyze_threshold', $defaults['autovacuum_analyze_threshold']]), + 'type' => 'verbatim', + ], + 'autovacuum_analyze_scale_factor' => [ + 'title' => $lang['stranalyzescalefactor'], + 'field' => callback('enlight', ['autovacuum_analyze_scale_factor', $defaults['autovacuum_analyze_scale_factor']]), + 'type' => 'verbatim', + ], + 'autovacuum_vacuum_cost_delay' => [ + 'title' => $lang['strvacuumcostdelay'], + 'field' => concat(callback('enlight', ['autovacuum_vacuum_cost_delay', $defaults['autovacuum_vacuum_cost_delay']]), 'ms'), + 'type' => 'verbatim', + ], + 'autovacuum_vacuum_cost_limit' => [ + 'title' => $lang['strvacuumcostlimit'], + 'field' => callback('enlight', ['autovacuum_vacuum_cost_limit', $defaults['autovacuum_vacuum_cost_limit']]), + 'type' => 'verbatim', + ], + ]; + + // Maybe we need to check permissions here? + $columns['actions'] = ['title' => $lang['stractions']]; + + $actions = [ + 'edit' => [ + 'content' => $lang['stredit'], + 'attr' => [ + 'href' => [ + 'url' => $script, + 'urlvars' => [ + 'subject' => $type, + 'action' => 'confeditautovac', + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'delete' => [ + 'content' => $lang['strdelete'], + 'attr' => [ + 'href' => [ + 'url' => $script, + 'urlvars' => [ + 'subject' => $type, + 'action' => 'confdelautovac', + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + if ($type == 'table') { + unset($actions['edit']['vars']['schema'], + $actions['delete']['vars']['schema'], + $columns['namespace'], + $columns['relname'] + ); + } + + echo $misc->printTable($autovac, $columns, $actions, 'admin-admin', $lang['strnovacuumconf']); + + if (($type == 'table') and ($autovac->recordCount() == 0)) { + echo "<br />"; + echo "<a href=\"tables.php?action=confeditautovac&{$misc->href}&table=", htmlspecialchars($_REQUEST['table']) + , "\">{$lang['straddvacuumtable']}</a>"; + } + } + } + + function adminActions($action, $type) { + + if ($type == 'database') { + $_REQUEST['object'] = $_REQUEST['database']; + $this->script = 'database.php'; + } else { + // $_REQUEST['table'] is no set if we are in the schema page + $_REQUEST['object'] = (isset($_REQUEST['table']) ? $_REQUEST['table'] : ''); + $this->script = 'tables.php'; + } + + $script = $this->script; + + switch ($action) { + case 'confirm_cluster': + $this->doCluster($type, true); + break; + case 'confirm_reindex': + $this->doReindex($type, true); + break; + case 'confirm_analyze': + $this->doAnalyze($type, true); + break; + case 'confirm_vacuum': + $this->doVacuum($type, true); + break; + case 'cluster': + if (isset($_POST['cluster'])) { + $this->doCluster($type); + } + + // if multi-action from table canceled: back to the schema default page + else if (($type == 'table') && is_array($_REQUEST['object'])) { + $this->doDefault(); + } else { + $this->doAdmin($type); + } + + break; + case 'reindex': + if (isset($_POST['reindex'])) { + $this->doReindex($type); + } + + // if multi-action from table canceled: back to the schema default page + else if (($type == 'table') && is_array($_REQUEST['object'])) { + $this->doDefault(); + } else { + $this->doAdmin($type); + } + + break; + case 'analyze': + if (isset($_POST['analyze'])) { + $this->doAnalyze($type); + } + + // if multi-action from table canceled: back to the schema default page + else if (($type == 'table') && is_array($_REQUEST['object'])) { + $this->doDefault(); + } else { + $this->doAdmin($type); + } + + break; + case 'vacuum': + if (isset($_POST['vacuum'])) { + $this->doVacuum($type); + } + + // if multi-action from table canceled: back to the schema default page + else if (($type == 'table') && is_array($_REQUEST['object'])) { + $this->doDefault(); + } else { + $this->doAdmin($type); + } + + break; + case 'admin': + $this->doAdmin($type); + break; + case 'confeditautovac': + $this->doEditAutovacuum($type, true); + break; + case 'confdelautovac': + $this->doDropAutovacuum($type, true); + break; + case 'confaddautovac': + $this->doAddAutovacuum(true); + break; + case 'editautovac': + if (isset($_POST['save'])) { + $this->doEditAutovacuum($type, false); + } else { + $this->doAdmin($type); + } + + break; + case 'delautovac': + $this->doDropAutovacuum($type, false); + break; + default: + return false; + } + return true; + } + +}
\ No newline at end of file diff --git a/src/controllers/AggregateController.php b/src/controllers/AggregateController.php new file mode 100644 index 00000000..9246bbd3 --- /dev/null +++ b/src/controllers/AggregateController.php @@ -0,0 +1,428 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class AggregateController extends BaseController { + public $_name = 'AggregateController'; + +/** + * Actually creates the new aggregate in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + // Check inputs + if (trim($_REQUEST['name']) == '') { + $this->doCreate($lang['straggrneedsname']); + return; + } else if (trim($_REQUEST['basetype']) == '') { + $this->doCreate($lang['straggrneedsbasetype']); + return; + } else if (trim($_REQUEST['sfunc']) == '') { + $this->doCreate($lang['straggrneedssfunc']); + return; + } else if (trim($_REQUEST['stype']) == '') { + $this->doCreate($lang['straggrneedsstype']); + return; + } + + $status = $data->createAggregate($_REQUEST['name'], $_REQUEST['basetype'], $_REQUEST['sfunc'], $_REQUEST['stype'], + $_REQUEST['ffunc'], $_REQUEST['initcond'], $_REQUEST['sortop'], $_REQUEST['aggrcomment']); + + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['straggrcreated']); + } else { + $this->doCreate($lang['straggrcreatedbad']); + } + } + +/** + * Displays a screen for create a new aggregate function + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['name'])) { + $_REQUEST['name'] = ''; + } + + if (!isset($_REQUEST['basetype'])) { + $_REQUEST['basetype'] = ''; + } + + if (!isset($_REQUEST['sfunc'])) { + $_REQUEST['sfunc'] = ''; + } + + if (!isset($_REQUEST['stype'])) { + $_REQUEST['stype'] = ''; + } + + if (!isset($_REQUEST['ffunc'])) { + $_REQUEST['ffunc'] = ''; + } + + if (!isset($_REQUEST['initcond'])) { + $_REQUEST['initcond'] = ''; + } + + if (!isset($_REQUEST['sortop'])) { + $_REQUEST['sortop'] = ''; + } + + if (!isset($_REQUEST['aggrcomment'])) { + $_REQUEST['aggrcomment'] = ''; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreateaggregate'], 'pg.aggregate.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/aggregates.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrbasetype']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"basetype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['basetype']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrsfunc']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"sfunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['sfunc']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrstype']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"stype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['stype']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrffunc']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"ffunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['ffunc']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrinitcond']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"initcond\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['initcond']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrsortop']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"sortop\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['sortop']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"aggrcomment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['aggrcomment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Function to save after altering an aggregate + */ + public function doSaveAlter() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check inputs + if (trim($_REQUEST['aggrname']) == '') { + $this->doAlter($lang['straggrneedsname']); + return; + } + + $status = $data->alterAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype'], $_REQUEST['aggrowner'], + $_REQUEST['aggrschema'], $_REQUEST['aggrcomment'], $_REQUEST['newaggrname'], $_REQUEST['newaggrowner'], + $_REQUEST['newaggrschema'], $_REQUEST['newaggrcomment']); + if ($status == 0) { + $this->doDefault($lang['straggraltered']); + } else { + $this->doAlter($lang['straggralteredbad']); + return; + } + } + +/** + * Function to allow editing an aggregate function + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('aggregate'); + $misc->printTitle($lang['stralter'], 'pg.aggregate.alter'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/aggregates.php\" method=\"post\">\n"; + $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']); + if ($aggrdata->recordCount() > 0) { + // Output table header + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data required\">{$lang['strname']}</th>"; + echo "<th class=\"data required\">{$lang['strowner']}</th>"; + echo "<th class=\"data required\">{$lang['strschema']}</th>\n\t</tr>\n"; + + // Display aggregate's name, owner and schema + echo "\t<tr>\n\t\t<td><input name=\"newaggrname\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" /></td>"; + echo "<td><input name=\"newaggrowner\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($aggrdata->fields['usename']), "\" /></td>"; + echo "<td><input name=\"newaggrschema\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"newaggrcomment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($aggrdata->fields['aggrcomment']), "</textarea></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_alter\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n"; + echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n"; + echo "<input type=\"hidden\" name=\"aggrowner\" value=\"", htmlspecialchars($aggrdata->fields['usename']), "\" />\n"; + echo "<input type=\"hidden\" name=\"aggrschema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n"; + echo "<input type=\"hidden\" name=\"aggrcomment\" value=\"", htmlspecialchars($aggrdata->fields['aggrcomment']), "\" />\n"; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strback']}\" /></p>\n"; + } + echo "</form>\n"; + } + +/** + * Show confirmation of drop and perform actual drop of the aggregate function selected + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('aggregate'); + $misc->printTitle($lang['strdrop'], 'pg.aggregate.drop'); + + echo "<p>", sprintf($lang['strconfdropaggregate'], htmlspecialchars($_REQUEST['aggrname'])), "</p>\n"; + + echo "<form action=\"/src/views/aggregates.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n"; + echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropAggregate($_POST['aggrname'], $_POST['aggrtype'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['straggregatedropped']); + } else { + $this->doDefault($lang['straggregatedroppedbad']); + } + + } + } + +/** + * Show the properties of an aggregate + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('aggregate'); + $misc->printTitle($lang['strproperties'], 'pg.aggregate'); + $misc->printMsg($msg); + + $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']); + + if ($aggrdata->recordCount() > 0) { + // Display aggregate's info + echo "<table>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['strname']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($_REQUEST['aggrname']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrbasetype']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($_REQUEST['aggrtype']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrsfunc']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggtransfn']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrstype']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggstype']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrffunc']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggfinalfn']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrinitcond']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['agginitval']), "</td>\n</tr>\n"; + if ($data->hasAggregateSortOp()) { + echo "<tr>\n\t<th class=\"data left\">{$lang['straggrsortop']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggsortop']), "</td>\n</tr>\n"; + } + echo "<tr>\n\t<th class=\"data left\">{$lang['strowner']}</th>\n"; + echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['usename']), "</td>\n</tr>\n"; + echo "<tr>\n\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t<td class=\"data1\">", $misc->printVal($aggrdata->fields['aggrcomment']), "</td>\n</tr>\n"; + echo "</table>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + $navlinks = [ + 'showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['straggrshowall'], + ], + ]; + + if ($data->hasAlterAggregate()) { + $navlinks['alter'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'action' => 'alter', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'aggrname' => $_REQUEST['aggrname'], + 'aggrtype' => $_REQUEST['aggrtype'], + ], + ], + ], + 'content' => $lang['stralter'], + ]; + } + + $navlinks['drop'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'aggrname' => $_REQUEST['aggrname'], + 'aggrtype' => $_REQUEST['aggrtype'], + ], + ], + ], + 'content' => $lang['strdrop'], + ]; + + $misc->printNavLinks($navlinks, 'aggregates-properties', get_defined_vars()); + } + +/** + * Show default list of aggregate functions in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + $misc->printTrail('schema'); + $misc->printTabs('schema', 'aggregates'); + $misc->printMsg($msg); + + $aggregates = $data->getAggregates(); + + $columns = [ + 'aggrname' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('proname'), + 'url' => "/redirect/aggregate?action=properties&{$misc->href}&", + 'vars' => ['aggrname' => 'proname', 'aggrtype' => 'proargtypes'], + ], + 'aggrtype' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('proargtypes'), + ], + 'aggrtransfn' => [ + 'title' => $lang['straggrsfunc'], + 'field' => Decorator::field('aggtransfn'), + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('usename'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('aggrcomment'), + ], + ]; + + $actions = [ + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'action' => 'alter', + 'aggrname' => Decorator::field('proname'), + 'aggrtype' => Decorator::field('proargtypes'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'aggrname' => Decorator::field('proname'), + 'aggrtype' => Decorator::field('proargtypes'), + ], + ], + ], + ], + ]; + + if (!$data->hasAlterAggregate()) { + unset($actions['alter']); + } + + echo $misc->printTable($aggregates, $columns, $actions, 'aggregates-aggregates', $lang['strnoaggregates']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'aggregates.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateaggregate'], + ], + ]; + $misc->printNavLinks($navlinks, 'aggregates-aggregates', get_defined_vars()); + } + +} diff --git a/src/controllers/AllDBController.php b/src/controllers/AllDBController.php new file mode 100644 index 00000000..f1237d84 --- /dev/null +++ b/src/controllers/AllDBController.php @@ -0,0 +1,521 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class AllDBController extends BaseController { + public $_name = 'AllDBController'; +/** + * Display a form for alter and perform actual alter + */ + public function doAlter($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('database'); + $misc->printTitle($lang['stralter'], 'pg.database.alter'); + + echo "<form action=\"/src/views/all_db.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"newname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['alterdatabase']), "\" /></td></tr>\n"; + + if ($data->hasAlterDatabaseOwner() && $data->isSuperUser()) { + // Fetch all users + + $rs = $data->getDatabaseOwner($_REQUEST['alterdatabase']); + $owner = isset($rs->fields['usename']) ? $rs->fields['usename'] : ''; + $users = $data->getUsers(); + + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\"><select name=\"owner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $owner) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + } + if ($data->hasSharedComments()) { + $rs = $data->getDatabaseComment($_REQUEST['alterdatabase']); + $comment = isset($rs->fields['description']) ? $rs->fields['description'] : ''; + echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<textarea rows=\"3\" cols=\"32\" name=\"dbcomment\">", + htmlspecialchars($comment), "</textarea></td></tr>\n"; + } + echo "</table>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"oldname\" value=\"", + htmlspecialchars($_REQUEST['alterdatabase']), "\" />\n"; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + if (!isset($_POST['owner'])) { + $_POST['owner'] = ''; + } + + if (!isset($_POST['dbcomment'])) { + $_POST['dbcomment'] = ''; + } + + if ($data->alterDatabase($_POST['oldname'], $_POST['newname'], $_POST['owner'], $_POST['dbcomment']) == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strdatabasealtered']); + } else { + $this->doDefault($lang['strdatabasealteredbad']); + } + + } + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['dropdatabase']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifydatabasetodrop']); + exit(); + } + + if ($confirm) { + + $misc->printTrail('database'); + $misc->printTitle($lang['strdrop'], 'pg.database.drop'); + + echo "<form action=\"/src/views/all_db.php\" method=\"post\">\n"; + //If multi drop + if (isset($_REQUEST['ma'])) { + + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($a['database'])), "</p>\n"; + printf('<input type="hidden" name="dropdatabase[]" value="%s" />', htmlspecialchars($a['database'])); + } + + } else { + echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($_REQUEST['dropdatabase'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"dropdatabase\" value=\"", htmlspecialchars($_REQUEST['dropdatabase']), "\" />\n"; + } // END if multi drop + + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END confirm + else { + //If multi drop + if (is_array($_REQUEST['dropdatabase'])) { + $msg = ''; + foreach ($_REQUEST['dropdatabase'] as $d) { + $status = $data->dropDatabase($d); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($d, ENT_QUOTES, 'UTF-8'), $lang['strdatabasedropped']); + } else { + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($d, ENT_QUOTES, 'UTF-8'), $lang['strdatabasedroppedbad'])); + return; + } + } // Everything went fine, back to Default page... + $misc->setReloadDropDatabase(true); + $this->doDefault($msg); + } else { + $status = $data->dropDatabase($_POST['dropdatabase']); + if ($status == 0) { + $misc->setReloadDropDatabase(true); + $this->doDefault($lang['strdatabasedropped']); + } else { + $this->doDefault($lang['strdatabasedroppedbad']); + } + + } + } //END DROP + } // END FUNCTION + +/** + * Displays a screen where they can enter a new database + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('server'); + $misc->printTitle($lang['strcreatedatabase'], 'pg.database.create'); + $misc->printMsg($msg); + + if (!isset($_POST['formName'])) { + $_POST['formName'] = ''; + } + + // Default encoding is that in language file + if (!isset($_POST['formEncoding'])) { + $_POST['formEncoding'] = ''; + } + if (!isset($_POST['formTemplate'])) { + $_POST['formTemplate'] = 'template1'; + } + + if (!isset($_POST['formSpc'])) { + $_POST['formSpc'] = ''; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = ''; + } + + // Fetch a list of databases in the cluster + $templatedbs = $data->getDatabases(false); + + // Fetch all tablespaces from the database + if ($data->hasTablespaces()) { + $tablespaces = $data->getTablespaces(); + } + + echo "<form action=\"/src/views/all_db.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; + + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strtemplatedb']}</th>\n"; + echo "\t\t<td class=\"data1\">\n"; + echo "\t\t\t<select name=\"formTemplate\">\n"; + // Always offer template0 and template1 + echo "\t\t\t\t<option value=\"template0\"", + ($_POST['formTemplate'] == 'template0') ? ' selected="selected"' : '', ">template0</option>\n"; + echo "\t\t\t\t<option value=\"template1\"", + ($_POST['formTemplate'] == 'template1') ? ' selected="selected"' : '', ">template1</option>\n"; + while (!$templatedbs->EOF) { + $dbname = htmlspecialchars($templatedbs->fields['datname']); + if ($dbname != 'template1') { + // filter out for $conf[show_system] users so we dont get duplicates + echo "\t\t\t\t<option value=\"{$dbname}\"", + ($dbname == $_POST['formTemplate']) ? ' selected="selected"' : '', ">{$dbname}</option>\n"; + } + $templatedbs->moveNext(); + } + echo "\t\t\t</select>\n"; + echo "\t\t</td>\n\t</tr>\n"; + + // ENCODING + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strencoding']}</th>\n"; + echo "\t\t<td class=\"data1\">\n"; + echo "\t\t\t<select name=\"formEncoding\">\n"; + echo "\t\t\t\t<option value=\"\"></option>\n"; + while (list($key) = each($data->codemap)) { + echo "\t\t\t\t<option value=\"", htmlspecialchars($key), "\"", + ($key == $_POST['formEncoding']) ? ' selected="selected"' : '', ">", + $misc->printVal($key), "</option>\n"; + } + echo "\t\t\t</select>\n"; + echo "\t\t</td>\n\t</tr>\n"; + + if ($data->hasDatabaseCollation()) { + if (!isset($_POST['formCollate'])) { + $_POST['formCollate'] = ''; + } + + if (!isset($_POST['formCType'])) { + $_POST['formCType'] = ''; + } + + // LC_COLLATE + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcollation']}</th>\n"; + echo "\t\t<td class=\"data1\">\n"; + echo "\t\t\t<input name=\"formCollate\" value=\"", htmlspecialchars($_POST['formCollate']), "\" />\n"; + echo "\t\t</td>\n\t</tr>\n"; + + // LC_CTYPE + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strctype']}</th>\n"; + echo "\t\t<td class=\"data1\">\n"; + echo "\t\t\t<input name=\"formCType\" value=\"", htmlspecialchars($_POST['formCType']), "\" />\n"; + echo "\t\t</td>\n\t</tr>\n"; + } + + // Tablespace (if there are any) + if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; + echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formSpc\">\n"; + // Always offer the default (empty) option + echo "\t\t\t\t<option value=\"\"", + ($_POST['formSpc'] == '') ? ' selected="selected"' : '', "></option>\n"; + // Display all other tablespaces + while (!$tablespaces->EOF) { + $spcname = htmlspecialchars($tablespaces->fields['spcname']); + echo "\t\t\t\t<option value=\"{$spcname}\"", + ($spcname == $_POST['formSpc']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; + $tablespaces->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; + } + + // Comments (if available) + if ($data->hasSharedComments()) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; + } + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new view in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Default tablespace to null if it isn't set + if (!isset($_POST['formSpc'])) { + $_POST['formSpc'] = null; + } + + // Default comment to blank if it isn't set + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = null; + } + + // Default collate to blank if it isn't set + if (!isset($_POST['formCollate'])) { + $_POST['formCollate'] = null; + } + + // Default ctype to blank if it isn't set + if (!isset($_POST['formCType'])) { + $_POST['formCType'] = null; + } + + // Check that they've given a name and a definition + if ($_POST['formName'] == '') { + $this->doCreate($lang['strdatabaseneedsname']); + } else { + $status = $data->createDatabase($_POST['formName'], $_POST['formEncoding'], $_POST['formSpc'], + $_POST['formComment'], $_POST['formTemplate'], $_POST['formCollate'], $_POST['formCType']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strdatabasecreated']); + } else { + $this->doCreate($lang['strdatabasecreatedbad']); + } + + } + } + +/** + * Displays options for cluster download + */ + public function doExport($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('server'); + $misc->printTabs('server', 'export'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/dbexport.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\">{$lang['stroptions']}</th></tr>\n"; + // Data only + echo "<tr><th class=\"data left\" rowspan=\"2\">"; + echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; + echo "<td>{$lang['strformat']}\n"; + echo "<select name=\"d_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /><label for=\"d_oids\">{$lang['stroids']}</label></td>\n</tr>\n"; + // Structure only + echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; + echo "<td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /><label for=\"s_clean\">{$lang['strdrop']}</label></td>\n</tr>\n"; + // Structure and data + echo "<tr><th class=\"data left\" rowspan=\"3\">"; + echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; + echo "<td>{$lang['strformat']}\n"; + echo "<select name=\"sd_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /><label for=\"sd_clean\">{$lang['strdrop']}</label></td>\n</tr>\n"; + echo "<tr><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /><label for=\"sd_oids\">{$lang['stroids']}</label></td>\n</tr>\n"; + echo "</table>\n"; + + echo "<h3>{$lang['stroptions']}</h3>\n"; + echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; + echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"server\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Show default list of databases in the server + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + + $misc->printTrail('server'); + $misc->printTabs('server', 'databases'); + $misc->printMsg($msg); + $data = $misc->getDatabaseAccessor(); + $databases = $data->getDatabases(); + + $columns = [ + 'database' => [ + 'title' => $lang['strdatabase'], + 'field' => Decorator::field('datname'), + 'url' => "/redirect/database?{$misc->href}&", + 'vars' => ['database' => 'datname'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('datowner'), + ], + 'encoding' => [ + 'title' => $lang['strencoding'], + 'field' => Decorator::field('datencoding'), + ], + 'lc_collate' => [ + 'title' => $lang['strcollation'], + 'field' => Decorator::field('datcollate'), + ], + 'lc_ctype' => [ + 'title' => $lang['strctype'], + 'field' => Decorator::field('datctype'), + ], + 'tablespace' => [ + 'title' => $lang['strtablespace'], + 'field' => Decorator::field('tablespace'), + ], + 'dbsize' => [ + 'title' => $lang['strsize'], + 'field' => Decorator::field('dbsize'), + 'type' => 'prettysize', + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('datcomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['database' => 'datname'], + 'url' => 'all_db.php', + 'default' => null, + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'all_db.php', + 'urlvars' => [ + 'subject' => 'database', + 'action' => 'confirm_drop', + 'dropdatabase' => Decorator::field('datname'), + ], + ], + ], + 'multiaction' => 'confirm_drop', + ], + 'privileges' => [ + 'content' => $lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges.php', + 'urlvars' => [ + 'subject' => 'database', + 'database' => Decorator::field('datname'), + ], + ], + ], + ], + ]; + if ($data->hasAlterDatabase()) { + $actions['alter'] = [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'all_db.php', + 'urlvars' => [ + 'subject' => 'database', + 'action' => 'confirm_alter', + 'alterdatabase' => Decorator::field('datname'), + ], + ], + ], + ]; + } + + if (!$data->hasTablespaces()) { + unset($columns['tablespace']); + } + + if (!$data->hasServerAdminFuncs()) { + unset($columns['dbsize']); + } + + if (!$data->hasDatabaseCollation()) { + unset($columns['lc_collate'], $columns['lc_ctype']); + } + + if (!isset($data->privlist['database'])) { + unset($actions['privileges']); + } + + echo $misc->printTable($databases, $columns, $actions, 'all_db-databases', $lang['strnodatabases']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'all_db.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + ], + ], + ], + 'content' => $lang['strcreatedatabase'], + ], + ]; + $misc->printNavLinks($navlinks, 'all_db-databases', get_defined_vars()); + + } + +} diff --git a/src/controllers/BaseController.php b/src/controllers/BaseController.php new file mode 100644 index 00000000..6c5de796 --- /dev/null +++ b/src/controllers/BaseController.php @@ -0,0 +1,45 @@ +<?php + +namespace PHPPgAdmin\Controller; + +/** + * Base controller class + */ +class BaseController { + + private $_connection = null; + private $_no_db_connection = false; + private $_reload_browser = false; + private $app = null; + private $data = null; + private $database = null; + private $server_id = null; + public $appLangFiles = []; + public $appThemes = []; + public $appName = ''; + public $appVersion = ''; + public $form = ''; + public $href = ''; + public $lang = []; + public $_name = 'BaseController'; + + /* Constructor */ + function __construct(\Slim\Container $container) { + + $this->lang = $container->get('lang'); + $this->conf = $container->get('conf'); + $this->view = $container->get('view'); + $this->plugin_manager = $container->get('plugin_manager'); + $this->appName = $container->get('settings')['appName']; + $this->appVersion = $container->get('settings')['appVersion']; + $this->appLangFiles = $container->get('appLangFiles'); + $this->misc = $container->get('misc'); + $this->appThemes = $container->get('appThemes'); + + \PC::debug($this->_name, 'instanced controller'); + } + + public function doDefault() { + return $this; + } +}
\ No newline at end of file diff --git a/src/controllers/CastController.php b/src/controllers/CastController.php new file mode 100644 index 00000000..bed5d1ff --- /dev/null +++ b/src/controllers/CastController.php @@ -0,0 +1,66 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class CastController extends BaseController { + public $_name = 'CastController'; + +/** + * Show default list of casts in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + function renderCastContext($val) { + global $lang; + switch ($val) { + case 'e':return $lang['strno']; + case 'a':return $lang['strinassignment']; + default:return $lang['stryes']; + } + } + + $misc->printTrail('database'); + $misc->printTabs('database', 'casts'); + $misc->printMsg($msg); + + $casts = $data->getCasts(); + + $columns = [ + 'source_type' => [ + 'title' => $lang['strsourcetype'], + 'field' => Decorator::field('castsource'), + ], + 'target_type' => [ + 'title' => $lang['strtargettype'], + 'field' => Decorator::field('casttarget'), + ], + 'function' => [ + 'title' => $lang['strfunction'], + 'field' => Decorator::field('castfunc'), + 'params' => ['null' => $lang['strbinarycompat']], + ], + 'implicit' => [ + 'title' => $lang['strimplicit'], + 'field' => Decorator::field('castcontext'), + 'type' => 'callback', + 'params' => ['function' => 'renderCastContext', 'align' => 'center'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('castcomment'), + ], + ]; + + $actions = []; + + echo $misc->printTable($casts, $columns, $actions, 'casts-casts', $lang['strnocasts']); + } +} diff --git a/src/controllers/ColPropertyController.php b/src/controllers/ColPropertyController.php new file mode 100644 index 00000000..c83c2a53 --- /dev/null +++ b/src/controllers/ColPropertyController.php @@ -0,0 +1,338 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class ColPropertyController extends BaseController { + public $_name = 'ColPropertyController'; + + /** + * Displays a screen where they can alter a column + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + } + + switch ($_REQUEST['stage']) { + case 1: + $misc->printTrail('column'); + $misc->printTitle($lang['stralter'], 'pg.column.alter'); + $misc->printMsg($msg); + + echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; + echo "<form action=\"/src/views/colproperties.php\" method=\"post\">\n"; + + // Output table header + echo "<table>\n"; + echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n"; + if ($data->hasAlterColumnType()) { + echo "<th class=\"data required\" colspan=\"2\">{$lang['strtype']}</th>\n"; + echo "<th class=\"data\">{$lang['strlength']}</th>\n"; + } else { + echo "<th class=\"data required\">{$lang['strtype']}</th>\n"; + } + echo "<th class=\"data\">{$lang['strnotnull']}</th>\n<th class=\"data\">{$lang['strdefault']}</th>\n<th class=\"data\">{$lang['strcomment']}</th></tr>\n"; + + $column = $data->getTableAttributes($_REQUEST['table'], $_REQUEST['column']); + $column->fields['attnotnull'] = $data->phpBool($column->fields['attnotnull']); + + // Upon first drawing the screen, load the existing column information + // from the database. + if (!isset($_REQUEST['default'])) { + $_REQUEST['field'] = $column->fields['attname']; + $_REQUEST['type'] = $column->fields['base_type']; + // Check to see if its' an array type... + // XXX: HACKY + if (substr($column->fields['base_type'], strlen($column->fields['base_type']) - 2) == '[]') { + $_REQUEST['type'] = substr($column->fields['base_type'], 0, strlen($column->fields['base_type']) - 2); + $_REQUEST['array'] = '[]'; + } else { + $_REQUEST['type'] = $column->fields['base_type']; + $_REQUEST['array'] = ''; + } + // To figure out the length, look in the brackets :( + // XXX: HACKY + if ($column->fields['type'] != $column->fields['base_type'] && preg_match('/\\(([0-9, ]*)\\)/', $column->fields['type'], $bits)) { + $_REQUEST['length'] = $bits[1]; + } else { + $_REQUEST['length'] = ''; + } + + $_REQUEST['default'] = $_REQUEST['olddefault'] = $column->fields['adsrc']; + if ($column->fields['attnotnull']) { + $_REQUEST['notnull'] = 'YES'; + } + + $_REQUEST['comment'] = $column->fields['comment']; + } + + // Column name + echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['field']), "\" /></td>\n"; + + // Column type + $escaped_predef_types = []; // the JS escaped array elements + if ($data->hasAlterColumnType()) { + // Fetch all available types + $types = $data->getTypes(true, false, true); + $types_for_js = []; + + echo "<td><select name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">\n"; + while (!$types->EOF) { + $typname = $types->fields['typname']; + $types_for_js[] = $typname; + echo "\t<option value=\"", htmlspecialchars($typname), "\"", ($typname == $_REQUEST['type']) ? ' selected="selected"' : '', ">", + $misc->printVal($typname), "</option>\n"; + $types->moveNext(); + } + echo "</select>\n"; + echo "<script>jQuery('#type').select2();</script>\n"; + echo "</td>\n"; + + // Output array type selector + echo "<td><select name=\"array\">\n"; + echo "\t<option value=\"\"", ($_REQUEST['array'] == '') ? ' selected="selected"' : '', "></option>\n"; + echo "\t<option value=\"[]\"", ($_REQUEST['array'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; + echo "</select></td>\n"; + $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js); + foreach ($predefined_size_types as $value) { + $escaped_predef_types[] = "'{$value}'"; + } + + echo "<td><input name=\"length\" id=\"lengths\" size=\"8\" value=\"", + htmlspecialchars($_REQUEST['length']), "\" /></td>\n"; + } else { + // Otherwise draw the read-only type name + echo "<td>", $misc->printVal($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "</td>\n"; + } + + echo "<td><input type=\"checkbox\" name=\"notnull\"", (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', " /></td>\n"; + echo "<td><input name=\"default\" size=\"20\" value=\"", + htmlspecialchars($_REQUEST['default']), "\" /></td>\n"; + echo "<td><input name=\"comment\" size=\"40\" value=\"", + htmlspecialchars($_REQUEST['comment']), "\" /></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"properties\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; + echo "<input type=\"hidden\" name=\"olddefault\" value=\"", htmlspecialchars($_REQUEST['olddefault']), "\" />\n"; + if ($column->fields['attnotnull']) { + echo "<input type=\"hidden\" name=\"oldnotnull\" value=\"on\" />\n"; + } + + echo "<input type=\"hidden\" name=\"oldtype\" value=\"", htmlspecialchars($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "\" />\n"; + // Add hidden variables to suppress error notices if we don't support altering column type + if (!$data->hasAlterColumnType()) { + echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; + echo "<input type=\"hidden\" name=\"length\" value=\"", htmlspecialchars($_REQUEST['length']), "\" />\n"; + echo "<input type=\"hidden\" name=\"array\" value=\"", htmlspecialchars($_REQUEST['array']), "\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>\n"; + break; + case 2: + // Check inputs + if (trim($_REQUEST['field']) == '') { + $_REQUEST['stage'] = 1; + $this->doAlter($lang['strcolneedsname']); + return; + } + if (!isset($_REQUEST['length'])) { + $_REQUEST['length'] = ''; + } + + $status = $data->alterColumn($_REQUEST['table'], $_REQUEST['column'], $_REQUEST['field'], + isset($_REQUEST['notnull']), isset($_REQUEST['oldnotnull']), + $_REQUEST['default'], $_REQUEST['olddefault'], + $_REQUEST['type'], $_REQUEST['length'], $_REQUEST['array'], $_REQUEST['oldtype'], + $_REQUEST['comment']); + if ($status == 0) { + if ($_REQUEST['column'] != $_REQUEST['field']) { + $_REQUEST['column'] = $_REQUEST['field']; + $_reload_browser = true; + } + $this->doDefault($lang['strcolumnaltered']); + } else { + $_REQUEST['stage'] = 1; + $this->doAlter($lang['strcolumnalteredbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + + /** + * Show default list of columns in the table + */ + public function doDefault($msg = '', $isTable = true) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + global $tableName; + + $attPre = function (&$rowdata) use ($data) { + + $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); + }; + + if (empty($_REQUEST['column'])) { + $msg .= "<br/>{$lang['strnoobjects']}"; + } + + $misc->printTrail('column'); + //$misc->printTitle($lang['strcolprop']); + $misc->printTabs('column', 'properties'); + $misc->printMsg($msg); + + if (!empty($_REQUEST['column'])) { + // Get table + $tdata = $data->getTable($tableName); + // Get columns + $attrs = $data->getTableAttributes($tableName, $_REQUEST['column']); + + // Show comment if any + if ($attrs->fields['comment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($attrs->fields['comment']), "</p>\n"; + } + + $column = [ + 'column' => [ + 'title' => $lang['strcolumn'], + 'field' => Decorator::field('attname'), + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('+type'), + ], + ]; + + if ($isTable) { + $column['notnull'] = [ + 'title' => $lang['strnotnull'], + 'field' => Decorator::field('attnotnull'), + 'type' => 'bool', + 'params' => ['true' => 'NOT NULL', 'false' => ''], + ]; + $column['default'] = [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('adsrc'), + ]; + } + + $actions = []; + echo $misc->printTable($attrs, $column, $actions, 'colproperties-colproperties', null, $attPre); + + echo "<br />\n"; + + $f_attname = $_REQUEST['column']; + $f_table = $tableName; + $f_schema = $data->_schema; + $data->fieldClean($f_attname); + $data->fieldClean($f_table); + $data->fieldClean($f_schema); + $query = "SELECT \"{$f_attname}\", count(*) AS \"count\" FROM \"{$f_schema}\".\"{$f_table}\" GROUP BY \"{$f_attname}\" ORDER BY \"{$f_attname}\""; + + if ($isTable) { + + /* Browse link */ + /* FIXME browsing a col should somehow be a action so we don't + * send an ugly SQL in the URL */ + + $navlinks = [ + 'browse' => [ + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'subject' => 'column', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $tableName, + 'column' => $_REQUEST['column'], + 'return' => 'column', + 'query' => $query, + ], + ], + ], + 'content' => $lang['strbrowse'], + ], + 'alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'colproperties.php', + 'urlvars' => [ + 'action' => 'properties', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $tableName, + 'column' => $_REQUEST['column'], + ], + ], + ], + 'content' => $lang['stralter'], + ], + 'drop' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $tableName, + 'column' => $_REQUEST['column'], + ], + ], + ], + 'content' => $lang['strdrop'], + ], + ]; + } else { + /* Browse link */ + $navlinks = [ + 'browse' => [ + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'subject' => 'column', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $tableName, + 'column' => $_REQUEST['column'], + 'return' => 'column', + 'query' => $query, + ], + ], + ], + 'content' => $lang['strbrowse'], + ], + ]; + } + + $misc->printNavLinks($navlinks, 'colproperties-colproperties', get_defined_vars()); + } + } + +} diff --git a/src/controllers/ConstraintController.php b/src/controllers/ConstraintController.php new file mode 100644 index 00000000..dd02702f --- /dev/null +++ b/src/controllers/ConstraintController.php @@ -0,0 +1,616 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class ConstraintController extends BaseController { + public $_name = 'ConstraintController'; + +/** + * Confirm and then actually add a FOREIGN KEY constraint + */ + function addForeignKey($stage, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['target'])) { + $_POST['target'] = ''; + } + + switch ($stage) { + case 2: + // Check that they've given at least one source column + if (!isset($_REQUEST['SourceColumnList']) && (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) || sizeof($_POST['IndexColumnList']) == 0)) { + $this->addForeignKey(1, $lang['strfkneedscols']); + } else { + // Copy the IndexColumnList variable from stage 1 + if (isset($_REQUEST['IndexColumnList']) && !isset($_REQUEST['SourceColumnList'])) { + $_REQUEST['SourceColumnList'] = serialize($_REQUEST['IndexColumnList']); + } + + // Initialise variables + if (!isset($_POST['upd_action'])) { + $_POST['upd_action'] = null; + } + + if (!isset($_POST['del_action'])) { + $_POST['del_action'] = null; + } + + if (!isset($_POST['match'])) { + $_POST['match'] = null; + } + + if (!isset($_POST['deferrable'])) { + $_POST['deferrable'] = null; + } + + if (!isset($_POST['initially'])) { + $_POST['initially'] = null; + } + + $_REQUEST['target'] = unserialize($_REQUEST['target']); + + $misc->printTrail('table'); + $misc->printTitle($lang['straddfk'], 'pg.constraint.foreign_key'); + $misc->printMsg($msg); + + // Unserialize target and fetch appropriate table. This is a bit messy + // because the table could be in another schema. + $data->setSchema($_REQUEST['target']['schemaname']); + $attrs = $data->getTableAttributes($_REQUEST['target']['tablename']); + $data->setSchema($_REQUEST['schema']); + + $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); + $selColumns->set_style('width: 15em;'); + + if ($attrs->recordCount() > 0) { + while (!$attrs->EOF) { + $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); + $attrs->moveNext(); + } + } + + $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); + $selIndex->set_style('width: 15em;'); + $selIndex->set_attribute('id', 'IndexColumnList'); + $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); + $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); + $buttonAdd->set_attribute('type', 'button'); + + $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); + $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); + $buttonRemove->set_attribute('type', 'button'); + + echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; + + echo "<table>\n"; + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strfktarget']}</th></tr>"; + echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=data>{$lang['strfkcolumnlist']}</th></tr>\n"; + echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; + echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; + echo "<td class=\"data1\">" . $selIndex->fetch() . "</td></tr>\n"; + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['stractions']}</th></tr>"; + echo "<tr>"; + echo "<td class=\"data1\" colspan=\"3\">\n"; + // ON SELECT actions + echo "{$lang['stronupdate']} <select name=\"upd_action\">"; + foreach ($data->fkactions as $v) { + echo "<option value=\"{$v}\"", ($_POST['upd_action'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + + echo "</select><br />\n"; + + // ON DELETE actions + echo "{$lang['strondelete']} <select name=\"del_action\">"; + foreach ($data->fkactions as $v) { + echo "<option value=\"{$v}\"", ($_POST['del_action'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + + echo "</select><br />\n"; + + // MATCH options + echo "<select name=\"match\">"; + foreach ($data->fkmatches as $v) { + echo "<option value=\"{$v}\"", ($_POST['match'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + + echo "</select><br />\n"; + + // DEFERRABLE options + echo "<select name=\"deferrable\">"; + foreach ($data->fkdeferrable as $v) { + echo "<option value=\"{$v}\"", ($_POST['deferrable'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + + echo "</select><br />\n"; + + // INITIALLY options + echo "<select name=\"initially\">"; + foreach ($data->fkinitial as $v) { + echo "<option value=\"{$v}\"", ($_POST['initially'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + + echo "</select>\n"; + echo "</td></tr>\n"; + echo "</table>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_foreign_key\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; + echo "<input type=\"hidden\" name=\"target\" value=\"", htmlspecialchars(serialize($_REQUEST['target'])), "\" />\n"; + echo "<input type=\"hidden\" name=\"SourceColumnList\" value=\"", htmlspecialchars($_REQUEST['SourceColumnList']), "\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + break; + case 3: + // Unserialize target + $_POST['target'] = unserialize($_POST['target']); + + // Check that they've given at least one column + if (isset($_POST['SourceColumnList'])) { + $temp = unserialize($_POST['SourceColumnList']); + } + + if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) + || sizeof($_POST['IndexColumnList']) == 0 || !isset($temp) + || !is_array($temp) || sizeof($temp) == 0) { + $this->addForeignKey(2, $lang['strfkneedscols']); + } else { + $status = $data->addForeignKey($_POST['table'], $_POST['target']['schemaname'], $_POST['target']['tablename'], + unserialize($_POST['SourceColumnList']), $_POST['IndexColumnList'], $_POST['upd_action'], $_POST['del_action'], + $_POST['match'], $_POST['deferrable'], $_POST['initially'], $_POST['name']); + if ($status == 0) { + $this->doDefault($lang['strfkadded']); + } else { + $this->addForeignKey(2, $lang['strfkaddedbad']); + } + + } + break; + default: + $misc->printTrail('table'); + $misc->printTitle($lang['straddfk'], 'pg.constraint.foreign_key'); + $misc->printMsg($msg); + + $attrs = $data->getTableAttributes($_REQUEST['table']); + $tables = $data->getTables(true); + + $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); + $selColumns->set_style('width: 15em;'); + + if ($attrs->recordCount() > 0) { + while (!$attrs->EOF) { + $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); + $attrs->moveNext(); + } + } + + $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); + $selIndex->set_style('width: 15em;'); + $selIndex->set_attribute('id', 'IndexColumnList'); + $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); + $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); + $buttonAdd->set_attribute('type', 'button'); + + $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); + $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); + $buttonRemove->set_attribute('type', 'button'); + + echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; + + echo "<table>\n"; + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strname']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" /></td></tr>\n"; + echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=\"data required\">{$lang['strfkcolumnlist']}</th></tr>\n"; + echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; + echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>\n"; + echo "<td class=data1>" . $selIndex->fetch() . "</td></tr>\n"; + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strfktarget']}</th></tr>"; + echo "<tr>"; + echo "<td class=\"data1\" colspan=\"3\"><select name=\"target\">"; + while (!$tables->EOF) { + $key = ['schemaname' => $tables->fields['nspname'], 'tablename' => $tables->fields['relname']]; + $key = serialize($key); + echo "<option value=\"", htmlspecialchars($key), "\">"; + if ($tables->fields['nspname'] != $_REQUEST['schema']) { + echo htmlspecialchars($tables->fields['nspname']), '.'; + } + echo htmlspecialchars($tables->fields['relname']), "</option>\n"; + $tables->moveNext(); + } + echo "</select>\n"; + echo "</td></tr>"; + echo "</table>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_foreign_key\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + break; + } + + } + +/** + * Confirm and then actually add a PRIMARY KEY or UNIQUE constraint + */ + function addPrimaryOrUniqueKey($type, $confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if ($confirm) { + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['tablespace'])) { + $_POST['tablespace'] = ''; + } + + $misc->printTrail('table'); + + switch ($type) { + case 'primary': + $misc->printTitle($lang['straddpk'], 'pg.constraint.primary_key'); + break; + case 'unique': + $misc->printTitle($lang['stradduniq'], 'pg.constraint.unique_key'); + break; + default: + $this->doDefault($lang['strinvalidparam']); + return; + } + + $misc->printMsg($msg); + + $attrs = $data->getTableAttributes($_REQUEST['table']); + // Fetch all tablespaces from the database + if ($data->hasTablespaces()) { + $tablespaces = $data->getTablespaces(); + } + + $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); + $selColumns->set_style('width: 15em;'); + + if ($attrs->recordCount() > 0) { + while (!$attrs->EOF) { + $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); + $attrs->moveNext(); + } + } + + $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); + $selIndex->set_style('width: 15em;'); + $selIndex->set_attribute('id', 'IndexColumnList'); + $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); + $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); + $buttonAdd->set_attribute('type', 'button'); + + $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); + $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); + $buttonRemove->set_attribute('type', 'button'); + + echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; + + echo "<table>\n"; + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strname']}</th></tr>"; + echo "<tr>"; + echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), + "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" /></td></tr>"; + echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=\"data required\">{$lang['strindexcolumnlist']}</th></tr>\n"; + echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; + echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; + echo "<td class=data1>" . $selIndex->fetch() . "</td></tr>\n"; + + // Tablespace (if there are any) + if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { + echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strtablespace']}</th></tr>"; + echo "<tr><td class=\"data1\" colspan=\"3\"><select name=\"tablespace\">\n"; + // Always offer the default (empty) option + echo "\t\t\t\t<option value=\"\"", + ($_POST['tablespace'] == '') ? ' selected="selected"' : '', "></option>\n"; + // Display all other tablespaces + while (!$tablespaces->EOF) { + $spcname = htmlspecialchars($tablespaces->fields['spcname']); + echo "\t\t\t\t<option value=\"{$spcname}\"", + ($spcname == $_POST['tablespace']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; + $tablespaces->moveNext(); + } + echo "</select></td></tr>\n"; + } + + echo "</table>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_primary_key\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($type), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + // Default tablespace to empty if it isn't set + if (!isset($_POST['tablespace'])) { + $_POST['tablespace'] = ''; + } + + if ($_POST['type'] == 'primary') { + // Check that they've given at least one column + if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) + || sizeof($_POST['IndexColumnList']) == 0) { + $this->addPrimaryOrUniqueKey($_POST['type'], true, $lang['strpkneedscols']); + } else { + $status = $data->addPrimaryKey($_POST['table'], $_POST['IndexColumnList'], $_POST['name'], $_POST['tablespace']); + if ($status == 0) { + $this->doDefault($lang['strpkadded']); + } else { + $this->addPrimaryOrUniqueKey($_POST['type'], true, $lang['strpkaddedbad']); + } + + } + } elseif ($_POST['type'] == 'unique') { + // Check that they've given at least one column + if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) + || sizeof($_POST['IndexColumnList']) == 0) { + $this->addPrimaryOrUniqueKey($_POST['type'], true, $lang['struniqneedscols']); + } else { + $status = $data->addUniqueKey($_POST['table'], $_POST['IndexColumnList'], $_POST['name'], $_POST['tablespace']); + if ($status == 0) { + $this->doDefault($lang['struniqadded']); + } else { + $this->addPrimaryOrUniqueKey($_POST['type'], true, $lang['struniqaddedbad']); + } + + } + } else { + $this->doDefault($lang['strinvalidparam']); + } + + } + } + +/** + * Confirm and then actually add a CHECK constraint + */ + function addCheck($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['definition'])) { + $_POST['definition'] = ''; + } + + if ($confirm) { + $misc->printTrail('table'); + $misc->printTitle($lang['straddcheck'], 'pg.constraint.check'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/constraints.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; + echo "<th class=\"data required\">{$lang['strdefinition']}</th></tr>\n"; + + echo "<tr><td class=\"data1\"><input name=\"name\" size=\"24\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" /></td>\n"; + + echo "<td class=\"data1\">(<input name=\"definition\" size=\"64\" value=\"", + htmlspecialchars($_POST['definition']), "\" />)</td></tr>\n"; + echo "</table>\n"; + + echo "<input type=\"hidden\" name=\"action\" value=\"save_add_check\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"submit\" name=\"ok\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + } else { + if (trim($_POST['definition']) == '') { + $this->addCheck(true, $lang['strcheckneedsdefinition']); + } else { + $status = $data->addCheckConstraint($_POST['table'], + $_POST['definition'], $_POST['name']); + if ($status == 0) { + $this->doDefault($lang['strcheckadded']); + } else { + $this->addCheck(true, $lang['strcheckaddedbad']); + } + + } + } + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('constraint'); + $misc->printTitle($lang['strdrop'], 'pg.constraint.drop'); + + echo "<p>", sprintf($lang['strconfdropconstraint'], $misc->printVal($_REQUEST['constraint']), + $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/constraints.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"constraint\" value=\"", htmlspecialchars($_REQUEST['constraint']), "\" />\n"; + echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropConstraint($_POST['constraint'], $_POST['table'], $_POST['type'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strconstraintdropped']); + } else { + $this->doDefault($lang['strconstraintdroppedbad']); + } + + } + } + + /** + * List all the constraints on the table + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $cnPre = function (&$rowdata) use ($data) { + + if (is_null($rowdata->fields['consrc'])) { + $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $rowdata->fields['indkey'])); + $rowdata->fields['+definition'] = ($rowdata->fields['contype'] == 'u' ? "UNIQUE (" : "PRIMARY KEY (") . join(',', $atts) . ')'; + } else { + $rowdata->fields['+definition'] = $rowdata->fields['consrc']; + } + }; + + $misc->printTrail('table'); + $misc->printTabs('table', 'constraints'); + $misc->printMsg($msg); + + $constraints = $data->getConstraints($_REQUEST['table']); + + $columns = [ + 'constraint' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('conname'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('+definition'), + 'type' => 'pre', + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('constcomment'), + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'table' => $_REQUEST['table'], + 'constraint' => Decorator::field('conname'), + 'type' => Decorator::field('contype'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($constraints, $columns, $actions, 'constraints-constraints', $lang['strnoconstraints'], $cnPre); + + $navlinks = [ + 'addcheck' => [ + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'action' => 'add_check', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['straddcheck'], + ], + 'adduniq' => [ + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'action' => 'add_unique_key', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['stradduniq'], + ], + 'addpk' => [ + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'action' => 'add_primary_key', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['straddpk'], + ], + 'addfk' => [ + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'action' => 'add_foreign_key', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['straddfk'], + ], + ]; + $misc->printNavLinks($navlinks, 'constraints-constraints', get_defined_vars()); + } +} diff --git a/src/controllers/ConversionController.php b/src/controllers/ConversionController.php new file mode 100644 index 00000000..a33243a8 --- /dev/null +++ b/src/controllers/ConversionController.php @@ -0,0 +1,55 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class ConversionController extends BaseController { + public $_name = 'ConversionController'; +/** + * Show default list of conversions in the database + */ + public function doDefault($msg = '') { + + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'conversions'); + $misc->printMsg($msg); + + $conversions = $data->getconversions(); + + $columns = [ + 'conversion' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('conname'), + ], + 'source_encoding' => [ + 'title' => $lang['strsourceencoding'], + 'field' => Decorator::field('conforencoding'), + ], + 'target_encoding' => [ + 'title' => $lang['strtargetencoding'], + 'field' => Decorator::field('contoencoding'), + ], + 'default' => [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('condefault'), + 'type' => 'yesno', + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('concomment'), + ], + ]; + + $actions = []; + + echo $misc->printTable($conversions, $columns, $actions, 'conversions-conversions', $lang['strnoconversions']); + } +} diff --git a/src/controllers/DatabaseController.php b/src/controllers/DatabaseController.php new file mode 100644 index 00000000..b3f47e40 --- /dev/null +++ b/src/controllers/DatabaseController.php @@ -0,0 +1,654 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class DatabaseController extends BaseController { + use AdminTrait; + public $script = 'database.php'; + public $_name = 'DatabaseController'; + + function _highlight($string, $term) { + return str_replace($term, "<b>{$term}</b>", $string); + } + +/** + * Sends a signal to a process + */ + public function doSignal() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->sendSignal($_REQUEST['pid'], $_REQUEST['signal']); + if ($status == 0) { + $this->doProcesses($lang['strsignalsent']); + } else { + $this->doProcesses($lang['strsignalsentbad']); + } + + } + +/** + * Searches for a named database object + */ + public function doFind($confirm = true, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['term'])) { + $_REQUEST['term'] = ''; + } + + if (!isset($_REQUEST['filter'])) { + $_REQUEST['filter'] = ''; + } + + $misc->printTrail('database'); + $misc->printTabs('database', 'find'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/database.php\" method=\"post\">\n"; + echo "<p><input name=\"term\" value=\"", htmlspecialchars($_REQUEST['term']), + "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n"; + // Output list of filters. This is complex due to all the 'has' and 'conf' feature possibilities + echo "<select name=\"filter\">\n"; + echo "\t<option value=\"\"", ($_REQUEST['filter'] == '') ? ' selected="selected"' : '', ">{$lang['strallobjects']}</option>\n"; + echo "\t<option value=\"SCHEMA\"", ($_REQUEST['filter'] == 'SCHEMA') ? ' selected="selected"' : '', ">{$lang['strschemas']}</option>\n"; + echo "\t<option value=\"TABLE\"", ($_REQUEST['filter'] == 'TABLE') ? ' selected="selected"' : '', ">{$lang['strtables']}</option>\n"; + echo "\t<option value=\"VIEW\"", ($_REQUEST['filter'] == 'VIEW') ? ' selected="selected"' : '', ">{$lang['strviews']}</option>\n"; + echo "\t<option value=\"SEQUENCE\"", ($_REQUEST['filter'] == 'SEQUENCE') ? ' selected="selected"' : '', ">{$lang['strsequences']}</option>\n"; + echo "\t<option value=\"COLUMN\"", ($_REQUEST['filter'] == 'COLUMN') ? ' selected="selected"' : '', ">{$lang['strcolumns']}</option>\n"; + echo "\t<option value=\"RULE\"", ($_REQUEST['filter'] == 'RULE') ? ' selected="selected"' : '', ">{$lang['strrules']}</option>\n"; + echo "\t<option value=\"INDEX\"", ($_REQUEST['filter'] == 'INDEX') ? ' selected="selected"' : '', ">{$lang['strindexes']}</option>\n"; + echo "\t<option value=\"TRIGGER\"", ($_REQUEST['filter'] == 'TRIGGER') ? ' selected="selected"' : '', ">{$lang['strtriggers']}</option>\n"; + echo "\t<option value=\"CONSTRAINT\"", ($_REQUEST['filter'] == 'CONSTRAINT') ? ' selected="selected"' : '', ">{$lang['strconstraints']}</option>\n"; + echo "\t<option value=\"FUNCTION\"", ($_REQUEST['filter'] == 'FUNCTION') ? ' selected="selected"' : '', ">{$lang['strfunctions']}</option>\n"; + echo "\t<option value=\"DOMAIN\"", ($_REQUEST['filter'] == 'DOMAIN') ? ' selected="selected"' : '', ">{$lang['strdomains']}</option>\n"; + if ($conf['show_advanced']) { + echo "\t<option value=\"AGGREGATE\"", ($_REQUEST['filter'] == 'AGGREGATE') ? ' selected="selected"' : '', ">{$lang['straggregates']}</option>\n"; + echo "\t<option value=\"TYPE\"", ($_REQUEST['filter'] == 'TYPE') ? ' selected="selected"' : '', ">{$lang['strtypes']}</option>\n"; + echo "\t<option value=\"OPERATOR\"", ($_REQUEST['filter'] == 'OPERATOR') ? ' selected="selected"' : '', ">{$lang['stroperators']}</option>\n"; + echo "\t<option value=\"OPCLASS\"", ($_REQUEST['filter'] == 'OPCLASS') ? ' selected="selected"' : '', ">{$lang['stropclasses']}</option>\n"; + echo "\t<option value=\"CONVERSION\"", ($_REQUEST['filter'] == 'CONVERSION') ? ' selected="selected"' : '', ">{$lang['strconversions']}</option>\n"; + echo "\t<option value=\"LANGUAGE\"", ($_REQUEST['filter'] == 'LANGUAGE') ? ' selected="selected"' : '', ">{$lang['strlanguages']}</option>\n"; + } + echo "</select>\n"; + echo "<input type=\"submit\" value=\"{$lang['strfind']}\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"action\" value=\"find\" /></p>\n"; + echo "</form>\n"; + + // Default focus + $misc->setFocus('forms[0].term'); + + // If a search term has been specified, then perform the search + // and display the results, grouped by object type + if ($_REQUEST['term'] != '') { + $rs = $data->findObject($_REQUEST['term'], $_REQUEST['filter']); + if ($rs->recordCount() > 0) { + $curr = ''; + while (!$rs->EOF) { + // Output a new header if the current type has changed, but not if it's just changed the rule type + if ($rs->fields['type'] != $curr) { + // Short-circuit in the case of changing from table rules to view rules; table cols to view cols; + // table constraints to domain constraints + if ($rs->fields['type'] == 'RULEVIEW' && $curr == 'RULETABLE') { + $curr = $rs->fields['type']; + } elseif ($rs->fields['type'] == 'COLUMNVIEW' && $curr == 'COLUMNTABLE') { + $curr = $rs->fields['type']; + } elseif ($rs->fields['type'] == 'CONSTRAINTTABLE' && $curr == 'CONSTRAINTDOMAIN') { + $curr = $rs->fields['type']; + } else { + if ($curr != '') { + echo "</ul>\n"; + } + + $curr = $rs->fields['type']; + echo "<h3>"; + switch ($curr) { + case 'SCHEMA': + echo $lang['strschemas']; + break; + case 'TABLE': + echo $lang['strtables']; + break; + case 'VIEW': + echo $lang['strviews']; + break; + case 'SEQUENCE': + echo $lang['strsequences']; + break; + case 'COLUMNTABLE': + case 'COLUMNVIEW': + echo $lang['strcolumns']; + break; + case 'INDEX': + echo $lang['strindexes']; + break; + case 'CONSTRAINTTABLE': + case 'CONSTRAINTDOMAIN': + echo $lang['strconstraints']; + break; + case 'TRIGGER': + echo $lang['strtriggers']; + break; + case 'RULETABLE': + case 'RULEVIEW': + echo $lang['strrules']; + break; + case 'FUNCTION': + echo $lang['strfunctions']; + break; + case 'TYPE': + echo $lang['strtypes']; + break; + case 'DOMAIN': + echo $lang['strdomains']; + break; + case 'OPERATOR': + echo $lang['stroperators']; + break; + case 'CONVERSION': + echo $lang['strconversions']; + break; + case 'LANGUAGE': + echo $lang['strlanguages']; + break; + case 'AGGREGATE': + echo $lang['straggregates']; + break; + case 'OPCLASS': + echo $lang['stropclasses']; + break; + } + echo "</h3>"; + echo "<ul>\n"; + } + } + + switch ($curr) { + case 'SCHEMA': + echo "<li><a href=\"/redirect/schema?{$misc->href}&schema=", $misc->printVal($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'TABLE': + echo "<li>"; + echo "<a href=\"tables.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/table?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", + urlencode($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'VIEW': + echo "<li>"; + echo "<a href=\"views.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/view?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&view=", + urlencode($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'SEQUENCE': + echo "<li>"; + echo "<a href=\"sequences.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"sequences.php?subject=sequence&action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), + "&sequence=", urlencode($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'COLUMNTABLE': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"tblproperties.php?subject=table&{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"colproperties.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", + urlencode($rs->fields['relname']), "&column=", urlencode($rs->fields['name']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'COLUMNVIEW': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"viewproperties.php?subject=view&{$misc->href}&view=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"colproperties.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&view=", + urlencode($rs->fields['relname']), "&column=", urlencode($rs->fields['name']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'INDEX': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"indexes.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", urlencode($rs->fields['relname']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'CONSTRAINTTABLE': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"constraints.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", + urlencode($rs->fields['relname']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'CONSTRAINTDOMAIN': + echo "<li>"; + echo "<a href=\"domains.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"domains.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&domain=", urlencode($rs->fields['relname']), "\">", + $misc->printVal($rs->fields['relname']), '.', $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'TRIGGER': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"triggers.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", urlencode($rs->fields['relname']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'RULETABLE': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"rules.php?subject=table&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&reltype=table&table=", + urlencode($rs->fields['relname']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'RULEVIEW': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"/redirect/view?{$misc->href}&view=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; + echo "<a href=\"rules.php?subject=view&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&reltype=view&view=", + urlencode($rs->fields['relname']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'FUNCTION': + echo "<li>"; + echo "<a href=\"functions.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"functions.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&function=", + urlencode($rs->fields['name']), "&function_oid=", urlencode($rs->fields['oid']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'TYPE': + echo "<li>"; + echo "<a href=\"types.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"types.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&type=", + urlencode($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'DOMAIN': + echo "<li>"; + echo "<a href=\"domains.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"domains.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&domain=", + urlencode($rs->fields['name']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'OPERATOR': + echo "<li>"; + echo "<a href=\"operators.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"operators.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&operator=", + urlencode($rs->fields['name']), "&operator_oid=", urlencode($rs->fields['oid']), "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'CONVERSION': + echo "<li>"; + echo "<a href=\"conversions.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"conversions.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), + "\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'LANGUAGE': + echo "<li><a href=\"languages.php?{$misc->href}\">", $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'AGGREGATE': + echo "<li>"; + echo "<a href=\"aggregates.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"aggregates.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + case 'OPCLASS': + echo "<li>"; + echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; + echo "<a href=\"opclasses.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", + $this->_highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; + break; + } + $rs->moveNext(); + } + echo "</ul>\n"; + + echo "<p>", $rs->recordCount(), " ", $lang['strobjects'], "</p>\n"; + } else { + echo "<p>{$lang['strnoobjects']}</p>\n"; + } + + } + } + +/** + * Displays options for database download + */ + public function doExport($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('database'); + $misc->printTabs('database', 'export'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/dbexport.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; + // Data only + echo "<tr><th class=\"data left\" rowspan=\"2\">"; + echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"d_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; + // Structure only + echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; + echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; + // Structure and data + echo "<tr><th class=\"data left\" rowspan=\"3\">"; + echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"sd_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; + echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; + echo "</table>\n"; + + echo "<h3>{$lang['stroptions']}</h3>\n"; + echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; + echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label>\n"; + // MSIE cannot download gzip in SSL mode - it's just broken + if (!(strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS']))) { + echo "<br /><input type=\"radio\" id=\"output3\" name=\"output\" value=\"gzipped\" /><label for=\"output3\">{$lang['strdownloadgzipped']}</label>\n"; + } + echo "</p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"database\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Show the current status of all database variables + */ + public function doVariables() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Fetch the variables from the database + $variables = $data->getVariables(); + $misc->printTrail('database'); + $misc->printTabs('database', 'variables'); + + $columns = [ + 'variable' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('name'), + ], + 'value' => [ + 'title' => $lang['strsetting'], + 'field' => Decorator::field('setting'), + ], + ]; + + $actions = []; + + echo $misc->printTable($variables, $columns, $actions, 'database-variables', $lang['strnodata']); + } + +/** + * Show all current database connections and any queries they + * are running. + */ + public function doProcesses($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('database'); + $misc->printTabs('database', 'processes'); + $misc->printMsg($msg); + + if (strlen($msg) === 0) { + echo "<br /><a id=\"control\" href=\"\"><img src=\"" . $misc->icon('Refresh') . "\" alt=\"{$lang['strrefresh']}\" title=\"{$lang['strrefresh']}\"/> {$lang['strrefresh']}</a>"; + } + + echo "<div id=\"data_block\">"; + $this->currentProcesses(); + echo "</div>"; + } + + function currentProcesses($isAjax = false) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Display prepared transactions + if ($data->hasPreparedXacts()) { + echo "<h3>{$lang['strpreparedxacts']}</h3>\n"; + $prep_xacts = $data->getPreparedXacts($_REQUEST['database']); + + $columns = [ + 'transaction' => [ + 'title' => $lang['strxactid'], + 'field' => Decorator::field('transaction'), + ], + 'gid' => [ + 'title' => $lang['strgid'], + 'field' => Decorator::field('gid'), + ], + 'prepared' => [ + 'title' => $lang['strstarttime'], + 'field' => Decorator::field('prepared'), + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('owner'), + ], + ]; + + $actions = []; + + echo $misc->printTable($prep_xacts, $columns, $actions, 'database-processes-preparedxacts', $lang['strnodata']); + } + + // Fetch the processes from the database + echo "<h3>{$lang['strprocesses']}</h3>\n"; + $processes = $data->getProcesses($_REQUEST['database']); + + $columns = [ + 'user' => [ + 'title' => $lang['strusername'], + 'field' => Decorator::field('usename'), + ], + 'process' => [ + 'title' => $lang['strprocess'], + 'field' => Decorator::field('pid'), + ], + 'blocked' => [ + 'title' => $lang['strblocked'], + 'field' => Decorator::field('waiting'), + ], + 'query' => [ + 'title' => $lang['strsql'], + 'field' => Decorator::field('query'), + ], + 'start_time' => [ + 'title' => $lang['strstarttime'], + 'field' => Decorator::field('query_start'), + ], + ]; + + // Build possible actions for our process list + $columns['actions'] = ['title' => $lang['stractions']]; + + $actions = []; + if ($data->hasUserSignals() || $data->isSuperUser()) { + $actions = [ + 'cancel' => [ + 'content' => $lang['strcancel'], + 'attr' => [ + 'href' => [ + 'url' => 'database.php', + 'urlvars' => [ + 'action' => 'signal', + 'signal' => 'CANCEL', + 'pid' => Decorator::field('pid'), + ], + ], + ], + ], + 'kill' => [ + 'content' => $lang['strkill'], + 'attr' => [ + 'href' => [ + 'url' => 'database.php', + 'urlvars' => [ + 'action' => 'signal', + 'signal' => 'KILL', + 'pid' => Decorator::field('pid'), + ], + ], + ], + ], + ]; + + // Remove actions where not supported + if (!$data->hasQueryKill()) { + unset($actions['kill']); + } + + if (!$data->hasQueryCancel()) { + unset($actions['cancel']); + } + + } + + if (count($actions) == 0) { + unset($columns['actions']); + } + + echo $misc->printTable($processes, $columns, $actions, 'database-processes', $lang['strnodata']); + + if ($isAjax) { + exit; + } + + } + + function currentLocks($isAjax = false) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Get the info from the pg_locks view + $variables = $data->getLocks(); + + $columns = [ + 'namespace' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'tablename' => [ + 'title' => $lang['strtablename'], + 'field' => Decorator::field('tablename'), + ], + 'vxid' => [ + 'title' => $lang['strvirtualtransaction'], + 'field' => Decorator::field('virtualtransaction'), + ], + 'transactionid' => [ + 'title' => $lang['strtransaction'], + 'field' => Decorator::field('transaction'), + ], + 'processid' => [ + 'title' => $lang['strprocessid'], + 'field' => Decorator::field('pid'), + ], + 'mode' => [ + 'title' => $lang['strmode'], + 'field' => Decorator::field('mode'), + ], + 'granted' => [ + 'title' => $lang['strislockheld'], + 'field' => Decorator::field('granted'), + 'type' => 'yesno', + ], + ]; + + if (!$data->hasVirtualTransactionId()) { + unset($columns['vxid']); + } + + $actions = []; + echo $misc->printTable($variables, $columns, $actions, 'database-locks', $lang['strnodata']); + + if ($isAjax) { + exit; + } + + } + +/** + * Show the existing table locks in the current database + */ + public function doLocks() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('database'); + $misc->printTabs('database', 'locks'); + + echo "<br /><a id=\"control\" href=\"\"><img src=\"" . $misc->icon('Refresh') . "\" alt=\"{$lang['strrefresh']}\" title=\"{$lang['strrefresh']}\"/> {$lang['strrefresh']}</a>"; + + echo "<div id=\"data_block\">"; + $this->currentLocks(); + echo "</div>"; + } + +/** + * Allow execution of arbitrary SQL statements on a database + */ + public function doSQL() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ((!isset($_SESSION['sqlquery'])) || isset($_REQUEST['new'])) { + $_SESSION['sqlquery'] = ''; + $_REQUEST['paginate'] = 'on'; + } + + $misc->printTrail('database'); + $misc->printTabs('database', 'sql'); + echo "<p>{$lang['strentersql']}</p>\n"; + echo "<form action=\"/src/views/sql.php\" method=\"post\" enctype=\"multipart/form-data\">\n"; + echo "<p>{$lang['strsql']}<br />\n"; + echo "<textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"query\">", + htmlspecialchars($_SESSION['sqlquery']), "</textarea></p>\n"; + + // Check that file uploads are enabled + if (ini_get('file_uploads')) { + // Don't show upload option if max size of uploads is zero + $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize')); + if (is_double($max_size) && $max_size > 0) { + echo "<p><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />\n"; + echo "<label for=\"script\">{$lang['struploadscript']}</label> <input id=\"script\" name=\"script\" type=\"file\" /></p>\n"; + } + } + + echo "<p><input type=\"checkbox\" id=\"paginate\" name=\"paginate\"", (isset($_REQUEST['paginate']) ? ' checked="checked"' : ''), " /><label for=\"paginate\">{$lang['strpaginate']}</label></p>\n"; + echo "<p><input type=\"submit\" name=\"execute\" accesskey=\"r\" value=\"{$lang['strexecute']}\" />\n"; + echo $misc->form; + echo "<input type=\"reset\" accesskey=\"q\" value=\"{$lang['strreset']}\" /></p>\n"; + echo "</form>\n"; + + // Default focus + $misc->setFocus('forms[0].query'); + } +} diff --git a/src/controllers/DomainController.php b/src/controllers/DomainController.php new file mode 100644 index 00000000..22f8a841 --- /dev/null +++ b/src/controllers/DomainController.php @@ -0,0 +1,566 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class DomainController extends BaseController { + public $_name = 'DomainController'; + +/** + * Function to save after altering a domain + */ + public function doSaveAlter() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->alterDomain($_POST['domain'], $_POST['domdefault'], + isset($_POST['domnotnull']), $_POST['domowner']); + if ($status == 0) { + $this->doProperties($lang['strdomainaltered']); + } else { + $this->doAlter($lang['strdomainalteredbad']); + } + + } + +/** + * Allow altering a domain + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('domain'); + $misc->printTitle($lang['stralter'], 'pg.domain.alter'); + $misc->printMsg($msg); + + // Fetch domain info + $domaindata = $data->getDomain($_REQUEST['domain']); + // Fetch all users + $users = $data->getUsers(); + + if ($domaindata->recordCount() > 0) { + if (!isset($_POST['domname'])) { + $_POST['domtype'] = $domaindata->fields['domtype']; + $_POST['domdefault'] = $domaindata->fields['domdef']; + $domaindata->fields['domnotnull'] = $data->phpBool($domaindata->fields['domnotnull']); + if ($domaindata->fields['domnotnull']) { + $_POST['domnotnull'] = 'on'; + } + + $_POST['domowner'] = $domaindata->fields['domowner']; + } + + // Display domain info + echo "<form action=\"/src/views/domains.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\" style=\"width: 70px\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domname']), "</td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['strtype']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domtype']), "</td></tr>\n"; + echo "<tr><th class=\"data left\"><label for=\"domnotnull\">{$lang['strnotnull']}</label></th>\n"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"domnotnull\" name=\"domnotnull\"", (isset($_POST['domnotnull']) ? ' checked="checked"' : ''), " /></td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; + echo "<td class=\"data1\"><input name=\"domdefault\" size=\"32\" value=\"", + htmlspecialchars($_POST['domdefault']), "\" /></td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\"><select name=\"domowner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['domowner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_alter\" />\n"; + echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Confirm and then actually add a CHECK constraint + */ + function addCheck($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['definition'])) { + $_POST['definition'] = ''; + } + + if ($confirm) { + $misc->printTrail('domain'); + $misc->printTitle($lang['straddcheck'], 'pg.constraint.check'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/domains.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; + echo "<th class=\"data required\">{$lang['strdefinition']}</th></tr>\n"; + + echo "<tr><td class=\"data1\"><input name=\"name\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" /></td>\n"; + + echo "<td class=\"data1\">(<input name=\"definition\" size=\"32\" value=\"", + htmlspecialchars($_POST['definition']), "\" />)</td></tr>\n"; + echo "</table>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_check\" />\n"; + echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"add\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + } else { + if (trim($_POST['definition']) == '') { + $this->addCheck(true, $lang['strcheckneedsdefinition']); + } else { + $status = $data->addDomainCheckConstraint($_POST['domain'], + $_POST['definition'], $_POST['name']); + if ($status == 0) { + $this->doProperties($lang['strcheckadded']); + } else { + $this->addCheck(true, $lang['strcheckaddedbad']); + } + + } + } + } + +/** + * Show confirmation of drop constraint and perform actual drop + */ + public function doDropConstraint($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('domain'); + $misc->printTitle($lang['strdrop'], 'pg.constraint.drop'); + $misc->printMsg($msg); + + echo "<p>", sprintf($lang['strconfdropconstraint'], $misc->printVal($_REQUEST['constraint']), + $misc->printVal($_REQUEST['domain'])), "</p>\n"; + echo "<form action=\"/src/views/domains.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop_con\" />\n"; + echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; + echo "<input type=\"hidden\" name=\"constraint\" value=\"", htmlspecialchars($_REQUEST['constraint']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropDomainConstraint($_POST['domain'], $_POST['constraint'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doProperties($lang['strconstraintdropped']); + } else { + $this->doDropConstraint(true, $lang['strconstraintdroppedbad']); + } + + } + + } + +/** + * Show properties for a domain. Allow manipulating constraints as well. + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('domain'); + $misc->printTitle($lang['strproperties'], 'pg.domain'); + $misc->printMsg($msg); + + $domaindata = $data->getDomain($_REQUEST['domain']); + + if ($domaindata->recordCount() > 0) { + // Show comment if any + if ($domaindata->fields['domcomment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($domaindata->fields['domcomment']), "</p>\n"; + } + + // Display domain info + $domaindata->fields['domnotnull'] = $data->phpBool($domaindata->fields['domnotnull']); + echo "<table>\n"; + echo "<tr><th class=\"data left\" style=\"width: 70px\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domname']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strtype']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domtype']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strnotnull']}</th>\n"; + echo "<td class=\"data1\">", ($domaindata->fields['domnotnull'] ? 'NOT NULL' : ''), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domdef']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domowner']), "</td></tr>\n"; + echo "</table>\n"; + + // Display domain constraints + echo "<h3>{$lang['strconstraints']}</h3>\n"; + if ($data->hasDomainConstraints()) { + $domaincons = $data->getDomainConstraints($_REQUEST['domain']); + + $columns = [ + 'name' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('conname'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('consrc'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'confirm_drop_con', + 'domain' => $_REQUEST['domain'], + 'constraint' => Decorator::field('conname'), + 'type' => Decorator::field('contype'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($domaincons, $columns, $actions, 'domains-properties', $lang['strnodata']); + } + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + $navlinks = [ + 'drop' => [ + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'domain' => $_REQUEST['domain'], + ], + ], + ], + 'content' => $lang['strdrop'], + ], + ]; + if ($data->hasAlterDomains()) { + $navlinks['addcheck'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'add_check', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'domain' => $_REQUEST['domain'], + ], + ], + ], + 'content' => $lang['straddcheck'], + ]; + $navlinks['alter'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'alter', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'domain' => $_REQUEST['domain'], + ], + ], + ], + 'content' => $lang['stralter'], + ]; + } + + $misc->printNavLinks($navlinks, 'domains-properties', get_defined_vars()); + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('domain'); + $misc->printTitle($lang['strdrop'], 'pg.domain.drop'); + + echo "<p>", sprintf($lang['strconfdropdomain'], $misc->printVal($_REQUEST['domain'])), "</p>\n"; + echo "<form action=\"/src/views/domains.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /><label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropDomain($_POST['domain'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strdomaindropped']); + } else { + $this->doDefault($lang['strdomaindroppedbad']); + } + + } + + } + +/** + * Displays a screen where they can enter a new domain + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['domname'])) { + $_POST['domname'] = ''; + } + + if (!isset($_POST['domtype'])) { + $_POST['domtype'] = ''; + } + + if (!isset($_POST['domlength'])) { + $_POST['domlength'] = ''; + } + + if (!isset($_POST['domarray'])) { + $_POST['domarray'] = ''; + } + + if (!isset($_POST['domdefault'])) { + $_POST['domdefault'] = ''; + } + + if (!isset($_POST['domcheck'])) { + $_POST['domcheck'] = ''; + } + + $types = $data->getTypes(true); + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatedomain'], 'pg.domain.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/domains.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\" style=\"width: 70px\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\"><input name=\"domname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['domname']), "\" /></td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['strtype']}</th>\n"; + echo "<td class=\"data1\">\n"; + // Output return type list + echo "<select name=\"domtype\">\n"; + while (!$types->EOF) { + echo "<option value=\"", htmlspecialchars($types->fields['typname']), "\"", + ($types->fields['typname'] == $_POST['domtype']) ? ' selected="selected"' : '', ">", + $misc->printVal($types->fields['typname']), "</option>\n"; + $types->moveNext(); + } + echo "</select>\n"; + + // Type length + echo "<input type=\"text\" size=\"4\" name=\"domlength\" value=\"", htmlspecialchars($_POST['domlength']), "\" />"; + + // Output array type selector + echo "<select name=\"domarray\">\n"; + echo "<option value=\"\"", ($_POST['domarray'] == '') ? ' selected="selected"' : '', "></option>\n"; + echo "<option value=\"[]\"", ($_POST['domarray'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; + echo "</select></td></tr>\n"; + + echo "<tr><th class=\"data left\"><label for=\"domnotnull\">{$lang['strnotnull']}</label></th>\n"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"domnotnull\" name=\"domnotnull\"", + (isset($_POST['domnotnull']) ? ' checked="checked"' : ''), " /></td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; + echo "<td class=\"data1\"><input name=\"domdefault\" size=\"32\" value=\"", + htmlspecialchars($_POST['domdefault']), "\" /></td></tr>\n"; + if ($data->hasDomainConstraints()) { + echo "<tr><th class=\"data left\">{$lang['strconstraints']}</th>\n"; + echo "<td class=\"data1\">CHECK (<input name=\"domcheck\" size=\"32\" value=\"", + htmlspecialchars($_POST['domcheck']), "\" />)</td></tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new domain in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['domcheck'])) { + $_POST['domcheck'] = ''; + } + + // Check that they've given a name and a definition + if ($_POST['domname'] == '') { + $this->doCreate($lang['strdomainneedsname']); + } else { + $status = $data->createDomain($_POST['domname'], $_POST['domtype'], $_POST['domlength'], $_POST['domarray'] != '', + isset($_POST['domnotnull']), $_POST['domdefault'], $_POST['domcheck']); + if ($status == 0) { + $this->doDefault($lang['strdomaincreated']); + } else { + $this->doCreate($lang['strdomaincreatedbad']); + } + + } + } + +/** + * Show default list of domains in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'domains'); + $misc->printMsg($msg); + + $domains = $data->getDomains(); + + $columns = [ + 'domain' => [ + 'title' => $lang['strdomain'], + 'field' => Decorator::field('domname'), + 'url' => "domains.php?action=properties&{$misc->href}&", + 'vars' => ['domain' => 'domname'], + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('domtype'), + ], + 'notnull' => [ + 'title' => $lang['strnotnull'], + 'field' => Decorator::field('domnotnull'), + 'type' => 'bool', + 'params' => ['true' => 'NOT NULL', 'false' => ''], + ], + 'default' => [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('domdef'), + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('domowner'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('domcomment'), + ], + ]; + + $actions = [ + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'alter', + 'domain' => Decorator::field('domname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'domain' => Decorator::field('domname'), + ], + ], + ], + ], + ]; + + if (!$data->hasAlterDomains()) { + unset($actions['alter']); + } + + echo $misc->printTable($domains, $columns, $actions, 'domains-domains', $lang['strnodomains']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'domains.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatedomain'], + ], + ]; + $misc->printNavLinks($navlinks, 'domains-domains', get_defined_vars()); + } +} diff --git a/src/controllers/FulltextController.php b/src/controllers/FulltextController.php new file mode 100644 index 00000000..0649166f --- /dev/null +++ b/src/controllers/FulltextController.php @@ -0,0 +1,1120 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class FulltextController extends BaseController { + public $_name = 'FulltextController'; + + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'fulltext'); + $misc->printTabs('fulltext', 'ftsconfigs'); + $misc->printMsg($msg); + + $cfgs = $data->getFtsConfigurations(false); + + $columns = [ + 'configuration' => [ + 'title' => $lang['strftsconfig'], + 'field' => Decorator::field('name'), + 'url' => "fulltext.php?action=viewconfig&{$misc->href}&", + 'vars' => ['ftscfg' => 'name'], + ], + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('schema'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'dropconfig', + 'ftscfg' => Decorator::field('name'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'alterconfig', + 'ftscfg' => Decorator::field('name'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($cfgs, $columns, $actions, 'fulltext-fulltext', $lang['strftsnoconfigs']); + + $navlinks = [ + 'createconf' => [ + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'createconfig', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strftscreateconfig'], + ], + ]; + + $misc->printNavLinks($navlinks, 'fulltext-fulltext', get_defined_vars()); + } + + public function doDropConfig($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('ftscfg'); + $misc->printTitle($lang['strdrop'], 'pg.ftscfg.drop'); + + echo "<p>", sprintf($lang['strconfdropftsconfig'], $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"dropconfig\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_REQUEST['ftscfg']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropFtsConfiguration($_POST['ftscfg'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strftsconfigdropped']); + } else { + $this->doDefault($lang['strftsconfigdroppedbad']); + } + + } + + } + + public function doDropDict($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('ftscfg'); // TODO: change to smth related to dictionary + $misc->printTitle($lang['strdrop'], 'pg.ftsdict.drop'); + + echo "<p>", sprintf($lang['strconfdropftsdict'], $misc->printVal($_REQUEST['ftsdict'])), "</p>\n"; + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"dropdict\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo "<input type=\"hidden\" name=\"ftsdict\" value=\"", htmlspecialchars($_REQUEST['ftsdict']), "\" />\n"; + //echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_REQUEST['ftscfg']), "\" />\n"; + echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewdicts\" /></p>\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropFtsDictionary($_POST['ftsdict'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doViewDicts($lang['strftsdictdropped']); + } else { + $this->doViewDicts($lang['strftsdictdroppedbad']); + } + + } + + } + +/** + * Displays a screen where one can enter a new FTS configuration + */ + public function doCreateConfig($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + include_once BASE_PATH . '/classes/Gui.php'; + + $server_info = $misc->getServerInfo(); + + if (!isset($_POST['formName'])) { + $_POST['formName'] = ''; + } + + if (!isset($_POST['formParser'])) { + $_POST['formParser'] = ''; + } + + if (!isset($_POST['formTemplate'])) { + $_POST['formTemplate'] = ''; + } + + if (!isset($_POST['formWithMap'])) { + $_POST['formWithMap'] = ''; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = ''; + } + + // Fetch all FTS configurations from the database + $ftscfgs = $data->getFtsConfigurations(); + // Fetch all FTS parsers from the database + $ftsparsers = $data->getFtsParsers(); + + $misc->printTrail('schema'); + $misc->printTitle($lang['strftscreateconfig'], 'pg.ftscfg.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<table>\n"; + /* conf name */ + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; + + // Template + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftstemplate']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + + $tpls = []; + $tplsel = ''; + while (!$ftscfgs->EOF) { + $data->fieldClean($ftscfgs->fields['schema']); + $data->fieldClean($ftscfgs->fields['name']); + $tplname = $ftscfgs->fields['schema'] . '.' . $ftscfgs->fields['name']; + $tpls[$tplname] = serialize([ + 'name' => $ftscfgs->fields['name'], + 'schema' => $ftscfgs->fields['schema'], + ]); + if ($_POST['formTemplate'] == $tpls[$tplname]) { + $tplsel = htmlspecialchars($tpls[$tplname]); + } + $ftscfgs->moveNext(); + } + echo \PHPPgAdmin\GUI::printCombo($tpls, 'formTemplate', true, $tplsel, false); + echo "\n\t\t</td>\n\t</tr>\n"; + + // Parser + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsparser']}</th>\n"; + echo "\t\t<td class=\"data1\">\n"; + $ftsparsers_ = []; + $ftsparsel = ''; + while (!$ftsparsers->EOF) { + $data->fieldClean($ftsparsers->fields['schema']); + $data->fieldClean($ftsparsers->fields['name']); + $parsername = $ftsparsers->fields['schema'] . '.' . $ftsparsers->fields['name']; + + $ftsparsers_[$parsername] = serialize([ + 'parser' => $ftsparsers->fields['name'], + 'schema' => $ftsparsers->fields['schema'], + ]); + if ($_POST['formParser'] == $ftsparsers_[$parsername]) { + $ftsparsel = htmlspecialchars($ftsparsers_[$parsername]); + } + $ftsparsers->moveNext(); + } + echo \PHPPgAdmin\GUI::printCombo($ftsparsers_, 'formParser', true, $ftsparsel, false); + echo "\n\t\t</td>\n\t</tr>\n"; + + // Comment + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"createconfig\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new FTS configuration in the database + */ + public function doSaveCreateConfig() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $err = ''; + // Check that they've given a name + if ($_POST['formName'] == '') { + $err .= "{$lang['strftsconfigneedsname']}<br />"; + } + + if (($_POST['formParser'] != '') && ($_POST['formTemplate'] != '')) { + $err .= "{$lang['strftscantparsercopy']}<br />"; + } + + if ($err != '') { + return doCreateConfig($err); + } + + if ($_POST['formParser'] != '') { + $formParser = unserialize($_POST['formParser']); + } else { + $formParser = ''; + } + + if ($_POST['formTemplate'] != '') { + $formTemplate = unserialize($_POST['formTemplate']); + } else { + $formTemplate = ''; + } + + $status = $data->createFtsConfiguration($_POST['formName'], $formParser, $formTemplate, $_POST['formComment']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strftsconfigcreated']); + } else { + $this->doCreateConfig($lang['strftsconfigcreatedbad']); + } + + } + +/** + * Display a form to permit editing FTS configuration properies. + */ + public function doAlterConfig($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('ftscfg'); + $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); + $misc->printMsg($msg); + + $ftscfg = $data->getFtsConfigurationByName($_REQUEST['ftscfg']); + if ($ftscfg->recordCount() > 0) { + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = $ftscfg->fields['comment']; + } + + if (!isset($_POST['ftscfg'])) { + $_POST['ftscfg'] = $_REQUEST['ftscfg']; + } + + if (!isset($_POST['formName'])) { + $_POST['formName'] = $_REQUEST['ftscfg']; + } + + if (!isset($_POST['formParser'])) { + $_POST['formParser'] = ''; + } + + // Fetch all FTS parsers from the database + $ftsparsers = $data->getFtsParsers(); + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<table>\n"; + + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" />\n"; + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + // Comment + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\"name=\"formComment\">", htmlspecialchars($_POST['formComment']), "</textarea></td>\n"; + echo "\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alterconfig\" />\n"; + echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + } + +/** + * Save the form submission containing changes to a FTS configuration + */ + public function doSaveAlterConfig() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + $status = $data->updateFtsConfiguration($_POST['ftscfg'], $_POST['formComment'], $_POST['formName']); + if ($status == 0) { + $this->doDefault($lang['strftsconfigaltered']); + } else { + $this->doAlterConfig($lang['strftsconfigalteredbad']); + } + + } + +/** + * View list of FTS parsers + */ + public function doViewParsers($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'fulltext'); + $misc->printTabs('fulltext', 'ftsparsers'); + $misc->printMsg($msg); + + $parsers = $data->getFtsParsers(false); + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('schema'), + ], + 'name' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('name'), + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = []; + + echo $misc->printTable($parsers, $columns, $actions, 'fulltext-viewparsers', $lang['strftsnoparsers']); + + //TODO: navlink to "create parser" + } + +/** + * View list of FTS dictionaries + */ + public function doViewDicts($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'fulltext'); + $misc->printTabs('fulltext', 'ftsdicts'); + $misc->printMsg($msg); + + $dicts = $data->getFtsDictionaries(false); + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('schema'), + ], + 'name' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('name'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'dropdict', + 'ftsdict' => Decorator::field('name'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'alterdict', + 'ftsdict' => Decorator::field('name'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($dicts, $columns, $actions, 'fulltext-viewdicts', $lang['strftsnodicts']); + + $navlinks = [ + 'createdict' => [ + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'createdict', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strftscreatedict'], + ], + ]; + + $misc->printNavLinks($navlinks, 'fulltext-viewdicts', get_defined_vars()); + } + +/** + * View details of FTS configuration given + */ + public function doViewConfig($ftscfg, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('ftscfg'); + $misc->printTabs('schema', 'fulltext'); + $misc->printTabs('fulltext', 'ftsconfigs'); + $misc->printMsg($msg); + + echo "<h3>{$lang['strftsconfigmap']}</h3>\n"; + + $map = $data->getFtsConfigurationMap($ftscfg); + + $columns = [ + 'name' => [ + 'title' => $lang['strftsmapping'], + 'field' => Decorator::field('name'), + ], + 'dictionaries' => [ + 'title' => $lang['strftsdicts'], + 'field' => Decorator::field('dictionaries'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('description'), + ], + ]; + + $actions = [ + 'drop' => [ + 'multiaction' => 'dropmapping', + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'dropmapping', + 'mapping' => Decorator::field('name'), + 'ftscfg' => Decorator::field('cfgname'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'altermapping', + 'mapping' => Decorator::field('name'), + 'ftscfg' => Decorator::field('cfgname'), + ], + ], + ], + ], + 'multiactions' => [ + 'keycols' => ['mapping' => 'name'], + 'url' => 'fulltext.php', + 'default' => null, + 'vars' => ['ftscfg' => $ftscfg], + ], + + ]; + + echo $misc->printTable($map, $columns, $actions, 'fulltext-viewconfig', $lang['strftsemptymap']); + + $navlinks = [ + 'addmapping' => [ + 'attr' => [ + 'href' => [ + 'url' => 'fulltext.php', + 'urlvars' => [ + 'action' => 'addmapping', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'ftscfg' => $ftscfg, + ], + ], + ], + 'content' => $lang['strftsaddmapping'], + ], + ]; + + $misc->printNavLinks($navlinks, 'fulltext-viewconfig', get_defined_vars()); + } + +/** + * Displays a screen where one can enter a details of a new FTS dictionary + */ + public function doCreateDict($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + include_once BASE_PATH . '/classes/Gui.php'; + + $server_info = $misc->getServerInfo(); + + if (!isset($_POST['formName'])) { + $_POST['formName'] = ''; + } + + if (!isset($_POST['formIsTemplate'])) { + $_POST['formIsTemplate'] = false; + } + + if (!isset($_POST['formTemplate'])) { + $_POST['formTemplate'] = ''; + } + + if (!isset($_POST['formLexize'])) { + $_POST['formLexize'] = ''; + } + + if (!isset($_POST['formInit'])) { + $_POST['formInit'] = ''; + } + + if (!isset($_POST['formOption'])) { + $_POST['formOption'] = ''; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = ''; + } + + // Fetch all FTS dictionaries from the database + $ftstpls = $data->getFtsDictionaryTemplates(); + + $misc->printTrail('schema'); + // TODO: create doc links + $misc->printTitle($lang['strftscreatedict'], 'pg.ftsdict.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" /> ", + "<input type=\"checkbox\" name=\"formIsTemplate\" id=\"formIsTemplate\"", $_POST['formIsTemplate'] ? ' checked="checked" ' : '', " />\n", + "<label for=\"formIsTemplate\">{$lang['strftscreatedicttemplate']}</label></td>\n\t</tr>\n"; + + // Template + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftstemplate']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + $tpls = []; + $tplsel = ''; + while (!$ftstpls->EOF) { + $data->fieldClean($ftstpls->fields['schema']); + $data->fieldClean($ftstpls->fields['name']); + $tplname = $ftstpls->fields['schema'] . '.' . $ftstpls->fields['name']; + $tpls[$tplname] = serialize([ + 'name' => $ftstpls->fields['name'], + 'schema' => $ftstpls->fields['schema'], + ]); + if ($_POST['formTemplate'] == $tpls[$tplname]) { + $tplsel = htmlspecialchars($tpls[$tplname]); + } + $ftstpls->moveNext(); + } + echo \PHPPgAdmin\GUI::printCombo($tpls, 'formTemplate', true, $tplsel, false); + echo "\n\t\t</td>\n\t</tr>\n"; + + // TODO: what about maxlengths? + // Lexize + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftslexize']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formLexize\" size=\"32\" maxlength=\"1000\" value=\"", + htmlspecialchars($_POST['formLexize']), "\" ", isset($_POST['formIsTemplate']) ? '' : ' disabled="disabled" ', + "/></td>\n\t</tr>\n"; + + // Init + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsinit']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formInit\" size=\"32\" maxlength=\"1000\" value=\"", + htmlspecialchars($_POST['formInit']), "\"", @$_POST['formIsTemplate'] ? '' : ' disabled="disabled" ', + "/></td>\n\t</tr>\n"; + + // Option + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsoptionsvalues']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formOption\" size=\"32\" maxlength=\"1000\" value=\"", + htmlspecialchars($_POST['formOption']), "\" /></td>\n\t</tr>\n"; + + // Comment + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"createdict\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</p>\n"; + echo "</form>\n", + "<script type=\"text/javascript\"> + function templateOpts() { + isTpl = document.getElementsByName('formIsTemplate')[0].checked; + $this->document.getElementsByName('formTemplate')[0].disabled = isTpl; + $this->document.getElementsByName('formOption')[0].disabled = isTpl; + $this->document.getElementsByName('formLexize')[0].disabled = !isTpl; + $this->document.getElementsByName('formInit')[0].disabled = !isTpl; + } + + $this->document.getElementsByName('formIsTemplate')[0].onchange = templateOpts; + + templateOpts(); + </script>\n"; + } + +/** + * Actually creates the new FTS dictionary in the database + */ + public function doSaveCreateDict() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've given a name + if ($_POST['formName'] == '') { + $this->doCreateDict($lang['strftsdictneedsname']); + } else { + + if (!isset($_POST['formIsTemplate'])) { + $_POST['formIsTemplate'] = false; + } + + if (isset($_POST['formTemplate'])) { + $formTemplate = unserialize($_POST['formTemplate']); + } else { + $formTemplate = ''; + } + + if (!isset($_POST['formLexize'])) { + $_POST['formLexize'] = ''; + } + + if (!isset($_POST['formInit'])) { + $_POST['formInit'] = ''; + } + + if (!isset($_POST['formOption'])) { + $_POST['formOption'] = ''; + } + + $status = $data->createFtsDictionary($_POST['formName'], $_POST['formIsTemplate'], + $formTemplate, $_POST['formLexize'], + $_POST['formInit'], $_POST['formOption'], $_POST['formComment'] + ); + + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doViewDicts($lang['strftsdictcreated']); + } else { + $this->doCreateDict($lang['strftsdictcreatedbad']); + } + + } + } + +/** + * Display a form to permit editing FTS dictionary properies. + */ + public function doAlterDict($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('ftscfg'); // TODO: change to smth related to dictionary + $misc->printTitle($lang['stralter'], 'pg.ftsdict.alter'); + $misc->printMsg($msg); + + $ftsdict = $data->getFtsDictionaryByName($_REQUEST['ftsdict']); + if ($ftsdict->recordCount() > 0) { + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = $ftsdict->fields['comment']; + } + + if (!isset($_POST['ftsdict'])) { + $_POST['ftsdict'] = $_REQUEST['ftsdict']; + } + + if (!isset($_POST['formName'])) { + $_POST['formName'] = $_REQUEST['ftsdict']; + } + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<table>\n"; + + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" />\n"; + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + // Comment + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\"name=\"formComment\">", htmlspecialchars($_POST['formComment']), "</textarea></td>\n"; + echo "\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alterdict\" />\n"; + echo "<input type=\"hidden\" name=\"ftsdict\" value=\"", htmlspecialchars($_POST['ftsdict']), "\" />\n"; + echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewdicts\" /></p>\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + } + +/** + * Save the form submission containing changes to a FTS dictionary + */ + public function doSaveAlterDict() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->updateFtsDictionary($_POST['ftsdict'], $_POST['formComment'], $_POST['formName']); + if ($status == 0) { + $this->doViewDicts($lang['strftsdictaltered']); + } else { + $this->doAlterDict($lang['strftsdictalteredbad']); + } + + } + +/** + * Show confirmation of drop and perform actual drop of FTS mapping + */ + public function doDropMapping($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['mapping']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strftsspecifymappingtodrop']); + return; + } + + if (empty($_REQUEST['ftscfg'])) { + $this->doDefault($lang['strftsspecifyconfigtoalter']); + return; + } + + if ($confirm) { + $misc->printTrail('ftscfg'); // TODO: proper breadcrumbs + $misc->printTitle($lang['strdrop'], 'pg.ftscfg.alter'); + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + + // Case of multiaction drop + if (isset($_REQUEST['ma'])) { + + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdropftsmapping'], $misc->printVal($a['mapping']), $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; + printf('<input type="hidden" name="mapping[]" value="%s" />', htmlspecialchars($a['mapping'])); + } + + } else { + echo "<p>", sprintf($lang['strconfdropftsmapping'], $misc->printVal($_REQUEST['mapping']), $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"mapping\" value=\"", htmlspecialchars($_REQUEST['mapping']), "\" />\n"; + } + + echo "<input type=\"hidden\" name=\"ftscfg\" value=\"{$_REQUEST['ftscfg']}\" />\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"dropmapping\" />\n"; + echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + // Case of multiaction drop + if (is_array($_REQUEST['mapping'])) { + $status = $data->changeFtsMapping($_REQUEST['ftscfg'], $_REQUEST['mapping'], 'drop'); + if ($status != 0) { + $this->doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdroppedbad']); + return; + } + $this->doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdropped']); + } else { + $status = $data->changeFtsMapping($_REQUEST['ftscfg'], [$_REQUEST['mapping']], 'drop'); + if ($status == 0) { + $this->doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdropped']); + } else { + $this->doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdroppedbad']); + } + } + } + } + + public function doAlterMapping($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + $misc->printTrail('ftscfg'); + $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); + $misc->printMsg($msg); + + $ftsdicts = $data->getFtsDictionaries(); + if ($ftsdicts->recordCount() > 0) { + if (!isset($_POST['formMapping'])) { + $_POST['formMapping'] = @$_REQUEST['mapping']; + } + + if (!isset($_POST['formDictionary'])) { + $_POST['formDictionary'] = ''; + } + + if (!isset($_POST['ftscfg'])) { + $_POST['ftscfg'] = $_REQUEST['ftscfg']; + } + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strftsmapping']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + + // Case of multiaction drop + if (isset($_REQUEST['ma'])) { + $ma_mappings = []; + $ma_mappings_names = []; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + printf('<input type="hidden" name="formMapping[]" value="%s" />', htmlspecialchars($a['mapping'])); + $ma_mappings[] = $data->getFtsMappingByName($_POST['ftscfg'], $a['mapping']); + $ma_mappings_names[] = $a['mapping']; + } + echo implode(", ", $ma_mappings_names); + } else { + $mapping = $data->getFtsMappingByName($_POST['ftscfg'], $_POST['formMapping']); + echo $mapping->fields['name']; + echo "<input type=\"hidden\" name=\"formMapping\" value=\"", htmlspecialchars($_POST['formMapping']), "\" />\n"; + } + + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + // Dictionary + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strftsdict']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<select name=\"formDictionary\">\n"; + while (!$ftsdicts->EOF) { + $ftsdict = htmlspecialchars($ftsdicts->fields['name']); + echo "\t\t\t\t<option value=\"{$ftsdict}\"", + ($ftsdict == $_POST['formDictionary'] || $ftsdict == @$mapping->fields['dictionaries'] || $ftsdict == @$ma_mappings[0]->fields['dictionaries']) ? ' selected="selected"' : '', ">{$ftsdict}</option>\n"; + $ftsdicts->moveNext(); + } + + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"altermapping\" />\n"; + echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; + echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; + + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strftsnodictionaries']}</p>\n"; + } + } + +/** + * Save the form submission containing changes to a FTS mapping + */ + public function doSaveAlterMapping() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $mappingArray = (is_array($_POST['formMapping']) ? $_POST['formMapping'] : [$_POST['formMapping']]); + $status = $data->changeFtsMapping($_POST['ftscfg'], $mappingArray, 'alter', $_POST['formDictionary']); + if ($status == 0) { + $this->doViewConfig($_POST['ftscfg'], $lang['strftsmappingaltered']); + } else { + $this->doAlterMapping($lang['strftsmappingalteredbad']); + } + + } + +/** + * Show the form to enter parameters of a new FTS mapping + */ + public function doAddMapping($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('ftscfg'); + $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); + $misc->printMsg($msg); + + $ftsdicts = $data->getFtsDictionaries(); + if ($ftsdicts->recordCount() > 0) { + if (!isset($_POST['formMapping'])) { + $_POST['formMapping'] = ''; + } + + if (!isset($_POST['formDictionary'])) { + $_POST['formDictionary'] = ''; + } + + if (!isset($_POST['ftscfg'])) { + $_POST['ftscfg'] = $_REQUEST['ftscfg']; + } + + $mappings = $data->getFtsMappings($_POST['ftscfg']); + + echo "<form action=\"/src/views/fulltext.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strftsmapping']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<select name=\"formMapping\">\n"; + while (!$mappings->EOF) { + $mapping = htmlspecialchars($mappings->fields['name']); + $mapping_desc = htmlspecialchars($mappings->fields['description']); + echo "\t\t\t\t<option value=\"{$mapping}\"", + $mapping == $_POST['formMapping'] ? ' selected="selected"' : '', ">{$mapping}", $mapping_desc ? " - {$mapping_desc}" : "", "</option>\n"; + $mappings->moveNext(); + } + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + // Dictionary + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strftsdict']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<select name=\"formDictionary\">\n"; + while (!$ftsdicts->EOF) { + $ftsdict = htmlspecialchars($ftsdicts->fields['name']); + echo "\t\t\t\t<option value=\"{$ftsdict}\"", + $ftsdict == $_POST['formDictionary'] ? ' selected="selected"' : '', ">{$ftsdict}</option>\n"; + $ftsdicts->moveNext(); + } + + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"addmapping\" />\n"; + echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; + echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"add\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strftsnodictionaries']}</p>\n"; + } + } + +/** + * Save the form submission containing parameters of a new FTS mapping + */ + public function doSaveAddMapping() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $mappingArray = (is_array($_POST['formMapping']) ? $_POST['formMapping'] : [$_POST['formMapping']]); + $status = $data->changeFtsMapping($_POST['ftscfg'], $mappingArray, 'add', $_POST['formDictionary']); + if ($status == 0) { + $this->doViewConfig($_POST['ftscfg'], $lang['strftsmappingadded']); + } else { + $this->doAddMapping($lang['strftsmappingaddedbad']); + } + + } + +} diff --git a/src/controllers/FunctionController.php b/src/controllers/FunctionController.php new file mode 100644 index 00000000..0100aef6 --- /dev/null +++ b/src/controllers/FunctionController.php @@ -0,0 +1,1085 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class FunctionController extends BaseController { + public $_name = 'FunctionController'; + +/** + * Function to save after editing a function + */ + public function doSaveEdit() { + + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $fnlang = strtolower($_POST['original_lang']); + + if ($fnlang == 'c') { + $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']]; + } else if ($fnlang == 'internal') { + $def = $_POST['formLinkSymbol']; + } else { + $def = $_POST['formDefinition']; + } + if (!$data->hasFunctionAlterSchema()) { + $_POST['formFuncSchema'] = ''; + } + + $status = $data->setFunction($_POST['function_oid'], $_POST['original_function'], $_POST['formFunction'], + $_POST['original_arguments'], $_POST['original_returns'], $def, + $_POST['original_lang'], $_POST['formProperties'], isset($_POST['original_setof']), + $_POST['original_owner'], $_POST['formFuncOwn'], $_POST['original_schema'], + $_POST['formFuncSchema'], isset($_POST['formCost']) ? $_POST['formCost'] : null, + isset($_POST['formRows']) ? $_POST['formRows'] : 0, $_POST['formComment']); + + if ($status == 0) { + // If function has had schema altered, need to change to the new schema + // and reload the browser frame. + if (!empty($_POST['formFuncSchema']) && ($_POST['formFuncSchema'] != $_POST['original_schema'])) { + // Jump them to the new function schema + $misc->setCurrentSchema($_POST['formFuncSchema']); + // Force a browser reload + $this->misc->setReloadBrowser(true); + } + $this->doProperties($lang['strfunctionupdated']); + } else { + $this->doEdit($lang['strfunctionupdatedbad']); + } + } + +/** + * Function to allow editing of a Function + */ + public function doEdit($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('function'); + $misc->printTitle($lang['stralter'], 'pg.function.alter'); + $misc->printMsg($msg); + + $fndata = $data->getFunction($_REQUEST['function_oid']); + + if ($fndata->recordCount() > 0) { + $fndata->fields['proretset'] = $data->phpBool($fndata->fields['proretset']); + + // Initialise variables + if (!isset($_POST['formDefinition'])) { + $_POST['formDefinition'] = $fndata->fields['prosrc']; + } + + if (!isset($_POST['formProperties'])) { + $_POST['formProperties'] = $data->getFunctionProperties($fndata->fields); + } + + if (!isset($_POST['formFunction'])) { + $_POST['formFunction'] = $fndata->fields['proname']; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = $fndata->fields['procomment']; + } + + if (!isset($_POST['formObjectFile'])) { + $_POST['formObjectFile'] = $fndata->fields['probin']; + } + + if (!isset($_POST['formLinkSymbol'])) { + $_POST['formLinkSymbol'] = $fndata->fields['prosrc']; + } + + if (!isset($_POST['formFuncOwn'])) { + $_POST['formFuncOwn'] = $fndata->fields['proowner']; + } + + if (!isset($_POST['formFuncSchema'])) { + $_POST['formFuncSchema'] = $fndata->fields['proschema']; + } + + if ($data->hasFunctionCosting()) { + if (!isset($_POST['formCost'])) { + $_POST['formCost'] = $fndata->fields['procost']; + } + + if (!isset($_POST['formRows'])) { + $_POST['formRows'] = $fndata->fields['prorows']; + } + + } + + // Deal with named parameters + if ($data->hasNamedParams()) { + if (isset($fndata->fields['proallarguments'])) { + $args_arr = $data->phpArray($fndata->fields['proallarguments']); + } else { + $args_arr = explode(', ', $fndata->fields['proarguments']); + } + $names_arr = $data->phpArray($fndata->fields['proargnames']); + $modes_arr = $data->phpArray($fndata->fields['proargmodes']); + $args = ''; + $i = 0; + for ($i = 0; $i < sizeof($args_arr); $i++) { + if ($i != 0) { + $args .= ', '; + } + + if (isset($modes_arr[$i])) { + switch ($modes_arr[$i]) { + case 'i':$args .= " IN "; + break; + case 'o':$args .= " OUT "; + break; + case 'b':$args .= " INOUT "; + break; + case 'v':$args .= " VARIADIC "; + break; + case 't':$args .= " TABLE "; + break; + } + } + if (isset($names_arr[$i]) && $names_arr[$i] != '') { + $data->fieldClean($names_arr[$i]); + $args .= '"' . $names_arr[$i] . '" '; + } + $args .= $args_arr[$i]; + } + } else { + $args = $fndata->fields['proarguments']; + } + + $func_full = $fndata->fields['proname'] . "(" . $fndata->fields['proarguments'] . ")"; + echo "<form action=\"/src/views/functions.php\" method=\"post\">\n"; + echo "<table style=\"width: 90%\">\n"; + echo "<tr>\n"; + echo "<th class=\"data required\">{$lang['strschema']}</th>\n"; + echo "<th class=\"data required\">{$lang['strfunction']}</th>\n"; + echo "<th class=\"data\">{$lang['strarguments']}</th>\n"; + echo "<th class=\"data required\">{$lang['strreturns']}</th>\n"; + echo "<th class=\"data required\">{$lang['strproglanguage']}</th>\n"; + echo "</tr>\n"; + + echo "<tr>\n"; + echo "<td class=\"data1\">"; + echo "<input type=\"hidden\" name=\"original_schema\" value=\"", htmlspecialchars($fndata->fields['proschema']), "\" />\n"; + if ($data->hasFunctionAlterSchema()) { + $schemas = $data->getSchemas(); + echo "<select name=\"formFuncSchema\">"; + while (!$schemas->EOF) { + $schema = $schemas->fields['nspname']; + echo "<option value=\"", htmlspecialchars($schema), "\"", + ($schema == $_POST['formFuncSchema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; + $schemas->moveNext(); + } + echo "</select>\n"; + } else { + echo $fndata->fields['proschema']; + } + + echo "</td>\n"; + echo "<td class=\"data1\">"; + echo "<input type=\"hidden\" name=\"original_function\" value=\"", htmlspecialchars($fndata->fields['proname']), "\" />\n"; + echo "<input name=\"formFunction\" style=\"width: 100%\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_POST['formFunction']), "\" />"; + echo "</td>\n"; + + echo "<td class=\"data1\">", $misc->printVal($args), "\n"; + echo "<input type=\"hidden\" name=\"original_arguments\" value=\"", htmlspecialchars($args), "\" />\n"; + echo "</td>\n"; + + echo "<td class=\"data1\">"; + if ($fndata->fields['proretset']) { + echo "setof "; + } + + echo $misc->printVal($fndata->fields['proresult']), "\n"; + echo "<input type=\"hidden\" name=\"original_returns\" value=\"", htmlspecialchars($fndata->fields['proresult']), "\" />\n"; + if ($fndata->fields['proretset']) { + echo "<input type=\"hidden\" name=\"original_setof\" value=\"yes\" />\n"; + } + + echo "</td>\n"; + + echo "<td class=\"data1\">", $misc->printVal($fndata->fields['prolanguage']), "\n"; + echo "<input type=\"hidden\" name=\"original_lang\" value=\"", htmlspecialchars($fndata->fields['prolanguage']), "\" />\n"; + echo "</td>\n"; + echo "</tr>\n"; + + $fnlang = strtolower($fndata->fields['prolanguage']); + if ($fnlang == 'c') { + echo "<tr><th class=\"data required\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; + echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formObjectFile\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n"; + echo "<td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; + } else if ($fnlang == 'internal') { + echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"5\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; + } else { + echo "<tr><th class=\"data required\" colspan=\"5\">{$lang['strdefinition']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"5\"><textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", + htmlspecialchars($_POST['formDefinition']), "</textarea></td></tr>\n"; + } + + // Display function comment + echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strcomment']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"5\"><textarea style=\"width:100%;\" name=\"formComment\" rows=\"3\" cols=\"50\">", + htmlspecialchars($_POST['formComment']), "</textarea></td></tr>\n"; + + // Display function cost options + if ($data->hasFunctionCosting()) { + echo "<tr><th class=\"data required\" colspan=\"5\">{$lang['strfunctioncosting']}</th></tr>\n"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" . + htmlspecialchars($_POST['formCost']) . "\" /></td>"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"", + htmlspecialchars($_POST['formRows']), "\"", (!$fndata->fields['proretset']) ? 'disabled' : '', "/></td>"; + } + + // Display function properties + if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { + echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strproperties']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"5\">\n"; + $i = 0; + foreach ($data->funcprops as $k => $v) { + echo "<select name=\"formProperties[{$i}]\">\n"; + foreach ($v as $p) { + echo "<option value=\"", htmlspecialchars($p), "\"", + ($p == $_POST['formProperties'][$i]) ? ' selected="selected"' : '', + ">", $misc->printVal($p), "</option>\n"; + } + echo "</select><br />\n"; + $i++; + } + echo "</td></tr>\n"; + } + + // function owner + if ($data->hasFunctionAlterOwner()) { + $users = $data->getUsers(); + echo "<tr><td class=\"data1\" colspan=\"5\">{$lang['strowner']}: <select name=\"formFuncOwn\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['formFuncOwn']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select>\n"; + echo "<input type=\"hidden\" name=\"original_owner\" value=\"", htmlspecialchars($fndata->fields['proowner']), "\" />\n"; + echo "</td></tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; + echo "<input type=\"hidden\" name=\"function\" value=\"", htmlspecialchars($_REQUEST['function']), "\" />\n"; + echo "<input type=\"hidden\" name=\"function_oid\" value=\"", htmlspecialchars($_REQUEST['function_oid']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Show read only properties of a function + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('function'); + $misc->printTitle($lang['strproperties'], 'pg.function'); + $misc->printMsg($msg); + + $funcdata = $data->getFunction($_REQUEST['function_oid']); + + if ($funcdata->recordCount() > 0) { + // Deal with named parameters + if ($data->hasNamedParams()) { + if (isset($funcdata->fields['proallarguments'])) { + $args_arr = $data->phpArray($funcdata->fields['proallarguments']); + } else { + $args_arr = explode(', ', $funcdata->fields['proarguments']); + } + $names_arr = $data->phpArray($funcdata->fields['proargnames']); + $modes_arr = $data->phpArray($funcdata->fields['proargmodes']); + $args = ''; + $i = 0; + for ($i = 0; $i < sizeof($args_arr); $i++) { + if ($i != 0) { + $args .= ', '; + } + + if (isset($modes_arr[$i])) { + switch ($modes_arr[$i]) { + case 'i':$args .= " IN "; + break; + case 'o':$args .= " OUT "; + break; + case 'b':$args .= " INOUT "; + break; + case 'v':$args .= " VARIADIC "; + break; + case 't':$args .= " TABLE "; + break; + } + } + if (isset($names_arr[$i]) && $names_arr[$i] != '') { + $data->fieldClean($names_arr[$i]); + $args .= '"' . $names_arr[$i] . '" '; + } + $args .= $args_arr[$i]; + } + } else { + $args = $funcdata->fields['proarguments']; + } + + // Show comment if any + if ($funcdata->fields['procomment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($funcdata->fields['procomment']), "</p>\n"; + } + + $funcdata->fields['proretset'] = $data->phpBool($funcdata->fields['proretset']); + $func_full = $funcdata->fields['proname'] . "(" . $funcdata->fields['proarguments'] . ")"; + echo "<table style=\"width: 90%\">\n"; + echo "<tr><th class=\"data\">{$lang['strfunction']}</th>\n"; + echo "<th class=\"data\">{$lang['strarguments']}</th>\n"; + echo "<th class=\"data\">{$lang['strreturns']}</th>\n"; + echo "<th class=\"data\">{$lang['strproglanguage']}</th></tr>\n"; + echo "<tr><td class=\"data1\">", $misc->printVal($funcdata->fields['proname']), "</td>\n"; + echo "<td class=\"data1\">", $misc->printVal($args), "</td>\n"; + echo "<td class=\"data1\">"; + if ($funcdata->fields['proretset']) { + echo "setof "; + } + + echo $misc->printVal($funcdata->fields['proresult']), "</td>\n"; + echo "<td class=\"data1\">", $misc->printVal($funcdata->fields['prolanguage']), "</td></tr>\n"; + + $fnlang = strtolower($funcdata->fields['prolanguage']); + if ($fnlang == 'c') { + echo "<tr><th class=\"data\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; + echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"2\">", $misc->printVal($funcdata->fields['probin']), "</td>\n"; + echo "<td class=\"data1\" colspan=\"2\">", $misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n"; + } else if ($fnlang == 'internal') { + echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\">", $misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n"; + } else { + include_once BASE_PATH . '/src/highlight.php'; + echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strdefinition']}</th></tr>\n"; + // Check to see if we have syntax highlighting for this language + if (isset($data->langmap[$funcdata->fields['prolanguage']])) { + $temp = syntax_highlight(htmlspecialchars($funcdata->fields['prosrc']), $data->langmap[$funcdata->fields['prolanguage']]); + $tag = 'prenoescape'; + } else { + $temp = $funcdata->fields['prosrc']; + $tag = 'pre'; + } + echo "<tr><td class=\"data1\" colspan=\"4\">", $misc->printVal($temp, $tag, ['lineno' => true, 'class' => 'data1']), "</td></tr>\n"; + } + + // Display function cost options + if ($data->hasFunctionCosting()) { + echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strfunctioncosting']}</th></tr>\n"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: ", $misc->printVal($funcdata->fields['procost']), " </td>"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: ", $misc->printVal($funcdata->fields['prorows']), " </td>"; + } + + // Show flags + if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { + // Fetch an array of the function properties + $funcprops = $data->getFunctionProperties($funcdata->fields); + echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strproperties']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\">\n"; + foreach ($funcprops as $v) { + echo $misc->printVal($v), "<br />\n"; + } + echo "</td></tr>\n"; + } + + echo "<tr><td class=\"data1\" colspan=\"5\">{$lang['strowner']}: ", htmlspecialchars($funcdata->fields['proowner']), "\n"; + echo "</td></tr>\n"; + echo "</table>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + $navlinks = [ + 'showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strshowallfunctions'], + ], + 'alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'edit', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'function' => $_REQUEST['function'], + 'function_oid' => $_REQUEST['function_oid'], + ], + ], + ], + 'content' => $lang['stralter'], + ], + 'drop' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'function' => $func_full, + 'function_oid' => $_REQUEST['function_oid'], + ], + ], + ], + 'content' => $lang['strdrop'], + ], + ]; + + $misc->printNavLinks($navlinks, 'functions-properties', get_defined_vars()); + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['function']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifyfunctiontodrop']); + exit(); + } + + if ($confirm) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strdrop'], 'pg.function.drop'); + + echo "<form action=\"/src/views/functions.php\" method=\"post\">\n"; + + //If multi drop + if (isset($_REQUEST['ma'])) { + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdropfunction'], $misc->printVal($a['function'])), "</p>\n"; + echo '<input type="hidden" name="function[]" value="', htmlspecialchars($a['function']), "\" />\n"; + echo "<input type=\"hidden\" name=\"function_oid[]\" value=\"", htmlspecialchars($a['function_oid']), "\" />\n"; + } + } else { + echo "<p>", sprintf($lang['strconfdropfunction'], $misc->printVal($_REQUEST['function'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"function\" value=\"", htmlspecialchars($_REQUEST['function']), "\" />\n"; + echo "<input type=\"hidden\" name=\"function_oid\" value=\"", htmlspecialchars($_REQUEST['function_oid']), "\" />\n"; + } + + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /><label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + if (is_array($_POST['function_oid'])) { + $msg = ''; + $status = $data->beginTransaction(); + if ($status == 0) { + foreach ($_POST['function_oid'] as $k => $s) { + $status = $data->dropFunction($s, isset($_POST['cascade'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $lang['strfunctiondropped']); + } else { + $data->endTransaction(); + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $lang['strfunctiondroppedbad'])); + return; + } + } + } + if ($data->endTransaction() == 0) { + // Everything went fine, back to the Default page.... + $this->misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + $this->doDefault($lang['strfunctiondroppedbad']); + } + + } else { + $status = $data->dropFunction($_POST['function_oid'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strfunctiondropped']); + } else { + $this->doDefault($lang['strfunctiondroppedbad']); + } + } + } + + } + +/** + * Displays a screen where they can enter a new function + */ + public function doCreate($msg = '', $szJS = "") { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + if (!isset($_POST['formFunction'])) { + $_POST['formFunction'] = ''; + } + + if (!isset($_POST['formArguments'])) { + $_POST['formArguments'] = ''; + } + + if (!isset($_POST['formReturns'])) { + $_POST['formReturns'] = ''; + } + + if (!isset($_POST['formLanguage'])) { + $_POST['formLanguage'] = isset($_REQUEST['language']) ? $_REQUEST['language'] : 'sql'; + } + + if (!isset($_POST['formDefinition'])) { + $_POST['formDefinition'] = ''; + } + + if (!isset($_POST['formObjectFile'])) { + $_POST['formObjectFile'] = ''; + } + + if (!isset($_POST['formLinkSymbol'])) { + $_POST['formLinkSymbol'] = ''; + } + + if (!isset($_POST['formProperties'])) { + $_POST['formProperties'] = $data->defaultprops; + } + + if (!isset($_POST['formSetOf'])) { + $_POST['formSetOf'] = ''; + } + + if (!isset($_POST['formArray'])) { + $_POST['formArray'] = ''; + } + + if (!isset($_POST['formCost'])) { + $_POST['formCost'] = ''; + } + + if (!isset($_POST['formRows'])) { + $_POST['formRows'] = ''; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = ''; + } + + $types = $data->getTypes(true, true, true); + $langs = $data->getLanguages(true); + $fnlang = strtolower($_POST['formLanguage']); + + switch ($fnlang) { + case 'c': + $misc->printTitle($lang['strcreatecfunction'], 'pg.function.create.c'); + break; + case 'internal': + $misc->printTitle($lang['strcreateinternalfunction'], 'pg.function.create.internal'); + break; + default: + $misc->printTitle($lang['strcreateplfunction'], 'pg.function.create.pl'); + break; + } + $misc->printMsg($msg); + + // Create string for return type list + $szTypes = ""; + while (!$types->EOF) { + $szSelected = ""; + if ($types->fields['typname'] == $_POST['formReturns']) { + $szSelected = " selected=\"selected\""; + } + /* this variable is include in the JS code bellow, so we need to ENT_QUOTES */ + $szTypes .= "<option value=\"" . htmlspecialchars($types->fields['typname'], ENT_QUOTES) . "\"{$szSelected}>"; + $szTypes .= htmlspecialchars($types->fields['typname'], ENT_QUOTES) . "</option>"; + $types->moveNext(); + } + + $szFunctionName = "<td class=\"data1\"><input name=\"formFunction\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"" . + htmlspecialchars($_POST['formFunction']) . "\" /></td>"; + + $szArguments = "<td class=\"data1\"><input name=\"formArguments\" style=\"width:100%;\" size=\"16\" value=\"" . + htmlspecialchars($_POST['formArguments']) . "\" /></td>"; + + $szSetOfSelected = ""; + $szNotSetOfSelected = ""; + if ($_POST['formSetOf'] == '') { + $szNotSetOfSelected = " selected=\"selected\""; + } else if ($_POST['formSetOf'] == 'SETOF') { + $szSetOfSelected = " selected=\"selected\""; + } + $szReturns = "<td class=\"data1\" colspan=\"2\">"; + $szReturns .= "<select name=\"formSetOf\">"; + $szReturns .= "<option value=\"\"{$szNotSetOfSelected}></option>"; + $szReturns .= "<option value=\"SETOF\"{$szSetOfSelected}>SETOF</option>"; + $szReturns .= "</select>"; + + $szReturns .= "<select name=\"formReturns\">" . $szTypes . "</select>"; + + // Create string array type selector + + $szArraySelected = ""; + $szNotArraySelected = ""; + if ($_POST['formArray'] == '') { + $szNotArraySelected = " selected=\"selected\""; + } else if ($_POST['formArray'] == '[]') { + $szArraySelected = " selected=\"selected\""; + } + + $szReturns .= "<select name=\"formArray\">"; + $szReturns .= "<option value=\"\"{$szNotArraySelected}></option>"; + $szReturns .= "<option value=\"[]\"{$szArraySelected}>[ ]</option>"; + $szReturns .= "</select>\n</td>"; + + // Create string for language + $szLanguage = "<td class=\"data1\">"; + if ($fnlang == 'c' || $fnlang == 'internal') { + $szLanguage .= $_POST['formLanguage'] . "\n"; + $szLanguage .= "<input type=\"hidden\" name=\"formLanguage\" value=\"{$_POST['formLanguage']}\" />\n"; + } else { + $szLanguage .= "<select name=\"formLanguage\">\n"; + while (!$langs->EOF) { + $szSelected = ''; + if ($langs->fields['lanname'] == $_POST['formLanguage']) { + $szSelected = ' selected="selected"'; + } + if (strtolower($langs->fields['lanname']) != 'c' && strtolower($langs->fields['lanname']) != 'internal') { + $szLanguage .= "<option value=\"" . htmlspecialchars($langs->fields['lanname']) . "\"{$szSelected}>\n" . + $misc->printVal($langs->fields['lanname']) . "</option>"; + } + + $langs->moveNext(); + } + $szLanguage .= "</select>\n"; + } + + $szLanguage .= "</td>"; + $szJSArguments = "<tr><th class=\"data\" colspan=\"7\">{$lang['strarguments']}</th></tr>"; + $arrayModes = ["IN", "OUT", "INOUT"]; + $szModes = "<select name=\"formArgModes[]\" style=\"width:100%;\">"; + foreach ($arrayModes as $pV) { + $szModes .= "<option value=\"{$pV}\">{$pV}</option>"; + } + $szModes .= "</select>"; + $szArgReturns = "<select name=\"formArgArray[]\">"; + $szArgReturns .= "<option value=\"\"></option>"; + $szArgReturns .= "<option value=\"[]\">[]</option>"; + $szArgReturns .= "</select>"; + if (!empty($conf['theme'])) { + $szImgPath = "images/themes/{$conf['theme']}"; + } else { + $szImgPath = "images/themes/default"; + } + if (empty($msg)) { + $szJSTRArg = "<script type=\"text/javascript\" >addArg();</script>\n"; + } else { + $szJSTRArg = ""; + } + $szJSAddTR = "<tr id=\"parent_add_tr\" onclick=\"addArg();\" onmouseover=\"this.style.cursor='pointer'\">\n<td style=\"text-align: right\" colspan=\"6\" class=\"data3\"><table><tr><td class=\"data3\"><img src=\"{$szImgPath}/AddArguments.png\" alt=\"Add Argument\" /></td><td class=\"data3\"><span style=\"font-size: 8pt\">{$lang['strargadd']}</span></td></tr></table></td>\n</tr>\n"; + + echo "<script src=\"/js/functions.js\" type=\"text/javascript\"></script> + <script type=\"text/javascript\"> + //<![CDATA[ + var g_types_select = '<select name=\"formArgType[]\">{$szTypes}</select>{$szArgReturns}'; + var g_modes_select = '{$szModes}'; + var g_name = ''; + var g_lang_strargremove = '", htmlspecialchars($lang["strargremove"], ENT_QUOTES), "'; + var g_lang_strargnoargs = '", htmlspecialchars($lang["strargnoargs"], ENT_QUOTES), "'; + var g_lang_strargenableargs = '", htmlspecialchars($lang["strargenableargs"], ENT_QUOTES), "'; + var g_lang_strargnorowabove = '", htmlspecialchars($lang["strargnorowabove"], ENT_QUOTES), "'; + var g_lang_strargnorowbelow = '", htmlspecialchars($lang["strargnorowbelow"], ENT_QUOTES), "'; + var g_lang_strargremoveconfirm = '", htmlspecialchars($lang["strargremoveconfirm"], ENT_QUOTES), "'; + var g_lang_strargraise = '", htmlspecialchars($lang["strargraise"], ENT_QUOTES), "'; + var g_lang_strarglower = '", htmlspecialchars($lang["strarglower"], ENT_QUOTES), "'; + //]]> + </script> + "; + echo "<form action=\"/src/views//views/functions.php\" method=\"post\">\n"; + echo "<table><tbody id=\"args_table\">\n"; + echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n"; + echo "<th class=\"data required\" colspan=\"2\">{$lang['strreturns']}</th>\n"; + echo "<th class=\"data required\">{$lang['strproglanguage']}</th></tr>\n"; + echo "<tr>\n"; + echo "{$szFunctionName}\n"; + echo "{$szReturns}\n"; + echo "{$szLanguage}\n"; + echo "</tr>\n"; + echo "{$szJSArguments}\n"; + echo "<tr>\n"; + echo "<th class=\"data required\">{$lang['strargmode']}</th>\n"; + echo "<th class=\"data required\">{$lang['strname']}</th>\n"; + echo "<th class=\"data required\" colspan=\"2\">{$lang['strargtype']}</th>\n"; + echo "</tr>\n"; + echo "{$szJSAddTR}\n"; + + if ($fnlang == 'c') { + echo "<tr><th class=\"data required\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; + echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formObjectFile\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n"; + echo "<td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; + } else if ($fnlang == 'internal') { + echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strlinksymbol']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", + htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; + } else { + echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strdefinition']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\"><textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", + htmlspecialchars($_POST['formDefinition']), "</textarea></td></tr>\n"; + } + + // Display function comment + echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strcomment']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\"><textarea style=\"width:100%;\" name=\"formComment\" rows=\"3\" cols=\"50\">", + htmlspecialchars($_POST['formComment']), "</textarea></td></tr>\n"; + + // Display function cost options + if ($data->hasFunctionCosting()) { + echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strfunctioncosting']}</th></tr>\n"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" . + htmlspecialchars($_POST['formCost']) . "\" /></td>"; + echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"" . + htmlspecialchars($_POST['formRows']) . "\" /></td>"; + } + + // Display function properties + if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { + echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strproperties']}</th></tr>\n"; + echo "<tr><td class=\"data1\" colspan=\"4\">\n"; + $i = 0; + foreach ($data->funcprops as $k => $v) { + echo "<select name=\"formProperties[{$i}]\">\n"; + foreach ($v as $p) { + echo "<option value=\"", htmlspecialchars($p), "\"", + ($p == $_POST['formProperties'][$i]) ? ' selected="selected"' : '', + ">", $misc->printVal($p), "</option>\n"; + } + echo "</select><br />\n"; + $i++; + } + echo "</td></tr>\n"; + } + echo "</tbody></table>\n"; + echo $szJSTRArg; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + echo $szJS; + } + +/** + * Actually creates the new function in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $fnlang = strtolower($_POST['formLanguage']); + + if ($fnlang == 'c') { + $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']]; + } else if ($fnlang == 'internal') { + $def = $_POST['formLinkSymbol']; + } else { + $def = $_POST['formDefinition']; + } + + $szJS = ''; + + echo "<script src=\"/js/functions.js\" type=\"text/javascript\"></script>"; + echo "<script type=\"text/javascript\">" . buildJSData() . '</script>'; + if (!empty($_POST['formArgName'])) { + $szJS = buildJSRows(buildFunctionArguments($_POST)); + } else { + $szJS = "<script type=\"text/javascript\" src=\"/js/functions.js\">noArgsRebuild(addArg());</script>"; + } + + $cost = (isset($_POST['formCost'])) ? $_POST['formCost'] : null; + if ($cost == '' || !is_numeric($cost) || $cost != (int) $cost || $cost < 0) { + $cost = null; + } + + $rows = (isset($_POST['formRows'])) ? $_POST['formRows'] : null; + if ($rows == '' || !is_numeric($rows) || $rows != (int) $rows) { + $rows = null; + } + + // Check that they've given a name and a definition + if ($_POST['formFunction'] == '') { + $this->doCreate($lang['strfunctionneedsname'], $szJS); + } elseif ($fnlang != 'internal' && !$def) { + $this->doCreate($lang['strfunctionneedsdef'], $szJS); + } else { + // Append array symbol to type if chosen + $status = $data->createFunction($_POST['formFunction'], empty($_POST['nojs']) ? buildFunctionArguments($_POST) : $_POST['formArguments'], + $_POST['formReturns'] . $_POST['formArray'], $def, $_POST['formLanguage'], + $_POST['formProperties'], $_POST['formSetOf'] == 'SETOF', + $cost, $rows, $_POST['formComment'], false); + if ($status == 0) { + $this->doDefault($lang['strfunctioncreated']); + } else { + $this->doCreate($lang['strfunctioncreatedbad'], $szJS); + } + } + } + +/** + * Build out the function arguments string + */ + function buildFunctionArguments($arrayVars) { + if (isset($_POST['formArgName'])) { + $arrayArgs = []; + foreach ($arrayVars['formArgName'] as $pK => $pV) { + $arrayArgs[] = $arrayVars['formArgModes'][$pK] . ' ' . trim($pV) . ' ' . trim($arrayVars['formArgType'][$pK]) . $arrayVars['formArgArray'][$pK]; + } + return implode(",", $arrayArgs); + } + return ''; + } + +/** + * Build out JS to re-create table rows for arguments + */ + function buildJSRows($szArgs) { + $arrayModes = ['IN', 'OUT', 'INOUT']; + $arrayArgs = explode(',', $szArgs); + $arrayProperArgs = []; + $nC = 0; + $szReturn = ''; + foreach ($arrayArgs as $pV) { + $arrayWords = explode(' ', $pV); + if (in_array($arrayWords[0], $arrayModes) === true) { + $szMode = $arrayWords[0]; + array_shift($arrayWords); + } + $szArgName = array_shift($arrayWords); + if (strpos($arrayWords[count($arrayWords) - 1], '[]') === false) { + $szArgType = implode(" ", $arrayWords); + $bArgIsArray = "false"; + } else { + $szArgType = str_replace('[]', '', implode(' ', $arrayWords)); + $bArgIsArray = "true"; + } + $arrayProperArgs[] = [$szMode, $szArgName, $szArgType, $bArgIsArray]; + $szReturn .= "<script type=\"text/javascript\">RebuildArgTR('{$szMode}','{$szArgName}','{$szArgType}',new Boolean({$bArgIsArray}));</script>"; + $nC++; + } + return $szReturn; + } + + function buildJSData() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $arrayModes = ['IN', 'OUT', 'INOUT']; + $arrayTypes = $data->getTypes(true, true, true); + $arrayPTypes = []; + $arrayPModes = []; + $szTypes = ''; + + while (!$arrayTypes->EOF) { + $arrayPTypes[] = "'" . $arrayTypes->fields['typname'] . "'"; + $arrayTypes->moveNext(); + } + + foreach ($arrayModes as $pV) { + $arrayPModes[] = "'{$pV}'"; + } + + $szTypes = 'g_main_types = new Array(' . implode(',', $arrayPTypes) . ');'; + $szModes = 'g_main_modes = new Array(' . implode(',', $arrayPModes) . ');'; + return $szTypes . $szModes; + } + +/** + * Show default list of functions in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'functions'); + $misc->printMsg($msg); + + $funcs = $data->getFunctions(); + + $columns = [ + 'function' => [ + 'title' => $lang['strfunction'], + 'field' => Decorator::field('proproto'), + 'url' => "/redirect/function?action=properties&{$misc->href}&", + 'vars' => ['function' => 'proproto', 'function_oid' => 'prooid'], + ], + 'returns' => [ + 'title' => $lang['strreturns'], + 'field' => Decorator::field('proreturns'), + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('proowner'), + ], + 'proglanguage' => [ + 'title' => $lang['strproglanguage'], + 'field' => Decorator::field('prolanguage'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('procomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['function' => 'proproto', 'function_oid' => 'prooid'], + 'url' => 'functions.php', + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'edit', + 'function' => Decorator::field('proproto'), + 'function_oid' => Decorator::field('prooid'), + ], + ], + ], + ], + 'drop' => [ + 'multiaction' => 'confirm_drop', + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'function' => Decorator::field('proproto'), + 'function_oid' => Decorator::field('prooid'), + ], + ], + ], + ], + 'privileges' => [ + 'content' => $lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges.php', + 'urlvars' => [ + 'subject' => 'function', + 'function' => Decorator::field('proproto'), + 'function_oid' => Decorator::field('prooid'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($funcs, $columns, $actions, 'functions-functions', $lang['strnofunctions']); + + $navlinks = [ + 'createpl' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateplfunction'], + ], + 'createinternal' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'create', + 'language' => 'internal', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateinternalfunction'], + ], + 'createc' => [ + 'attr' => [ + 'href' => [ + 'url' => 'functions.php', + 'urlvars' => [ + 'action' => 'create', + 'language' => 'C', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatecfunction'], + ], + ]; + + $misc->printNavLinks($navlinks, 'functions-functions', get_defined_vars()); + } +} diff --git a/src/controllers/GroupController.php b/src/controllers/GroupController.php new file mode 100644 index 00000000..9895fca0 --- /dev/null +++ b/src/controllers/GroupController.php @@ -0,0 +1,311 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class GroupController extends BaseController { + public $_name = 'GroupController'; + +/** + * Add user to a group + */ + public function doAddMember() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->addGroupMember($_REQUEST['group'], $_REQUEST['user']); + if ($status == 0) { + $this->doProperties($lang['strmemberadded']); + } else { + $this->doProperties($lang['strmemberaddedbad']); + } + + } + +/** + * Show confirmation of drop user from group and perform actual drop + */ + public function doDropMember($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('group'); + $misc->printTitle($lang['strdropmember'], 'pg.group.alter'); + + echo "<p>", sprintf($lang['strconfdropmember'], $misc->printVal($_REQUEST['user']), $misc->printVal($_REQUEST['group'])), "</p>\n"; + + echo "<form action=\"/src/views/groups.php\" method=\"post\">\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"action\" value=\"drop_member\" />\n"; + echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; + echo "<input type=\"hidden\" name=\"user\" value=\"", htmlspecialchars($_REQUEST['user']), "\" />\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropGroupMember($_REQUEST['group'], $_REQUEST['user']); + if ($status == 0) { + $this->doProperties($lang['strmemberdropped']); + } else { + $this->doDropMember(true, $lang['strmemberdroppedbad']); + } + + } + } + +/** + * Show read only properties for a group + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['user'])) { + $_POST['user'] = ''; + } + + $misc->printTrail('group'); + $misc->printTitle($lang['strproperties'], 'pg.group'); + $misc->printMsg($msg); + + $groupdata = $data->getGroup($_REQUEST['group']); + $users = $data->getUsers(); + + if ($groupdata->recordCount() > 0) { + $columns = [ + 'members' => [ + 'title' => $lang['strmembers'], + 'field' => Decorator::field('usename'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'groups.php', + 'urlvars' => [ + 'action' => 'confirm_drop_member', + 'group' => $_REQUEST['group'], + 'user' => Decorator::field('usename'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($groupdata, $columns, $actions, 'groups-members', $lang['strnousers']); + } + + // Display form for adding a user to the group + echo "<form action=\"/src/views/groups.php\" method=\"post\">\n"; + echo "<select name=\"user\">"; + while (!$users->EOF) { + $uname = $misc->printVal($users->fields['usename']); + echo "<option value=\"{$uname}\"", + ($uname == $_POST['user']) ? ' selected="selected"' : '', ">{$uname}</option>\n"; + $users->moveNext(); + } + echo "</select>\n"; + echo "<input type=\"submit\" value=\"{$lang['straddmember']}\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"add_member\" />\n"; + echo "</form>\n"; + + $misc->printNavLinks(['showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'groups.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + ], + ], + ], + 'content' => $lang['strshowallgroups'], + ]], 'groups-properties', get_defined_vars()); + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('group'); + $misc->printTitle($lang['strdrop'], 'pg.group.drop'); + + echo "<p>", sprintf($lang['strconfdropgroup'], $misc->printVal($_REQUEST['group'])), "</p>\n"; + + echo "<form action=\"/src/views/groups.php\" method=\"post\">\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropGroup($_REQUEST['group']); + if ($status == 0) { + $this->doDefault($lang['strgroupdropped']); + } else { + $this->doDefault($lang['strgroupdroppedbad']); + } + + } + } + +/** + * Displays a screen where they can enter a new group + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['members'])) { + $_POST['members'] = []; + } + + // Fetch a list of all users in the cluster + $users = $data->getUsers(); + + $misc->printTrail('server'); + $misc->printTitle($lang['strcreategroup'], 'pg.group.create'); + $misc->printMsg($msg); + + echo "<form action=\"\" method=\"post\">\n"; + echo $misc->form; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input size=\"32\" maxlength=\"{$data->_maxNameLen}\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), "\" /></td>\n\t</tr>\n"; + if ($users->recordCount() > 0) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strmembers']}</th>\n"; + + echo "\t\t<td class=\"data\">\n"; + echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(40, $users->recordCount()), "\">\n"; + while (!$users->EOF) { + $username = $users->fields['usename']; + echo "\t\t\t\t<option value=\"{$username}\"", + (in_array($username, $_POST['members']) ? ' selected="selected"' : ''), ">", $misc->printVal($username), "</option>\n"; + $users->moveNext(); + } + echo "\t\t\t</select>\n"; + echo "\t\t</td>\n\t</tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new group in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['members'])) { + $_POST['members'] = []; + } + + // Check form vars + if (trim($_POST['name']) == '') { + $this->doCreate($lang['strgroupneedsname']); + } else { + $status = $data->createGroup($_POST['name'], $_POST['members']); + if ($status == 0) { + $this->doDefault($lang['strgroupcreated']); + } else { + $this->doCreate($lang['strgroupcreatedbad']); + } + + } + } + +/** + * Show default list of groups in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('server'); + $misc->printTabs('server', 'groups'); + $misc->printMsg($msg); + + $groups = $data->getGroups(); + + $columns = [ + 'group' => [ + 'title' => $lang['strgroup'], + 'field' => Decorator::field('groname'), + 'url' => "groups.php?action=properties&{$misc->href}&", + 'vars' => ['group' => 'groname'], + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'groups.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'group' => Decorator::field('groname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($groups, $columns, $actions, 'groups-properties', $lang['strnogroups']); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'groups.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + ], + ], + ], + 'content' => $lang['strcreategroup'], + ]], 'groups-groups', get_defined_vars()); + + } + +} diff --git a/src/controllers/HelpController.php b/src/controllers/HelpController.php new file mode 100644 index 00000000..20e77795 --- /dev/null +++ b/src/controllers/HelpController.php @@ -0,0 +1,88 @@ +<?php + +namespace PHPPgAdmin\Controller; + +/** + * Base controller class + */ +class HelpController extends BaseController { + public $_name = 'HelpController'; + + public function doDefault() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (isset($_REQUEST['help'])) { + $url = $data->getHelp($_REQUEST['help']); + + if (is_array($url)) { + $this->doChoosePage($url); + return; + } + + if ($url) { + header("Location: $url"); + exit; + } + } + + $this->doBrowse($lang['strinvalidhelppage']); + } + + public function doBrowse($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printHeader($lang['strhelppagebrowser']); + $misc->printBody(); + + $misc->printTitle($lang['strselecthelppage']); + + echo $misc->printMsg($msg); + + echo "<dl>\n"; + + $pages = $data->getHelpPages(); + foreach ($pages as $page => $dummy) { + echo "<dt>{$page}</dt>\n"; + + $urls = $data->getHelp($page); + if (!is_array($urls)) { + $urls = [$urls]; + } + + foreach ($urls as $url) { + echo "<dd><a href=\"{$url}\">{$url}</a></dd>\n"; + } + } + + echo "</dl>\n"; + + $misc->printFooter(); + } + + public function doChoosePage($urls) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printHeader($lang['strhelppagebrowser']); + $misc->printBody(); + + $misc->printTitle($lang['strselecthelppage']); + + echo "<ul>\n"; + foreach ($urls as $url) { + echo "<li><a href=\"{$url}\">{$url}</a></li>\n"; + } + echo "</ul>\n"; + + $misc->printFooter(); + } + +} diff --git a/src/controllers/HistoryController.php b/src/controllers/HistoryController.php new file mode 100644 index 00000000..ecd5d6e3 --- /dev/null +++ b/src/controllers/HistoryController.php @@ -0,0 +1,211 @@ +<?php + +namespace PHPPgAdmin\Controller; + +/** + * Base controller class + */ +class HistoryController extends BaseController { + public $_name = 'HistoryController'; + + public function doDefault() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $onchange = "onchange=\"location.href='/views/history.php?server=' + encodeURI(server.options[server.selectedIndex].value) + '&database=' + encodeURI(database.options[database.selectedIndex].value) + '&'\""; + + $misc->printHeader($lang['strhistory']); + + // Bring to the front always + echo "<body onload=\"window.focus();\">\n"; + + echo "<form action=\"/src/views/history.php\" method=\"post\">\n"; + $misc->printConnection($onchange); + echo "</form><br />"; + + if (!isset($_REQUEST['database'])) { + echo "<p>{$lang['strnodatabaseselected']}</p>\n"; + return; + } + + if (isset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']])) { + + $history = new \PHPPgAdmin\ArrayRecordSet($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]); + + //Kint::dump($history); + $columns = [ + 'query' => [ + 'title' => $lang['strsql'], + 'field' => Decorator::field('query'), + ], + 'paginate' => [ + 'title' => $lang['strpaginate'], + 'field' => Decorator::field('paginate'), + 'type' => 'yesno', + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'run' => [ + 'content' => $lang['strexecute'], + 'attr' => [ + 'href' => [ + 'url' => 'sql.php', + 'urlvars' => [ + 'subject' => 'history', + 'nohistory' => 't', + 'queryid' => Decorator::field('queryid'), + 'paginate' => Decorator::field('paginate'), + ], + ], + 'target' => 'detail', + ], + ], + 'remove' => [ + 'content' => $lang['strdelete'], + 'attr' => [ + 'href' => [ + 'url' => 'history.php', + 'urlvars' => [ + 'action' => 'confdelhistory', + 'queryid' => Decorator::field('queryid'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($history, $columns, $actions, 'history-history', $lang['strnohistory']); + } else { + echo "<p>{$lang['strnohistory']}</p>\n"; + } + + $navlinks = [ + 'refresh' => [ + 'attr' => [ + 'href' => [ + 'url' => 'history.php', + 'urlvars' => [ + 'action' => 'history', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + ], + ], + ], + 'content' => $lang['strrefresh'], + ], + ]; + + if (isset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]) + && count($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']])) { + $navlinks['download'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'history.php', + 'urlvars' => [ + 'action' => 'download', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + ], + ], + ], + 'content' => $lang['strdownload'], + ]; + $navlinks['clear'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'history.php', + 'urlvars' => [ + 'action' => 'confclearhistory', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + ], + ], + ], + 'content' => $lang['strclearhistory'], + ]; + } + + $misc->printNavLinks($navlinks, 'history-history', get_defined_vars()); + } + + public function doDelHistory($qid, $confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printHeader($lang['strhistory']); + + // Bring to the front always + echo "<body onload=\"window.focus();\">\n"; + + echo "<h3>{$lang['strdelhistory']}</h3>\n"; + echo "<p>{$lang['strconfdelhistory']}</p>\n"; + + echo "<pre>", htmlentities($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']][$qid]['query'], ENT_QUOTES, 'UTF-8'), "</pre>"; + echo "<form action=\"/src/views/history.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"delhistory\" />\n"; + echo "<input type=\"hidden\" name=\"queryid\" value=\"$qid\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + unset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']][$qid]); + } + + } + + public function doClearHistory($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printHeader($lang['strhistory']); + + // Bring to the front always + echo "<body onload=\"window.focus();\">\n"; + + echo "<h3>{$lang['strclearhistory']}</h3>\n"; + echo "<p>{$lang['strconfclearhistory']}</p>\n"; + + echo "<form action=\"/src/views/history.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"clearhistory\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + unset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]); + } + + } + + public function doDownloadHistory() { + header('Content-Type: application/download'); + $datetime = date('YmdHis'); + header("Content-Disposition: attachment; filename=history{$datetime}.sql"); + + foreach ($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']] as $queries) { + $query = rtrim($queries['query']); + echo $query; + if (substr($query, -1) != ';') { + echo ';'; + } + + echo "\n"; + } + + exit; + } + +} diff --git a/src/controllers/IndexController.php b/src/controllers/IndexController.php new file mode 100644 index 00000000..69cc0655 --- /dev/null +++ b/src/controllers/IndexController.php @@ -0,0 +1,394 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class IndexController extends BaseController { + public $_name = 'IndexController'; + + /** + * Show confirmation of cluster index and perform actual cluster + */ + public function doClusterIndex($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + // Default analyze to on + $_REQUEST['analyze'] = true; + + $misc->printTrail('index'); + $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); + + echo "<p>", sprintf($lang['strconfcluster'], $misc->printVal($_REQUEST['index'])), "</p>\n"; + + echo "<form action=\"/src/views/indexes.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"analyze\" name=\"analyze\"", (isset($_REQUEST['analyze']) ? ' checked="checked"' : ''), " /><label for=\"analyze\">{$lang['stranalyze']}</label></p>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"cluster_index\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"cluster\" value=\"{$lang['strclusterindex']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->clusterIndex($_POST['table'], $_POST['index']); + if ($status == 0) { + if (isset($_POST['analyze'])) { + $status = $data->analyzeDB($_POST['table']); + if ($status == 0) { + $this->doDefault($lang['strclusteredgood'] . ' ' . $lang['stranalyzegood']); + } else { + $this->doDefault($lang['stranalyzebad']); + } + + } else { + $this->doDefault($lang['strclusteredgood']); + } + } else { + $this->doDefault($lang['strclusteredbad']); + } + + } + + } + + public function doReindex() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + $status = $data->reindex('INDEX', $_REQUEST['index']); + if ($status == 0) { + $this->doDefault($lang['strreindexgood']); + } else { + $this->doDefault($lang['strreindexbad']); + } + + } + +/** + * Displays a screen where they can enter a new index + */ + public function doCreateIndex($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['formIndexName'])) { + $_POST['formIndexName'] = ''; + } + + if (!isset($_POST['formIndexType'])) { + $_POST['formIndexType'] = null; + } + + if (!isset($_POST['formCols'])) { + $_POST['formCols'] = ''; + } + + if (!isset($_POST['formWhere'])) { + $_POST['formWhere'] = ''; + } + + if (!isset($_POST['formSpc'])) { + $_POST['formSpc'] = ''; + } + + $attrs = $data->getTableAttributes($_REQUEST['table']); + // Fetch all tablespaces from the database + if ($data->hasTablespaces()) { + $tablespaces = $data->getTablespaces(); + } + + $misc->printTrail('table'); + $misc->printTitle($lang['strcreateindex'], 'pg.index.create'); + $misc->printMsg($msg); + + $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select("TableColumnList", true, 10); + $selColumns->set_style("width: 10em;"); + + if ($attrs->recordCount() > 0) { + while (!$attrs->EOF) { + $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); + $attrs->moveNext(); + } + } + + $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select("IndexColumnList[]", true, 10); + $selIndex->set_style("width: 10em;"); + $selIndex->set_attribute("id", "IndexColumnList"); + $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button("add", ">>"); + $buttonAdd->set_attribute("onclick", "buttonPressed(this);"); + $buttonAdd->set_attribute("type", "button"); + + $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button("remove", "<<"); + $buttonRemove->set_attribute("onclick", "buttonPressed(this);"); + $buttonRemove->set_attribute("type", "button"); + + echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"indexes.php\" method=\"post\">\n"; + + echo "<table>\n"; + echo "<tr><th class=\"data required\" colspan=\"3\">{$lang['strindexname']}</th></tr>"; + echo "<tr>"; + echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"formIndexName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formIndexName']), "\" /></td></tr>"; + echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th>"; + echo "<th class=\"data required\">{$lang['strindexcolumnlist']}</th></tr>\n"; + echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; + echo "<td class=\"data1\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; + echo "<td class=\"data1\">" . $selIndex->fetch() . "</td></tr>\n"; + echo "</table>\n"; + + echo "<table> \n"; + echo "<tr>"; + echo "<th class=\"data left required\" scope=\"row\">{$lang['strindextype']}</th>"; + echo "<td class=\"data1\"><select name=\"formIndexType\">"; + foreach ($data->typIndexes as $v) { + echo "<option value=\"", htmlspecialchars($v), "\"", + ($v == $_POST['formIndexType']) ? ' selected="selected"' : '', ">", htmlspecialchars($v), "</option>\n"; + } + echo "</select></td></tr>\n"; + echo "<tr>"; + echo "<th class=\"data left\" scope=\"row\"><label for=\"formUnique\">{$lang['strunique']}</label></th>"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formUnique\" name=\"formUnique\"", (isset($_POST['formUnique']) ? 'checked="checked"' : ''), " /></td>"; + echo "</tr>"; + echo "<tr>"; + echo "<th class=\"data left\" scope=\"row\">{$lang['strwhere']}</th>"; + echo "<td class=\"data1\">(<input name=\"formWhere\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formWhere']), "\" />)</td>"; + echo "</tr>"; + + // Tablespace (if there are any) + if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; + echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formSpc\">\n"; + // Always offer the default (empty) option + echo "\t\t\t\t<option value=\"\"", + ($_POST['formSpc'] == '') ? ' selected="selected"' : '', "></option>\n"; + // Display all other tablespaces + while (!$tablespaces->EOF) { + $spcname = htmlspecialchars($tablespaces->fields['spcname']); + echo "\t\t\t\t<option value=\"{$spcname}\"", + ($spcname == $_POST['formSpc']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; + $tablespaces->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; + } + + if ($data->hasConcurrentIndexBuild()) { + echo "<tr>"; + echo "<th class=\"data left\" scope=\"row\"><label for=\"formConcur\">{$lang['strconcurrently']}</label></th>"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formConcur\" name=\"formConcur\"", (isset($_POST['formConcur']) ? 'checked="checked"' : ''), " /></td>"; + echo "</tr>"; + } + + echo "</table>"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_index\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new index in the database + * @@ Note: this function can't handle columns with commas in them + */ + public function doSaveCreateIndex() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Handle databases that don't have partial indexes + if (!isset($_POST['formWhere'])) { + $_POST['formWhere'] = ''; + } + + // Default tablespace to null if it isn't set + if (!isset($_POST['formSpc'])) { + $_POST['formSpc'] = null; + } + + // Check that they've given a name and at least one column + if ($_POST['formIndexName'] == '') { + $this->doCreateIndex($lang['strindexneedsname']); + } elseif (!isset($_POST['IndexColumnList']) || $_POST['IndexColumnList'] == '') { + $this->doCreateIndex($lang['strindexneedscols']); + } else { + $status = $data->createIndex($_POST['formIndexName'], $_POST['table'], $_POST['IndexColumnList'], + $_POST['formIndexType'], isset($_POST['formUnique']), $_POST['formWhere'], $_POST['formSpc'], + isset($_POST['formConcur'])); + if ($status == 0) { + $this->doDefault($lang['strindexcreated']); + } else { + $this->doCreateIndex($lang['strindexcreatedbad']); + } + + } + } + +/** + * Show confirmation of drop index and perform actual drop + */ + public function doDropIndex($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('index'); + $misc->printTitle($lang['strdrop'], 'pg.index.drop'); + + echo "<p>", sprintf($lang['strconfdropindex'], $misc->printVal($_REQUEST['index'])), "</p>\n"; + + echo "<form action=\"/src/views/indexes.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop_index\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropIndex($_POST['index'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strindexdropped']); + } else { + $this->doDefault($lang['strindexdroppedbad']); + } + + } + + } + + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $indPre = function (&$rowdata, $actions) use ($data, $lang) { + if ($data->phpBool($rowdata->fields['indisprimary'])) { + $rowdata->fields['+constraints'] = $lang['strprimarykey']; + $actions['drop']['disable'] = true; + } elseif ($data->phpBool($rowdata->fields['indisunique'])) { + $rowdata->fields['+constraints'] = $lang['struniquekey']; + $actions['drop']['disable'] = true; + } else { + $rowdata->fields['+constraints'] = ''; + } + + return $actions; + }; + + $misc->printTrail('table'); + $misc->printTabs('table', 'indexes'); + $misc->printMsg($msg); + + $indexes = $data->getIndexes($_REQUEST['table']); + + $columns = [ + 'index' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('indname'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('inddef'), + ], + 'constraints' => [ + 'title' => $lang['strconstraints'], + 'field' => Decorator::field('+constraints'), + 'type' => 'verbatim', + 'params' => ['align' => 'center'], + ], + 'clustered' => [ + 'title' => $lang['strclustered'], + 'field' => Decorator::field('indisclustered'), + 'type' => 'yesno', + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('idxcomment'), + ], + ]; + + $actions = [ + 'cluster' => [ + 'content' => $lang['strclusterindex'], + 'attr' => [ + 'href' => [ + 'url' => 'indexes.php', + 'urlvars' => [ + 'action' => 'confirm_cluster_index', + 'table' => $_REQUEST['table'], + 'index' => Decorator::field('indname'), + ], + ], + ], + ], + 'reindex' => [ + 'content' => $lang['strreindex'], + 'attr' => [ + 'href' => [ + 'url' => 'indexes.php', + 'urlvars' => [ + 'action' => 'reindex', + 'table' => $_REQUEST['table'], + 'index' => Decorator::field('indname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'indexes.php', + 'urlvars' => [ + 'action' => 'confirm_drop_index', + 'table' => $_REQUEST['table'], + 'index' => Decorator::field('indname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($indexes, $columns, $actions, 'indexes-indexes', $lang['strnoindexes'], $indPre); + + $misc->printNavLinks([ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'indexes.php', + 'urlvars' => [ + 'action' => 'create_index', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strcreateindex'], + ], + ], 'indexes-indexes', get_defined_vars()); + } + +} diff --git a/src/controllers/InfoController.php b/src/controllers/InfoController.php new file mode 100644 index 00000000..899f0d35 --- /dev/null +++ b/src/controllers/InfoController.php @@ -0,0 +1,346 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class InfoController extends BaseController { + public $_name = 'InfoController'; + +/** + * List all the information on the table + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('table'); + $misc->printTabs('table', 'info'); + $misc->printMsg($msg); + + // common params for printVal + $shownull = ['null' => true]; + + // Fetch info + $referrers = $data->getReferrers($_REQUEST['table']); + $parents = $data->getTableParents($_REQUEST['table']); + $children = $data->getTableChildren($_REQUEST['table']); + $tablestatstups = $data->getStatsTableTuples($_REQUEST['table']); + $tablestatsio = $data->getStatsTableIO($_REQUEST['table']); + $indexstatstups = $data->getStatsIndexTuples($_REQUEST['table']); + $indexstatsio = $data->getStatsIndexIO($_REQUEST['table']); + + // Check that there is some info + if (($referrers === -99 || ($referrers !== -99 && $referrers->recordCount() == 0)) + && $parents->recordCount() == 0 && $children->recordCount() == 0 + && ($tablestatstups->recordCount() == 0 && $tablestatsio->recordCount() == 0 + && $indexstatstups->recordCount() == 0 && $indexstatsio->recordCount() == 0)) { + $misc->printMsg($lang['strnoinfo']); + } else { + // Referring foreign tables + if ($referrers !== -99 && $referrers->recordCount() > 0) { + echo "<h3>{$lang['strreferringtables']}</h3>\n"; + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'name' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('conname'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('consrc'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'constraints.php', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($referrers, $columns, $actions, 'info-referrers', $lang['strnodata']); + } + + // Parent tables + if ($parents->recordCount() > 0) { + echo "<h3>{$lang['strparenttables']}</h3>\n"; + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($parents, $columns, $actions, 'info-parents', $lang['strnodata']); + } + + // Child tables + if ($children->recordCount() > 0) { + echo "<h3>{$lang['strchildtables']}</h3>\n"; + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + ], + 'table' => [ + 'title' => $lang['strtable'], + 'field' => Decorator::field('relname'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'properties' => [ + 'content' => $lang['strproperties'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'schema' => Decorator::field('nspname'), + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($children, $columns, $actions, 'info-children', $lang['strnodata']); + + } + + // Row performance + if ($tablestatstups->recordCount() > 0) { + echo "<h3>{$lang['strrowperf']}</h3>\n"; + + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\" colspan=\"2\">{$lang['strsequential']}</th>\n"; + echo "\t\t<th class=\"data\" colspan=\"2\">{$lang['strindex']}</th>\n"; + echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strrows2']}</th>\n"; + echo "\t</tr>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strread']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strfetch']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strinsert']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strupdate']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strdelete']}</th>\n"; + echo "\t</tr>\n"; + $i = 0; + + while (!$tablestatstups->EOF) { + $id = (($i % 2) == 0 ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['seq_scan'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['seq_tup_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['idx_scan'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['idx_tup_fetch'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_ins'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_upd'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_del'], 'int4', $shownull), "</td>\n"; + echo "\t</tr>\n"; + $tablestatstups->movenext(); + $i++; + } + + echo "</table>\n"; + } + + // I/O performance + if ($tablestatsio->recordCount() > 0) { + echo "<h3>{$lang['strioperf']}</h3>\n"; + + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strheap']}</th>\n"; + echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strindex']}</th>\n"; + echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strtoast']}</th>\n"; + echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strtoastindex']}</th>\n"; + echo "\t</tr>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; + echo "\t</tr>\n"; + $i = 0; + + while (!$tablestatsio->EOF) { + $id = (($i % 2) == 0 ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">\n"; + + $total = $tablestatsio->fields['heap_blks_hit'] + $tablestatsio->fields['heap_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['heap_blks_hit'] / $total) * 100); + } else { + $percentage = 0; + } + + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['heap_blks_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['heap_blks_hit'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; + + $total = $tablestatsio->fields['idx_blks_hit'] + $tablestatsio->fields['idx_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['idx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; + } + + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['idx_blks_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['idx_blks_hit'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; + + $total = $tablestatsio->fields['toast_blks_hit'] + $tablestatsio->fields['toast_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['toast_blks_hit'] / $total) * 100); + } else { + $percentage = 0; + } + + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['toast_blks_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['toast_blks_hit'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; + + $total = $tablestatsio->fields['tidx_blks_hit'] + $tablestatsio->fields['tidx_blks_read']; + if ($total > 0) { + $percentage = round(($tablestatsio->fields['tidx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; + } + + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['tidx_blks_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($tablestatsio->fields['tidx_blks_hit'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; + echo "\t</tr>\n"; + $tablestatsio->movenext(); + $i++; + } + + echo "</table>\n"; + } + + // Index row performance + if ($indexstatstups->recordCount() > 0) { + echo "<h3>{$lang['stridxrowperf']}</h3>\n"; + + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strindex']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strread']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strfetch']}</th>\n"; + echo "\t</tr>\n"; + $i = 0; + + while (!$indexstatstups->EOF) { + $id = (($i % 2) == 0 ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">\n"; + echo "\t\t<td>", $misc->printVal($indexstatstups->fields['indexrelname']), "</td>\n"; + echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_scan'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_tup_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_tup_fetch'], 'int4', $shownull), "</td>\n"; + echo "\t</tr>\n"; + $indexstatstups->movenext(); + $i++; + } + + echo "</table>\n"; + } + + // Index I/0 performance + if ($indexstatsio->recordCount() > 0) { + echo "<h3>{$lang['stridxioperf']}</h3>\n"; + + echo "<table>\n"; + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strindex']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; + echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; + echo "\t</tr>\n"; + $i = 0; + + while (!$indexstatsio->EOF) { + $id = (($i % 2) == 0 ? '1' : '2'); + echo "\t<tr class=\"data{$id}\">\n"; + $total = $indexstatsio->fields['idx_blks_hit'] + $indexstatsio->fields['idx_blks_read']; + if ($total > 0) { + $percentage = round(($indexstatsio->fields['idx_blks_hit'] / $total) * 100); + } else { + $percentage = 0; + } + + echo "\t\t<td>", $misc->printVal($indexstatsio->fields['indexrelname']), "</td>\n"; + echo "\t\t<td>", $misc->printVal($indexstatsio->fields['idx_blks_read'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>", $misc->printVal($indexstatsio->fields['idx_blks_hit'], 'int4', $shownull), "</td>\n"; + echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; + echo "\t</tr>\n"; + $indexstatsio->movenext(); + $i++; + } + + echo "</table>\n"; + } + } + } +} diff --git a/src/controllers/IntroController.php b/src/controllers/IntroController.php new file mode 100644 index 00000000..77143ee3 --- /dev/null +++ b/src/controllers/IntroController.php @@ -0,0 +1,86 @@ +<?php + +namespace PHPPgAdmin\Controller; + +/** + * Base controller class + */ +class IntroController extends BaseController { + public $_name = 'IntroController'; + + /** + * Intro screen + * + * $Id: intro.php,v 1.19 2007/07/12 19:26:22 xzilla Exp $ + */ + public function doDefault() { + + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + + $appLangFiles = $this->appLangFiles; + $misc = $this->misc; + $appThemes = $this->appThemes; + $appName = $this->appName; + $appVersion = $this->appVersion; + + $misc->setNoDBConnection(true); + + $intro_html = $misc->printTrail('root', false); + + $intro_html .= $misc->printTabs('root', 'intro', false); + + $intro_html .= "<h1> $appName $appVersion (PHP " . phpversion() . ')</h1>'; + + $intro_html .= '<form method="get" action="intro.php">'; + $intro_html .= '<table>'; + $intro_html .= '<tr class="data1">'; + $intro_html .= '<th class="data">' . $lang['strlanguage'] . '</th>'; + $intro_html .= '<td>'; + $intro_html .= '<select name="language" onchange="this.form.submit()">'; + + $language = isset($_SESSION['webdbLanguage']) ? $_SESSION['webdbLanguage'] : 'english'; + foreach ($appLangFiles as $k => $v) { + $selected = ($k == $language) ? ' selected="selected"' : ''; + $intro_html .= "\t<option value=\"{$k}\"" . $selected . ">{$v}</option>\n"; + } + + $intro_html .= '</select>'; + $intro_html .= '</td>'; + $intro_html .= '</tr>'; + $intro_html .= '<tr class="data2">'; + $intro_html .= '<th class="data">' . $lang['strtheme'] . '</th>'; + $intro_html .= '<td>'; + $intro_html .= '<select name="theme" onchange="this.form.submit()">'; + + foreach ($appThemes as $k => $v) { + $selected = ($k == $conf['theme']) ? ' selected="selected"' : ''; + $intro_html .= "\t<option value=\"{$k}\"" . $selected . ">{$v}</option>\n"; + } + + $intro_html .= '</select>'; + $intro_html .= '</td>'; + $intro_html .= '</tr>'; + $intro_html .= '</table>'; + $intro_html .= '<noscript><p><input type="submit" value="' . $lang['stralter'] . '" /></p></noscript>'; + $intro_html .= '</form>'; + + $intro_html .= '<p>' . $lang['strintro'] . '</p>'; + + $intro_html .= '<ul class="intro">'; + $intro_html .= ' <li><a href="http://phppgadmin.sourceforge.net/">' . $lang['strppahome'] . '</a></li>'; + $intro_html .= '<li><a href="' . $lang['strpgsqlhome_url'] . '">' . $lang['strpgsqlhome'] . '</a></li>'; + $intro_html .= '<li><a href="http://sourceforge.net/tracker/?group_id=37132&atid=418980">' . $lang['strreportbug'] . '</a></li>'; + $intro_html .= '<li><a href="' . $lang['strviewfaq_url'] . '">' . $lang['strviewfaq'] . '</a></li>'; + $intro_html .= '<li><a target="_top" href="tests/selenium/selenium-lib/core/TestRunner.html?test=..%2F..%2FTestSuite.php&resultsUrl=..%2FpostResults">Selenium tests</a></li>'; + $intro_html .= '</ul>'; + + if (isset($_GET['language'])) { + $misc->setReloadBrowser(true); + } + + echo $intro_html; + + } +}
\ No newline at end of file diff --git a/src/controllers/LangController.php b/src/controllers/LangController.php new file mode 100644 index 00000000..f3b09c98 --- /dev/null +++ b/src/controllers/LangController.php @@ -0,0 +1,47 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class LangController extends BaseController { + public $_name = 'LangController'; + +/** + * Show default list of languages in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('database'); + $misc->printTabs('database', 'languages'); + $misc->printMsg($msg); + + $languages = $data->getLanguages(); + + $columns = [ + 'language' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('lanname'), + ], + 'trusted' => [ + 'title' => $lang['strtrusted'], + 'field' => Decorator::field('lanpltrusted'), + 'type' => 'yesno', + ], + 'function' => [ + 'title' => $lang['strfunction'], + 'field' => Decorator::field('lanplcallf'), + ], + ]; + + $actions = []; + + echo $misc->printTable($languages, $columns, $actions, 'languages-languages', $lang['strnolanguages']); + } +} diff --git a/src/controllers/OpClassesController.php b/src/controllers/OpClassesController.php new file mode 100644 index 00000000..18a0a066 --- /dev/null +++ b/src/controllers/OpClassesController.php @@ -0,0 +1,56 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class OpClassesController extends BaseController { + public $_name = 'OpClassesController'; + +/** + * Show default list of opclasss in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'opclasses'); + $misc->printMsg($msg); + + $opclasses = $data->getOpClasses(); + + $columns = [ + 'accessmethod' => [ + 'title' => $lang['straccessmethod'], + 'field' => Decorator::field('amname'), + ], + 'opclass' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('opcname'), + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('opcintype'), + ], + 'default' => [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('opcdefault'), + 'type' => 'yesno', + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('opccomment'), + ], + ]; + + $actions = []; + + echo $misc->printTable($opclasses, $columns, $actions, 'opclasses-opclasses', $lang['strnoopclasses']); + } + +} diff --git a/src/controllers/OperatorController.php b/src/controllers/OperatorController.php new file mode 100644 index 00000000..2791d945 --- /dev/null +++ b/src/controllers/OperatorController.php @@ -0,0 +1,189 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class OperatorController extends BaseController { + public $_name = 'OperatorController'; + +/** + * Show read only properties for an operator + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('operator'); + $misc->printTitle($lang['strproperties'], 'pg.operator'); + $misc->printMsg($msg); + + $oprdata = $data->getOperator($_REQUEST['operator_oid']); + $oprdata->fields['oprcanhash'] = $data->phpBool($oprdata->fields['oprcanhash']); + + if ($oprdata->recordCount() > 0) { + echo "<table>\n"; + echo "<tr><th class=\"data left\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprname']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strleftarg']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprleftname']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strrightarg']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrightname']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strcommutator']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprcom']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strnegator']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprnegate']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strjoin']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprjoin']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strhashes']}</th>\n"; + echo "<td class=\"data1\">", ($oprdata->fields['oprcanhash']) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; + + /* these field only exists in 8.2 and before in pg_catalog */ + if (isset($oprdata->fields['oprlsortop'])) { + echo "<tr><th class=\"data left\">{$lang['strmerges']}</th>\n"; + echo "<td class=\"data1\">", ($oprdata->fields['oprlsortop'] !== '0' && $oprdata->fields['oprrsortop'] !== '0') ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strrestrict']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrest']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strleftsort']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprlsortop']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strrightsort']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrsortop']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strlessthan']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprltcmpop']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strgreaterthan']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprgtcmpop']), "</td></tr>\n"; + } else { + echo "<tr><th class=\"data left\">{$lang['strmerges']}</th>\n"; + echo "<td class=\"data1\">", $data->phpBool($oprdata->fields['oprcanmerge']) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; + } + echo "</table>\n"; + + $misc->printNavLinks([ + 'showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'operators.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strshowalloperators'], + ]], 'operators-properties', get_defined_vars() + ); + } else { + $this->doDefault($lang['strinvalidparam']); + } + + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('operator'); + $misc->printTitle($lang['strdrop'], 'pg.operator.drop'); + + echo "<p>", sprintf($lang['strconfdropoperator'], $misc->printVal($_REQUEST['operator'])), "</p>\n"; + + echo "<form action=\"/src/views/operators.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"operator\" value=\"", htmlspecialchars($_REQUEST['operator']), "\" />\n"; + echo "<input type=\"hidden\" name=\"operator_oid\" value=\"", htmlspecialchars($_REQUEST['operator_oid']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropOperator($_POST['operator_oid'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['stroperatordropped']); + } else { + $this->doDefault($lang['stroperatordroppedbad']); + } + + } + + } + +/** + * Show default list of operators in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'operators'); + $misc->printMsg($msg); + + $operators = $data->getOperators(); + + $columns = [ + 'operator' => [ + 'title' => $lang['stroperator'], + 'field' => Decorator::field('oprname'), + 'url' => "operators.php?action=properties&{$misc->href}&", + 'vars' => ['operator' => 'oprname', 'operator_oid' => 'oid'], + ], + 'leftarg' => [ + 'title' => $lang['strleftarg'], + 'field' => Decorator::field('oprleftname'), + ], + 'rightarg' => [ + 'title' => $lang['strrightarg'], + 'field' => Decorator::field('oprrightname'), + ], + 'returns' => [ + 'title' => $lang['strreturns'], + 'field' => Decorator::field('resultname'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('oprcomment'), + ], + ]; + + $actions = [ + 'drop' => [ + // 'title' => $lang['strdrop'], + // 'url' => "operators.php?action=confirm_drop&{$misc->href}&", + // 'vars' => array('operator' => 'oprname', 'operator_oid' => 'oid'), + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'operators.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'operator' => Decorator::field('oprname'), + 'operator_oid' => Decorator::field('oid'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($operators, $columns, $actions, 'operators-operators', $lang['strnooperators']); + +// TODO operators.php action=create $lang['strcreateoperator'] + } + +} diff --git a/src/controllers/RuleController.php b/src/controllers/RuleController.php new file mode 100644 index 00000000..a19be99e --- /dev/null +++ b/src/controllers/RuleController.php @@ -0,0 +1,208 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class RuleController extends BaseController { + public $_name = 'RuleController'; + +/** + * Confirm and then actually create a rule + */ + function createRule($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['name'])) { + $_POST['name'] = ''; + } + + if (!isset($_POST['event'])) { + $_POST['event'] = ''; + } + + if (!isset($_POST['where'])) { + $_POST['where'] = ''; + } + + if (!isset($_POST['type'])) { + $_POST['type'] = 'SOMETHING'; + } + + if (!isset($_POST['raction'])) { + $_POST['raction'] = ''; + } + + if ($confirm) { + $misc->printTrail($_REQUEST['subject']); + $misc->printTitle($lang['strcreaterule'], 'pg.rule.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/rules.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\"><input name=\"name\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['strevent']}</th>\n"; + echo "<td class=\"data1\"><select name=\"event\">\n"; + foreach ($data->rule_events as $v) { + echo "<option value=\"{$v}\"", ($v == $_POST['event']) ? ' selected="selected"' : '', + ">{$v}</option>\n"; + } + echo "</select></td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strwhere']}</th>\n"; + echo "<td class=\"data1\"><input name=\"where\" size=\"32\" value=\"", + htmlspecialchars($_POST['where']), "\" /></td></tr>\n"; + echo "<tr><th class=\"data left\"><label for=\"instead\">{$lang['strinstead']}</label></th>\n"; + echo "<td class=\"data1\">"; + echo "<input type=\"checkbox\" id=\"instead\" name=\"instead\" ", (isset($_POST['instead'])) ? ' checked="checked"' : '', " />\n"; + echo "</td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['straction']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input type=\"radio\" id=\"type1\" name=\"type\" value=\"NOTHING\"", ($_POST['type'] == 'NOTHING') ? ' checked="checked"' : '', " /> <label for=\"type1\">NOTHING</label><br />\n"; + echo "<input type=\"radio\" name=\"type\" value=\"SOMETHING\"", ($_POST['type'] == 'SOMETHING') ? ' checked="checked"' : '', " />\n"; + echo "(<input name=\"raction\" size=\"32\" value=\"", + htmlspecialchars($_POST['raction']), "\" />)</td></tr>\n"; + echo "</table>\n"; + + echo "<input type=\"hidden\" name=\"action\" value=\"save_create_rule\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"", htmlspecialchars($_REQUEST['subject']), "\" />\n"; + echo "<input type=\"hidden\" name=\"", htmlspecialchars($_REQUEST['subject']), + "\" value=\"", htmlspecialchars($_REQUEST[$_REQUEST['subject']]), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"submit\" name=\"ok\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + } else { + if (trim($_POST['name']) == '') { + $this->createRule(true, $lang['strruleneedsname']); + } else { + $status = $data->createRule($_POST['name'], + $_POST['event'], $_POST[$_POST['subject']], $_POST['where'], + isset($_POST['instead']), $_POST['type'], $_POST['raction']); + if ($status == 0) { + $this->doDefault($lang['strrulecreated']); + } else { + $this->createRule(true, $lang['strrulecreatedbad']); + } + + } + } + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail($_REQUEST['subject']); + $misc->printTitle($lang['strdrop'], 'pg.rule.drop'); + + echo "<p>", sprintf($lang['strconfdroprule'], $misc->printVal($_REQUEST['rule']), + $misc->printVal($_REQUEST[$_REQUEST['reltype']])), "</p>\n"; + + echo "<form action=\"/src/views/rules.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"", htmlspecialchars($_REQUEST['reltype']), "\" />\n"; + echo "<input type=\"hidden\" name=\"", htmlspecialchars($_REQUEST['reltype']), + "\" value=\"", htmlspecialchars($_REQUEST[$_REQUEST['reltype']]), "\" />\n"; + echo "<input type=\"hidden\" name=\"rule\" value=\"", htmlspecialchars($_REQUEST['rule']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropRule($_POST['rule'], $_POST[$_POST['subject']], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strruledropped']); + } else { + $this->doDefault($lang['strruledroppedbad']); + } + + } + + } + +/** + * List all the rules on the table + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail($_REQUEST['subject']); + $misc->printTabs($_REQUEST['subject'], 'rules'); + $misc->printMsg($msg); + + $rules = $data->getRules($_REQUEST[$_REQUEST['subject']]); + + $columns = [ + 'rule' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('rulename'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('definition'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $subject = urlencode($_REQUEST['subject']); + $object = urlencode($_REQUEST[$_REQUEST['subject']]); + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'rules.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'reltype' => $subject, + $subject => $object, + 'subject' => 'rule', + 'rule' => Decorator::field('rulename'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($rules, $columns, $actions, 'rules-rules', $lang['strnorules']); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'rules.php', + 'urlvars' => [ + 'action' => 'create_rule', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + $subject => $object, + 'subject' => $subject, + ], + ], + ], + 'content' => $lang['strcreaterule'], + ]], 'rules-rules', get_defined_vars()); + } + +} diff --git a/src/controllers/SchemaController.php b/src/controllers/SchemaController.php new file mode 100644 index 00000000..e1d81cfa --- /dev/null +++ b/src/controllers/SchemaController.php @@ -0,0 +1,411 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class SchemaController extends BaseController { + public $_name = 'SchemaController'; + +/** + * Show default list of schemas in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('database'); + $misc->printTabs('database', 'schemas'); + $misc->printMsg($msg); + + // Check that the DB actually supports schemas + $schemas = $data->getSchemas(); + + $columns = [ + 'schema' => [ + 'title' => $lang['strschema'], + 'field' => Decorator::field('nspname'), + 'url' => "/redirect/schema?{$misc->href}&", + 'vars' => ['schema' => 'nspname'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('nspowner'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('nspcomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['nsp' => 'nspname'], + 'url' => 'schemas.php', + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'schemas.php', + 'urlvars' => [ + 'action' => 'drop', + 'nsp' => Decorator::field('nspname'), + ], + ], + ], + 'multiaction' => 'drop', + ], + 'privileges' => [ + 'content' => $lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges.php', + 'urlvars' => [ + 'subject' => 'schema', + 'schema' => Decorator::field('nspname'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'schemas.php', + 'urlvars' => [ + 'action' => 'alter', + 'schema' => Decorator::field('nspname'), + ], + ], + ], + ], + ]; + + if (!$data->hasAlterSchema()) { + unset($actions['alter']); + } + + echo $misc->printTable($schemas, $columns, $actions, 'schemas-schemas', $lang['strnoschemas']); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'schemas.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + ], + ], + ], + 'content' => $lang['strcreateschema'], + ]], 'schemas-schemas', get_defined_vars()); + } + +/** + * Displays a screen where they can enter a new schema + */ + public function doCreate($msg = '') { + global $data, $misc; + global $lang; + + $server_info = $misc->getServerInfo(); + + if (!isset($_POST['formName'])) { + $_POST['formName'] = ''; + } + + if (!isset($_POST['formAuth'])) { + $_POST['formAuth'] = $server_info['username']; + } + + if (!isset($_POST['formSpc'])) { + $_POST['formSpc'] = ''; + } + + if (!isset($_POST['formComment'])) { + $_POST['formComment'] = ''; + } + + // Fetch all users from the database + $users = $data->getUsers(); + + $misc->printTrail('database'); + $misc->printTitle($lang['strcreateschema'], 'pg.schema.create'); + $misc->printMsg($msg); + + echo '<form action="/src/views/schemas.php" method="post">' . "\n"; + echo "<table style=\"width: 100%\">\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; + // Owner + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formAuth\">\n"; + while (!$users->EOF) { + $uname = htmlspecialchars($users->fields['usename']); + echo "\t\t\t\t<option value=\"{$uname}\"", + ($uname == $_POST['formAuth']) ? ' selected="selected"' : '', ">{$uname}</option>\n"; + $users->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"create\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new schema in the database + */ + public function doSaveCreate() { + global $data, $lang, $_reload_browser; + + // Check that they've given a name + if ($_POST['formName'] == '') { + $this->doCreate($lang['strschemaneedsname']); + } else { + $status = $data->createSchema($_POST['formName'], $_POST['formAuth'], $_POST['formComment']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strschemacreated']); + } else { + $this->doCreate($lang['strschemacreatedbad']); + } + + } + } + +/** + * Display a form to permit editing schema properies. + * TODO: permit changing owner + */ + public function doAlter($msg = '') { + global $data, $misc, $lang; + + $misc->printTrail('schema'); + $misc->printTitle($lang['stralter'], 'pg.schema.alter'); + $misc->printMsg($msg); + + $schema = $data->getSchemaByName($_REQUEST['schema']); + if ($schema->recordCount() > 0) { + if (!isset($_POST['comment'])) { + $_POST['comment'] = $schema->fields['nspcomment']; + } + + if (!isset($_POST['schema'])) { + $_POST['schema'] = $_REQUEST['schema']; + } + + if (!isset($_POST['name'])) { + $_POST['name'] = $_REQUEST['schema']; + } + + if (!isset($_POST['owner'])) { + $_POST['owner'] = $schema->fields['ownername']; + } + + echo '<form action="/src/views/schemas.php" method="post">' . "\n"; + echo "<table>\n"; + + echo "\t<tr>\n"; + echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data1\">"; + echo "\t\t\t<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" />\n"; + echo "\t\t</td>\n"; + echo "\t</tr>\n"; + + if ($data->hasAlterSchemaOwner()) { + $users = $data->getUsers(); + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data2\"><select name=\"owner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + } else { + echo "<input name=\"owner\" value=\"{$_POST['owner']}\" type=\"hidden\" />"; + } + + echo "\t<tr>\n"; + echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\" name=\"comment\">", htmlspecialchars($_POST['comment']), "</textarea></td>\n"; + echo "\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo "<input type=\"hidden\" name=\"schema\" value=\"", htmlspecialchars($_POST['schema']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + } + +/** + * Save the form submission containing changes to a schema + */ + public function doSaveAlter($msg = '') { + global $data, $misc, $lang, $_reload_browser; + + $status = $data->updateSchema($_POST['schema'], $_POST['comment'], $_POST['name'], $_POST['owner']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strschemaaltered']); + } else { + $this->doAlter($lang['strschemaalteredbad']); + } + + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + global $data, $misc; + global $lang, $_reload_browser; + + if (empty($_REQUEST['nsp']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifyschematodrop']); + exit(); + } + + if ($confirm) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strdrop'], 'pg.schema.drop'); + + echo '<form action="/src/views/schemas.php" method="post">' . "\n"; + //If multi drop + if (isset($_REQUEST['ma'])) { + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo '<p>', sprintf($lang['strconfdropschema'], $misc->printVal($a['nsp'])), "</p>\n"; + echo '<input type="hidden" name="nsp[]" value="', htmlspecialchars($a['nsp']), "\" />\n"; + } + } else { + echo "<p>", sprintf($lang['strconfdropschema'], $misc->printVal($_REQUEST['nsp'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"nsp\" value=\"", htmlspecialchars($_REQUEST['nsp']), "\" />\n"; + } + + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + if (is_array($_POST['nsp'])) { + $msg = ''; + $status = $data->beginTransaction(); + if ($status == 0) { + foreach ($_POST['nsp'] as $s) { + $status = $data->dropSchema($s, isset($_POST['cascade'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadropped']); + } else { + $data->endTransaction(); + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadroppedbad'])); + return; + } + } + } + if ($data->endTransaction() == 0) { + // Everything went fine, back to the Default page.... + $this->misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + $this->doDefault($lang['strschemadroppedbad']); + } + + } else { + $status = $data->dropSchema($_POST['nsp'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strschemadropped']); + } else { + $this->doDefault($lang['strschemadroppedbad']); + } + + } + } + } + +/** + * Displays options for database download + */ + public function doExport($msg = '') { + global $data, $misc; + global $lang; + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'export'); + $misc->printMsg($msg); + + echo '<form action="/src/views/dbexport.php" method="post">' . "\n"; + + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; + // Data only + echo "<tr><th class=\"data left\" rowspan=\"2\">"; + echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"d_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; + // Structure only + echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; + echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; + // Structure and data + echo "<tr><th class=\"data left\" rowspan=\"3\">"; + echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"sd_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; + echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; + echo "</table>\n"; + + echo "<h3>{$lang['stroptions']}</h3>\n"; + echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; + echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label>\n"; + // MSIE cannot download gzip in SSL mode - it's just broken + if (!(strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS']))) { + echo "<br /><input type=\"radio\" id=\"output3\" name=\"output\" value=\"gzipped\" /><label for=\"output3\">{$lang['strdownloadgzipped']}</label>\n"; + } + echo "</p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"schema\" />\n"; + echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; + echo "<input type=\"hidden\" name=\"schema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; + echo "</form>\n"; + } +} diff --git a/src/controllers/SequenceController.php b/src/controllers/SequenceController.php new file mode 100644 index 00000000..db988c60 --- /dev/null +++ b/src/controllers/SequenceController.php @@ -0,0 +1,742 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class SequenceController extends BaseController { + public $_name = 'SequenceController'; + +/** + * Display list of all sequences in the database/schema + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'sequences'); + $misc->printMsg($msg); + + // Get all sequences + $sequences = $data->getSequences(); + + $columns = [ + 'sequence' => [ + 'title' => $lang['strsequence'], + 'field' => Decorator::field('seqname'), + 'url' => "sequences.php?action=properties&{$misc->href}&", + 'vars' => ['sequence' => 'seqname'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('seqowner'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('seqcomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['sequence' => 'seqname'], + 'url' => 'sequences.php', + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'subject' => 'sequence', + 'sequence' => Decorator::field('seqname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'sequence' => Decorator::field('seqname'), + ], + ], + ], + 'multiaction' => 'confirm_drop', + ], + 'privileges' => [ + 'content' => $lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges.php', + 'urlvars' => [ + 'subject' => 'sequence', + 'sequence' => Decorator::field('seqname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($sequences, $columns, $actions, 'sequences-sequences', $lang['strnosequences']); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatesequence'], + ]], 'sequences-sequences', get_defined_vars()); + } + +/** + * Display the properties of a sequence + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + $misc->printTrail('sequence'); + $misc->printTitle($lang['strproperties'], 'pg.sequence'); + $misc->printMsg($msg); + + // Fetch the sequence information + $sequence = $data->getSequence($_REQUEST['sequence']); + + if (is_object($sequence) && $sequence->recordCount() > 0) { + $sequence->fields['is_cycled'] = $data->phpBool($sequence->fields['is_cycled']); + $sequence->fields['is_called'] = $data->phpBool($sequence->fields['is_called']); + + // Show comment if any + if ($sequence->fields['seqcomment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($sequence->fields['seqcomment']), "</p>\n"; + } + + echo "<table border=\"0\">"; + echo "<tr><th class=\"data\">{$lang['strname']}</th>"; + if ($data->hasAlterSequenceStart()) { + echo "<th class=\"data\">{$lang['strstartvalue']}</th>"; + } + echo "<th class=\"data\">{$lang['strlastvalue']}</th>"; + echo "<th class=\"data\">{$lang['strincrementby']}</th>"; + echo "<th class=\"data\">{$lang['strmaxvalue']}</th>"; + echo "<th class=\"data\">{$lang['strminvalue']}</th>"; + echo "<th class=\"data\">{$lang['strcachevalue']}</th>"; + echo "<th class=\"data\">{$lang['strlogcount']}</th>"; + echo "<th class=\"data\">{$lang['strcancycle']}</th>"; + echo "<th class=\"data\">{$lang['striscalled']}</th></tr>"; + echo "<tr>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['seqname']), "</td>"; + if ($data->hasAlterSequenceStart()) { + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['start_value']), "</td>"; + } + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['last_value']), "</td>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['increment_by']), "</td>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['max_value']), "</td>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['min_value']), "</td>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['cache_value']), "</td>"; + echo "<td class=\"data1\">", $misc->printVal($sequence->fields['log_cnt']), "</td>"; + echo "<td class=\"data1\">", ($sequence->fields['is_cycled'] ? $lang['stryes'] : $lang['strno']), "</td>"; + echo "<td class=\"data1\">", ($sequence->fields['is_called'] ? $lang['stryes'] : $lang['strno']), "</td>"; + echo "</tr>"; + echo "</table>"; + + $navlinks = [ + 'alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'sequence' => $sequence->fields['seqname'], + ], + ], + ], + 'content' => $lang['stralter'], + ], + 'setval' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'confirm_setval', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'sequence' => $sequence->fields['seqname'], + ], + ], + ], + 'content' => $lang['strsetval'], + ], + 'nextval' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'nextval', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'sequence' => $sequence->fields['seqname'], + ], + ], + ], + 'content' => $lang['strnextval'], + ], + 'restart' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'restart', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'sequence' => $sequence->fields['seqname'], + ], + ], + ], + 'content' => $lang['strrestart'], + ], + 'reset' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'action' => 'reset', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'sequence' => $sequence->fields['seqname'], + ], + ], + ], + 'content' => $lang['strreset'], + ], + 'showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'sequences.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strshowallsequences'], + ], + ]; + + if (!$data->hasAlterSequenceStart()) { + unset($navlinks['restart']); + } + + $misc->printNavLinks($navlinks, 'sequences-properties', get_defined_vars()); + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Drop a sequence + */ + public function doDrop($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['sequence']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifysequencetodrop']); + exit(); + } + + if ($confirm) { + $misc->printTrail('sequence'); + $misc->printTitle($lang['strdrop'], 'pg.sequence.drop'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/sequences.php\" method=\"post\">\n"; + + //If multi drop + if (isset($_REQUEST['ma'])) { + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdropsequence'], $misc->printVal($a['sequence'])), "</p>\n"; + printf('<input type="hidden" name="sequence[]" value="%s" />', htmlspecialchars($a['sequence'])); + } + } else { + echo "<p>", sprintf($lang['strconfdropsequence'], $misc->printVal($_REQUEST['sequence'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; + } + + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + if (is_array($_POST['sequence'])) { + $msg = ''; + $status = $data->beginTransaction(); + if ($status == 0) { + foreach ($_POST['sequence'] as $s) { + $status = $data->dropSequence($s, isset($_POST['cascade'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strsequencedropped']); + } else { + $data->endTransaction(); + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strsequencedroppedbad'])); + return; + } + } + } + if ($data->endTransaction() == 0) { + // Everything went fine, back to the Default page.... + $this->misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + $this->doDefault($lang['strsequencedroppedbad']); + } + + } else { + $status = $data->dropSequence($_POST['sequence'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strsequencedropped']); + } else { + $this->doDrop(true, $lang['strsequencedroppedbad']); + } + + } + } + } + +/** + * Displays a screen where they can enter a new sequence + */ + public function doCreateSequence($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['formSequenceName'])) { + $_POST['formSequenceName'] = ''; + } + + if (!isset($_POST['formIncrement'])) { + $_POST['formIncrement'] = ''; + } + + if (!isset($_POST['formMinValue'])) { + $_POST['formMinValue'] = ''; + } + + if (!isset($_POST['formMaxValue'])) { + $_POST['formMaxValue'] = ''; + } + + if (!isset($_POST['formStartValue'])) { + $_POST['formStartValue'] = ''; + } + + if (!isset($_POST['formCacheValue'])) { + $_POST['formCacheValue'] = ''; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatesequence'], 'pg.sequence.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/sequences.php\" method=\"post\">\n"; + echo "<table>\n"; + + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formSequenceName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['formSequenceName']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strincrementby']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formIncrement\" size=\"5\" value=\"", + htmlspecialchars($_POST['formIncrement']), "\" /> </td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strminvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formMinValue\" size=\"5\" value=\"", + htmlspecialchars($_POST['formMinValue']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strmaxvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formMaxValue\" size=\"5\" value=\"", + htmlspecialchars($_POST['formMaxValue']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strstartvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formStartValue\" size=\"5\" value=\"", + htmlspecialchars($_POST['formStartValue']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strcachevalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formCacheValue\" size=\"5\" value=\"", + htmlspecialchars($_POST['formCacheValue']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\"><label for=\"formCycledValue\">{$lang['strcancycle']}</label></th>\n"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formCycledValue\" name=\"formCycledValue\" ", + (isset($_POST['formCycledValue']) ? ' checked="checked"' : ''), " /></td></tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_sequence\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new sequence in the database + */ + public function doSaveCreateSequence() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've given a name and at least one column + if ($_POST['formSequenceName'] == '') { + $this->doCreateSequence($lang['strsequenceneedsname']); + } else { + $status = $data->createSequence($_POST['formSequenceName'], + $_POST['formIncrement'], $_POST['formMinValue'], + $_POST['formMaxValue'], $_POST['formStartValue'], + $_POST['formCacheValue'], isset($_POST['formCycledValue'])); + if ($status == 0) { + $this->doDefault($lang['strsequencecreated']); + } else { + $this->doCreateSequence($lang['strsequencecreatedbad']); + } + } + } + +/** + * Restarts a sequence + */ + public function doRestart() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->restartSequence($_REQUEST['sequence']); + if ($status == 0) { + $this->doProperties($lang['strsequencerestart']); + } else { + $this->doProperties($lang['strsequencerestartbad']); + } + + } + +/** + * Resets a sequence + */ + public function doReset() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->resetSequence($_REQUEST['sequence']); + if ($status == 0) { + $this->doProperties($lang['strsequencereset']); + } else { + $this->doProperties($lang['strsequenceresetbad']); + } + + } + +/** + * Set Nextval of a sequence + */ + public function doNextval() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->nextvalSequence($_REQUEST['sequence']); + if ($status == 0) { + $this->doProperties($lang['strsequencenextval']); + } else { + $this->doProperties($lang['strsequencenextvalbad']); + } + + } + +/** + * Function to save after 'setval'ing a sequence + */ + public function doSaveSetval() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->setvalSequence($_POST['sequence'], $_POST['nextvalue']); + if ($status == 0) { + $this->doProperties($lang['strsequencesetval']); + } else { + $this->doProperties($lang['strsequencesetvalbad']); + } + + } + +/** + * Function to allow 'setval'ing of a sequence + */ + public function doSetval($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('sequence'); + $misc->printTitle($lang['strsetval'], 'pg.sequence'); + $misc->printMsg($msg); + + // Fetch the sequence information + $sequence = $data->getSequence($_REQUEST['sequence']); + + if (is_object($sequence) && $sequence->recordCount() > 0) { + echo "<form action=\"/src/views/sequences.php\" method=\"post\">\n"; + echo "<table border=\"0\">"; + echo "<tr><th class=\"data left required\">{$lang['strlastvalue']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"nextvalue\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + $misc->printVal($sequence->fields['last_value']), "\" /></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"setval\" />\n"; + echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"setval\" value=\"{$lang['strsetval']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Function to save after altering a sequence + */ + public function doSaveAlter() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['owner'])) { + $_POST['owner'] = null; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = null; + } + + if (!isset($_POST['formIncrement'])) { + $_POST['formIncrement'] = null; + } + + if (!isset($_POST['formMinValue'])) { + $_POST['formMinValue'] = null; + } + + if (!isset($_POST['formMaxValue'])) { + $_POST['formMaxValue'] = null; + } + + if (!isset($_POST['formStartValue'])) { + $_POST['formStartValue'] = null; + } + + if (!isset($_POST['formRestartValue'])) { + $_POST['formRestartValue'] = null; + } + + if (!isset($_POST['formCacheValue'])) { + $_POST['formCacheValue'] = null; + } + + if (!isset($_POST['formCycledValue'])) { + $_POST['formCycledValue'] = null; + } + + $status = $data->alterSequence($_POST['sequence'], $_POST['name'], $_POST['comment'], $_POST['owner'], + $_POST['newschema'], $_POST['formIncrement'], $_POST['formMinValue'], $_POST['formMaxValue'], + $_POST['formRestartValue'], $_POST['formCacheValue'], isset($_POST['formCycledValue']), $_POST['formStartValue']); + + if ($status == 0) { + if ($_POST['sequence'] != $_POST['name']) { + // Jump them to the new view name + $_REQUEST['sequence'] = $_POST['name']; + // Force a browser reload + $this->misc->setReloadBrowser(true); + } + if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { + // Jump them to the new sequence schema + $misc->setCurrentSchema($_POST['newschema']); + $this->misc->setReloadBrowser(true); + } + $this->doProperties($lang['strsequencealtered']); + } else { + $this->doProperties($lang['strsequencealteredbad']); + } + + } + +/** + * Function to allow altering of a sequence + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('sequence'); + $misc->printTitle($lang['stralter'], 'pg.sequence.alter'); + $misc->printMsg($msg); + + // Fetch the sequence information + $sequence = $data->getSequence($_REQUEST['sequence']); + + if (is_object($sequence) && $sequence->recordCount() > 0) { + if (!isset($_POST['name'])) { + $_POST['name'] = $_REQUEST['sequence']; + } + + if (!isset($_POST['comment'])) { + $_POST['comment'] = $sequence->fields['seqcomment']; + } + + if (!isset($_POST['owner'])) { + $_POST['owner'] = $sequence->fields['seqowner']; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = $sequence->fields['nspname']; + } + + // Handle Checkbox Value + $sequence->fields['is_cycled'] = $data->phpBool($sequence->fields['is_cycled']); + if ($sequence->fields['is_cycled']) { + $_POST['formCycledValue'] = 'on'; + } + + echo "<form action=\"/src/views/sequences.php\" method=\"post\">\n"; + echo "<table>\n"; + + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; + + if ($data->isSuperUser()) { + // Fetch all users + $users = $data->getUsers(); + + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\"><select name=\"owner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + } + + if ($data->hasAlterSequenceSchema()) { + $schemas = $data->getSchemas(); + echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; + echo "<td class=\"data1\"><select name=\"newschema\">"; + while (!$schemas->EOF) { + $schema = $schemas->fields['nspname']; + echo "<option value=\"", htmlspecialchars($schema), "\"", + ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; + $schemas->moveNext(); + } + echo "</select></td></tr>\n"; + } + + echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", + htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; + + if ($data->hasAlterSequenceStart()) { + echo "<tr><th class=\"data left\">{$lang['strstartvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formStartValue\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['start_value']), "\" /></td></tr>\n"; + } + + echo "<tr><th class=\"data left\">{$lang['strrestartvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formRestartValue\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['last_value']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strincrementby']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formIncrement\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['increment_by']), "\" /> </td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strmaxvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formMaxValue\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['max_value']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strminvalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formMinValue\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['min_value']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\">{$lang['strcachevalue']}</th>\n"; + echo "<td class=\"data1\"><input name=\"formCacheValue\" size=\"5\" value=\"", + htmlspecialchars($sequence->fields['cache_value']), "\" /></td></tr>\n"; + + echo "<tr><th class=\"data left\"><label for=\"formCycledValue\">{$lang['strcancycle']}</label></th>\n"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formCycledValue\" name=\"formCycledValue\" ", + (isset($_POST['formCycledValue']) ? ' checked="checked"' : ''), " /></td></tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +} diff --git a/src/controllers/TableController.php b/src/controllers/TableController.php new file mode 100644 index 00000000..7ed7498e --- /dev/null +++ b/src/controllers/TableController.php @@ -0,0 +1,1025 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class TableController extends BaseController { + use AdminTrait; + public $script = 'table.php'; + public $_name = 'TableController'; + +/** + * Displays a screen where they can enter a new table + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + $default_with_oids = $data->getDefaultWithOid(); + if ($default_with_oids == 'off') { + $_REQUEST['withoutoids'] = 'on'; + } + + } + + if (!isset($_REQUEST['name'])) { + $_REQUEST['name'] = ''; + } + + if (!isset($_REQUEST['fields'])) { + $_REQUEST['fields'] = ''; + } + + if (!isset($_REQUEST['tblcomment'])) { + $_REQUEST['tblcomment'] = ''; + } + + if (!isset($_REQUEST['spcname'])) { + $_REQUEST['spcname'] = ''; + } + + switch ($_REQUEST['stage']) { + case 1: + // Fetch all tablespaces from the database + if ($data->hasTablespaces()) { + $tablespaces = $data->getTablespaces(); + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumcols']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['stroptions']}</th>\n"; + echo "\t\t<td class=\"data\"><label for=\"withoutoids\"><input type=\"checkbox\" id=\"withoutoids\" name=\"withoutoids\"", isset($_REQUEST['withoutoids']) ? ' checked="checked"' : '', " />WITHOUT OIDS</label></td>\n\t</tr>\n"; + + // Tablespace (if there are any) + if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; + echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"spcname\">\n"; + // Always offer the default (empty) option + echo "\t\t\t\t<option value=\"\"", + ($_REQUEST['spcname'] == '') ? ' selected="selected"' : '', "></option>\n"; + // Display all other tablespaces + while (!$tablespaces->EOF) { + $spcname = htmlspecialchars($tablespaces->fields['spcname']); + echo "\t\t\t\t<option value=\"{$spcname}\"", + ($tablespaces->fields['spcname'] == $_REQUEST['spcname']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; + $tablespaces->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; + } + + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"tblcomment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['tblcomment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + break; + case 2: + + // Check inputs + $fields = trim($_REQUEST['fields']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreate($lang['strtableneedsname']); + return; + } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) { + $_REQUEST['stage'] = 1; + $this->doCreate($lang['strtableneedscols']); + return; + } + + $types = $data->getTypes(true, false, true); + $types_for_js = []; + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); + $misc->printMsg($msg); + + echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + + // Output table header + echo "<table>\n"; + echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strcolumn']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>"; + echo "<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strnotnull']}</th>"; + echo "<th class=\"data\">{$lang['struniquekey']}</th><th class=\"data\">{$lang['strprimarykey']}</th>"; + echo "<th class=\"data\">{$lang['strdefault']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n"; + + for ($i = 0; $i < $_REQUEST['fields']; $i++) { + if (!isset($_REQUEST['field'][$i])) { + $_REQUEST['field'][$i] = ''; + } + + if (!isset($_REQUEST['length'][$i])) { + $_REQUEST['length'][$i] = ''; + } + + if (!isset($_REQUEST['default'][$i])) { + $_REQUEST['default'][$i] = ''; + } + + if (!isset($_REQUEST['colcomment'][$i])) { + $_REQUEST['colcomment'][$i] = ''; + } + + echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; + echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n"; + echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\" id=\"types{$i}\" onchange=\"checkLengths(this.options[this.selectedIndex].value,{$i});\">\n"; + // Output any "magic" types + foreach ($data->extraTypes as $v) { + $types_for_js[strtolower($v)] = 1; + echo "\t\t\t\t<option value=\"", htmlspecialchars($v), "\"", + (isset($_REQUEST['type'][$i]) && $v == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", + $misc->printVal($v), "</option>\n"; + } + $types->moveFirst(); + while (!$types->EOF) { + $typname = $types->fields['typname']; + $types_for_js[$typname] = 1; + echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"", + (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", + $misc->printVal($typname), "</option>\n"; + $types->moveNext(); + } + echo "\t\t\t</select>\n\t\t\n"; + if ($i == 0) { + // only define js types array once + $predefined_size_types = array_intersect($data->predefined_size_types, array_keys($types_for_js)); + $escaped_predef_types = []; // the JS escaped array elements + foreach ($predefined_size_types as $value) { + $escaped_predef_types[] = "'{$value}'"; + } + echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");</script>\n\t</td>"; + } + + // Output array type selector + echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n"; + echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n"; + echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; + echo "\t\t\t</select>\n\t\t</td>\n"; + + echo "\t\t<td><input name=\"length[{$i}]\" id=\"lengths{$i}\" size=\"10\" value=\"", + htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n"; + echo "\t\t<td><input type=\"checkbox\" name=\"notnull[{$i}]\"", (isset($_REQUEST['notnull'][$i])) ? ' checked="checked"' : '', " /></td>\n"; + echo "\t\t<td style=\"text-align: center\"><input type=\"checkbox\" name=\"uniquekey[{$i}]\"" + . (isset($_REQUEST['uniquekey'][$i]) ? ' checked="checked"' : '') . " /></td>\n"; + echo "\t\t<td style=\"text-align: center\"><input type=\"checkbox\" name=\"primarykey[{$i}]\" " + . (isset($_REQUEST['primarykey'][$i]) ? ' checked="checked"' : '') + . " /></td>\n"; + echo "\t\t<td><input name=\"default[{$i}]\" size=\"20\" value=\"", + htmlspecialchars($_REQUEST['default'][$i]), "\" /></td>\n"; + echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"", + htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /> + <script type=\"text/javascript\">checkLengths(document.getElementById('types{$i}').value,{$i});</script> + </td>\n\t</tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; + echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n"; + if (isset($_REQUEST['withoutoids'])) { + echo "<input type=\"hidden\" name=\"withoutoids\" value=\"true\" />\n"; + } + echo "<input type=\"hidden\" name=\"tblcomment\" value=\"", htmlspecialchars($_REQUEST['tblcomment']), "\" />\n"; + if (isset($_REQUEST['spcname'])) { + echo "<input type=\"hidden\" name=\"spcname\" value=\"", htmlspecialchars($_REQUEST['spcname']), "\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + break; + case 3: + + if (!isset($_REQUEST['notnull'])) { + $_REQUEST['notnull'] = []; + } + + if (!isset($_REQUEST['uniquekey'])) { + $_REQUEST['uniquekey'] = []; + } + + if (!isset($_REQUEST['primarykey'])) { + $_REQUEST['primarykey'] = []; + } + + if (!isset($_REQUEST['length'])) { + $_REQUEST['length'] = []; + } + + // Default tablespace to null if it isn't set + if (!isset($_REQUEST['spcname'])) { + $_REQUEST['spcname'] = null; + } + + // Check inputs + $fields = trim($_REQUEST['fields']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreate($lang['strtableneedsname']); + return; + } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) { + $_REQUEST['stage'] = 1; + $this->doCreate($lang['strtableneedscols']); + return; + } + + $status = $data->createTable($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'], + $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['notnull'], $_REQUEST['default'], + isset($_REQUEST['withoutoids']), $_REQUEST['colcomment'], $_REQUEST['tblcomment'], $_REQUEST['spcname'], + $_REQUEST['uniquekey'], $_REQUEST['primarykey']); + + if ($status == 0) { + $misc->setReloadBrowser(true); + return $this->doDefault($lang['strtablecreated']); + } elseif ($status == -1) { + $_REQUEST['stage'] = 2; + $this->doCreate($lang['strtableneedsfield']); + return; + } else { + $_REQUEST['stage'] = 2; + $this->doCreate($lang['strtablecreatedbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + +/** + * Dsiplay a screen where user can create a table from an existing one. + * We don't have to check if pg supports schema cause create table like + * is available under pg 7.4+ which has schema. + */ + public function doCreateLike($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!$confirm) { + + include_once BASE_PATH . '/classes/Gui.php'; + + if (!isset($_REQUEST['name'])) { + $_REQUEST['name'] = ''; + } + + if (!isset($_REQUEST['like'])) { + $_REQUEST['like'] = ''; + } + + if (!isset($_REQUEST['tablespace'])) { + $_REQUEST['tablespace'] = ''; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); + $misc->printMsg($msg); + + $tbltmp = $data->getTables(true); + $tbltmp = $tbltmp->getArray(); + + $tables = []; + $tblsel = ''; + foreach ($tbltmp as $a) { + $data->fieldClean($a['nspname']); + $data->fieldClean($a['relname']); + $tables["\"{$a['nspname']}\".\"{$a['relname']}\""] = serialize(['schema' => $a['nspname'], 'table' => $a['relname']]); + if ($_REQUEST['like'] == $tables["\"{$a['nspname']}\".\"{$a['relname']}\""]) { + $tblsel = htmlspecialchars($tables["\"{$a['nspname']}\".\"{$a['relname']}\""]); + } + + } + + unset($tbltmp); + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + echo "<table>\n\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strcreatetablelikeparent']}</th>\n"; + echo "\t\t<td class=\"data\">"; + echo \PHPPgAdmin\GUI::printCombo($tables, 'like', true, $tblsel, false); + echo "</td>\n\t</tr>\n"; + if ($data->hasTablespaces()) { + $tblsp_ = $data->getTablespaces(); + if ($tblsp_->recordCount() > 0) { + $tblsp_ = $tblsp_->getArray(); + $tblsp = []; + foreach ($tblsp_ as $a) { + $tblsp[$a['spcname']] = $a['spcname']; + } + + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; + echo "\t\t<td class=\"data\">"; + echo \PHPPgAdmin\GUI::printCombo($tblsp, 'tablespace', true, $_REQUEST['tablespace'], false); + echo "</td>\n\t</tr>\n"; + } + } + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['stroptions']}</th>\n\t\t<td class=\"data\">"; + echo "<label for=\"withdefaults\"><input type=\"checkbox\" id=\"withdefaults\" name=\"withdefaults\"", + isset($_REQUEST['withdefaults']) ? ' checked="checked"' : '', + "/>{$lang['strcreatelikewithdefaults']}</label>"; + if ($data->hasCreateTableLikeWithConstraints()) { + echo "<br /><label for=\"withconstraints\"><input type=\"checkbox\" id=\"withconstraints\" name=\"withconstraints\"", + isset($_REQUEST['withconstraints']) ? ' checked="checked"' : '', + "/>{$lang['strcreatelikewithconstraints']}</label>"; + } + if ($data->hasCreateTableLikeWithIndexes()) { + echo "<br /><label for=\"withindexes\"><input type=\"checkbox\" id=\"withindexes\" name=\"withindexes\"", + isset($_REQUEST['withindexes']) ? ' checked="checked"' : '', + "/>{$lang['strcreatelikewithindexes']}</label>"; + } + echo "</td>\n\t</tr>\n"; + echo "</table>"; + + echo "<input type=\"hidden\" name=\"action\" value=\"confcreatelike\" />\n"; + echo $misc->form; + echo "<p><input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + + if (trim($_REQUEST['name']) == '') { + $this->doCreateLike(false, $lang['strtableneedsname']); + return; + } + if (trim($_REQUEST['like']) == '') { + $this->doCreateLike(false, $lang['strtablelikeneedslike']); + return; + } + + if (!isset($_REQUEST['tablespace'])) { + $_REQUEST['tablespace'] = ''; + } + + $status = $data->createTableLike($_REQUEST['name'], unserialize($_REQUEST['like']), isset($_REQUEST['withdefaults']), + isset($_REQUEST['withconstraints']), isset($_REQUEST['withindexes']), $_REQUEST['tablespace']); + + if ($status == 0) { + $misc->setReloadBrowser(true); + return $this->doDefault($lang['strtablecreated']); + } else { + $this->doCreateLike(false, $lang['strtablecreatedbad']); + return; + } + } + } + +/** + * Ask for select parameters and perform select + */ + public function doSelectRows($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('table'); + $misc->printTabs('table', 'select'); + $misc->printMsg($msg); + + $attrs = $data->getTableAttributes($_REQUEST['table']); + + echo "<form action=\"/src/views/tables.php\" method=\"post\" id=\"selectform\">\n"; + if ($attrs->recordCount() > 0) { + // JavaScript for select all feature + echo "<script type=\"text/javascript\">\n"; + echo "//<![CDATA[\n"; + echo " function selectAll() {\n"; + echo " for (var i=0; i<document.getElementById('selectform').elements.length; i++) {\n"; + echo " var e = document.getElementById('selectform').elements[i];\n"; + echo " if (e.name.indexOf('show') == 0) e.checked = document.getElementById('selectform').selectall.checked;\n"; + echo " }\n"; + echo " }\n"; + echo "//]]>\n"; + echo "</script>\n"; + + echo "<table>\n"; + + // Output table header + echo "<tr><th class=\"data\">{$lang['strshow']}</th><th class=\"data\">{$lang['strcolumn']}</th>"; + echo "<th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['stroperator']}</th>"; + echo "<th class=\"data\">{$lang['strvalue']}</th></tr>"; + + $i = 0; + while (!$attrs->EOF) { + $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); + // Set up default value if there isn't one already + if (!isset($_REQUEST['values'][$attrs->fields['attname']])) { + $_REQUEST['values'][$attrs->fields['attname']] = null; + } + + if (!isset($_REQUEST['ops'][$attrs->fields['attname']])) { + $_REQUEST['ops'][$attrs->fields['attname']] = null; + } + + // Continue drawing row + $id = (($i % 2) == 0 ? '1' : '2'); + echo "<tr class=\"data{$id}\">\n"; + echo "<td style=\"white-space:nowrap;\">"; + echo "<input type=\"checkbox\" name=\"show[", htmlspecialchars($attrs->fields['attname']), "]\"", + isset($_REQUEST['show'][$attrs->fields['attname']]) ? ' checked="checked"' : '', " /></td>"; + echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; + echo "<td style=\"white-space:nowrap;\">", $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])), "</td>"; + echo "<td style=\"white-space:nowrap;\">"; + echo "<select name=\"ops[{$attrs->fields['attname']}]\">\n"; + foreach (array_keys($data->selectOps) as $v) { + echo "<option value=\"", htmlspecialchars($v), "\"", ($v == $_REQUEST['ops'][$attrs->fields['attname']]) ? ' selected="selected"' : '', + ">", htmlspecialchars($v), "</option>\n"; + } + echo "</select>\n</td>\n"; + echo "<td style=\"white-space:nowrap;\">", $data->printField("values[{$attrs->fields['attname']}]", + $_REQUEST['values'][$attrs->fields['attname']], $attrs->fields['type']), "</td>"; + echo "</tr>\n"; + $i++; + $attrs->moveNext(); + } + // Select all checkbox + echo "<tr><td colspan=\"5\"><input type=\"checkbox\" id=\"selectall\" name=\"selectall\" accesskey=\"a\" onclick=\"javascript:selectAll()\" /><label for=\"selectall\">{$lang['strselectallfields']}</label></td>"; + echo "</tr></table>\n"; + } else { + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + + echo "<p><input type=\"hidden\" name=\"action\" value=\"selectrows\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"select\" accesskey=\"r\" value=\"{$lang['strselect']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + if (!isset($_POST['show'])) { + $_POST['show'] = []; + } + + if (!isset($_POST['values'])) { + $_POST['values'] = []; + } + + if (!isset($_POST['nulls'])) { + $_POST['nulls'] = []; + } + + // Verify that they haven't supplied a value for unary operators + foreach ($_POST['ops'] as $k => $v) { + if ($data->selectOps[$v] == 'p' && $_POST['values'][$k] != '') { + $this->doSelectRows(true, $lang['strselectunary']); + return; + } + } + + if (sizeof($_POST['show']) == 0) { + $this->doSelectRows(true, $lang['strselectneedscol']); + } else { + // Generate query SQL + $query = $data->getSelectSQL($_REQUEST['table'], array_keys($_POST['show']), + $_POST['values'], $_POST['ops']); + $_REQUEST['query'] = $query; + $_REQUEST['return'] = 'selectrows'; + + $misc->setNoOutput(true); + include './display.php'; + exit; + } + } + } + +/** + * Ask for insert parameters and then actually insert row + */ + public function doInsertRow($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('table'); + $misc->printTabs('table', 'insert'); + + $misc->printMsg($msg); + + $attrs = $data->getTableAttributes($_REQUEST['table']); + + if (($conf['autocomplete'] != 'disable')) { + $fksprops = $misc->getAutocompleteFKProperties($_REQUEST['table']); + if ($fksprops !== false) { + echo $fksprops['code']; + } + + } else { + $fksprops = false; + } + + echo "<form action=\"/src/views/tables.php\" method=\"post\" id=\"ac_form\">\n"; + if ($attrs->recordCount() > 0) { + echo "<table>\n"; + + // Output table header + echo "<tr><th class=\"data\">{$lang['strcolumn']}</th><th class=\"data\">{$lang['strtype']}</th>"; + echo "<th class=\"data\">{$lang['strformat']}</th>"; + echo "<th class=\"data\">{$lang['strnull']}</th><th class=\"data\">{$lang['strvalue']}</th></tr>"; + + $i = 0; + $fields = []; + while (!$attrs->EOF) { + $fields[$attrs->fields['attnum']] = $attrs->fields['attname']; + $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); + // Set up default value if there isn't one already + if (!isset($_REQUEST['values'][$attrs->fields['attnum']])) { + $_REQUEST['values'][$attrs->fields['attnum']] = $attrs->fields['adsrc']; + } + + // Default format to 'VALUE' if there is no default, + // otherwise default to 'EXPRESSION' + if (!isset($_REQUEST['format'][$attrs->fields['attnum']])) { + $_REQUEST['format'][$attrs->fields['attnum']] = ($attrs->fields['adsrc'] === null) ? 'VALUE' : 'EXPRESSION'; + } + + // Continue drawing row + $id = (($i % 2) == 0 ? '1' : '2'); + echo "<tr class=\"data{$id}\">\n"; + echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; + echo "<td style=\"white-space:nowrap;\">\n"; + echo $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])); + echo "<input type=\"hidden\" name=\"types[{$attrs->fields['attnum']}]\" value=\"", + htmlspecialchars($attrs->fields['type']), "\" /></td>"; + echo "<td style=\"white-space:nowrap;\">\n"; + echo "<select name=\"format[{$attrs->fields['attnum']}]\">\n"; + echo "<option value=\"VALUE\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'VALUE') ? ' selected="selected"' : '', ">{$lang['strvalue']}</option>\n"; + echo "<option value=\"EXPRESSION\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'EXPRESSION') ? ' selected="selected"' : '', ">{$lang['strexpression']}</option>\n"; + echo "</select>\n</td>\n"; + echo "<td style=\"white-space:nowrap;\">"; + // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS) + if (!$attrs->fields['attnotnull']) { + echo "<label><span><input type=\"checkbox\" name=\"nulls[{$attrs->fields['attnum']}]\"", + isset($_REQUEST['nulls'][$attrs->fields['attnum']]) ? ' checked="checked"' : '', " /></span></label></td>"; + } else { + echo " </td>"; + } + echo "<td id=\"row_att_{$attrs->fields['attnum']}\" style=\"white-space:nowrap;\">"; + if (($fksprops !== false) && isset($fksprops['byfield'][$attrs->fields['attnum']])) { + echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], 'fktype' /*force FK*/, + [ + 'id' => "attr_{$attrs->fields['attnum']}", + 'autocomplete' => 'off', + ] + ); + } else { + echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], $attrs->fields['type']); + } + echo "</td>\n"; + echo "</tr>\n"; + $i++; + $attrs->moveNext(); + } + echo "</table>\n"; + + if (!isset($_SESSION['counter'])) {$_SESSION['counter'] = 0;} + + echo "<input type=\"hidden\" name=\"action\" value=\"insertrow\" />\n"; + echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlentities(serialize($fields), ENT_QUOTES, 'UTF-8'), "\" />\n"; + echo "<input type=\"hidden\" name=\"protection_counter\" value=\"" . $_SESSION['counter'] . "\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<p><input type=\"submit\" name=\"insert\" value=\"{$lang['strinsert']}\" />\n"; + echo "<input type=\"submit\" name=\"insertandrepeat\" accesskey=\"r\" value=\"{$lang['strinsertandrepeat']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + + if ($fksprops !== false) { + if ($conf['autocomplete'] != 'default off') { + echo "<input type=\"checkbox\" id=\"no_ac\" value=\"1\" checked=\"checked\" /><label for=\"no_ac\">{$lang['strac']}</label>\n"; + } else { + echo "<input type=\"checkbox\" id=\"no_ac\" value=\"0\" /><label for=\"no_ac\">{$lang['strac']}</label>\n"; + } + + } + echo "</p>\n"; + } else { + echo "<p>{$lang['strnofieldsforinsert']}</p>\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + } + echo $misc->form; + echo "</form>\n"; + } else { + if (!isset($_POST['values'])) { + $_POST['values'] = []; + } + + if (!isset($_POST['nulls'])) { + $_POST['nulls'] = []; + } + + $_POST['fields'] = unserialize(htmlspecialchars_decode($_POST['fields'], ENT_QUOTES)); + + if ($_SESSION['counter']++ == $_POST['protection_counter']) { + $status = $data->insertRow($_POST['table'], $_POST['fields'], $_POST['values'], $_POST['nulls'], $_POST['format'], $_POST['types']); + if ($status == 0) { + if (isset($_POST['insert'])) { + return $this->doDefault($lang['strrowinserted']); + } else { + $_REQUEST['values'] = []; + $_REQUEST['nulls'] = []; + $this->doInsertRow(true, $lang['strrowinserted']); + } + } else { + $this->doInsertRow(true, $lang['strrowinsertedbad']); + } + + } else { + $this->doInsertRow(true, $lang['strrowduplicate']); + } + + } + + } + +/** + * Show confirmation of empty and perform actual empty + */ + public function doEmpty($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + return $this->doDefault($lang['strspecifytabletoempty']); + exit(); + } + + if ($confirm) { + if (isset($_REQUEST['ma'])) { + $misc->printTrail('schema'); + $misc->printTitle($lang['strempty'], 'pg.table.empty'); + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfemptytable'], $misc->printVal($a['table'])), "</p>\n"; + printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table'])); + } + } // END mutli empty + else { + $misc->printTrail('table'); + $misc->printTitle($lang['strempty'], 'pg.table.empty'); + + echo "<p>", sprintf($lang['strconfemptytable'], $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + } // END not mutli empty + + echo "<input type=\"hidden\" name=\"action\" value=\"empty\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"empty\" value=\"{$lang['strempty']}\" /> <input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END if confirm + else { + // Do Empty + if (is_array($_REQUEST['table'])) { + $msg = ''; + foreach ($_REQUEST['table'] as $t) { + $status = $data->emptyTable($t); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtableemptied']); + } else { + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtableemptiedbad'])); + return; + } + } + $this->doDefault($msg); + } // END mutli empty + else { + $status = $data->emptyTable($_POST['table']); + if ($status == 0) { + return $this->doDefault($lang['strtableemptied']); + } else { + return $this->doDefault($lang['strtableemptiedbad']); + } + + } // END not mutli empty + } // END do Empty + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { + return $this->doDefault($lang['strspecifytabletodrop']); + exit(); + } + + if ($confirm) { + //If multi drop + if (isset($_REQUEST['ma'])) { + + $misc->printTrail('schema'); + $misc->printTitle($lang['strdrop'], 'pg.table.drop'); + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdroptable'], $misc->printVal($a['table'])), "</p>\n"; + printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table'])); + } + } else { + + $misc->printTrail('table'); + $misc->printTitle($lang['strdrop'], 'pg.table.drop'); + + echo "<p>", sprintf($lang['strconfdroptable'], $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/tables.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + } // END if multi drop + + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } // END confirm + else { + //If multi drop + if (is_array($_REQUEST['table'])) { + $msg = ''; + $status = $data->beginTransaction(); + if ($status == 0) { + foreach ($_REQUEST['table'] as $t) { + $status = $data->dropTable($t, isset($_POST['cascade'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtabledropped']); + } else { + $data->endTransaction(); + return $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtabledroppedbad'])); + return; + } + } + } + if ($data->endTransaction() == 0) { + // Everything went fine, back to the Default page.... + $misc->setReloadBrowser(true); + return $this->doDefault($msg); + } else { + return $this->doDefault($lang['strtabledroppedbad']); + } + + } else { + $status = $data->dropTable($_POST['table'], isset($_POST['cascade'])); + if ($status == 0) { + $misc->setReloadBrowser(true); + return $this->doDefault($lang['strtabledropped']); + } else { + return $this->doDefault($lang['strtabledroppedbad']); + } + + } + } // END DROP + } // END Function + +/** + * Show default list of tables in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'tables'); + $misc->printMsg($msg); + + $tables = $data->getTables(); + + $columns = [ + 'table' => [ + 'title' => $lang['strtable'], + 'field' => Decorator::field('relname'), + 'url' => "/redirect/table?{$misc->href}&", + 'vars' => ['table' => 'relname'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('relowner'), + ], + 'tablespace' => [ + 'title' => $lang['strtablespace'], + 'field' => Decorator::field('tablespace'), + ], + 'tuples' => [ + 'title' => $lang['strestimatedrowcount'], + 'field' => Decorator::field('reltuples'), + 'type' => 'numeric', + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('relcomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['table' => 'relname'], + 'url' => 'tables.php', + 'default' => 'analyze', + ], + 'browse' => [ + 'content' => $lang['strbrowse'], + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'subject' => 'table', + 'return' => 'table', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'select' => [ + 'content' => $lang['strselect'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confselectrows', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'insert' => [ + 'content' => $lang['strinsert'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confinsertrow', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'empty' => [ + 'multiaction' => 'confirm_empty', + 'content' => $lang['strempty'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_empty', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'drop' => [ + 'multiaction' => 'confirm_drop', + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'vacuum' => [ + 'multiaction' => 'confirm_vacuum', + 'content' => $lang['strvacuum'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_vacuum', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'analyze' => [ + 'multiaction' => 'confirm_analyze', + 'content' => $lang['stranalyze'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_analyze', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + 'reindex' => [ + 'multiaction' => 'confirm_reindex', + 'content' => $lang['strreindex'], + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_reindex', + 'table' => Decorator::field('relname'), + ], + ], + ], + ], + //'cluster' TODO ? + ]; + + if (!$data->hasTablespaces()) { + unset($columns['tablespace']); + } + + echo $misc->printTable($tables, $columns, $actions, 'tables-tables', $lang['strnotables']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatetable'], + ], + ]; + + if (($tables->recordCount() > 0) && $data->hasCreateTableLike()) { + $navlinks['createlike'] = [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'createlike', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatetablelike'], + ]; + } + $misc->printNavLinks($navlinks, 'tables-tables', get_defined_vars()); + } + +} diff --git a/src/controllers/TablePropertyController.php b/src/controllers/TablePropertyController.php new file mode 100644 index 00000000..96deb1bd --- /dev/null +++ b/src/controllers/TablePropertyController.php @@ -0,0 +1,763 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class TablePropertyController extends BaseController { + public $_name = 'TablePropertyController'; + + public function doSaveAlter() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // For databases that don't allow owner change + if (!isset($_POST['owner'])) { + $_POST['owner'] = ''; + } + + // Default tablespace to null if it isn't set + if (!isset($_POST['tablespace'])) { + $_POST['tablespace'] = null; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = null; + } + + $status = $data->alterTable($_POST['table'], $_POST['name'], $_POST['owner'], $_POST['newschema'], $_POST['comment'], $_POST['tablespace']); + if ($status == 0) { + // If table has been renamed, need to change to the new name and + // reload the browser frame. + if ($_POST['table'] != $_POST['name']) { + // Jump them to the new table name + $_REQUEST['table'] = $_POST['name']; + // Force a browser reload + $_reload_browser = true; + } + // If schema has changed, need to change to the new schema and reload the browser + if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { + // Jump them to the new sequence schema + $misc->setCurrentSchema($_POST['newschema']); + $_reload_browser = true; + } + $this->doDefault($lang['strtablealtered']); + } else { + $this->doAlter($lang['strtablealteredbad']); + } + + } + +/** + * Function to allow altering of a table + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('table'); + $misc->printTitle($lang['stralter'], 'pg.table.alter'); + $misc->printMsg($msg); + + // Fetch table info + $table = $data->getTable($_REQUEST['table']); + // Fetch all users + $users = $data->getUsers(); + // Fetch all tablespaces from the database + if ($data->hasTablespaces()) { + $tablespaces = $data->getTablespaces(true); + } + + if ($table->recordCount() > 0) { + + if (!isset($_POST['name'])) { + $_POST['name'] = $table->fields['relname']; + } + + if (!isset($_POST['owner'])) { + $_POST['owner'] = $table->fields['relowner']; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = $table->fields['nspname']; + } + + if (!isset($_POST['comment'])) { + $_POST['comment'] = $table->fields['relcomment']; + } + + if ($data->hasTablespaces() && !isset($_POST['tablespace'])) { + $_POST['tablespace'] = $table->fields['tablespace']; + } + + echo "<form action=\"/src/views/tblproperties.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name'], ENT_QUOTES), "\" /></td></tr>\n"; + + if ($data->isSuperUser()) { + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\"><select name=\"owner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + } + + if ($data->hasAlterTableSchema()) { + $schemas = $data->getSchemas(); + echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; + echo "<td class=\"data1\"><select name=\"newschema\">"; + while (!$schemas->EOF) { + $schema = $schemas->fields['nspname']; + echo "<option value=\"", htmlspecialchars($schema), "\"", + ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; + $schemas->moveNext(); + } + echo "</select></td></tr>\n"; + } + + // Tablespace (if there are any) + if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; + echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"tablespace\">\n"; + // Always offer the default (empty) option + echo "\t\t\t\t<option value=\"\"", + ($_POST['tablespace'] == '') ? ' selected="selected"' : '', "></option>\n"; + // Display all other tablespaces + while (!$tablespaces->EOF) { + $spcname = htmlspecialchars($tablespaces->fields['spcname']); + echo "\t\t\t\t<option value=\"{$spcname}\"", + ($spcname == $_POST['tablespace']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; + $tablespaces->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; + } + + echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", + htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + + public function doExport($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Determine whether or not the table has an object ID + $hasID = $data->hasObjectID($_REQUEST['table']); + + $misc->printTrail('table'); + $misc->printTabs('table', 'export'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/dataexport.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; + // Data only + echo "<tr><th class=\"data left\" rowspan=\"", ($hasID) ? 2 : 1, "\">"; + echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"d_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "<option value=\"csv\">CSV</option>\n"; + echo "<option value=\"tab\">{$lang['strtabbed']}</option>\n"; + echo "<option value=\"html\">XHTML</option>\n"; + echo "<option value=\"xml\">XML</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + if ($hasID) { + echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; + } + // Structure only + echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; + echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; + // Structure and data + echo "<tr><th class=\"data left\" rowspan=\"", ($hasID) ? 3 : 2, "\">"; + echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"sd_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; + if ($hasID) { + echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; + } + echo "</table>\n"; + + echo "<h3>{$lang['stroptions']}</h3>\n"; + echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; + echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; + echo "</form>\n"; + } + + public function doImport($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('table'); + $misc->printTabs('table', 'import'); + $misc->printMsg($msg); + + // Check that file uploads are enabled + if (ini_get('file_uploads')) { + // Don't show upload option if max size of uploads is zero + $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize')); + if (is_double($max_size) && $max_size > 0) { + echo "<form action=\"/src/views/dataimport.php\" method=\"post\" enctype=\"multipart/form-data\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strformat']}</th>\n"; + echo "\t\t<td><select name=\"format\">\n"; + echo "\t\t\t<option value=\"auto\">{$lang['strauto']}</option>\n"; + echo "\t\t\t<option value=\"csv\">CSV</option>\n"; + echo "\t\t\t<option value=\"tab\">{$lang['strtabbed']}</option>\n"; + if (function_exists('xml_parser_create')) { + echo "\t\t\t<option value=\"xml\">XML</option>\n"; + } + echo "\t\t</select></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strallowednulls']}</th>\n"; + echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$lang['strbackslashn']}</label><br />\n"; + echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />\n"; + echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$lang['stremptystring']}</label></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strfile']}</th>\n"; + echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />"; + echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"import\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strimport']}\" /></p>\n"; + echo "</form>\n"; + } + } else { + echo "<p>{$lang['strnouploads']}</p>\n"; + } + + } + +/** + * Displays a screen where they can add a column + */ + public function doAddColumn($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + } + + switch ($_REQUEST['stage']) { + case 1: + // Set variable defaults + if (!isset($_POST['field'])) { + $_POST['field'] = ''; + } + + if (!isset($_POST['type'])) { + $_POST['type'] = ''; + } + + if (!isset($_POST['array'])) { + $_POST['array'] = ''; + } + + if (!isset($_POST['length'])) { + $_POST['length'] = ''; + } + + if (!isset($_POST['default'])) { + $_POST['default'] = ''; + } + + if (!isset($_POST['comment'])) { + $_POST['comment'] = ''; + } + + // Fetch all available types + $types = $data->getTypes(true, false, true); + $types_for_js = []; + + $misc->printTrail('table'); + $misc->printTitle($lang['straddcolumn'], 'pg.column.add'); + $misc->printMsg($msg); + + echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; + echo "<form action=\"/src/views/tblproperties.php\" method=\"post\">\n"; + + // Output table header + echo "<table>\n"; + echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n<th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>\n"; + echo "<th class=\"data\">{$lang['strlength']}</th>\n"; + if ($data->hasCreateFieldWithConstraints()) { + echo "<th class=\"data\">{$lang['strnotnull']}</th>\n<th class=\"data\">{$lang['strdefault']}</th>\n"; + } + + echo "<th class=\"data\">{$lang['strcomment']}</th></tr>\n"; + + echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['field']), "\" /></td>\n"; + echo "<td><select name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">\n"; + // Output any "magic" types. This came in with the alter column type so we'll check that + if ($data->hasMagicTypes()) { + foreach ($data->extraTypes as $v) { + $types_for_js[] = strtolower($v); + echo "\t<option value=\"", htmlspecialchars($v), "\"", + ($v == $_POST['type']) ? ' selected="selected"' : '', ">", + $misc->printVal($v), "</option>\n"; + } + } + while (!$types->EOF) { + $typname = $types->fields['typname']; + $types_for_js[] = $typname; + echo "\t<option value=\"", htmlspecialchars($typname), "\"", ($typname == $_POST['type']) ? ' selected="selected"' : '', ">", + $misc->printVal($typname), "</option>\n"; + $types->moveNext(); + } + echo "</select></td>\n"; + + // Output array type selector + echo "<td><select name=\"array\">\n"; + echo "\t<option value=\"\"", ($_POST['array'] == '') ? ' selected="selected"' : '', "></option>\n"; + echo "\t<option value=\"[]\"", ($_POST['array'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; + echo "</select></td>\n"; + $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js); + $escaped_predef_types = []; // the JS escaped array elements + foreach ($predefined_size_types as $value) { + $escaped_predef_types[] = "'{$value}'"; + } + + echo "<td><input name=\"length\" id=\"lengths\" size=\"8\" value=\"", + htmlspecialchars($_POST['length']), "\" /></td>\n"; + // Support for adding column with not null and default + if ($data->hasCreateFieldWithConstraints()) { + echo "<td><input type=\"checkbox\" name=\"notnull\"", + (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', " /></td>\n"; + echo "<td><input name=\"default\" size=\"20\" value=\"", + htmlspecialchars($_POST['default']), "\" /></td>\n"; + } + echo "<td><input name=\"comment\" size=\"40\" value=\"", + htmlspecialchars($_POST['comment']), "\" /></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"add_column\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + if (!$data->hasCreateFieldWithConstraints()) { + echo "<input type=\"hidden\" name=\"default\" value=\"\" />\n"; + } + echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>\n"; + break; + case 2: + // Check inputs + if (trim($_POST['field']) == '') { + $_REQUEST['stage'] = 1; + $this->doAddColumn($lang['strcolneedsname']); + return; + } + if (!isset($_POST['length'])) { + $_POST['length'] = ''; + } + + $status = $data->addColumn($_POST['table'], $_POST['field'], + $_POST['type'], $_POST['array'] != '', $_POST['length'], isset($_POST['notnull']), + $_POST['default'], $_POST['comment']); + if ($status == 0) { + $_reload_browser = true; + $this->doDefault($lang['strcolumnadded']); + } else { + $_REQUEST['stage'] = 1; + $this->doAddColumn($lang['strcolumnaddedbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + +/** + * Show confirmation of drop column and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('column'); + $misc->printTitle($lang['strdrop'], 'pg.column.drop'); + + echo "<p>", sprintf($lang['strconfdropcolumn'], $misc->printVal($_REQUEST['column']), + $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/tblproperties.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\"> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropColumn($_POST['table'], $_POST['column'], isset($_POST['cascade'])); + if ($status == 0) { + $_reload_browser = true; + $this->doDefault($lang['strcolumndropped']); + } else { + $this->doDefault($lang['strcolumndroppedbad']); + } + + } + + } + +/** + * Show default list of columns in the table + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $attPre = function (&$rowdata, $actions) use ($data) { + + $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); + $attname = $rowdata->fields['attname']; + $table = $_REQUEST['table']; + $data->fieldClean($attname); + $data->fieldClean($table); + + $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\" + FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\""; + + return $actions; + }; + + $cstrRender = function ($s, $p) use ($misc, $data) { + + $str = ''; + foreach ($p['keys'] as $k => $c) { + + if (is_null($p['keys'][$k]['consrc'])) { + $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $p['keys'][$k]['indkey'])); + $c['consrc'] = ($c['contype'] == 'u' ? "UNIQUE (" : "PRIMARY KEY (") . join(',', $atts) . ')'; + } + + if ($c['p_field'] == $s) { + switch ($c['contype']) { + case 'p': + $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . + $misc->icon('PrimaryKey') . '" alt="[pk]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; + break; + case 'f': + $str .= '<a href="tblproperties.php?' . $misc->href . "&table=" . urlencode($c['f_table']) . "&schema=" . urlencode($c['f_schema']) . "\"><img src=\"" . + $misc->icon('ForeignKey') . '" alt="[fk]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; + break; + case 'u': + $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . + $misc->icon('UniqueConstraint') . '" alt="[uniq]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; + break; + case 'c': + $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . + $misc->icon('CheckConstraint') . '" alt="[check]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; + } + } + + } + + return $str; + }; + + $misc->printTrail('table'); + $misc->printTabs('table', 'columns'); + $misc->printMsg($msg); + + // Get table + $tdata = $data->getTable($_REQUEST['table']); + // Get columns + $attrs = $data->getTableAttributes($_REQUEST['table']); + // Get constraints keys + $ck = $data->getConstraintsWithFields($_REQUEST['table']); + + // Show comment if any + if ($tdata->fields['relcomment'] !== null) { + echo '<p class="comment">', $misc->printVal($tdata->fields['relcomment']), "</p>\n"; + } + + $columns = [ + 'column' => [ + 'title' => $lang['strcolumn'], + 'field' => Decorator::field('attname'), + 'url' => "colproperties.php?subject=column&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", + 'vars' => ['column' => 'attname'], + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('+type'), + ], + 'notnull' => [ + 'title' => $lang['strnotnull'], + 'field' => Decorator::field('attnotnull'), + 'type' => 'bool', + 'params' => ['true' => 'NOT NULL', 'false' => ''], + ], + 'default' => [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('adsrc'), + ], + 'keyprop' => [ + 'title' => $lang['strconstraints'], + 'class' => 'constraint_cell', + 'field' => Decorator::field('attname'), + 'type' => 'callback', + 'params' => [ + 'function' => $cstrRender, + 'keys' => $ck->getArray(), + ], + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = [ + 'browse' => [ + 'title' => $lang['strbrowse'], + 'url' => "display.php?{$misc->href}&subject=column&return=table&table=" . urlencode($_REQUEST['table']) . '&', + 'vars' => ['column' => 'attname'], + ], + 'alter' => [ + 'title' => $lang['stralter'], + 'url' => "colproperties.php?action=properties&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", + 'vars' => ['column' => 'attname'], + ], + 'privileges' => [ + 'title' => $lang['strprivileges'], + 'url' => "privileges.php?subject=column&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", + 'vars' => ['column' => 'attname'], + ], + 'drop' => [ + 'title' => $lang['strdrop'], + 'url' => "tblproperties.php?action=confirm_drop&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", + 'vars' => ['column' => 'attname'], + ], + ]; + + $actions = [ + 'browse' => [ + 'content' => $lang['strbrowse'], + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'table' => $_REQUEST['table'], + 'subject' => 'column', + 'return' => 'table', + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'colproperties.php', + 'urlvars' => [ + 'subject' => 'column', + 'action' => 'properties', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'privileges' => [ + 'content' => $lang['strprivileges'], + 'attr' => [ + 'href' => [ + 'url' => 'privileges.php', + 'urlvars' => [ + 'subject' => 'column', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'subject' => 'column', + 'action' => 'confirm_drop', + 'table' => $_REQUEST['table'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', null, $attPre); + + $navlinks = [ + 'browse' => [ + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + 'subject' => 'table', + 'return' => 'table', + ], + ], + ], + 'content' => $lang['strbrowse'], + ], + 'select' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confselectrows', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strselect'], + ], + 'insert' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confinsertrow', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strinsert'], + ], + 'empty' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_empty', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strempty'], + ], + 'drop' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tables.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strdrop'], + ], + 'addcolumn' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'action' => 'add_column', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['straddcolumn'], + ], + 'alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'tblproperties.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['stralter'], + ], + ]; + $misc->printNavLinks($navlinks, 'tblproperties-tblproperties', get_defined_vars()); + + } + +} diff --git a/src/controllers/TriggerController.php b/src/controllers/TriggerController.php new file mode 100644 index 00000000..16e22338 --- /dev/null +++ b/src/controllers/TriggerController.php @@ -0,0 +1,404 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class TriggerController extends BaseController { + public $_name = 'TriggerController'; + +/** + * Function to save after altering a trigger + */ + public function doSaveAlter() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->alterTrigger($_POST['table'], $_POST['trigger'], $_POST['name']); + if ($status == 0) { + $this->doDefault($lang['strtriggeraltered']); + } else { + $this->doAlter($lang['strtriggeralteredbad']); + } + + } + +/** + * Function to allow altering of a trigger + */ + public function doAlter($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('trigger'); + $misc->printTitle($lang['stralter'], 'pg.trigger.alter'); + $misc->printMsg($msg); + + $triggerdata = $data->getTrigger($_REQUEST['table'], $_REQUEST['trigger']); + + if ($triggerdata->recordCount() > 0) { + + if (!isset($_POST['name'])) { + $_POST['name'] = $triggerdata->fields['tgname']; + } + + echo "<form action=\"/src/views/triggers.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" />\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['strok']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('trigger'); + $misc->printTitle($lang['strdrop'], 'pg.trigger.drop'); + + echo "<p>", sprintf($lang['strconfdroptrigger'], $misc->printVal($_REQUEST['trigger']), + $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/triggers.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->dropTrigger($_POST['trigger'], $_POST['table'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strtriggerdropped']); + } else { + $this->doDefault($lang['strtriggerdroppedbad']); + } + + } + + } + +/** + * Show confirmation of enable trigger and perform enabling the trigger + */ + public function doEnable($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('trigger'); + $misc->printTitle($lang['strenable'], 'pg.table.alter'); + + echo "<p>", sprintf($lang['strconfenabletrigger'], $misc->printVal($_REQUEST['trigger']), + $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/triggers.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"enable\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->enableTrigger($_POST['trigger'], $_POST['table']); + if ($status == 0) { + $this->doDefault($lang['strtriggerenabled']); + } else { + $this->doDefault($lang['strtriggerenabledbad']); + } + + } + + } + +/** + * Show confirmation of disable trigger and perform disabling the trigger + */ + public function doDisable($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('trigger'); + $misc->printTitle($lang['strdisable'], 'pg.table.alter'); + + echo "<p>", sprintf($lang['strconfdisabletrigger'], $misc->printVal($_REQUEST['trigger']), + $misc->printVal($_REQUEST['table'])), "</p>\n"; + + echo "<form action=\"/src/views/triggers.php\" method=\"post\">\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"disable\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; + echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; + echo "</form>\n"; + } else { + $status = $data->disableTrigger($_POST['trigger'], $_POST['table']); + if ($status == 0) { + $this->doDefault($lang['strtriggerdisabled']); + } else { + $this->doDefault($lang['strtriggerdisabledbad']); + } + + } + + } + +/** + * Let them create s.th. + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('table'); + $misc->printTitle($lang['strcreatetrigger'], 'pg.trigger.create'); + $misc->printMsg($msg); + + // Get all the functions that can be used in triggers + $funcs = $data->getTriggerFunctions(); + if ($funcs->recordCount() == 0) { + $this->doDefault($lang['strnofunctions']); + return; + } + + /* Populate functions */ + $sel0 = new \PHPPgAdmin\XHtml\XHTML_Select('formFunction'); + while (!$funcs->EOF) { + $sel0->add(new \PHPPgAdmin\XHtml\XHTML_Option($funcs->fields['proname'])); + $funcs->moveNext(); + } + + /* Populate times */ + $sel1 = new \PHPPgAdmin\XHtml\XHTML_Select('formExecTime'); + $sel1->set_data($data->triggerExecTimes); + + /* Populate events */ + $sel2 = new \PHPPgAdmin\XHtml\XHTML_Select('formEvent'); + $sel2->set_data($data->triggerEvents); + + /* Populate occurences */ + $sel3 = new \PHPPgAdmin\XHtml\XHTML_Select('formFrequency'); + $sel3->set_data($data->triggerFrequency); + + echo "<form action=\"/src/views/triggers.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr>\n"; + echo " <th class=\"data\">{$lang['strname']}</th>\n"; + echo " <th class=\"data\">{$lang['strwhen']}</th>\n"; + echo "</tr>\n"; + echo "<tr>\n"; + echo " <td class=\"data1\"> <input type=\"text\" name=\"formTriggerName\" size=\"32\" /></td>\n"; + echo " <td class=\"data1\"> ", $sel1->fetch(), "</td>\n"; + echo "</tr>\n"; + echo "<tr>\n"; + echo " <th class=\"data\">{$lang['strevent']}</th>\n"; + echo " <th class=\"data\">{$lang['strforeach']}</th>\n"; + echo "</tr>\n"; + echo "<tr>\n"; + echo " <td class=\"data1\"> ", $sel2->fetch(), "</td>\n"; + echo " <td class=\"data1\"> ", $sel3->fetch(), "</td>\n"; + echo "</tr>\n"; + echo "<tr><th class=\"data\"> {$lang['strfunction']}</th>\n"; + echo "<th class=\"data\"> {$lang['strarguments']}</th></tr>\n"; + echo "<tr><td class=\"data1\">", $sel0->fetch(), "</td>\n"; + echo "<td class=\"data1\">(<input type=\"text\" name=\"formTriggerArgs\" size=\"32\" />)</td>\n"; + echo "</tr></table>\n"; + echo "<p><input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; + echo $misc->form; + echo "</form>\n"; + } + +/** + * Actually creates the new trigger in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've given a name and a definition + + if ($_POST['formFunction'] == '') { + $this->doCreate($lang['strtriggerneedsfunc']); + } elseif ($_POST['formTriggerName'] == '') { + $this->doCreate($lang['strtriggerneedsname']); + } elseif ($_POST['formEvent'] == '') { + $this->doCreate(); + } else { + $status = $data->createTrigger($_POST['formTriggerName'], $_POST['table'], + $_POST['formFunction'], $_POST['formExecTime'], $_POST['formEvent'], + $_POST['formFrequency'], $_POST['formTriggerArgs']); + if ($status == 0) { + $this->doDefault($lang['strtriggercreated']); + } else { + $this->doCreate($lang['strtriggercreatedbad']); + } + + } + } + +/** + * List all the triggers on the table + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $tgPre = function (&$rowdata, $actions) use ($data) { + // toggle enable/disable trigger per trigger + if (!$data->phpBool($rowdata->fields["tgenabled"])) { + unset($actions['disable']); + } else { + unset($actions['enable']); + } + return $actions; + }; + + $misc->printTrail('table'); + $misc->printTabs('table', 'triggers'); + $misc->printMsg($msg); + + $triggers = $data->getTriggers($_REQUEST['table']); + + $columns = [ + 'trigger' => [ + 'title' => $lang['strname'], + 'field' => Decorator::field('tgname'), + ], + 'definition' => [ + 'title' => $lang['strdefinition'], + 'field' => Decorator::field('tgdef'), + ], + 'function' => [ + 'title' => $lang['strfunction'], + 'field' => Decorator::field('proproto'), + 'url' => "functions.php?action=properties&server={$_REQUEST['server']}&database={$_REQUEST['database']}&", + 'vars' => [ + 'schema' => 'pronamespace', + 'function' => 'proproto', + 'function_oid' => 'prooid', + ], + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'triggers.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'table' => $_REQUEST['table'], + 'trigger' => Decorator::field('tgname'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'triggers.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'table' => $_REQUEST['table'], + 'trigger' => Decorator::field('tgname'), + ], + ], + ], + ], + ]; + if ($data->hasDisableTriggers()) { + $actions['enable'] = [ + 'content' => $lang['strenable'], + 'attr' => [ + 'href' => [ + 'url' => 'triggers.php', + 'urlvars' => [ + 'action' => 'confirm_enable', + 'table' => $_REQUEST['table'], + 'trigger' => Decorator::field('tgname'), + ], + ], + ], + ]; + $actions['disable'] = [ + 'content' => $lang['strdisable'], + 'attr' => [ + 'href' => [ + 'url' => 'triggers.php', + 'urlvars' => [ + 'action' => 'confirm_disable', + 'table' => $_REQUEST['table'], + 'trigger' => Decorator::field('tgname'), + ], + ], + ], + ]; + } + + echo $misc->printTable($triggers, $columns, $actions, 'triggers-triggers', $lang['strnotriggers'], $tgPre); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'triggers.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'table' => $_REQUEST['table'], + ], + ], + ], + 'content' => $lang['strcreatetrigger'], + ]], 'triggers-triggers', get_defined_vars()); + } +} diff --git a/src/controllers/TypeController.php b/src/controllers/TypeController.php new file mode 100644 index 00000000..7ffe5a1b --- /dev/null +++ b/src/controllers/TypeController.php @@ -0,0 +1,709 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class TypeController extends BaseController { + public $_name = 'TypeController'; + +/** + * Show read only properties for a type + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + // Get type (using base name) + $typedata = $data->getType($_REQUEST['type']); + + $misc->printTrail('type'); + $misc->printTitle($lang['strproperties'], 'pg.type'); + $misc->printMsg($msg); + + $attPre = function (&$rowdata) use ($data) { + $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); + }; + + if ($typedata->recordCount() > 0) { + $vals = false; + switch ($typedata->fields['typtype']) { + case 'c': + $attrs = $data->getTableAttributes($_REQUEST['type']); + + $columns = [ + 'field' => [ + 'title' => $lang['strfield'], + 'field' => Decorator::field('attname'), + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('+type'), + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = []; + + echo $misc->printTable($attrs, $columns, $actions, 'types-properties', null, $attPre); + + break; + case 'e': + $vals = $data->getEnumValues($typedata->fields['typname']); + default: + $byval = $data->phpBool($typedata->fields['typbyval']); + echo "<table>\n"; + echo "<tr><th class=\"data left\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typname']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strinputfn']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typin']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['stroutputfn']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typout']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strlength']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typlen']), "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strpassbyval']}</th>\n"; + echo "<td class=\"data1\">", ($byval) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; + echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typalign']), "</td></tr>\n"; + if ($data->hasEnumTypes() && $vals) { + $vals = $vals->getArray(); + $nbVals = count($vals); + echo "<tr>\n\t<th class=\"data left\" rowspan=\"$nbVals\">{$lang['strenumvalues']}</th>\n"; + echo "<td class=\"data2\">{$vals[0]['enumval']}</td></tr>\n"; + for ($i = 1; $i < $nbVals; $i++) { + echo "<td class=\"data", 2 - ($i % 2), "\">{$vals[$i]['enumval']}</td></tr>\n"; + } + + } + echo "</table>\n"; + } + + $misc->printNavLinks(['showall' => [ + 'attr' => [ + 'href' => [ + 'url' => 'types.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strshowalltypes'], + ]], 'types-properties', get_defined_vars()); + } else { + $this->doDefault($lang['strinvalidparam']); + } + + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + global $data, $misc; + global $lang; + + if ($confirm) { + $misc->printTrail('type'); + $misc->printTitle($lang['strdrop'], 'pg.type.drop'); + + echo "<p>", sprintf($lang['strconfdroptype'], $misc->printVal($_REQUEST['type'])), "</p>\n"; + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropType($_POST['type'], isset($_POST['cascade'])); + if ($status == 0) { + $this->doDefault($lang['strtypedropped']); + } else { + $this->doDefault($lang['strtypedroppedbad']); + } + + } + + } + +/** + * Displays a screen where they can enter a new composite type + */ + public function doCreateComposite($msg = '') { + global $data, $misc; + global $lang; + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + } + + if (!isset($_REQUEST['name'])) { + $_REQUEST['name'] = ''; + } + + if (!isset($_REQUEST['fields'])) { + $_REQUEST['fields'] = ''; + } + + if (!isset($_REQUEST['typcomment'])) { + $_REQUEST['typcomment'] = ''; + } + + switch ($_REQUEST['stage']) { + case 1: + $misc->printTrail('type'); + $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumfields']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n"; + + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + break; + case 2: + global $lang; + + // Check inputs + $fields = trim($_REQUEST['fields']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreateComposite($lang['strtypeneedsname']); + return; + } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) { + $_REQUEST['stage'] = 1; + $this->doCreateComposite($lang['strtypeneedscols']); + return; + } + + $types = $data->getTypes(true, false, true); + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + + // Output table header + echo "<table>\n"; + echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>"; + echo "<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n"; + + for ($i = 0; $i < $_REQUEST['fields']; $i++) { + if (!isset($_REQUEST['field'][$i])) { + $_REQUEST['field'][$i] = ''; + } + + if (!isset($_REQUEST['length'][$i])) { + $_REQUEST['length'][$i] = ''; + } + + if (!isset($_REQUEST['colcomment'][$i])) { + $_REQUEST['colcomment'][$i] = ''; + } + + echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; + echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n"; + echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">\n"; + $types->moveFirst(); + while (!$types->EOF) { + $typname = $types->fields['typname']; + echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"", + (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", + $misc->printVal($typname), "</option>\n"; + $types->moveNext(); + } + echo "\t\t\t</select>\n\t\t</td>\n"; + + // Output array type selector + echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n"; + echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n"; + echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; + echo "\t\t\t</select>\n\t\t</td>\n"; + + echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"", + htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n"; + echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"", + htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; + echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n"; + echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + break; + case 3: + global $data, $lang; + + // Check inputs + $fields = trim($_REQUEST['fields']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreateComposite($lang['strtypeneedsname']); + return; + } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) { + $_REQUEST['stage'] = 1; + $this->doCreateComposite($lang['strtypeneedscols']); + return; + } + + $status = $data->createCompositeType($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'], + $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['colcomment'], + $_REQUEST['typcomment']); + + if ($status == 0) { + $this->doDefault($lang['strtypecreated']); + } elseif ($status == -1) { + $_REQUEST['stage'] = 2; + $this->doCreateComposite($lang['strtypeneedsfield']); + return; + } else { + $_REQUEST['stage'] = 2; + $this->doCreateComposite($lang['strtypecreatedbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + +/** + * Displays a screen where they can enter a new enum type + */ + public function doCreateEnum($msg = '') { + global $data, $misc; + global $lang; + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + } + + if (!isset($_REQUEST['name'])) { + $_REQUEST['name'] = ''; + } + + if (!isset($_REQUEST['values'])) { + $_REQUEST['values'] = ''; + } + + if (!isset($_REQUEST['typcomment'])) { + $_REQUEST['typcomment'] = ''; + } + + switch ($_REQUEST['stage']) { + case 1: + $misc->printTrail('type'); + $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumvalues']}</th>\n"; + echo "\t\t<td class=\"data\"><input name=\"values\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['values']), "\" /></td>\n\t</tr>\n"; + + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + break; + case 2: + global $lang; + + // Check inputs + $values = trim($_REQUEST['values']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreateEnum($lang['strtypeneedsname']); + return; + } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values < 1) { + $_REQUEST['stage'] = 1; + $this->doCreateEnum($lang['strtypeneedsvals']); + return; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + + // Output table header + echo "<table>\n"; + echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strvalue']}</th></tr>\n"; + + for ($i = 0; $i < $_REQUEST['values']; $i++) { + if (!isset($_REQUEST['value'][$i])) { + $_REQUEST['value'][$i] = ''; + } + + echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; + echo "\t\t<td><input name=\"value[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['value'][$i]), "\" /></td>\n\t</tr>\n"; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; + echo "<input type=\"hidden\" name=\"values\" value=\"", htmlspecialchars($_REQUEST['values']), "\" />\n"; + echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + break; + case 3: + global $data, $lang; + + // Check inputs + $values = trim($_REQUEST['values']); + if (trim($_REQUEST['name']) == '') { + $_REQUEST['stage'] = 1; + $this->doCreateEnum($lang['strtypeneedsname']); + return; + } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values <= 0) { + $_REQUEST['stage'] = 1; + $this->doCreateEnum($lang['strtypeneedsvals']); + return; + } + + $status = $data->createEnumType($_REQUEST['name'], $_REQUEST['value'], $_REQUEST['typcomment']); + + if ($status == 0) { + $this->doDefault($lang['strtypecreated']); + } elseif ($status == -1) { + $_REQUEST['stage'] = 2; + $this->doCreateEnum($lang['strtypeneedsvalue']); + return; + } else { + $_REQUEST['stage'] = 2; + $this->doCreateEnum($lang['strtypecreatedbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + +/** + * Displays a screen where they can enter a new type + */ + public function doCreate($msg = '') { + global $data, $misc; + global $lang; + + if (!isset($_POST['typname'])) { + $_POST['typname'] = ''; + } + + if (!isset($_POST['typin'])) { + $_POST['typin'] = ''; + } + + if (!isset($_POST['typout'])) { + $_POST['typout'] = ''; + } + + if (!isset($_POST['typlen'])) { + $_POST['typlen'] = ''; + } + + if (!isset($_POST['typdef'])) { + $_POST['typdef'] = ''; + } + + if (!isset($_POST['typelem'])) { + $_POST['typelem'] = ''; + } + + if (!isset($_POST['typdelim'])) { + $_POST['typdelim'] = ''; + } + + if (!isset($_POST['typalign'])) { + $_POST['typalign'] = $data->typAlignDef; + } + + if (!isset($_POST['typstorage'])) { + $_POST['typstorage'] = $data->typStorageDef; + } + + // Retrieve all functions and types in the database + $funcs = $data->getFunctions(true); + $types = $data->getTypes(true); + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreatetype'], 'pg.type.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/types.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\"><input name=\"typname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['typname']), "\" /></td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['strinputfn']}</th>\n"; + echo "<td class=\"data1\"><select name=\"typin\">"; + while (!$funcs->EOF) { + $proname = htmlspecialchars($funcs->fields['proname']); + echo "<option value=\"{$proname}\"", + ($proname == $_POST['typin']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; + $funcs->moveNext(); + } + echo "</select></td></tr>\n"; + echo "<tr><th class=\"data left required\">{$lang['stroutputfn']}</th>\n"; + echo "<td class=\"data1\"><select name=\"typout\">"; + $funcs->moveFirst(); + while (!$funcs->EOF) { + $proname = htmlspecialchars($funcs->fields['proname']); + echo "<option value=\"{$proname}\"", + ($proname == $_POST['typout']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; + $funcs->moveNext(); + } + echo "</select></td></tr>\n"; + echo "<tr><th class=\"data left" . (version_compare($data->major_version, '7.4', '<') ? ' required' : '') . "\">{$lang['strlength']}</th>\n"; + echo "<td class=\"data1\"><input name=\"typlen\" size=\"8\" value=\"", + htmlspecialchars($_POST['typlen']), "\" /></td></tr>"; + echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; + echo "<td class=\"data1\"><input name=\"typdef\" size=\"8\" value=\"", + htmlspecialchars($_POST['typdef']), "\" /></td></tr>"; + echo "<tr><th class=\"data left\">{$lang['strelement']}</th>\n"; + echo "<td class=\"data1\"><select name=\"typelem\">"; + echo "<option value=\"\"></option>\n"; + while (!$types->EOF) { + $currname = htmlspecialchars($types->fields['typname']); + echo "<option value=\"{$currname}\"", + ($currname == $_POST['typelem']) ? ' selected="selected"' : '', ">{$currname}</option>\n"; + $types->moveNext(); + } + echo "</select></td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strdelimiter']}</th>\n"; + echo "<td class=\"data1\"><input name=\"typdelim\" size=\"1\" maxlength=\"1\" value=\"", + htmlspecialchars($_POST['typdelim']), "\" /></td></tr>"; + echo "<tr><th class=\"data left\"><label for=\"typbyval\">{$lang['strpassbyval']}</label></th>\n"; + echo "<td class=\"data1\"><input type=\"checkbox\" id=\"typbyval\" name=\"typbyval\"", + isset($_POST['typbyval']) ? ' checked="checked"' : '', " /></td></tr>"; + echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; + echo "<td class=\"data1\"><select name=\"typalign\">"; + foreach ($data->typAligns as $v) { + echo "<option value=\"{$v}\"", + ($v == $_POST['typalign']) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + echo "</select></td></tr>\n"; + echo "<tr><th class=\"data left\">{$lang['strstorage']}</th>\n"; + echo "<td class=\"data1\"><select name=\"typstorage\">"; + foreach ($data->typStorages as $v) { + echo "<option value=\"{$v}\"", + ($v == $_POST['typstorage']) ? ' selected="selected"' : '', ">{$v}</option>\n"; + } + echo "</select></td></tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new type in the database + */ + public function doSaveCreate() { + global $data; + global $lang; + + // Check that they've given a name and a length. + // Note: We're assuming they've given in and out functions here + // which might be unwise... + if ($_POST['typname'] == '') { + $this->doCreate($lang['strtypeneedsname']); + } elseif ($_POST['typlen'] == '') { + $this->doCreate($lang['strtypeneedslen']); + } else { + $status = $data->createType( + $_POST['typname'], + $_POST['typin'], + $_POST['typout'], + $_POST['typlen'], + $_POST['typdef'], + $_POST['typelem'], + $_POST['typdelim'], + isset($_POST['typbyval']), + $_POST['typalign'], + $_POST['typstorage'] + ); + if ($status == 0) { + $this->doDefault($lang['strtypecreated']); + } else { + $this->doCreate($lang['strtypecreatedbad']); + } + + } + } + +/** + * Show default list of types in the database + */ + public function doDefault($msg = '') { + global $data, $conf, $misc; + global $lang; + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'types'); + $misc->printMsg($msg); + + $types = $data->getTypes(); + + $columns = [ + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('typname'), + 'url' => "types.php?action=properties&{$misc->href}&", + 'vars' => ['type' => 'basename'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('typowner'), + ], + 'flavour' => [ + 'title' => $lang['strflavor'], + 'field' => Decorator::field('typtype'), + 'type' => 'verbatim', + 'params' => [ + 'map' => [ + 'b' => $lang['strbasetype'], + 'c' => $lang['strcompositetype'], + 'd' => $lang['strdomain'], + 'p' => $lang['strpseudotype'], + 'e' => $lang['strenum'], + ], + 'align' => 'center', + ], + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('typcomment'), + ], + ]; + + if (!isset($types->fields['typtype'])) { + unset($columns['flavour']); + } + + $actions = [ + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'types.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'type' => Decorator::field('basename'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($types, $columns, $actions, 'types-types', $lang['strnotypes']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'types.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatetype'], + ], + 'createcomp' => [ + 'attr' => [ + 'href' => [ + 'url' => 'types.php', + 'urlvars' => [ + 'action' => 'create_comp', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreatecomptype'], + ], + 'createenum' => [ + 'attr' => [ + 'href' => [ + 'url' => 'types.php', + 'urlvars' => [ + 'action' => 'create_enum', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateenumtype'], + ], + ]; + + if (!$data->hasEnumTypes()) { + unset($navlinks['enum']); + } + + $misc->printNavLinks($navlinks, 'types-types', get_defined_vars()); + } + +} diff --git a/src/controllers/UserController.php b/src/controllers/UserController.php new file mode 100644 index 00000000..59a9d742 --- /dev/null +++ b/src/controllers/UserController.php @@ -0,0 +1,427 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class UserController extends BaseController { + public $_name = 'UserController'; + +/** + * If a user is not a superuser, then we have an 'account management' page + * where they can change their password, etc. We don't prevent them from + * messing with the URL to gain access to other user admin stuff, because + * the PostgreSQL permissions will prevent them changing anything anyway. + */ + public function doAccount($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $server_info = $misc->getServerInfo(); + + $userdata = $data->getUser($server_info['username']); + $_REQUEST['user'] = $server_info['username']; + + $misc->printTrail('user'); + $misc->printTabs('server', 'account'); + $misc->printMsg($msg); + + if ($userdata->recordCount() > 0) { + $userdata->fields['usesuper'] = $data->phpBool($userdata->fields['usesuper']); + $userdata->fields['usecreatedb'] = $data->phpBool($userdata->fields['usecreatedb']); + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strusername']}</th><th class=\"data\">{$lang['strsuper']}</th><th class=\"data\">{$lang['strcreatedb']}</th><th class=\"data\">{$lang['strexpires']}</th>"; + echo "<th class=\"data\">{$lang['strsessiondefaults']}</th>"; + echo "</tr>\n"; + echo "<tr>\n\t<td class=\"data1\">", $misc->printVal($userdata->fields['usename']), "</td>\n"; + echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['usesuper'], 'yesno'), "</td>\n"; + echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['usecreatedb'], 'yesno'), "</td>\n"; + echo "\t<td class=\"data1\">", ($userdata->fields['useexpires'] == 'infinity' || is_null($userdata->fields['useexpires']) ? $lang['strnever'] : $misc->printVal($userdata->fields['useexpires'])), "</td>\n"; + echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['useconfig']), "</td>\n"; + echo "</tr>\n</table>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + $misc->printNavLinks(['changepassword' => [ + 'attr' => [ + 'href' => [ + 'url' => 'users.php', + 'urlvars' => [ + 'action' => 'confchangepassword', + 'server' => $_REQUEST['server'], + ], + ], + ], + 'content' => $lang['strchangepassword'], + ]], 'users-account', get_defined_vars()); + } + +/** + * Show confirmation of change password and actually change password + */ + public function doChangePassword($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $server_info = $misc->getServerInfo(); + + if ($confirm) { + $_REQUEST['user'] = $server_info['username']; + $misc->printTrail('user'); + $misc->printTitle($lang['strchangepassword'], 'pg.user.alter'); + $misc->printMsg($msg); + + if (!isset($_POST['password'])) { + $_POST['password'] = ''; + } + + if (!isset($_POST['confirm'])) { + $_POST['confirm'] = ''; + } + + echo "<form action=\"/src/views/users.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strpassword']}</th>\n"; + echo "\t\t<td><input type=\"password\" name=\"password\" size=\"32\" value=\"", + htmlspecialchars($_POST['password']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strconfirm']}</th>\n"; + echo "\t\t<td><input type=\"password\" name=\"confirm\" size=\"32\" value=\"\" /></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"changepassword\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"ok\" value=\"{$lang['strok']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</p></form>\n"; + } else { + // Check that password is minimum length + if (strlen($_POST['password']) < $conf['min_password_length']) { + $this->doChangePassword(true, $lang['strpasswordshort']); + } + + // Check that password matches confirmation password + elseif ($_POST['password'] != $_POST['confirm']) { + $this->doChangePassword(true, $lang['strpasswordconfirm']); + } else { + $status = $data->changePassword($server_info['username'], + $_POST['password']); + if ($status == 0) { + $this->doAccount($lang['strpasswordchanged']); + } else { + $this->doAccount($lang['strpasswordchangedbad']); + } + + } + } + } + +/** + * Function to allow editing of a user + */ + public function doEdit($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('user'); + $misc->printTitle($lang['stralter'], 'pg.user.alter'); + $misc->printMsg($msg); + + $userdata = $data->getUser($_REQUEST['username']); + + if ($userdata->recordCount() > 0) { + $server_info = $misc->getServerInfo(); + $canRename = $data->hasUserRename() && ($_REQUEST['username'] != $server_info['username']); + $userdata->fields['usesuper'] = $data->phpBool($userdata->fields['usesuper']); + $userdata->fields['usecreatedb'] = $data->phpBool($userdata->fields['usecreatedb']); + + if (!isset($_POST['formExpires'])) { + if ($canRename) { + $_POST['newname'] = $userdata->fields['usename']; + } + + if ($userdata->fields['usesuper']) { + $_POST['formSuper'] = ''; + } + + if ($userdata->fields['usecreatedb']) { + $_POST['formCreateDB'] = ''; + } + + $_POST['formExpires'] = $userdata->fields['useexpires'] == 'infinity' ? '' : $userdata->fields['useexpires']; + $_POST['formPassword'] = ''; + } + + echo "<form action=\"/src/views/users.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strusername']}</th>\n"; + echo "\t\t<td class=\"data1\">", ($canRename ? "<input name=\"newname\" size=\"15\" maxlength=\"{$data->_maxNameLen}\" value=\"" . htmlspecialchars($_POST['newname']) . "\" />" : $misc->printVal($userdata->fields['usename'])), "</td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$lang['strsuper']}</label></th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"", + (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$lang['strcreatedb']}</label></th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"", + (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strexpires']}</th>\n"; + echo "\t\t<td class=\"data1\"><input size=\"16\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strpassword']}</th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"16\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strconfirm']}</th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"16\" name=\"formConfirm\" value=\"\" /></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; + echo "<input type=\"hidden\" name=\"username\" value=\"", htmlspecialchars($_REQUEST['username']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Function to save after editing a user + */ + public function doSaveEdit() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check name and password + if (isset($_POST['newname']) && $_POST['newname'] == '') { + $this->doEdit($lang['struserneedsname']); + } else if ($_POST['formPassword'] != $_POST['formConfirm']) { + $this->doEdit($lang['strpasswordconfirm']); + } else { + if (isset($_POST['newname'])) { + $status = $data->setRenameUser($_POST['username'], $_POST['formPassword'], isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires'], $_POST['newname']); + } else { + $status = $data->setUser($_POST['username'], $_POST['formPassword'], isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires']); + } + + if ($status == 0) { + $this->doDefault($lang['struserupdated']); + } else { + $this->doEdit($lang['struserupdatedbad']); + } + + } + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('user'); + $misc->printTitle($lang['strdrop'], 'pg.user.drop'); + + echo "<p>", sprintf($lang['strconfdropuser'], $misc->printVal($_REQUEST['username'])), "</p>\n"; + + echo "<form action=\"/src/views/users.php\" method=\"post\">\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + echo "<input type=\"hidden\" name=\"username\" value=\"", htmlspecialchars($_REQUEST['username']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + $status = $data->dropUser($_REQUEST['username']); + if ($status == 0) { + $this->doDefault($lang['struserdropped']); + } else { + $this->doDefault($lang['struserdroppedbad']); + } + + } + } + +/** + * Displays a screen where they can enter a new user + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_POST['formUsername'])) { + $_POST['formUsername'] = ''; + } + + if (!isset($_POST['formPassword'])) { + $_POST['formPassword'] = ''; + } + + if (!isset($_POST['formConfirm'])) { + $_POST['formConfirm'] = ''; + } + + if (!isset($_POST['formExpires'])) { + $_POST['formExpires'] = ''; + } + + $misc->printTrail('server'); + $misc->printTitle($lang['strcreateuser'], 'pg.user.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/users.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strusername']}</th>\n"; + echo "\t\t<td class=\"data1\"><input size=\"15\" maxlength=\"{$data->_maxNameLen}\" name=\"formUsername\" value=\"", htmlspecialchars($_POST['formUsername']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strpassword']}</th>\n"; + echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strconfirm']}</th>\n"; + echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formConfirm\" value=\"", htmlspecialchars($_POST['formConfirm']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$lang['strsuper']}</label></th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"", + (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$lang['strcreatedb']}</label></th>\n"; + echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"", + (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strexpires']}</th>\n"; + echo "\t\t<td class=\"data1\"><input size=\"30\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new user in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check data + if ($_POST['formUsername'] == '') { + $this->doCreate($lang['struserneedsname']); + } else if ($_POST['formPassword'] != $_POST['formConfirm']) { + $this->doCreate($lang['strpasswordconfirm']); + } else { + $status = $data->createUser($_POST['formUsername'], $_POST['formPassword'], + isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires'], []); + if ($status == 0) { + $this->doDefault($lang['strusercreated']); + } else { + $this->doCreate($lang['strusercreatedbad']); + } + + } + } + +/** + * Show default list of users in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + function renderUseExpires($val) { + global $lang; + return $val == 'infinity' ? $lang['strnever'] : htmlspecialchars($val); + } + + $misc->printTrail('server'); + $misc->printTabs('server', 'users'); + $misc->printMsg($msg); + + $users = $data->getUsers(); + + $columns = [ + 'user' => [ + 'title' => $lang['strusername'], + 'field' => Decorator::field('usename'), + ], + 'superuser' => [ + 'title' => $lang['strsuper'], + 'field' => Decorator::field('usesuper'), + 'type' => 'yesno', + ], + 'createdb' => [ + 'title' => $lang['strcreatedb'], + 'field' => Decorator::field('usecreatedb'), + 'type' => 'yesno', + ], + 'expires' => [ + 'title' => $lang['strexpires'], + 'field' => Decorator::field('useexpires'), + 'type' => 'callback', + 'params' => ['function' => 'renderUseExpires', 'null' => $lang['strnever']], + ], + 'defaults' => [ + 'title' => $lang['strsessiondefaults'], + 'field' => Decorator::field('useconfig'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + ]; + + $actions = [ + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'users.php', + 'urlvars' => [ + 'action' => 'edit', + 'username' => Decorator::field('usename'), + ], + ], + ], + ], + 'drop' => [ + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'users.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'username' => Decorator::field('usename'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($users, $columns, $actions, 'users-users', $lang['strnousers']); + + $misc->printNavLinks(['create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'users.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + ], + ], + ], + 'content' => $lang['strcreateuser'], + ]], 'users-users', get_defined_vars()); + + } + +} diff --git a/src/controllers/ViewController.php b/src/controllers/ViewController.php new file mode 100644 index 00000000..8273fd6f --- /dev/null +++ b/src/controllers/ViewController.php @@ -0,0 +1,755 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class ViewController extends BaseController { + public $script = 'view.php'; + public $_name = 'ViewController'; + +/** + * Ask for select parameters and perform select + */ + public function doSelectRows($confirm, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + $misc->printTrail('view'); + $misc->printTabs('view', 'select'); + $misc->printMsg($msg); + + $attrs = $data->getTableAttributes($_REQUEST['view']); + + echo "<form action=\"/src/views/views.php\" method=\"post\" id=\"selectform\">\n"; + if ($attrs->recordCount() > 0) { + // JavaScript for select all feature + echo "<script type=\"text/javascript\">\n"; + echo "//<![CDATA[\n"; + echo " function selectAll() {\n"; + echo " for (var i=0; i<document.getElementById('selectform').elements.length; i++) {\n"; + echo " var e = document.getElementById('selectform').elements[i];\n"; + echo " if (e.name.indexOf('show') == 0) { \n "; + echo " e.checked = document.getElementById('selectform').selectall.checked;\n"; + echo " }\n"; + echo " }\n"; + echo " }\n"; + echo "//]]>\n"; + echo "</script>\n"; + + echo "<table>\n"; + + // Output table header + echo "<tr><th class=\"data\">{$lang['strshow']}</th><th class=\"data\">{$lang['strcolumn']}</th>"; + echo "<th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['stroperator']}</th>"; + echo "<th class=\"data\">{$lang['strvalue']}</th></tr>"; + + $i = 0; + while (!$attrs->EOF) { + $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); + // Set up default value if there isn't one already + if (!isset($_REQUEST['values'][$attrs->fields['attname']])) { + $_REQUEST['values'][$attrs->fields['attname']] = null; + } + + if (!isset($_REQUEST['ops'][$attrs->fields['attname']])) { + $_REQUEST['ops'][$attrs->fields['attname']] = null; + } + + // Continue drawing row + $id = (($i % 2) == 0 ? '1' : '2'); + echo "<tr class=\"data{$id}\">\n"; + echo "<td style=\"white-space:nowrap;\">"; + echo "<input type=\"checkbox\" name=\"show[", htmlspecialchars($attrs->fields['attname']), "]\"", + isset($_REQUEST['show'][$attrs->fields['attname']]) ? ' checked="checked"' : '', " /></td>"; + echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; + echo "<td style=\"white-space:nowrap;\">", $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])), "</td>"; + echo "<td style=\"white-space:nowrap;\">"; + echo "<select name=\"ops[{$attrs->fields['attname']}]\">\n"; + foreach (array_keys($data->selectOps) as $v) { + echo "<option value=\"", htmlspecialchars($v), "\"", ($v == $_REQUEST['ops'][$attrs->fields['attname']]) ? ' selected="selected"' : '', + ">", htmlspecialchars($v), "</option>\n"; + } + echo "</select></td>\n"; + echo "<td style=\"white-space:nowrap;\">", $data->printField("values[{$attrs->fields['attname']}]", + $_REQUEST['values'][$attrs->fields['attname']], $attrs->fields['type']), "</td>"; + echo "</tr>\n"; + $i++; + $attrs->moveNext(); + } + // Select all checkbox + echo "<tr><td colspan=\"5\"><input type=\"checkbox\" id=\"selectall\" name=\"selectall\" accesskey=\"a\" onclick=\"javascript:selectAll()\" /><label for=\"selectall\">{$lang['strselectallfields']}</label></td></tr>"; + echo "</table>\n"; + } else { + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + + echo "<p><input type=\"hidden\" name=\"action\" value=\"selectrows\" />\n"; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" name=\"select\" accesskey=\"r\" value=\"{$lang['strselect']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + if (!isset($_POST['show'])) { + $_POST['show'] = []; + } + + if (!isset($_POST['values'])) { + $_POST['values'] = []; + } + + if (!isset($_POST['nulls'])) { + $_POST['nulls'] = []; + } + + // Verify that they haven't supplied a value for unary operators + foreach ($_POST['ops'] as $k => $v) { + if ($data->selectOps[$v] == 'p' && $_POST['values'][$k] != '') { + $this->doSelectRows(true, $lang['strselectunary']); + return; + } + } + + if (sizeof($_POST['show']) == 0) { + $this->doSelectRows(true, $lang['strselectneedscol']); + } else { + // Generate query SQL + $query = $data->getSelectSQL($_REQUEST['view'], array_keys($_POST['show']), + $_POST['values'], $_POST['ops']); + $_REQUEST['query'] = $query; + $_REQUEST['return'] = "schema"; + $misc->setNoOutput(true); + include './display.php'; + exit; + } + } + + } + +/** + * Show confirmation of drop and perform actual drop + */ + public function doDrop($confirm) { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (empty($_REQUEST['view']) && empty($_REQUEST['ma'])) { + $this->doDefault($lang['strspecifyviewtodrop']); + exit(); + } + + if ($confirm) { + $misc->printTrail('view'); + $misc->printTitle($lang['strdrop'], 'pg.view.drop'); + + echo "<form action=\"/src/views/views.php\" method=\"post\">\n"; + + //If multi drop + if (isset($_REQUEST['ma'])) { + foreach ($_REQUEST['ma'] as $v) { + $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); + echo "<p>", sprintf($lang['strconfdropview'], $misc->printVal($a['view'])), "</p>\n"; + echo '<input type="hidden" name="view[]" value="', htmlspecialchars($a['view']), "\" />\n"; + } + } else { + echo "<p>", sprintf($lang['strconfdropview'], $misc->printVal($_REQUEST['view'])), "</p>\n"; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + } + + echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; + + echo $misc->form; + echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; + echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; + echo "</form>\n"; + } else { + if (is_array($_POST['view'])) { + $msg = ''; + $status = $data->beginTransaction(); + if ($status == 0) { + foreach ($_POST['view'] as $s) { + $status = $data->dropView($s, isset($_POST['cascade'])); + if ($status == 0) { + $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdropped']); + } else { + $data->endTransaction(); + $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdroppedbad'])); + return; + } + } + } + if ($data->endTransaction() == 0) { + // Everything went fine, back to the Default page.... + $this->misc->setReloadBrowser(true); + $this->doDefault($msg); + } else { + $this->doDefault($lang['strviewdroppedbad']); + } + + } else { + $status = $data->dropView($_POST['view'], isset($_POST['cascade'])); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strviewdropped']); + } else { + $this->doDefault($lang['strviewdroppedbad']); + } + + } + } + + } + +/** + * Sets up choices for table linkage, and which fields to select for the view we're creating + */ + public function doSetParamsCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've chosen tables for the view definition + if (!isset($_POST['formTables'])) { + $this->doWizardCreate($lang['strviewneedsdef']); + } else { + // Initialise variables + if (!isset($_REQUEST['formView'])) { + $_REQUEST['formView'] = ''; + } + + if (!isset($_REQUEST['formComment'])) { + $_REQUEST['formComment'] = ''; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreateviewwiz'], 'pg.view.create'); + $misc->printMsg($msg); + + $tblCount = sizeof($_POST['formTables']); + //unserialize our schema/table information and store in arrSelTables + for ($i = 0; $i < $tblCount; $i++) { + $arrSelTables[] = unserialize($_POST['formTables'][$i]); + } + + $linkCount = $tblCount; + + //get linking keys + $rsLinkKeys = $data->getLinkingKeys($arrSelTables); + $linkCount = $rsLinkKeys->recordCount() > $tblCount ? $rsLinkKeys->recordCount() : $tblCount; + + $arrFields = []; //array that will hold all our table/field names + + //if we have schemas we need to specify the correct schema for each table we're retrieiving + //with getTableAttributes + $curSchema = $data->_schema; + for ($i = 0; $i < $tblCount; $i++) { + if ($data->_schema != $arrSelTables[$i]['schemaname']) { + $data->setSchema($arrSelTables[$i]['schemaname']); + } + + $attrs = $data->getTableAttributes($arrSelTables[$i]['tablename']); + while (!$attrs->EOF) { + $arrFields["{$arrSelTables[$i]['schemaname']}.{$arrSelTables[$i]['tablename']}.{$attrs->fields['attname']}"] = serialize([ + 'schemaname' => $arrSelTables[$i]['schemaname'], + 'tablename' => $arrSelTables[$i]['tablename'], + 'fieldname' => $attrs->fields['attname']] + ); + $attrs->moveNext(); + } + + $data->setSchema($curSchema); + } + asort($arrFields); + + echo "<form action=\"/src/views/views.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strviewname']}</th></tr>"; + echo "<tr>\n<td class=\"data1\">\n"; + // View name + echo "<input name=\"formView\" value=\"", htmlspecialchars($_REQUEST['formView']), "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n"; + echo "</td>\n</tr>\n"; + echo "<tr><th class=\"data\">{$lang['strcomment']}</th></tr>"; + echo "<tr>\n<td class=\"data1\">\n"; + // View comments + echo "<textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['formComment']), "</textarea>\n"; + echo "</td>\n</tr>\n"; + echo "</table>\n"; + + // Output selector for fields to be retrieved from view + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strcolumns']}</th></tr>"; + echo "<tr>\n<td class=\"data1\">\n"; + echo \PHPPgAdmin\GUI::printCombo($arrFields, 'formFields[]', false, '', true); + echo "</td>\n</tr>"; + echo "<tr><td><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth1\" value=\"rename\" /><label for=\"dblFldMeth1\">{$lang['strrenamedupfields']}</label>"; + echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth2\" value=\"drop\" /><label for=\"dblFldMeth2\">{$lang['strdropdupfields']}</label>"; + echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth3\" value=\"\" checked=\"checked\" /><label for=\"dblFldMeth3\">{$lang['strerrordupfields']}</label></td></tr></table><br />"; + + // Output the Linking keys combo boxes + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>"; + $rowClass = 'data1'; + for ($i = 0; $i < $linkCount; $i++) { + // Initialise variables + if (!isset($formLink[$i]['operator'])) { + $formLink[$i]['operator'] = 'INNER JOIN'; + } + + echo "<tr>\n<td class=\"$rowClass\">\n"; + + if (!$rsLinkKeys->EOF) { + $curLeftLink = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['p_schema'], 'tablename' => $rsLinkKeys->fields['p_table'], 'fieldname' => $rsLinkKeys->fields['p_field']])); + $curRightLink = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['f_schema'], 'tablename' => $rsLinkKeys->fields['f_table'], 'fieldname' => $rsLinkKeys->fields['f_field']])); + $rsLinkKeys->moveNext(); + } else { + $curLeftLink = ''; + $curRightLink = ''; + } + + echo \PHPPgAdmin\GUI::printCombo($arrFields, "formLink[$i][leftlink]", true, $curLeftLink, false); + echo \PHPPgAdmin\GUI::printCombo($data->joinOps, "formLink[$i][operator]", true, $formLink[$i]['operator']); + echo \PHPPgAdmin\GUI::printCombo($arrFields, "formLink[$i][rightlink]", true, $curRightLink, false); + echo "</td>\n</tr>\n"; + $rowClass = $rowClass == 'data1' ? 'data2' : 'data1'; + } + echo "</table>\n<br />\n"; + + // Build list of available operators (infix only) + $arrOperators = []; + foreach ($data->selectOps as $k => $v) { + if ($v == 'i') { + $arrOperators[$k] = $k; + } + + } + + // Output additional conditions, note that this portion of the wizard treats the right hand side as literal values + //(not as database objects) so field names will be treated as strings, use the above linking keys section to perform joins + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strviewconditions']}</th></tr>"; + $rowClass = 'data1'; + for ($i = 0; $i < $linkCount; $i++) { + echo "<tr>\n<td class=\"$rowClass\">\n"; + echo \PHPPgAdmin\GUI::printCombo($arrFields, "formCondition[$i][field]"); + echo \PHPPgAdmin\GUI::printCombo($arrOperators, "formCondition[$i][operator]", false, false); + echo "<input type=\"text\" name=\"formCondition[$i][txt]\" />\n"; + echo "</td>\n</tr>\n"; + $rowClass = $rowClass == 'data1' ? 'data2' : 'data1'; + } + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_wiz\" />\n"; + + foreach ($arrSelTables as $curTable) { + echo "<input type=\"hidden\" name=\"formTables[]\" value=\"" . htmlspecialchars(serialize($curTable)) . "\" />\n"; + } + + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + } + +/** + * Display a wizard where they can enter a new view + */ + public function doWizardCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $tables = $data->getTables(true); + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreateviewwiz'], 'pg.view.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/views.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strtables']}</th></tr>"; + echo "<tr>\n<td class=\"data1\">\n"; + + $arrTables = []; + while (!$tables->EOF) { + $arrTmp = []; + $arrTmp['schemaname'] = $tables->fields['nspname']; + $arrTmp['tablename'] = $tables->fields['relname']; + $arrTables[$tables->fields['nspname'] . '.' . $tables->fields['relname']] = serialize($arrTmp); + $tables->moveNext(); + } + echo \PHPPgAdmin\GUI::printCombo($arrTables, 'formTables[]', false, '', true); + + echo "</td>\n</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"set_params_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Displays a screen where they can enter a new view + */ + public function doCreate($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['formView'])) { + $_REQUEST['formView'] = ''; + } + + if (!isset($_REQUEST['formDefinition'])) { + if (isset($_SESSION['sqlquery'])) { + $_REQUEST['formDefinition'] = $_SESSION['sqlquery']; + } else { + $_REQUEST['formDefinition'] = 'SELECT '; + } + + } + if (!isset($_REQUEST['formComment'])) { + $_REQUEST['formComment'] = ''; + } + + $misc->printTrail('schema'); + $misc->printTitle($lang['strcreateview'], 'pg.view.create'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/views.php\" method=\"post\">\n"; + echo "<table style=\"width: 100%\">\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "\t<td class=\"data1\"><input name=\"formView\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_REQUEST['formView']), "\" /></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strdefinition']}</th>\n"; + echo "\t<td class=\"data1\"><textarea style=\"width:100%;\" rows=\"10\" cols=\"50\" name=\"formDefinition\">", + htmlspecialchars($_REQUEST['formDefinition']), "</textarea></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", + htmlspecialchars($_REQUEST['formComment']), "</textarea></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Actually creates the new view in the database + */ + public function doSaveCreate() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've given a name and a definition + if ($_POST['formView'] == '') { + $this->doCreate($lang['strviewneedsname']); + } elseif ($_POST['formDefinition'] == '') { + $this->doCreate($lang['strviewneedsdef']); + } else { + $status = $data->createView($_POST['formView'], $_POST['formDefinition'], false, $_POST['formComment']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strviewcreated']); + } else { + $this->doCreate($lang['strviewcreatedbad']); + } + + } + } + +/** + * Actually creates the new wizard view in the database + */ + public function doSaveCreateWiz() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Check that they've given a name and fields they want to select + + if (!strlen($_POST['formView'])) { + $this->doSetParamsCreate($lang['strviewneedsname']); + } else if (!isset($_POST['formFields']) || !count($_POST['formFields'])) { + $this->doSetParamsCreate($lang['strviewneedsfields']); + } else { + $selFields = ''; + + if (!empty($_POST['dblFldMeth'])) { + $tmpHsh = []; + } + + foreach ($_POST['formFields'] as $curField) { + $arrTmp = unserialize($curField); + $data->fieldArrayClean($arrTmp); + if (!empty($_POST['dblFldMeth'])) { + // doublon control + if (empty($tmpHsh[$arrTmp['fieldname']])) { + // field does not exist + $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", "; + $tmpHsh[$arrTmp['fieldname']] = 1; + } else if ($_POST['dblFldMeth'] == 'rename') { + // field exist and must be renamed + $tmpHsh[$arrTmp['fieldname']]++; + $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" AS \"{$arrTmp['schemaname']}_{$arrTmp['tablename']}_{$arrTmp['fieldname']}{$tmpHsh[$arrTmp['fieldname']]}\", "; + } + /* field already exist, just ignore this one */ + } else { + // no doublon control + $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", "; + } + } + + $selFields = substr($selFields, 0, -2); + unset($arrTmp, $tmpHsh); + $linkFields = ''; + + // If we have links, out put the JOIN ... ON statements + if (is_array($_POST['formLink'])) { + // Filter out invalid/blank entries for our links + $arrLinks = []; + foreach ($_POST['formLink'] as $curLink) { + if (strlen($curLink['leftlink']) && strlen($curLink['rightlink']) && strlen($curLink['operator'])) { + $arrLinks[] = $curLink; + } + } + // We must perform some magic to make sure that we have a valid join order + $count = sizeof($arrLinks); + $arrJoined = []; + $arrUsedTbls = []; + + // If we have at least one join condition, output it + if ($count > 0) { + $j = 0; + while ($j < $count) { + foreach ($arrLinks as $curLink) { + + $arrLeftLink = unserialize($curLink['leftlink']); + $arrRightLink = unserialize($curLink['rightlink']); + $data->fieldArrayClean($arrLeftLink); + $data->fieldArrayClean($arrRightLink); + + $tbl1 = "\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\""; + $tbl2 = "\"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\""; + + if ((!in_array($curLink, $arrJoined) && in_array($tbl1, $arrUsedTbls)) || !count($arrJoined)) { + + // Make sure for multi-column foreign keys that we use a table alias tables joined to more than once + // This can (and should be) more optimized for multi-column foreign keys + $adj_tbl2 = in_array($tbl2, $arrUsedTbls) ? "$tbl2 AS alias_ppa_" . mktime() : $tbl2; + + $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") " + : "$tbl1 {$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") "; + + $arrJoined[] = $curLink; + if (!in_array($tbl1, $arrUsedTbls)) { + $arrUsedTbls[] = $tbl1; + } + + if (!in_array($tbl2, $arrUsedTbls)) { + $arrUsedTbls[] = $tbl2; + } + + } + } + $j++; + } + } + } + + //if linkfields has no length then either _POST['formLink'] was not set, or there were no join conditions + //just select from all seleted tables - a cartesian join do a + if (!strlen($linkFields)) { + foreach ($_POST['formTables'] as $curTable) { + $arrTmp = unserialize($curTable); + $data->fieldArrayClean($arrTmp); + $linkFields .= strlen($linkFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\""; + } + } + + $addConditions = ''; + if (is_array($_POST['formCondition'])) { + foreach ($_POST['formCondition'] as $curCondition) { + if (strlen($curCondition['field']) && strlen($curCondition['txt'])) { + $arrTmp = unserialize($curCondition['field']); + $data->fieldArrayClean($arrTmp); + $addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' " + : " \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' "; + } + } + } + + $viewQuery = "SELECT $selFields FROM $linkFields "; + + //add where from additional conditions + if (strlen($addConditions)) { + $viewQuery .= ' WHERE ' . $addConditions; + } + + $status = $data->createView($_POST['formView'], $viewQuery, false, $_POST['formComment']); + if ($status == 0) { + $this->misc->setReloadBrowser(true); + $this->doDefault($lang['strviewcreated']); + } else { + $this->doSetParamsCreate($lang['strviewcreatedbad']); + } + + } + } + +/** + * Show default list of views in the database + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('schema'); + $misc->printTabs('schema', 'views'); + $misc->printMsg($msg); + + $views = $data->getViews(); + + $columns = [ + 'view' => [ + 'title' => $lang['strview'], + 'field' => Decorator::field('relname'), + 'url' => "/redirect/view?{$misc->href}&", + 'vars' => ['view' => 'relname'], + ], + 'owner' => [ + 'title' => $lang['strowner'], + 'field' => Decorator::field('relowner'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('relcomment'), + ], + ]; + + $actions = [ + 'multiactions' => [ + 'keycols' => ['view' => 'relname'], + 'url' => 'views.php', + ], + 'browse' => [ + 'content' => $lang['strbrowse'], + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'action' => 'confselectrows', + 'subject' => 'view', + 'return' => 'schema', + 'view' => Decorator::field('relname'), + ], + ], + ], + ], + 'select' => [ + 'content' => $lang['strselect'], + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'confselectrows', + 'view' => Decorator::field('relname'), + ], + ], + ], + ], + + // Insert is possible if the relevant rule for the view has been created. + // 'insert' => array( + // 'title' => $lang['strinsert'], + // 'url' => "views.php?action=confinsertrow&{$misc->href}&", + // 'vars' => array('view' => 'relname'), + // ), + + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'viewproperties.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'view' => Decorator::field('relname'), + ], + ], + ], + ], + 'drop' => [ + 'multiaction' => 'confirm_drop', + 'content' => $lang['strdrop'], + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'view' => Decorator::field('relname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($views, $columns, $actions, 'views-views', $lang['strnoviews']); + + $navlinks = [ + 'create' => [ + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateview'], + ], + 'createwiz' => [ + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'wiz_create', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + ], + ], + ], + 'content' => $lang['strcreateviewwiz'], + ], + ]; + $misc->printNavLinks($navlinks, 'views-views', get_defined_vars()); + + } + +} diff --git a/src/controllers/ViewPropertyController.php b/src/controllers/ViewPropertyController.php new file mode 100644 index 00000000..2c67d166 --- /dev/null +++ b/src/controllers/ViewPropertyController.php @@ -0,0 +1,524 @@ +<?php + +namespace PHPPgAdmin\Controller; +use \PHPPgAdmin\Decorators\Decorator; + +/** + * Base controller class + */ +class ViewPropertyController extends BaseController { + public $_name = 'ViewPropertyController'; + +/** + * Function to save after editing a view + */ + public function doSaveEdit() { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $status = $data->setView($_POST['view'], $_POST['formDefinition'], $_POST['formComment']); + if ($status == 0) { + $this->doDefinition($lang['strviewupdated']); + } else { + $this->doEdit($lang['strviewupdatedbad']); + } + + } + +/** + * Function to allow editing of a view + */ + public function doEdit($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('view'); + $misc->printTitle($lang['stredit'], 'pg.view.alter'); + $misc->printMsg($msg); + + $viewdata = $data->getView($_REQUEST['view']); + + if ($viewdata->recordCount() > 0) { + + if (!isset($_POST['formDefinition'])) { + $_POST['formDefinition'] = $viewdata->fields['vwdefinition']; + $_POST['formComment'] = $viewdata->fields['relcomment']; + } + + echo "<form action=\"/src/views/viewproperties.php\" method=\"post\">\n"; + echo "<table style=\"width: 100%\">\n"; + echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strdefinition']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea style=\"width: 100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", + htmlspecialchars($_POST['formDefinition']), "</textarea></td>\n\t</tr>\n"; + echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "\t\t<td class=\"data1\"><textarea rows=\"3\" cols=\"32\" name=\"formComment\">", + htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + echo $misc->form; + echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } + +/** + * Allow the dumping of the data "in" a view + * NOTE:: PostgreSQL doesn't currently support dumping the data in a view + * so I have disabled the data related parts for now. In the future + * we should allow it conditionally if it becomes supported. This is + * a SMOP since it is based on pg_dump version not backend version. + */ + public function doExport($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $misc->printTrail('view'); + $misc->printTabs('view', 'export'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/dataexport.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; + // Data only + echo "<!--\n"; + echo "<tr><th class=\"data left\">"; + echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"d_format\" >\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "<option value=\"csv\">CSV</option>\n"; + echo "<option value=\"tab\">{$lang['strtabbed']}</option>\n"; + echo "<option value=\"html\">XHTML</option>\n"; + echo "<option value=\"xml\">XML</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "-->\n"; + + // Structure only + echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" checked=\"checked\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; + echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; + // Structure and data + echo "<!--\n"; + echo "<tr><th class=\"data left\" rowspan=\"2\">"; + echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; + echo "<td>{$lang['strformat']}</td>\n"; + echo "<td><select name=\"sd_format\">\n"; + echo "<option value=\"copy\">COPY</option>\n"; + echo "<option value=\"sql\">SQL</option>\n"; + echo "</select>\n</td>\n</tr>\n"; + echo "<td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; + echo "-->\n"; + echo "</table>\n"; + + echo "<h3>{$lang['stroptions']}</h3>\n"; + echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; + echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; + + echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n"; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; + echo "</form>\n"; + } + +/** + * Show definition for a view + */ + public function doDefinition($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + // Get view + $vdata = $data->getView($_REQUEST['view']); + + $misc->printTrail('view'); + $misc->printTabs('view', 'definition'); + $misc->printMsg($msg); + + if ($vdata->recordCount() > 0) { + // Show comment if any + if ($vdata->fields['relcomment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($vdata->fields['relcomment']), "</p>\n"; + } + + echo "<table style=\"width: 100%\">\n"; + echo "<tr><th class=\"data\">{$lang['strdefinition']}</th></tr>\n"; + echo "<tr><td class=\"data1\">", $misc->printVal($vdata->fields['vwdefinition']), "</td></tr>\n"; + echo "</table>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + $misc->printNavLinks(['alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'viewproperties.php', + 'urlvars' => [ + 'action' => 'edit', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $_REQUEST['view'], + ], + ], + ], + 'content' => $lang['stralter'], + ]], 'viewproperties-definition', get_defined_vars()); + } + +/** + * Displays a screen where they can alter a column in a view + */ + public function doProperties($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if (!isset($_REQUEST['stage'])) { + $_REQUEST['stage'] = 1; + } + + switch ($_REQUEST['stage']) { + case 1: + global $lang; + + $misc->printTrail('column'); + $misc->printTitle($lang['stralter'], 'pg.column.alter'); + $misc->printMsg($msg); + + echo "<form action=\"/src/views/viewproperties.php\" method=\"post\">\n"; + + // Output view header + echo "<table>\n"; + echo "<tr><th class=\"data required\">{$lang['strname']}</th><th class=\"data required\">{$lang['strtype']}</th>"; + echo "<th class=\"data\">{$lang['strdefault']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>"; + + $column = $data->getTableAttributes($_REQUEST['view'], $_REQUEST['column']); + + if (!isset($_REQUEST['default'])) { + $_REQUEST['field'] = $column->fields['attname']; + $_REQUEST['default'] = $_REQUEST['olddefault'] = $column->fields['adsrc']; + $_REQUEST['comment'] = $column->fields['comment']; + } + + echo "<tr><td><input name=\"field\" size=\"32\" value=\"", + htmlspecialchars($_REQUEST['field']), "\" /></td>"; + + echo "<td>", $misc->printVal($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "</td>"; + echo "<td><input name=\"default\" size=\"20\" value=\"", + htmlspecialchars($_REQUEST['default']), "\" /></td>"; + echo "<td><input name=\"comment\" size=\"32\" value=\"", + htmlspecialchars($_REQUEST['comment']), "\" /></td>"; + + echo "</table>\n"; + echo "<p><input type=\"hidden\" name=\"action\" value=\"properties\" />\n"; + echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; + echo $misc->form; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; + echo "<input type=\"hidden\" name=\"olddefault\" value=\"", htmlspecialchars($_REQUEST['olddefault']), "\" />\n"; + echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + + break; + case 2: + global $data, $lang; + + // Check inputs + if (trim($_REQUEST['field']) == '') { + $_REQUEST['stage'] = 1; + $this->doProperties($lang['strcolneedsname']); + return; + } + + // Alter the view column + $status = $data->alterColumn($_REQUEST['view'], $_REQUEST['column'], $_REQUEST['field'], + false, false, $_REQUEST['default'], $_REQUEST['olddefault'], + '', '', '', '', $_REQUEST['comment']); + if ($status == 0) { + $this->doDefault($lang['strcolumnaltered']); + } else { + $_REQUEST['stage'] = 1; + $this->doProperties($lang['strcolumnalteredbad']); + return; + } + break; + default: + echo "<p>{$lang['strinvalidparam']}</p>\n"; + } + } + + public function doAlter($confirm = false, $msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + if ($confirm) { + + $misc->printTrail('view'); + $misc->printTitle($lang['stralter'], 'pg.view.alter'); + $misc->printMsg($msg); + + // Fetch view info + $view = $data->getView($_REQUEST['view']); + + if ($view->recordCount() > 0) { + if (!isset($_POST['name'])) { + $_POST['name'] = $view->fields['relname']; + } + + if (!isset($_POST['owner'])) { + $_POST['owner'] = $view->fields['relowner']; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = $view->fields['nspname']; + } + + if (!isset($_POST['comment'])) { + $_POST['comment'] = $view->fields['relcomment']; + } + + echo "<form action=\"/src/views/viewproperties.php\" method=\"post\">\n"; + echo "<table>\n"; + echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", + htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; + + if ($data->isSuperUser()) { + + // Fetch all users + $users = $data->getUsers(); + + echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; + echo "<td class=\"data1\"><select name=\"owner\">"; + while (!$users->EOF) { + $uname = $users->fields['usename']; + echo "<option value=\"", htmlspecialchars($uname), "\"", + ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; + $users->moveNext(); + } + echo "</select></td></tr>\n"; + } + + if ($data->hasAlterTableSchema()) { + $schemas = $data->getSchemas(); + echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; + echo "<td class=\"data1\"><select name=\"newschema\">"; + while (!$schemas->EOF) { + $schema = $schemas->fields['nspname']; + echo "<option value=\"", htmlspecialchars($schema), "\"", + ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; + $schemas->moveNext(); + } + echo "</select></td></tr>\n"; + } + + echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; + echo "<td class=\"data1\">"; + echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", + htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; + echo "</table>\n"; + echo "<input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; + echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; + echo $misc->form; + echo "<p><input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; + echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; + echo "</form>\n"; + } else { + echo "<p>{$lang['strnodata']}</p>\n"; + } + + } else { + global $data, $lang, $_reload_browser, $misc; + + // For databases that don't allow owner change + if (!isset($_POST['owner'])) { + $_POST['owner'] = ''; + } + + if (!isset($_POST['newschema'])) { + $_POST['newschema'] = null; + } + + $status = $data->alterView($_POST['view'], $_POST['name'], $_POST['owner'], $_POST['newschema'], $_POST['comment']); + if ($status == 0) { + // If view has been renamed, need to change to the new name and + // reload the browser frame. + if ($_POST['view'] != $_POST['name']) { + // Jump them to the new view name + $_REQUEST['view'] = $_POST['name']; + // Force a browser reload + $this->misc->setReloadBrowser(true); + } + // If schema has changed, need to change to the new schema and reload the browser + if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { + // Jump them to the new sequence schema + $misc->setCurrentSchema($_POST['newschema']); + $this->misc->setReloadBrowser(true); + } + $this->doDefault($lang['strviewaltered']); + } else { + $this->doAlter(true, $lang['strviewalteredbad']); + } + + } + } + +/** + * Show view definition and virtual columns + */ + public function doDefault($msg = '') { + $conf = $this->conf; + $misc = $this->misc; + $lang = $this->lang; + $data = $misc->getDatabaseAccessor(); + + $attPre = function (&$rowdata) use ($data) { + $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); + }; + + $misc->printTrail('view'); + $misc->printTabs('view', 'columns'); + $misc->printMsg($msg); + + // Get view + $vdata = $data->getView($_REQUEST['view']); + // Get columns (using same method for getting a view) + $attrs = $data->getTableAttributes($_REQUEST['view']); + + // Show comment if any + if ($vdata->fields['relcomment'] !== null) { + echo "<p class=\"comment\">", $misc->printVal($vdata->fields['relcomment']), "</p>\n"; + } + + $columns = [ + 'column' => [ + 'title' => $lang['strcolumn'], + 'field' => Decorator::field('attname'), + 'url' => "colproperties.php?subject=column&{$misc->href}&view=" . urlencode($_REQUEST['view']) . "&", + 'vars' => ['column' => 'attname'], + ], + 'type' => [ + 'title' => $lang['strtype'], + 'field' => Decorator::field('+type'), + ], + 'default' => [ + 'title' => $lang['strdefault'], + 'field' => Decorator::field('adsrc'), + ], + 'actions' => [ + 'title' => $lang['stractions'], + ], + 'comment' => [ + 'title' => $lang['strcomment'], + 'field' => Decorator::field('comment'), + ], + ]; + + $actions = [ + 'alter' => [ + 'content' => $lang['stralter'], + 'attr' => [ + 'href' => [ + 'url' => 'viewproperties.php', + 'urlvars' => [ + 'action' => 'properties', + 'view' => $_REQUEST['view'], + 'column' => Decorator::field('attname'), + ], + ], + ], + ], + ]; + + echo $misc->printTable($attrs, $columns, $actions, 'viewproperties-viewproperties', null, $attPre); + + echo "<br />\n"; + + $navlinks = [ + 'browse' => [ + 'attr' => [ + 'href' => [ + 'url' => 'display.php', + 'urlvars' => [ + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $_REQUEST['view'], + 'subject' => 'view', + 'return' => 'view', + ], + ], + ], + 'content' => $lang['strbrowse'], + ], + 'select' => [ + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'confselectrows', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $_REQUEST['view'], + ], + ], + ], + 'content' => $lang['strselect'], + ], + 'drop' => [ + 'attr' => [ + 'href' => [ + 'url' => 'views.php', + 'urlvars' => [ + 'action' => 'confirm_drop', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $_REQUEST['view'], + ], + ], + ], + 'content' => $lang['strdrop'], + ], + 'alter' => [ + 'attr' => [ + 'href' => [ + 'url' => 'viewproperties.php', + 'urlvars' => [ + 'action' => 'confirm_alter', + 'server' => $_REQUEST['server'], + 'database' => $_REQUEST['database'], + 'schema' => $_REQUEST['schema'], + 'view' => $_REQUEST['view'], + ], + ], + ], + 'content' => $lang['stralter'], + ], + ]; + + $misc->printNavLinks($navlinks, 'viewproperties-viewproperties', get_defined_vars()); + } + +} diff --git a/src/lib.inc.php b/src/lib.inc.php index 4de90651..5d3b2655 100644 --- a/src/lib.inc.php +++ b/src/lib.inc.php @@ -97,10 +97,7 @@ $config = [ $app = new \Slim\App($config); // Fetch DI Container -$container = $app->getContainer(); -$environment = $container->get('environment'); - -//$container['lang'] = $lang; +$container = $app->getContainer(); $plugin_manager = new \PHPPgAdmin\PluginManager($app); $container['plugin_manager'] = $plugin_manager; @@ -184,3 +181,7 @@ if (!isset($_no_db_connection)) { $data = $misc->getDatabaseAccessor(); } +$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; +if (!isset($msg)) { + $msg = ''; +}
\ No newline at end of file diff --git a/src/tree/all_db.php b/src/tree/all_db.php index eee57b3e..f713f784 100644 --- a/src/tree/all_db.php +++ b/src/tree/all_db.php @@ -1,5 +1,6 @@ <?php use \PHPPgAdmin\Decorators\Decorator; + function doTree($container) { $conf = $container->get('conf'); diff --git a/src/tree/operators.php b/src/tree/operators.php index 5dc29d34..47b6db64 100644 --- a/src/tree/operators.php +++ b/src/tree/operators.php @@ -40,7 +40,3 @@ function doTree($container) { return $misc->printTree($operators, $attrs, 'operators', false); } - -if ($action == 'tree') { - doTree(); -}
\ No newline at end of file diff --git a/src/tree/triggers.php b/src/tree/triggers.php index 31c91b93..775f44aa 100644 --- a/src/tree/triggers.php +++ b/src/tree/triggers.php @@ -6,393 +6,12 @@ use \PHPPgAdmin\Decorators\Decorator; * $Id: triggers.php,v 1.37 2007/09/19 14:42:12 ioguix Exp $ */ -// Include application functions -require_once '../lib.inc.php'; - -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Function to save after altering a trigger - */ -function doSaveAlter() { - global $data, $lang; - - $status = $data->alterTrigger($_POST['table'], $_POST['trigger'], $_POST['name']); - if ($status == 0) { - doDefault($lang['strtriggeraltered']); - } else { - doAlter($lang['strtriggeralteredbad']); - } - -} - -/** - * Function to allow altering of a trigger - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('trigger'); - $misc->printTitle($lang['stralter'], 'pg.trigger.alter'); - $misc->printMsg($msg); - - $triggerdata = $data->getTrigger($_REQUEST['table'], $_REQUEST['trigger']); - - if ($triggerdata->recordCount() > 0) { - - if (!isset($_POST['name'])) { - $_POST['name'] = $triggerdata->fields['tgname']; - } - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" />\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['strok']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strdrop'], 'pg.trigger.drop'); - - echo "<p>", sprintf($lang['strconfdroptrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropTrigger($_POST['trigger'], $_POST['table'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strtriggerdropped']); - } else { - doDefault($lang['strtriggerdroppedbad']); - } - - } - -} - -/** - * Show confirmation of enable trigger and perform enabling the trigger - */ -function doEnable($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strenable'], 'pg.table.alter'); - - echo "<p>", sprintf($lang['strconfenabletrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"enable\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->enableTrigger($_POST['trigger'], $_POST['table']); - if ($status == 0) { - doDefault($lang['strtriggerenabled']); - } else { - doDefault($lang['strtriggerenabledbad']); - } - - } - -} - -/** - * Show confirmation of disable trigger and perform disabling the trigger - */ -function doDisable($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strdisable'], 'pg.table.alter'); - - echo "<p>", sprintf($lang['strconfdisabletrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"disable\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->disableTrigger($_POST['trigger'], $_POST['table']); - if ($status == 0) { - doDefault($lang['strtriggerdisabled']); - } else { - doDefault($lang['strtriggerdisabledbad']); - } - - } - -} - -/** - * Let them create s.th. - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('table'); - $misc->printTitle($lang['strcreatetrigger'], 'pg.trigger.create'); - $misc->printMsg($msg); - - // Get all the functions that can be used in triggers - $funcs = $data->getTriggerFunctions(); - if ($funcs->recordCount() == 0) { - doDefault($lang['strnofunctions']); - return; - } - - /* Populate functions */ - $sel0 = new \PHPPgAdmin\XHtml\XHTML_Select('formFunction'); - while (!$funcs->EOF) { - $sel0->add(new \PHPPgAdmin\XHtml\XHTML_Option($funcs->fields['proname'])); - $funcs->moveNext(); - } - - /* Populate times */ - $sel1 = new \PHPPgAdmin\XHtml\XHTML_Select('formExecTime'); - $sel1->set_data($data->triggerExecTimes); - - /* Populate events */ - $sel2 = new \PHPPgAdmin\XHtml\XHTML_Select('formEvent'); - $sel2->set_data($data->triggerEvents); - - /* Populate occurences */ - $sel3 = new \PHPPgAdmin\XHtml\XHTML_Select('formFrequency'); - $sel3->set_data($data->triggerFrequency); - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr>\n"; - echo " <th class=\"data\">{$lang['strname']}</th>\n"; - echo " <th class=\"data\">{$lang['strwhen']}</th>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <td class=\"data1\"> <input type=\"text\" name=\"formTriggerName\" size=\"32\" /></td>\n"; - echo " <td class=\"data1\"> ", $sel1->fetch(), "</td>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <th class=\"data\">{$lang['strevent']}</th>\n"; - echo " <th class=\"data\">{$lang['strforeach']}</th>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <td class=\"data1\"> ", $sel2->fetch(), "</td>\n"; - echo " <td class=\"data1\"> ", $sel3->fetch(), "</td>\n"; - echo "</tr>\n"; - echo "<tr><th class=\"data\"> {$lang['strfunction']}</th>\n"; - echo "<th class=\"data\"> {$lang['strarguments']}</th></tr>\n"; - echo "<tr><td class=\"data1\">", $sel0->fetch(), "</td>\n"; - echo "<td class=\"data1\">(<input type=\"text\" name=\"formTriggerArgs\" size=\"32\" />)</td>\n"; - echo "</tr></table>\n"; - echo "<p><input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo $misc->form; - echo "</form>\n"; -} - -/** - * Actually creates the new trigger in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - // Check that they've given a name and a definition - - if ($_POST['formFunction'] == '') { - doCreate($lang['strtriggerneedsfunc']); - } elseif ($_POST['formTriggerName'] == '') { - doCreate($lang['strtriggerneedsname']); - } elseif ($_POST['formEvent'] == '') { - doCreate(); - } else { - $status = $data->createTrigger($_POST['formTriggerName'], $_POST['table'], - $_POST['formFunction'], $_POST['formExecTime'], $_POST['formEvent'], - $_POST['formFrequency'], $_POST['formTriggerArgs']); - if ($status == 0) { - doDefault($lang['strtriggercreated']); - } else { - doCreate($lang['strtriggercreatedbad']); - } - - } -} - -/** - * List all the triggers on the table - */ -function doDefault($msg = '') { - global $data, $misc, $database; - global $lang; - - function tgPre(&$rowdata, $actions) { - global $data; - // toggle enable/disable trigger per trigger - if (!$data->phpBool($rowdata->fields["tgenabled"])) { - unset($actions['disable']); - } else { - unset($actions['enable']); - } - - return $actions; - } - - $misc->printTrail('table'); - $misc->printTabs('table', 'triggers'); - $misc->printMsg($msg); - - $triggers = $data->getTriggers($_REQUEST['table']); - - $columns = [ - 'trigger' => [ - 'title' => $lang['strname'], - 'field' => Decorator::field('tgname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => Decorator::field('tgdef'), - ], - 'function' => [ - 'title' => $lang['strfunction'], - 'field' => Decorator::field('proproto'), - 'url' => "functions.php?action=properties&server={$_REQUEST['server']}&database={$_REQUEST['database']}&", - 'vars' => [ - 'schema' => 'pronamespace', - 'function' => 'proproto', - 'function_oid' => 'prooid', - ], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'table' => $_REQUEST['table'], - 'trigger' => Decorator::field('tgname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'table' => $_REQUEST['table'], - 'trigger' => Decorator::field('tgname'), - ], - ], - ], - ], - ]; - if ($data->hasDisableTriggers()) { - $actions['enable'] = [ - 'content' => $lang['strenable'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_enable', - 'table' => $_REQUEST['table'], - 'trigger' => Decorator::field('tgname'), - ], - ], - ], - ]; - $actions['disable'] = [ - 'content' => $lang['strdisable'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_disable', - 'table' => $_REQUEST['table'], - 'trigger' => Decorator::field('tgname'), - ], - ], - ], - ]; - } - - echo $misc->printTable($triggers, $columns, $actions, 'triggers-triggers', $lang['strnotriggers'], 'tgPre'); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strcreatetrigger'], - ]], 'triggers-triggers', get_defined_vars()); -} - -function doTree() { - - global $misc, $data; +function doTree($container) { + $conf = $container->get('conf'); + $misc = $container->get('misc'); + $lang = $container->get('lang'); + $data = $misc->getDatabaseAccessor(); $triggers = $data->getTriggers($_REQUEST['table']); $reqvars = $misc->getRequestVars('table'); @@ -405,73 +24,3 @@ function doTree() { $misc->printTree($triggers, $attrs, 'triggers'); exit; } - -if ($action == 'tree') { - doTree(); -} - -$misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table'] . ' - ' . $lang['strtriggers']); -$misc->printBody(); - -switch ($action) { - case 'alter': - if (isset($_POST['alter'])) { - doSaveAlter(); - } else { - doDefault(); - } - - break; - case 'confirm_alter': - doAlter(); - break; - case 'confirm_enable': - doEnable(true); - break; - case 'confirm_disable': - doDisable(true); - break; - case 'save_create': - if (isset($_POST['cancel'])) { - doDefault(); - } else { - doSaveCreate(); - } - - break; - case 'create': - doCreate(); - break; - case 'drop': - if (isset($_POST['yes'])) { - doDrop(false); - } else { - doDefault(); - } - - break; - case 'confirm_drop': - doDrop(true); - break; - case 'enable': - if (isset($_POST['yes'])) { - doEnable(false); - } else { - doDefault(); - } - - break; - case 'disable': - if (isset($_POST['yes'])) { - doDisable(false); - } else { - doDefault(); - } - - break; - default: - doDefault(); - break; -} - -$misc->printFooter(); diff --git a/src/tree/types.php b/src/tree/types.php index a43fa568..f4235955 100644 --- a/src/tree/types.php +++ b/src/tree/types.php @@ -6,711 +6,6 @@ use \PHPPgAdmin\Decorators\Decorator; * $Id: types.php,v 1.42 2007/11/30 15:25:23 soranzo Exp $ */ -// Include application functions -require_once '../lib.inc.php'; - -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show read only properties for a type - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - // Get type (using base name) - $typedata = $data->getType($_REQUEST['type']); - - $misc->printTrail('type'); - $misc->printTitle($lang['strproperties'], 'pg.type'); - $misc->printMsg($msg); - - function attPre(&$rowdata) { - global $data; - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - } - - if ($typedata->recordCount() > 0) { - $vals = false; - switch ($typedata->fields['typtype']) { - case 'c': - $attrs = $data->getTableAttributes($_REQUEST['type']); - - $columns = [ - 'field' => [ - 'title' => $lang['strfield'], - 'field' => Decorator::field('attname'), - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => Decorator::field('+type'), - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => Decorator::field('comment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($attrs, $columns, $actions, 'types-properties', null, 'attPre'); - - break; - case 'e': - $vals = $data->getEnumValues($typedata->fields['typname']); - default: - $byval = $data->phpBool($typedata->fields['typbyval']); - echo "<table>\n"; - echo "<tr><th class=\"data left\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strinputfn']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typin']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['stroutputfn']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typout']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strlength']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typlen']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strpassbyval']}</th>\n"; - echo "<td class=\"data1\">", ($byval) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typalign']), "</td></tr>\n"; - if ($data->hasEnumTypes() && $vals) { - $vals = $vals->getArray(); - $nbVals = count($vals); - echo "<tr>\n\t<th class=\"data left\" rowspan=\"$nbVals\">{$lang['strenumvalues']}</th>\n"; - echo "<td class=\"data2\">{$vals[0]['enumval']}</td></tr>\n"; - for ($i = 1; $i < $nbVals; $i++) { - echo "<td class=\"data", 2 - ($i % 2), "\">{$vals[$i]['enumval']}</td></tr>\n"; - } - - } - echo "</table>\n"; - } - - $misc->printNavLinks(['showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strshowalltypes'], - ]], 'types-properties', get_defined_vars()); - } else { - doDefault($lang['strinvalidparam']); - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('type'); - $misc->printTitle($lang['strdrop'], 'pg.type.drop'); - - echo "<p>", sprintf($lang['strconfdroptype'], $misc->printVal($_REQUEST['type'])), "</p>\n"; - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropType($_POST['type'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strtypedropped']); - } else { - doDefault($lang['strtypedroppedbad']); - } - - } - -} - -/** - * Displays a screen where they can enter a new composite type - */ -function doCreateComposite($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['fields'])) { - $_REQUEST['fields'] = ''; - } - - if (!isset($_REQUEST['typcomment'])) { - $_REQUEST['typcomment'] = ''; - } - - switch ($_REQUEST['stage']) { - case 1: - $misc->printTrail('type'); - $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumfields']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n"; - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - case 2: - global $lang; - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedscols']); - return; - } - - $types = $data->getTypes(true, false, true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>"; - echo "<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n"; - - for ($i = 0; $i < $_REQUEST['fields']; $i++) { - if (!isset($_REQUEST['field'][$i])) { - $_REQUEST['field'][$i] = ''; - } - - if (!isset($_REQUEST['length'][$i])) { - $_REQUEST['length'][$i] = ''; - } - - if (!isset($_REQUEST['colcomment'][$i])) { - $_REQUEST['colcomment'][$i] = ''; - } - - echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; - echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n"; - echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">\n"; - $types->moveFirst(); - while (!$types->EOF) { - $typname = $types->fields['typname']; - echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"", - (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", - $misc->printVal($typname), "</option>\n"; - $types->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n"; - - // Output array type selector - echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n"; - echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "\t\t\t</select>\n\t\t</td>\n"; - - echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"", - htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n"; - echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"", - htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n"; - echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 3: - global $data, $lang; - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedscols']); - return; - } - - $status = $data->createCompositeType($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'], - $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['colcomment'], - $_REQUEST['typcomment']); - - if ($status == 0) { - doDefault($lang['strtypecreated']); - } elseif ($status == -1) { - $_REQUEST['stage'] = 2; - doCreateComposite($lang['strtypeneedsfield']); - return; - } else { - $_REQUEST['stage'] = 2; - doCreateComposite($lang['strtypecreatedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Displays a screen where they can enter a new enum type - */ -function doCreateEnum($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['values'])) { - $_REQUEST['values'] = ''; - } - - if (!isset($_REQUEST['typcomment'])) { - $_REQUEST['typcomment'] = ''; - } - - switch ($_REQUEST['stage']) { - case 1: - $misc->printTrail('type'); - $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumvalues']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"values\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['values']), "\" /></td>\n\t</tr>\n"; - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - case 2: - global $lang; - - // Check inputs - $values = trim($_REQUEST['values']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsname']); - return; - } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values < 1) { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsvals']); - return; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strvalue']}</th></tr>\n"; - - for ($i = 0; $i < $_REQUEST['values']; $i++) { - if (!isset($_REQUEST['value'][$i])) { - $_REQUEST['value'][$i] = ''; - } - - echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; - echo "\t\t<td><input name=\"value[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['value'][$i]), "\" /></td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"values\" value=\"", htmlspecialchars($_REQUEST['values']), "\" />\n"; - echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 3: - global $data, $lang; - - // Check inputs - $values = trim($_REQUEST['values']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsname']); - return; - } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values <= 0) { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsvals']); - return; - } - - $status = $data->createEnumType($_REQUEST['name'], $_REQUEST['value'], $_REQUEST['typcomment']); - - if ($status == 0) { - doDefault($lang['strtypecreated']); - } elseif ($status == -1) { - $_REQUEST['stage'] = 2; - doCreateEnum($lang['strtypeneedsvalue']); - return; - } else { - $_REQUEST['stage'] = 2; - doCreateEnum($lang['strtypecreatedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Displays a screen where they can enter a new type - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['typname'])) { - $_POST['typname'] = ''; - } - - if (!isset($_POST['typin'])) { - $_POST['typin'] = ''; - } - - if (!isset($_POST['typout'])) { - $_POST['typout'] = ''; - } - - if (!isset($_POST['typlen'])) { - $_POST['typlen'] = ''; - } - - if (!isset($_POST['typdef'])) { - $_POST['typdef'] = ''; - } - - if (!isset($_POST['typelem'])) { - $_POST['typelem'] = ''; - } - - if (!isset($_POST['typdelim'])) { - $_POST['typdelim'] = ''; - } - - if (!isset($_POST['typalign'])) { - $_POST['typalign'] = $data->typAlignDef; - } - - if (!isset($_POST['typstorage'])) { - $_POST['typstorage'] = $data->typStorageDef; - } - - // Retrieve all functions and types in the database - $funcs = $data->getFunctions(true); - $types = $data->getTypes(true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatetype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['typname']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strinputfn']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typin\">"; - while (!$funcs->EOF) { - $proname = htmlspecialchars($funcs->fields['proname']); - echo "<option value=\"{$proname}\"", - ($proname == $_POST['typin']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; - $funcs->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['stroutputfn']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typout\">"; - $funcs->moveFirst(); - while (!$funcs->EOF) { - $proname = htmlspecialchars($funcs->fields['proname']); - echo "<option value=\"{$proname}\"", - ($proname == $_POST['typout']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; - $funcs->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left" . (version_compare($data->major_version, '7.4', '<') ? ' required' : '') . "\">{$lang['strlength']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typlen\" size=\"8\" value=\"", - htmlspecialchars($_POST['typlen']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typdef\" size=\"8\" value=\"", - htmlspecialchars($_POST['typdef']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['strelement']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typelem\">"; - echo "<option value=\"\"></option>\n"; - while (!$types->EOF) { - $currname = htmlspecialchars($types->fields['typname']); - echo "<option value=\"{$currname}\"", - ($currname == $_POST['typelem']) ? ' selected="selected"' : '', ">{$currname}</option>\n"; - $types->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strdelimiter']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typdelim\" size=\"1\" maxlength=\"1\" value=\"", - htmlspecialchars($_POST['typdelim']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\"><label for=\"typbyval\">{$lang['strpassbyval']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"typbyval\" name=\"typbyval\"", - isset($_POST['typbyval']) ? ' checked="checked"' : '', " /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typalign\">"; - foreach ($data->typAligns as $v) { - echo "<option value=\"{$v}\"", - ($v == $_POST['typalign']) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strstorage']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typstorage\">"; - foreach ($data->typStorages as $v) { - echo "<option value=\"{$v}\"", - ($v == $_POST['typstorage']) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - echo "</select></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new type in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - // Check that they've given a name and a length. - // Note: We're assuming they've given in and out functions here - // which might be unwise... - if ($_POST['typname'] == '') { - doCreate($lang['strtypeneedsname']); - } elseif ($_POST['typlen'] == '') { - doCreate($lang['strtypeneedslen']); - } else { - $status = $data->createType( - $_POST['typname'], - $_POST['typin'], - $_POST['typout'], - $_POST['typlen'], - $_POST['typdef'], - $_POST['typelem'], - $_POST['typdelim'], - isset($_POST['typbyval']), - $_POST['typalign'], - $_POST['typstorage'] - ); - if ($status == 0) { - doDefault($lang['strtypecreated']); - } else { - doCreate($lang['strtypecreatedbad']); - } - - } -} - -/** - * Show default list of types in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'types'); - $misc->printMsg($msg); - - $types = $data->getTypes(); - - $columns = [ - 'type' => [ - 'title' => $lang['strtype'], - 'field' => Decorator::field('typname'), - 'url' => "types.php?action=properties&{$misc->href}&", - 'vars' => ['type' => 'basename'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => Decorator::field('typowner'), - ], - 'flavour' => [ - 'title' => $lang['strflavor'], - 'field' => Decorator::field('typtype'), - 'type' => 'verbatim', - 'params' => [ - 'map' => [ - 'b' => $lang['strbasetype'], - 'c' => $lang['strcompositetype'], - 'd' => $lang['strdomain'], - 'p' => $lang['strpseudotype'], - 'e' => $lang['strenum'], - ], - 'align' => 'center', - ], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => Decorator::field('typcomment'), - ], - ]; - - if (!isset($types->fields['typtype'])) { - unset($columns['flavour']); - } - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'type' => Decorator::field('basename'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($types, $columns, $actions, 'types-types', $lang['strnotypes']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatetype'], - ], - 'createcomp' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create_comp', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatecomptype'], - ], - 'createenum' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create_enum', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateenumtype'], - ], - ]; - - if (!$data->hasEnumTypes()) { - unset($navlinks['enum']); - } - - $misc->printNavLinks($navlinks, 'types-types', get_defined_vars()); -} - /** * Generate XML for the browser tree. */ @@ -737,59 +32,3 @@ function doTree() { $misc->printTree($types, $attrs, 'types'); exit; } - -if ($action == 'tree') { - doTree(); -} - -$misc->printHeader($lang['strtypes']); -$misc->printBody(); - -switch ($action) { - case 'create_comp': - if (isset($_POST['cancel'])) { - doDefault(); - } else { - doCreateComposite(); - } - - break; - case 'create_enum': - if (isset($_POST['cancel'])) { - doDefault(); - } else { - doCreateEnum(); - } - - break; - case 'save_create': - if (isset($_POST['cancel'])) { - doDefault(); - } else { - doSaveCreate(); - } - - break; - case 'create': - doCreate(); - break; - case 'drop': - if (isset($_POST['cancel'])) { - doDefault(); - } else { - doDrop(false); - } - - break; - case 'confirm_drop': - doDrop(true); - break; - case 'properties': - doProperties(); - break; - default: - doDefault(); - break; -} - -$misc->printFooter(); diff --git a/src/tree/viewproperties.php b/src/tree/viewproperties.php index d7792990..3cb2acce 100755 --- a/src/tree/viewproperties.php +++ b/src/tree/viewproperties.php @@ -43,7 +43,3 @@ function doTree() { exit; } - -if ($action == 'tree') { - doTree(); -}
\ No newline at end of file diff --git a/src/views/admin.php b/src/views/admin.php deleted file mode 100644 index 8ab0d1f7..00000000 --- a/src/views/admin.php +++ /dev/null @@ -1,804 +0,0 @@ -<?php - -$script = ''; // init global value script - -/** - * Show confirmation of cluster and perform cluster - */ -function doCluster($type, $confirm = false) { - global $script, $data, $misc, $lang; - - if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletocluster']); - return; - } - - if ($confirm) { - if (isset($_REQUEST['ma'])) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfclustertable'], $misc->printVal($a['table'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; - } - } // END if multi cluster - else { - $misc->printTrail($type); - $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - - if ($type == 'table') { - echo "<p>", sprintf($lang['strconfclustertable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - } else { - echo "<p>", sprintf($lang['strconfclusterdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; - } - } - echo "<input type=\"hidden\" name=\"action\" value=\"cluster\" />\n"; - - echo $misc->form; - - echo "<input type=\"submit\" name=\"cluster\" value=\"{$lang['strcluster']}\" />\n"; //TODO - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END single cluster - else { - //If multi table cluster - if ($type == 'table') { - // cluster one or more table - if (is_array($_REQUEST['table'])) { - $msg = ''; - foreach ($_REQUEST['table'] as $o) { - $status = $data->clusterIndex($o); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strclusteredgood']); - } else { - doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strclusteredbad'])); - return; - } - } - // Everything went fine, back to the Default page.... - doDefault($msg); - } else { - $status = $data->clusterIndex($_REQUEST['object']); - if ($status == 0) { - doAdmin($type, $lang['strclusteredgood']); - } else { - doAdmin($type, $lang['strclusteredbad']); - } - - } - } else { - // Cluster all tables in database - $status = $data->clusterIndex(); - if ($status == 0) { - doAdmin($type, $lang['strclusteredgood']); - } else { - doAdmin($type, $lang['strclusteredbad']); - } - - } - } -} - -/** - * Show confirmation of reindex and perform reindex - */ -function doReindex($type, $confirm = false) { - global $script, $data, $misc, $lang, $_reload_browser; - - if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletoreindex']); - return; - } - - if ($confirm) { - if (isset($_REQUEST['ma'])) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strreindex'], 'pg.reindex'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfreindextable'], $misc->printVal($a['table'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; - } - } // END if multi reindex - else { - $misc->printTrail($type); - $misc->printTitle($lang['strreindex'], 'pg.reindex'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - - if ($type == 'table') { - echo "<p>", sprintf($lang['strconfreindextable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - } else { - echo "<p>", sprintf($lang['strconfreindexdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; - } - } - echo "<input type=\"hidden\" name=\"action\" value=\"reindex\" />\n"; - - if ($data->hasForceReindex()) { - echo "<p><input type=\"checkbox\" id=\"reindex_force\" name=\"reindex_force\" /><label for=\"reindex_force\">{$lang['strforce']}</label></p>\n"; - } - - echo $misc->form; - - echo "<input type=\"submit\" name=\"reindex\" value=\"{$lang['strreindex']}\" />\n"; //TODO - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END single reindex - else { - //If multi table reindex - if (($type == 'table') && is_array($_REQUEST['table'])) { - $msg = ''; - foreach ($_REQUEST['table'] as $o) { - $status = $data->reindex(strtoupper($type), $o, isset($_REQUEST['reindex_force'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strreindexgood']); - } else { - doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['strreindexbad'])); - return; - } - } - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - $status = $data->reindex(strtoupper($type), $_REQUEST['object'], isset($_REQUEST['reindex_force'])); - if ($status == 0) { - $_reload_browser = true; - doAdmin($type, $lang['strreindexgood']); - } else { - doAdmin($type, $lang['strreindexbad']); - } - - } - } -} - -/** - * Show confirmation of analyze and perform analyze - */ -function doAnalyze($type, $confirm = false) { - global $script, $data, $misc, $lang, $_reload_browser; - - if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletoanalyze']); - return; - } - - if ($confirm) { - if (isset($_REQUEST['ma'])) { - $misc->printTrail('schema'); - $misc->printTitle($lang['stranalyze'], 'pg.analyze'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfanalyzetable'], $misc->printVal($a['table'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; - } - } // END if multi analyze - else { - $misc->printTrail($type); - $misc->printTitle($lang['stranalyze'], 'pg.analyze'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - - if ($type == 'table') { - echo "<p>", sprintf($lang['strconfanalyzetable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - } else { - echo "<p>", sprintf($lang['strconfanalyzedatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; - } - } - echo "<input type=\"hidden\" name=\"action\" value=\"analyze\" />\n"; - echo $misc->form; - - echo "<input type=\"submit\" name=\"analyze\" value=\"{$lang['stranalyze']}\" />\n"; //TODO - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END single analyze - else { - //If multi table analyze - if (($type == 'table') && is_array($_REQUEST['table'])) { - $msg = ''; - foreach ($_REQUEST['table'] as $o) { - $status = $data->analyzeDB($o); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['stranalyzegood']); - } else { - doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($o, ENT_QUOTES, 'UTF-8'), $lang['stranalyzebad'])); - return; - } - } - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - //we must pass table here. When empty, analyze the whole db - $status = $data->analyzeDB($_REQUEST['table']); - if ($status == 0) { - $_reload_browser = true; - doAdmin($type, $lang['stranalyzegood']); - } else { - doAdmin($type, $lang['stranalyzebad']); - } - - } - } -} - -/** - * Show confirmation of vacuum and perform actual vacuum - */ -function doVacuum($type, $confirm = false) { - global $script, $data, $misc, $lang, $_reload_browser; - - if (($type == 'table') && empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletovacuum']); - return; - } - - if ($confirm) { - if (isset($_REQUEST['ma'])) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strvacuum'], 'pg.vacuum'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfvacuumtable'], $misc->printVal($a['table'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table[]\" value=\"", htmlspecialchars($a['table']), "\" />\n"; - } - } // END if multi vacuum - else { - $misc->printTrail($type); - $misc->printTitle($lang['strvacuum'], 'pg.vacuum'); - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - - if ($type == 'table') { - echo "<p>", sprintf($lang['strconfvacuumtable'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - } else { - echo "<p>", sprintf($lang['strconfvacuumdatabase'], $misc->printVal($_REQUEST['object'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"\" />\n"; - } - } - echo "<input type=\"hidden\" name=\"action\" value=\"vacuum\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"vacuum_full\" name=\"vacuum_full\" /> <label for=\"vacuum_full\">{$lang['strfull']}</label></p>\n"; - echo "<p><input type=\"checkbox\" id=\"vacuum_analyze\" name=\"vacuum_analyze\" /> <label for=\"vacuum_analyze\">{$lang['stranalyze']}</label></p>\n"; - echo "<p><input type=\"checkbox\" id=\"vacuum_freeze\" name=\"vacuum_freeze\" /> <label for=\"vacuum_freeze\">{$lang['strfreeze']}</label></p>\n"; - echo "<input type=\"submit\" name=\"vacuum\" value=\"{$lang['strvacuum']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END single vacuum - else { - //If multi drop - if (is_array($_REQUEST['table'])) { - $msg = ''; - foreach ($_REQUEST['table'] as $t) { - $status = $data->vacuumDB($t, isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strvacuumgood']); - } else { - doDefault($type, sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strvacuumbad'])); - return; - } - } - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - //we must pass table here. When empty, vacuum the whole db - $status = $data->vacuumDB($_REQUEST['table'], isset($_REQUEST['vacuum_analyze']), isset($_REQUEST['vacuum_full']), isset($_REQUEST['vacuum_freeze'])); - if ($status == 0) { - $_reload_browser = true; - doAdmin($type, $lang['strvacuumgood']); - } else { - doAdmin($type, $lang['strvacuumbad']); - } - - } - } -} - -/** - * Add or Edit autovacuum params and save them - */ -function doEditAutovacuum($type, $confirm, $msg = '') { - global $script, $data, $misc, $lang; - - if (empty($_REQUEST['table'])) { - doAdmin($type, '', $lang['strspecifyeditvacuumtable']); - return; - } - - $script = ($type == 'database') ? 'database.php' : 'tables.php'; - - if ($confirm) { - $misc->printTrail($type); - $misc->printTitle(sprintf($lang['streditvacuumtable'], $misc->printVal($_REQUEST['table']))); - $misc->printMsg(sprintf($msg, $misc->printVal($_REQUEST['table']))); - - if (empty($_REQUEST['table'])) { - doAdmin($type, '', $lang['strspecifyeditvacuumtable']); - return; - } - - $old_val = $data->getTableAutovacuum($_REQUEST['table']); - $defaults = $data->getAutovacuum(); - $old_val = $old_val->fields; - - if (isset($old_val['autovacuum_enabled']) and ($old_val['autovacuum_enabled'] == 'off')) { - $enabled = ''; - $disabled = 'checked="checked"'; - } else { - $enabled = 'checked="checked"'; - $disabled = ''; - } - - if (!isset($old_val['autovacuum_vacuum_threshold'])) { - $old_val['autovacuum_vacuum_threshold'] = ''; - } - - if (!isset($old_val['autovacuum_vacuum_scale_factor'])) { - $old_val['autovacuum_vacuum_scale_factor'] = ''; - } - - if (!isset($old_val['autovacuum_analyze_threshold'])) { - $old_val['autovacuum_analyze_threshold'] = ''; - } - - if (!isset($old_val['autovacuum_analyze_scale_factor'])) { - $old_val['autovacuum_analyze_scale_factor'] = ''; - } - - if (!isset($old_val['autovacuum_vacuum_cost_delay'])) { - $old_val['autovacuum_vacuum_cost_delay'] = ''; - } - - if (!isset($old_val['autovacuum_vacuum_cost_limit'])) { - $old_val['autovacuum_vacuum_cost_limit'] = ''; - } - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"action\" value=\"editautovac\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - - echo "<br />\n<br />\n<table>\n"; - echo "\t<tr><td> </td>\n"; - echo "<th class=\"data\">{$lang['strnewvalues']}</th><th class=\"data\">{$lang['strdefaultvalues']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['strenable']}</th>\n"; - echo "<td class=\"data1\">\n"; - echo "<label for=\"on\">on</label><input type=\"radio\" name=\"autovacuum_enabled\" id=\"on\" value=\"on\" {$enabled} />\n"; - echo "<label for=\"off\">off</label><input type=\"radio\" name=\"autovacuum_enabled\" id=\"off\" value=\"off\" {$disabled} /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['strvacuumbasethreshold']}</th>\n"; - echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_threshold\" value=\"{$old_val['autovacuum_vacuum_threshold']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_threshold']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['strvacuumscalefactor']}</th>\n"; - echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_scale_factor\" value=\"{$old_val['autovacuum_vacuum_scale_factor']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_scale_factor']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['stranalybasethreshold']}</th>\n"; - echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_analyze_threshold\" value=\"{$old_val['autovacuum_analyze_threshold']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_analyze_threshold']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['stranalyzescalefactor']}</th>\n"; - echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_analyze_scale_factor\" value=\"{$old_val['autovacuum_analyze_scale_factor']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_analyze_scale_factor']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['strvacuumcostdelay']}</th>\n"; - echo "<td class=\"data1\"><input type=\"text\" name=\"autovacuum_vacuum_cost_delay\" value=\"{$old_val['autovacuum_vacuum_cost_delay']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_cost_delay']}</th></tr>\n"; - echo "\t<tr><th class=\"data left\">{$lang['strvacuumcostlimit']}</th>\n"; - echo "<td class=\"datat1\"><input type=\"text\" name=\"autovacuum_vacuum_cost_limit\" value=\"{$old_val['autovacuum_vacuum_cost_limit']}\" /></td>\n"; - echo "<th class=\"data left\">{$defaults['autovacuum_vacuum_cost_limit']}</th></tr>\n"; - echo "</table>\n"; - echo "<br />"; - echo "<br />"; - echo "<input type=\"submit\" name=\"save\" value=\"{$lang['strsave']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - - echo "</form>\n"; - } else { - $status = $data->saveAutovacuum($_REQUEST['table'], $_POST['autovacuum_enabled'], $_POST['autovacuum_vacuum_threshold'], - $_POST['autovacuum_vacuum_scale_factor'], $_POST['autovacuum_analyze_threshold'], $_POST['autovacuum_analyze_scale_factor'], - $_POST['autovacuum_vacuum_cost_delay'], $_POST['autovacuum_vacuum_cost_limit']); - - if ($status == 0) { - doAdmin($type, '', sprintf($lang['strsetvacuumtablesaved'], $_REQUEST['table'])); - } else { - doEditAutovacuum($type, true, $lang['strsetvacuumtablefail']); - } - - } -} - -/** - * confirm drop autovacuum params for a table and drop it - */ -function doDropAutovacuum($type, $confirm) { - global $script, $data, $misc, $lang; - - if (empty($_REQUEST['table'])) { - doAdmin($type, '', $lang['strspecifydelvacuumtable']); - return; - } - - if ($confirm) { - $misc->printTrail($type); - $misc->printTabs($type, 'admin'); - - $script = ($type == 'database') ? 'database.php' : 'tables.php'; - - printf("<p>{$lang['strdelvacuumtable']}</p>\n", - $misc->printVal("\"{$_GET['schema']}\".\"{$_GET['table']}\"")); - - echo "<form style=\"float: left\" action=\"{$script}\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"delautovac\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"rel\" value=\"", htmlspecialchars(serialize([$_REQUEST['schema'], $_REQUEST['table']])), "\" />\n"; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "</form>\n"; - - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"admin\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - - $status = $data->dropAutovacuum($_POST['table']); - - if ($status == 0) { - doAdmin($type, '', sprintf($lang['strvacuumtablereset'], $misc->printVal($_POST['table']))); - } else { - doAdmin($type, '', sprintf($lang['strdelvacuumtablefail'], $misc->printVal($_POST['table']))); - } - - } -} - -/** - * database/table administration and tuning tasks - * - * $Id: admin.php - */ - -function doAdmin($type, $msg = '') { - global $script, $data, $misc, $lang; - - $misc->printTrail($type); - $misc->printTabs($type, 'admin'); - $misc->printMsg($msg); - - if ($type == 'database') { - printf("<p>{$lang['stradminondatabase']}</p>\n", $misc->printVal($_REQUEST['object'])); - } else { - printf("<p>{$lang['stradminontable']}</p>\n", $misc->printVal($_REQUEST['object'])); - } - - echo "<table style=\"width: 50%\">\n"; - echo "<tr>\n"; - echo "<th class=\"data\">"; - $misc->printHelp($lang['strvacuum'], 'pg.admin.vacuum') . "</th>\n"; - echo "</th>"; - echo "<th class=\"data\">"; - $misc->printHelp($lang['stranalyze'], 'pg.admin.analyze'); - echo "</th>"; - if ($data->hasRecluster()) { - echo "<th class=\"data\">"; - $misc->printHelp($lang['strclusterindex'], 'pg.index.cluster'); - echo "</th>"; - } - echo "<th class=\"data\">"; - $misc->printHelp($lang['strreindex'], 'pg.index.reindex'); - echo "</th>"; - echo "</tr>"; - - // Vacuum - echo "<tr class=\"row1\">\n"; - echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_vacuum\" />\n"; - echo $misc->form; - if ($type == 'table') { - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['strvacuum']}\" /></p>\n"; - echo "</form>\n"; - echo "</td>\n"; - - // Analyze - echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_analyze\" />\n"; - echo $misc->form; - if ($type == 'table') { - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['stranalyze']}\" /></p>\n"; - echo "</form>\n"; - echo "</td>\n"; - - // Cluster - if ($data->hasRecluster()) { - $disabled = ''; - echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - echo $misc->form; - if ($type == 'table') { - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - if (!$data->alreadyClustered($_REQUEST['object'])) { - $disabled = 'disabled="disabled" '; - echo "{$lang['strnoclusteravailable']}<br />"; - } - } - echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_cluster\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strclusterindex']}\" $disabled/></p>\n"; - echo "</form>\n"; - echo "</td>\n"; - } - - // Reindex - echo "<td style=\"text-align: center; vertical-align: bottom\">\n"; - echo "<form action=\"/views/{$script}\" method=\"post\">\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"confirm_reindex\" />\n"; - echo $misc->form; - if ($type == 'table') { - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['object']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['strreindex']}\" /></p>\n"; - echo "</form>\n"; - echo "</td>\n"; - echo "</tr>\n"; - echo "</table>\n"; - - // Autovacuum - if ($data->hasAutovacuum()) { - // get defaults values for autovacuum - $defaults = $data->getAutovacuum(); - // Fetch the autovacuum properties from the database or table if != '' - if ($type == 'table') { - $autovac = $data->getTableAutovacuum($_REQUEST['table']); - } else { - $autovac = $data->getTableAutovacuum(); - } - - echo "<br /><br /><h2>{$lang['strvacuumpertable']}</h2>"; - echo '<p>' . (($defaults['autovacuum'] == 'on') ? $lang['strturnedon'] : $lang['strturnedoff']) . '</p>'; - echo "<p class=\"message\">{$lang['strnotdefaultinred']}</p>"; - - function enlight($f, $p) { - if (isset($f[$p[0]]) and ($f[$p[0]] != $p[1])) { - return "<span style=\"color:#F33;font-weight:bold\">" . htmlspecialchars($f[$p[0]]) . "</span>"; - } - - return htmlspecialchars($p[1]); - } - - $columns = [ - 'namespace' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'url' => "/redirect/schema?{$misc->href}&", - 'vars' => ['schema' => 'nspname'], - ], - 'relname' => [ - 'title' => $lang['strtable'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - 'url' => "/redirect/table?{$misc->href}&", - 'vars' => ['table' => 'relname', 'schema' => 'nspname'], - ], - 'autovacuum_enabled' => [ - 'title' => $lang['strenabled'], - 'field' => callback('enlight', ['autovacuum_enabled', $defaults['autovacuum']]), - 'type' => 'verbatim', - ], - 'autovacuum_vacuum_threshold' => [ - 'title' => $lang['strvacuumbasethreshold'], - 'field' => callback('enlight', ['autovacuum_vacuum_threshold', $defaults['autovacuum_vacuum_threshold']]), - 'type' => 'verbatim', - ], - 'autovacuum_vacuum_scale_factor' => [ - 'title' => $lang['strvacuumscalefactor'], - 'field' => callback('enlight', ['autovacuum_vacuum_scale_factor', $defaults['autovacuum_vacuum_scale_factor']]), - 'type' => 'verbatim', - ], - 'autovacuum_analyze_threshold' => [ - 'title' => $lang['stranalybasethreshold'], - 'field' => callback('enlight', ['autovacuum_analyze_threshold', $defaults['autovacuum_analyze_threshold']]), - 'type' => 'verbatim', - ], - 'autovacuum_analyze_scale_factor' => [ - 'title' => $lang['stranalyzescalefactor'], - 'field' => callback('enlight', ['autovacuum_analyze_scale_factor', $defaults['autovacuum_analyze_scale_factor']]), - 'type' => 'verbatim', - ], - 'autovacuum_vacuum_cost_delay' => [ - 'title' => $lang['strvacuumcostdelay'], - 'field' => concat(callback('enlight', ['autovacuum_vacuum_cost_delay', $defaults['autovacuum_vacuum_cost_delay']]), 'ms'), - 'type' => 'verbatim', - ], - 'autovacuum_vacuum_cost_limit' => [ - 'title' => $lang['strvacuumcostlimit'], - 'field' => callback('enlight', ['autovacuum_vacuum_cost_limit', $defaults['autovacuum_vacuum_cost_limit']]), - 'type' => 'verbatim', - ], - ]; - - // Maybe we need to check permissions here? - $columns['actions'] = ['title' => $lang['stractions']]; - - $actions = [ - 'edit' => [ - 'content' => $lang['stredit'], - 'attr' => [ - 'href' => [ - 'url' => $script, - 'urlvars' => [ - 'subject' => $type, - 'action' => 'confeditautovac', - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'delete' => [ - 'content' => $lang['strdelete'], - 'attr' => [ - 'href' => [ - 'url' => $script, - 'urlvars' => [ - 'subject' => $type, - 'action' => 'confdelautovac', - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - ]; - - if ($type == 'table') { - unset($actions['edit']['vars']['schema'], - $actions['delete']['vars']['schema'], - $columns['namespace'], - $columns['relname'] - ); - } - - echo $misc->printTable($autovac, $columns, $actions, 'admin-admin', $lang['strnovacuumconf']); - - if (($type == 'table') and ($autovac->recordCount() == 0)) { - echo "<br />"; - echo "<a href=\"tables.php?action=confeditautovac&{$misc->href}&table=", htmlspecialchars($_REQUEST['table']) - , "\">{$lang['straddvacuumtable']}</a>"; - } - } -} - -function adminActions($action, $type) { - global $script; - - if ($type == 'database') { - $_REQUEST['object'] = $_REQUEST['database']; - $script = 'database.php'; - } else { - // $_REQUEST['table'] is no set if we are in the schema page - $_REQUEST['object'] = (isset($_REQUEST['table']) ? $_REQUEST['table'] : ''); - $script = 'tables.php'; - } - - switch ($action) { - case 'confirm_cluster': - doCluster($type, true); - break; - case 'confirm_reindex': - doReindex($type, true); - break; - case 'confirm_analyze': - doAnalyze($type, true); - break; - case 'confirm_vacuum': - doVacuum($type, true); - break; - case 'cluster': - if (isset($_POST['cluster'])) { - doCluster($type); - } - - // if multi-action from table canceled: back to the schema default page - else if (($type == 'table') && is_array($_REQUEST['object'])) { - doDefault(); - } else { - doAdmin($type); - } - - break; - case 'reindex': - if (isset($_POST['reindex'])) { - doReindex($type); - } - - // if multi-action from table canceled: back to the schema default page - else if (($type == 'table') && is_array($_REQUEST['object'])) { - doDefault(); - } else { - doAdmin($type); - } - - break; - case 'analyze': - if (isset($_POST['analyze'])) { - doAnalyze($type); - } - - // if multi-action from table canceled: back to the schema default page - else if (($type == 'table') && is_array($_REQUEST['object'])) { - doDefault(); - } else { - doAdmin($type); - } - - break; - case 'vacuum': - if (isset($_POST['vacuum'])) { - doVacuum($type); - } - - // if multi-action from table canceled: back to the schema default page - else if (($type == 'table') && is_array($_REQUEST['object'])) { - doDefault(); - } else { - doAdmin($type); - } - - break; - case 'admin': - doAdmin($type); - break; - case 'confeditautovac': - doEditAutovacuum($type, true); - break; - case 'confdelautovac': - doDropAutovacuum($type, true); - break; - case 'confaddautovac': - doAddAutovacuum(true); - break; - case 'editautovac': - if (isset($_POST['save'])) { - doEditAutovacuum($type, false); - } else { - doAdmin($type); - } - - break; - case 'delautovac': - doDropAutovacuum($type, false); - break; - default: - return false; - } - return true; -} diff --git a/src/views/aggregates.php b/src/views/aggregates.php index 878373d5..f6c51c9f 100644 --- a/src/views/aggregates.php +++ b/src/views/aggregates.php @@ -9,455 +9,50 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Actually creates the new aggregate in the database - */ -function doSaveCreate() { - global $data, $lang, $_reload_browser; - - // Check inputs - if (trim($_REQUEST['name']) == '') { - doCreate($lang['straggrneedsname']); - return; - } else if (trim($_REQUEST['basetype']) == '') { - doCreate($lang['straggrneedsbasetype']); - return; - } else if (trim($_REQUEST['sfunc']) == '') { - doCreate($lang['straggrneedssfunc']); - return; - } else if (trim($_REQUEST['stype']) == '') { - doCreate($lang['straggrneedsstype']); - return; - } - - $status = $data->createAggregate($_REQUEST['name'], $_REQUEST['basetype'], $_REQUEST['sfunc'], $_REQUEST['stype'], - $_REQUEST['ffunc'], $_REQUEST['initcond'], $_REQUEST['sortop'], $_REQUEST['aggrcomment']); - - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['straggrcreated']); - } else { - doCreate($lang['straggrcreatedbad']); - } -} - -/** - * Displays a screen for create a new aggregate function - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['basetype'])) { - $_REQUEST['basetype'] = ''; - } - - if (!isset($_REQUEST['sfunc'])) { - $_REQUEST['sfunc'] = ''; - } - - if (!isset($_REQUEST['stype'])) { - $_REQUEST['stype'] = ''; - } - - if (!isset($_REQUEST['ffunc'])) { - $_REQUEST['ffunc'] = ''; - } - - if (!isset($_REQUEST['initcond'])) { - $_REQUEST['initcond'] = ''; - } - - if (!isset($_REQUEST['sortop'])) { - $_REQUEST['sortop'] = ''; - } - - if (!isset($_REQUEST['aggrcomment'])) { - $_REQUEST['aggrcomment'] = ''; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateaggregate'], 'pg.aggregate.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/aggregates.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrbasetype']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"basetype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['basetype']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrsfunc']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"sfunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['sfunc']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['straggrstype']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"stype\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['stype']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrffunc']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"ffunc\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['ffunc']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrinitcond']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"initcond\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['initcond']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['straggrsortop']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"sortop\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['sortop']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"aggrcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['aggrcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Function to save after altering an aggregate - */ -function doSaveAlter() { - global $data, $lang; - - // Check inputs - if (trim($_REQUEST['aggrname']) == '') { - doAlter($lang['straggrneedsname']); - return; - } - - $status = $data->alterAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype'], $_REQUEST['aggrowner'], - $_REQUEST['aggrschema'], $_REQUEST['aggrcomment'], $_REQUEST['newaggrname'], $_REQUEST['newaggrowner'], - $_REQUEST['newaggrschema'], $_REQUEST['newaggrcomment']); - if ($status == 0) { - doDefault($lang['straggraltered']); - } else { - doAlter($lang['straggralteredbad']); - return; - } -} - -/** - * Function to allow editing an aggregate function - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('aggregate'); - $misc->printTitle($lang['stralter'], 'pg.aggregate.alter'); - $misc->printMsg($msg); - - echo "<form action=\"/views/aggregates.php\" method=\"post\">\n"; - $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']); - if ($aggrdata->recordCount() > 0) { - // Output table header - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data required\">{$lang['strname']}</th>"; - echo "<th class=\"data required\">{$lang['strowner']}</th>"; - echo "<th class=\"data required\">{$lang['strschema']}</th>\n\t</tr>\n"; - - // Display aggregate's name, owner and schema - echo "\t<tr>\n\t\t<td><input name=\"newaggrname\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" /></td>"; - echo "<td><input name=\"newaggrowner\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($aggrdata->fields['usename']), "\" /></td>"; - echo "<td><input name=\"newaggrschema\" size=\"32\" maxlength=\"32\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"newaggrcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($aggrdata->fields['aggrcomment']), "</textarea></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_alter\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n"; - echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n"; - echo "<input type=\"hidden\" name=\"aggrowner\" value=\"", htmlspecialchars($aggrdata->fields['usename']), "\" />\n"; - echo "<input type=\"hidden\" name=\"aggrschema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n"; - echo "<input type=\"hidden\" name=\"aggrcomment\" value=\"", htmlspecialchars($aggrdata->fields['aggrcomment']), "\" />\n"; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strback']}\" /></p>\n"; - } - echo "</form>\n"; -} - -/** - * Show confirmation of drop and perform actual drop of the aggregate function selected - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_browser; - - if ($confirm) { - $misc->printTrail('aggregate'); - $misc->printTitle($lang['strdrop'], 'pg.aggregate.drop'); - - echo "<p>", sprintf($lang['strconfdropaggregate'], htmlspecialchars($_REQUEST['aggrname'])), "</p>\n"; - - echo "<form action=\"/views/aggregates.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"aggrname\" value=\"", htmlspecialchars($_REQUEST['aggrname']), "\" />\n"; - echo "<input type=\"hidden\" name=\"aggrtype\" value=\"", htmlspecialchars($_REQUEST['aggrtype']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropAggregate($_POST['aggrname'], $_POST['aggrtype'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['straggregatedropped']); - } else { - doDefault($lang['straggregatedroppedbad']); - } - - } -} - -/** - * Show the properties of an aggregate - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('aggregate'); - $misc->printTitle($lang['strproperties'], 'pg.aggregate'); - $misc->printMsg($msg); - - $aggrdata = $data->getAggregate($_REQUEST['aggrname'], $_REQUEST['aggrtype']); - - if ($aggrdata->recordCount() > 0) { - // Display aggregate's info - echo "<table>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['strname']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($_REQUEST['aggrname']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrbasetype']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($_REQUEST['aggrtype']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrsfunc']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggtransfn']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrstype']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggstype']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrffunc']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggfinalfn']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrinitcond']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['agginitval']), "</td>\n</tr>\n"; - if ($data->hasAggregateSortOp()) { - echo "<tr>\n\t<th class=\"data left\">{$lang['straggrsortop']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['aggsortop']), "</td>\n</tr>\n"; - } - echo "<tr>\n\t<th class=\"data left\">{$lang['strowner']}</th>\n"; - echo "\t<td class=\"data1\">", htmlspecialchars($aggrdata->fields['usename']), "</td>\n</tr>\n"; - echo "<tr>\n\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t<td class=\"data1\">", $misc->printVal($aggrdata->fields['aggrcomment']), "</td>\n</tr>\n"; - echo "</table>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - $navlinks = [ - 'showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['straggrshowall'], - ], - ]; - - if ($data->hasAlterAggregate()) { - $navlinks['alter'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'action' => 'alter', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'aggrname' => $_REQUEST['aggrname'], - 'aggrtype' => $_REQUEST['aggrtype'], - ], - ], - ], - 'content' => $lang['stralter'], - ]; - } - - $navlinks['drop'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'aggrname' => $_REQUEST['aggrname'], - 'aggrtype' => $_REQUEST['aggrtype'], - ], - ], - ], - 'content' => $lang['strdrop'], - ]; - - $misc->printNavLinks($navlinks, 'aggregates-properties', get_defined_vars()); -} - -/** - * Show default list of aggregate functions in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'aggregates'); - $misc->printMsg($msg); - - $aggregates = $data->getAggregates(); - - $columns = [ - 'aggrname' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proname'), - 'url' => "/redirect/aggregate?action=properties&{$misc->href}&", - 'vars' => ['aggrname' => 'proname', 'aggrtype' => 'proargtypes'], - ], - 'aggrtype' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proargtypes'), - ], - 'aggrtransfn' => [ - 'title' => $lang['straggrsfunc'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('aggtransfn'), - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('aggrcomment'), - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'action' => 'alter', - 'aggrname' => \PHPPgAdmin\Decorators\Decorator::field('proname'), - 'aggrtype' => \PHPPgAdmin\Decorators\Decorator::field('proargtypes'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'aggrname' => \PHPPgAdmin\Decorators\Decorator::field('proname'), - 'aggrtype' => \PHPPgAdmin\Decorators\Decorator::field('proargtypes'), - ], - ], - ], - ], - ]; - - if (!$data->hasAlterAggregate()) { - unset($actions['alter']); - } - - echo $misc->printTable($aggregates, $columns, $actions, 'aggregates-aggregates', $lang['strnoaggregates']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'aggregates.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateaggregate'], - ], - ]; - $misc->printNavLinks($navlinks, 'aggregates-aggregates', get_defined_vars()); -} - $misc->printHeader($lang['straggregates']); $misc->printBody(); +$aggregate_controller = new \PHPPgAdmin\Controller\AggregateController($container); + switch ($action) { case 'create': - doCreate(); + $aggregate_controller->doCreate(); break; case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $aggregate_controller->doDefault(); } else { - doSaveCreate(); + $aggregate_controller->doSaveCreate(); } break; case 'alter': - doAlter(); + $aggregate_controller->doAlter(); break; case 'save_alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $aggregate_controller->doSaveAlter(); } else { - doProperties(); + $aggregate_controller->doProperties(); } break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $aggregate_controller->doDrop(false); } else { - doDefault(); + $aggregate_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $aggregate_controller->doDrop(true); break; default: - doDefault(); + $aggregate_controller->doDefault(); break; case 'properties': - doProperties(); + $aggregate_controller->doProperties(); break; } diff --git a/src/views/all_db.php b/src/views/all_db.php index da9aafcf..1e75659b 100644 --- a/src/views/all_db.php +++ b/src/views/all_db.php @@ -11,532 +11,31 @@ if (!defined('BASE_PATH')) { require_once '../lib.inc.php'; } -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Display a form for alter and perform actual alter - */ -function doAlter($confirm) { - global $data, $misc, $_reload_browser; - global $lang; - - if ($confirm) { - $misc->printTrail('database'); - $misc->printTitle($lang['stralter'], 'pg.database.alter'); - - echo "<form action=\"/views/all_db.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"newname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['alterdatabase']), "\" /></td></tr>\n"; - - if ($data->hasAlterDatabaseOwner() && $data->isSuperUser()) { - // Fetch all users - - $rs = $data->getDatabaseOwner($_REQUEST['alterdatabase']); - $owner = isset($rs->fields['usename']) ? $rs->fields['usename'] : ''; - $users = $data->getUsers(); - - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\"><select name=\"owner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $owner) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - } - if ($data->hasSharedComments()) { - $rs = $data->getDatabaseComment($_REQUEST['alterdatabase']); - $comment = isset($rs->fields['description']) ? $rs->fields['description'] : ''; - echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<textarea rows=\"3\" cols=\"32\" name=\"dbcomment\">", - htmlspecialchars($comment), "</textarea></td></tr>\n"; - } - echo "</table>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"oldname\" value=\"", - htmlspecialchars($_REQUEST['alterdatabase']), "\" />\n"; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - if (!isset($_POST['owner'])) { - $_POST['owner'] = ''; - } - - if (!isset($_POST['dbcomment'])) { - $_POST['dbcomment'] = ''; - } - - if ($data->alterDatabase($_POST['oldname'], $_POST['newname'], $_POST['owner'], $_POST['dbcomment']) == 0) { - $_reload_browser = true; - doDefault($lang['strdatabasealtered']); - } else { - doDefault($lang['strdatabasealteredbad']); - } - - } -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_drop_database; - - if (empty($_REQUEST['dropdatabase']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifydatabasetodrop']); - exit(); - } - - if ($confirm) { - - $misc->printTrail('database'); - $misc->printTitle($lang['strdrop'], 'pg.database.drop'); - - echo "<form action=\"/views/all_db.php\" method=\"post\">\n"; - //If multi drop - if (isset($_REQUEST['ma'])) { - - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($a['database'])), "</p>\n"; - printf('<input type="hidden" name="dropdatabase[]" value="%s" />', htmlspecialchars($a['database'])); - } - - } else { - echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($_REQUEST['dropdatabase'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"dropdatabase\" value=\"", htmlspecialchars($_REQUEST['dropdatabase']), "\" />\n"; - } // END if multi drop - - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END confirm - else { - //If multi drop - if (is_array($_REQUEST['dropdatabase'])) { - $msg = ''; - foreach ($_REQUEST['dropdatabase'] as $d) { - $status = $data->dropDatabase($d); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($d, ENT_QUOTES, 'UTF-8'), $lang['strdatabasedropped']); - } else { - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($d, ENT_QUOTES, 'UTF-8'), $lang['strdatabasedroppedbad'])); - return; - } - } // Everything went fine, back to Default page... - $_reload_drop_database = true; - doDefault($msg); - } else { - $status = $data->dropDatabase($_POST['dropdatabase']); - if ($status == 0) { - $_reload_drop_database = true; - doDefault($lang['strdatabasedropped']); - } else { - doDefault($lang['strdatabasedroppedbad']); - } - - } - } //END DROP -} // END FUNCTION - -/** - * Displays a screen where they can enter a new database - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('server'); - $misc->printTitle($lang['strcreatedatabase'], 'pg.database.create'); - $misc->printMsg($msg); - - if (!isset($_POST['formName'])) { - $_POST['formName'] = ''; - } - - // Default encoding is that in language file - if (!isset($_POST['formEncoding'])) { - $_POST['formEncoding'] = ''; - } - if (!isset($_POST['formTemplate'])) { - $_POST['formTemplate'] = 'template1'; - } - - if (!isset($_POST['formSpc'])) { - $_POST['formSpc'] = ''; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = ''; - } - - // Fetch a list of databases in the cluster - $templatedbs = $data->getDatabases(false); - - // Fetch all tablespaces from the database - if ($data->hasTablespaces()) { - $tablespaces = $data->getTablespaces(); - } - - echo "<form action=\"/views/all_db.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; - - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strtemplatedb']}</th>\n"; - echo "\t\t<td class=\"data1\">\n"; - echo "\t\t\t<select name=\"formTemplate\">\n"; - // Always offer template0 and template1 - echo "\t\t\t\t<option value=\"template0\"", - ($_POST['formTemplate'] == 'template0') ? ' selected="selected"' : '', ">template0</option>\n"; - echo "\t\t\t\t<option value=\"template1\"", - ($_POST['formTemplate'] == 'template1') ? ' selected="selected"' : '', ">template1</option>\n"; - while (!$templatedbs->EOF) { - $dbname = htmlspecialchars($templatedbs->fields['datname']); - if ($dbname != 'template1') { - // filter out for $conf[show_system] users so we dont get duplicates - echo "\t\t\t\t<option value=\"{$dbname}\"", - ($dbname == $_POST['formTemplate']) ? ' selected="selected"' : '', ">{$dbname}</option>\n"; - } - $templatedbs->moveNext(); - } - echo "\t\t\t</select>\n"; - echo "\t\t</td>\n\t</tr>\n"; - - // ENCODING - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strencoding']}</th>\n"; - echo "\t\t<td class=\"data1\">\n"; - echo "\t\t\t<select name=\"formEncoding\">\n"; - echo "\t\t\t\t<option value=\"\"></option>\n"; - while (list($key) = each($data->codemap)) { - echo "\t\t\t\t<option value=\"", htmlspecialchars($key), "\"", - ($key == $_POST['formEncoding']) ? ' selected="selected"' : '', ">", - $misc->printVal($key), "</option>\n"; - } - echo "\t\t\t</select>\n"; - echo "\t\t</td>\n\t</tr>\n"; - - if ($data->hasDatabaseCollation()) { - if (!isset($_POST['formCollate'])) { - $_POST['formCollate'] = ''; - } - - if (!isset($_POST['formCType'])) { - $_POST['formCType'] = ''; - } - - // LC_COLLATE - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcollation']}</th>\n"; - echo "\t\t<td class=\"data1\">\n"; - echo "\t\t\t<input name=\"formCollate\" value=\"", htmlspecialchars($_POST['formCollate']), "\" />\n"; - echo "\t\t</td>\n\t</tr>\n"; - - // LC_CTYPE - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strctype']}</th>\n"; - echo "\t\t<td class=\"data1\">\n"; - echo "\t\t\t<input name=\"formCType\" value=\"", htmlspecialchars($_POST['formCType']), "\" />\n"; - echo "\t\t</td>\n\t</tr>\n"; - } - - // Tablespace (if there are any) - if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; - echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formSpc\">\n"; - // Always offer the default (empty) option - echo "\t\t\t\t<option value=\"\"", - ($_POST['formSpc'] == '') ? ' selected="selected"' : '', "></option>\n"; - // Display all other tablespaces - while (!$tablespaces->EOF) { - $spcname = htmlspecialchars($tablespaces->fields['spcname']); - echo "\t\t\t\t<option value=\"{$spcname}\"", - ($spcname == $_POST['formSpc']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; - $tablespaces->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; - } - - // Comments (if available) - if ($data->hasSharedComments()) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; - } - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new view in the database - */ -function doSaveCreate() { - global $data, $lang, $_reload_browser; - - // Default tablespace to null if it isn't set - if (!isset($_POST['formSpc'])) { - $_POST['formSpc'] = null; - } - - // Default comment to blank if it isn't set - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = null; - } - - // Default collate to blank if it isn't set - if (!isset($_POST['formCollate'])) { - $_POST['formCollate'] = null; - } - - // Default ctype to blank if it isn't set - if (!isset($_POST['formCType'])) { - $_POST['formCType'] = null; - } - - // Check that they've given a name and a definition - if ($_POST['formName'] == '') { - doCreate($lang['strdatabaseneedsname']); - } else { - $status = $data->createDatabase($_POST['formName'], $_POST['formEncoding'], $_POST['formSpc'], - $_POST['formComment'], $_POST['formTemplate'], $_POST['formCollate'], $_POST['formCType']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strdatabasecreated']); - } else { - doCreate($lang['strdatabasecreatedbad']); - } - - } -} - -/** - * Displays options for cluster download - */ -function doExport($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('server'); - $misc->printTabs('server', 'export'); - $misc->printMsg($msg); - - echo "<form action=\"/views/dbexport.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\">{$lang['stroptions']}</th></tr>\n"; - // Data only - echo "<tr><th class=\"data left\" rowspan=\"2\">"; - echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; - echo "<td>{$lang['strformat']}\n"; - echo "<select name=\"d_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /><label for=\"d_oids\">{$lang['stroids']}</label></td>\n</tr>\n"; - // Structure only - echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; - echo "<td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /><label for=\"s_clean\">{$lang['strdrop']}</label></td>\n</tr>\n"; - // Structure and data - echo "<tr><th class=\"data left\" rowspan=\"3\">"; - echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; - echo "<td>{$lang['strformat']}\n"; - echo "<select name=\"sd_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /><label for=\"sd_clean\">{$lang['strdrop']}</label></td>\n</tr>\n"; - echo "<tr><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /><label for=\"sd_oids\">{$lang['stroids']}</label></td>\n</tr>\n"; - echo "</table>\n"; - - echo "<h3>{$lang['stroptions']}</h3>\n"; - echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; - echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"server\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Show default list of databases in the server - */ -function doDefault($msg = '') { - global $conf, $misc; - global $lang; - - $misc->printTrail('server'); - $misc->printTabs('server', 'databases'); - $misc->printMsg($msg); - $data = $misc->getDatabaseAccessor(); - $databases = $data->getDatabases(); - - $columns = [ - 'database' => [ - 'title' => $lang['strdatabase'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datname'), - 'url' => "/redirect/database?{$misc->href}&", - 'vars' => ['database' => 'datname'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datowner'), - ], - 'encoding' => [ - 'title' => $lang['strencoding'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datencoding'), - ], - 'lc_collate' => [ - 'title' => $lang['strcollation'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datcollate'), - ], - 'lc_ctype' => [ - 'title' => $lang['strctype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datctype'), - ], - 'tablespace' => [ - 'title' => $lang['strtablespace'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('tablespace'), - ], - 'dbsize' => [ - 'title' => $lang['strsize'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('dbsize'), - 'type' => 'prettysize', - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('datcomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['database' => 'datname'], - 'url' => 'all_db.php', - 'default' => null, - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'all_db.php', - 'urlvars' => [ - 'subject' => 'database', - 'action' => 'confirm_drop', - 'dropdatabase' => \PHPPgAdmin\Decorators\Decorator::field('datname'), - ], - ], - ], - 'multiaction' => 'confirm_drop', - ], - 'privileges' => [ - 'content' => $lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges.php', - 'urlvars' => [ - 'subject' => 'database', - 'database' => \PHPPgAdmin\Decorators\Decorator::field('datname'), - ], - ], - ], - ], - ]; - if ($data->hasAlterDatabase()) { - $actions['alter'] = [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'all_db.php', - 'urlvars' => [ - 'subject' => 'database', - 'action' => 'confirm_alter', - 'alterdatabase' => \PHPPgAdmin\Decorators\Decorator::field('datname'), - ], - ], - ], - ]; - } - - if (!$data->hasTablespaces()) { - unset($columns['tablespace']); - } - - if (!$data->hasServerAdminFuncs()) { - unset($columns['dbsize']); - } - - if (!$data->hasDatabaseCollation()) { - unset($columns['lc_collate'], $columns['lc_ctype']); - } - - if (!isset($data->privlist['database'])) { - unset($actions['privileges']); - } - - echo $misc->printTable($databases, $columns, $actions, 'all_db-databases', $lang['strnodatabases']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'all_db.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - ], - ], - ], - 'content' => $lang['strcreatedatabase'], - ], - ]; - $misc->printNavLinks($navlinks, 'all_db-databases', get_defined_vars()); - -} +$all_db_controller = new \PHPPgAdmin\Controller\AllDBController($container); $misc->printHeader($lang['strdatabases']); $misc->printBody(); switch ($action) { case 'export': - doExport(); + $all_db_controller->doExport(); break; case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $all_db_controller->doDefault(); } else { - doSaveCreate(); + $all_db_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $all_db_controller->doCreate(); break; case 'drop': if (isset($_REQUEST['drop'])) { - doDrop(false); + $all_db_controller->doDrop(false); } else { - doDefault(); + $all_db_controller->doDefault(); } break; @@ -545,17 +44,17 @@ switch ($action) { break; case 'alter': if (isset($_POST['oldname']) && isset($_POST['newname']) && !isset($_POST['cancel'])) { - doAlter(false); + $all_db_controller->doAlter(false); } else { - doDefault(); + $all_db_controller->doDefault(); } break; case 'confirm_alter': - doAlter(true); + $all_db_controller->doAlter(true); break; default: - doDefault(); + $all_db_controller->doDefault(); break; } diff --git a/src/views/casts.php b/src/views/casts.php index dca5bb25..b46b7d56 100644 --- a/src/views/casts.php +++ b/src/views/casts.php @@ -9,63 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show default list of casts in the database - */ -function doDefault($msg = '') { - global $data, $misc, $database; - global $lang; - - function renderCastContext($val) { - global $lang; - switch ($val) { - case 'e':return $lang['strno']; - case 'a':return $lang['strinassignment']; - default:return $lang['stryes']; - } - } - - $misc->printTrail('database'); - $misc->printTabs('database', 'casts'); - $misc->printMsg($msg); - - $casts = $data->getCasts(); - - $columns = [ - 'source_type' => [ - 'title' => $lang['strsourcetype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('castsource'), - ], - 'target_type' => [ - 'title' => $lang['strtargettype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('casttarget'), - ], - 'function' => [ - 'title' => $lang['strfunction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('castfunc'), - 'params' => ['null' => $lang['strbinarycompat']], - ], - 'implicit' => [ - 'title' => $lang['strimplicit'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('castcontext'), - 'type' => 'callback', - 'params' => ['function' => 'renderCastContext', 'align' => 'center'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('castcomment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($casts, $columns, $actions, 'casts-casts', $lang['strnocasts']); -} +$cast_controller = new \PHPPgAdmin\Controller\CastController($container); $misc->printHeader($lang['strcasts']); $misc->printBody(); @@ -73,7 +17,7 @@ $misc->printBody(); switch ($action) { default: - doDefault(); + $cast_controller->doDefault(); break; } diff --git a/src/views/colproperties.php b/src/views/colproperties.php index 30724166..1b504422 100644 --- a/src/views/colproperties.php +++ b/src/views/colproperties.php @@ -9,7 +9,6 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; if (isset($_REQUEST['table'])) { $tableName = &$_REQUEST['table']; } elseif (isset($_REQUEST['view'])) { @@ -18,343 +17,25 @@ if (isset($_REQUEST['table'])) { die($lang['strnotableprovided']); } -/** - * Displays a screen where they can alter a column - */ -function doAlter($msg = '') { - global $data, $misc, $_reload_browser; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - switch ($_REQUEST['stage']) { - case 1: - $misc->printTrail('column'); - $misc->printTitle($lang['stralter'], 'pg.column.alter'); - $misc->printMsg($msg); - - echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; - echo "<form action=\"/views/colproperties.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n"; - if ($data->hasAlterColumnType()) { - echo "<th class=\"data required\" colspan=\"2\">{$lang['strtype']}</th>\n"; - echo "<th class=\"data\">{$lang['strlength']}</th>\n"; - } else { - echo "<th class=\"data required\">{$lang['strtype']}</th>\n"; - } - echo "<th class=\"data\">{$lang['strnotnull']}</th>\n<th class=\"data\">{$lang['strdefault']}</th>\n<th class=\"data\">{$lang['strcomment']}</th></tr>\n"; - - $column = $data->getTableAttributes($_REQUEST['table'], $_REQUEST['column']); - $column->fields['attnotnull'] = $data->phpBool($column->fields['attnotnull']); - - // Upon first drawing the screen, load the existing column information - // from the database. - if (!isset($_REQUEST['default'])) { - $_REQUEST['field'] = $column->fields['attname']; - $_REQUEST['type'] = $column->fields['base_type']; - // Check to see if its' an array type... - // XXX: HACKY - if (substr($column->fields['base_type'], strlen($column->fields['base_type']) - 2) == '[]') { - $_REQUEST['type'] = substr($column->fields['base_type'], 0, strlen($column->fields['base_type']) - 2); - $_REQUEST['array'] = '[]'; - } else { - $_REQUEST['type'] = $column->fields['base_type']; - $_REQUEST['array'] = ''; - } - // To figure out the length, look in the brackets :( - // XXX: HACKY - if ($column->fields['type'] != $column->fields['base_type'] && preg_match('/\\(([0-9, ]*)\\)/', $column->fields['type'], $bits)) { - $_REQUEST['length'] = $bits[1]; - } else { - $_REQUEST['length'] = ''; - } - - $_REQUEST['default'] = $_REQUEST['olddefault'] = $column->fields['adsrc']; - if ($column->fields['attnotnull']) { - $_REQUEST['notnull'] = 'YES'; - } - - $_REQUEST['comment'] = $column->fields['comment']; - } - - // Column name - echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['field']), "\" /></td>\n"; - - // Column type - $escaped_predef_types = []; // the JS escaped array elements - if ($data->hasAlterColumnType()) { - // Fetch all available types - $types = $data->getTypes(true, false, true); - $types_for_js = []; - - echo "<td><select name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">\n"; - while (!$types->EOF) { - $typname = $types->fields['typname']; - $types_for_js[] = $typname; - echo "\t<option value=\"", htmlspecialchars($typname), "\"", ($typname == $_REQUEST['type']) ? ' selected="selected"' : '', ">", - $misc->printVal($typname), "</option>\n"; - $types->moveNext(); - } - echo "</select>\n"; - echo "<script>jQuery('#type').select2();</script>\n"; - echo "</td>\n"; - - // Output array type selector - echo "<td><select name=\"array\">\n"; - echo "\t<option value=\"\"", ($_REQUEST['array'] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "\t<option value=\"[]\"", ($_REQUEST['array'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "</select></td>\n"; - $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js); - foreach ($predefined_size_types as $value) { - $escaped_predef_types[] = "'{$value}'"; - } - - echo "<td><input name=\"length\" id=\"lengths\" size=\"8\" value=\"", - htmlspecialchars($_REQUEST['length']), "\" /></td>\n"; - } else { - // Otherwise draw the read-only type name - echo "<td>", $misc->printVal($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "</td>\n"; - } - - echo "<td><input type=\"checkbox\" name=\"notnull\"", (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', " /></td>\n"; - echo "<td><input name=\"default\" size=\"20\" value=\"", - htmlspecialchars($_REQUEST['default']), "\" /></td>\n"; - echo "<td><input name=\"comment\" size=\"40\" value=\"", - htmlspecialchars($_REQUEST['comment']), "\" /></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"properties\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; - echo "<input type=\"hidden\" name=\"olddefault\" value=\"", htmlspecialchars($_REQUEST['olddefault']), "\" />\n"; - if ($column->fields['attnotnull']) { - echo "<input type=\"hidden\" name=\"oldnotnull\" value=\"on\" />\n"; - } - - echo "<input type=\"hidden\" name=\"oldtype\" value=\"", htmlspecialchars($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "\" />\n"; - // Add hidden variables to suppress error notices if we don't support altering column type - if (!$data->hasAlterColumnType()) { - echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; - echo "<input type=\"hidden\" name=\"length\" value=\"", htmlspecialchars($_REQUEST['length']), "\" />\n"; - echo "<input type=\"hidden\" name=\"array\" value=\"", htmlspecialchars($_REQUEST['array']), "\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>\n"; - break; - case 2: - // Check inputs - if (trim($_REQUEST['field']) == '') { - $_REQUEST['stage'] = 1; - doAlter($lang['strcolneedsname']); - return; - } - if (!isset($_REQUEST['length'])) { - $_REQUEST['length'] = ''; - } - - $status = $data->alterColumn($_REQUEST['table'], $_REQUEST['column'], $_REQUEST['field'], - isset($_REQUEST['notnull']), isset($_REQUEST['oldnotnull']), - $_REQUEST['default'], $_REQUEST['olddefault'], - $_REQUEST['type'], $_REQUEST['length'], $_REQUEST['array'], $_REQUEST['oldtype'], - $_REQUEST['comment']); - if ($status == 0) { - if ($_REQUEST['column'] != $_REQUEST['field']) { - $_REQUEST['column'] = $_REQUEST['field']; - $_reload_browser = true; - } - doDefault($lang['strcolumnaltered']); - } else { - $_REQUEST['stage'] = 1; - doAlter($lang['strcolumnalteredbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Show default list of columns in the table - */ -function doDefault($msg = '', $isTable = true) { - global $data, $conf, $misc, $tableName; - global $lang; - - function attPre(&$rowdata) { - global $data; - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - } - - if (empty($_REQUEST['column'])) { - $msg .= "<br/>{$lang['strnoobjects']}"; - } - - $misc->printTrail('column'); - //$misc->printTitle($lang['strcolprop']); - $misc->printTabs('column', 'properties'); - $misc->printMsg($msg); - - if (!empty($_REQUEST['column'])) { - // Get table - $tdata = $data->getTable($tableName); - // Get columns - $attrs = $data->getTableAttributes($tableName, $_REQUEST['column']); - - // Show comment if any - if ($attrs->fields['comment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($attrs->fields['comment']), "</p>\n"; - } - - $column = [ - 'column' => [ - 'title' => $lang['strcolumn'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+type'), - ], - ]; - - if ($isTable) { - $column['notnull'] = [ - 'title' => $lang['strnotnull'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attnotnull'), - 'type' => 'bool', - 'params' => ['true' => 'NOT NULL', 'false' => ''], - ]; - $column['default'] = [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('adsrc'), - ]; - } - - $actions = []; - echo $misc->printTable($attrs, $column, $actions, 'colproperties-colproperties', null, 'attPre'); - - echo "<br />\n"; - - $f_attname = $_REQUEST['column']; - $f_table = $tableName; - $f_schema = $data->_schema; - $data->fieldClean($f_attname); - $data->fieldClean($f_table); - $data->fieldClean($f_schema); - $query = "SELECT \"{$f_attname}\", count(*) AS \"count\" FROM \"{$f_schema}\".\"{$f_table}\" GROUP BY \"{$f_attname}\" ORDER BY \"{$f_attname}\""; - - if ($isTable) { - - /* Browse link */ - /* FIXME browsing a col should somehow be a action so we don't - * send an ugly SQL in the URL */ - - $navlinks = [ - 'browse' => [ - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'subject' => 'column', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $tableName, - 'column' => $_REQUEST['column'], - 'return' => 'column', - 'query' => $query, - ], - ], - ], - 'content' => $lang['strbrowse'], - ], - 'alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'colproperties.php', - 'urlvars' => [ - 'action' => 'properties', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $tableName, - 'column' => $_REQUEST['column'], - ], - ], - ], - 'content' => $lang['stralter'], - ], - 'drop' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $tableName, - 'column' => $_REQUEST['column'], - ], - ], - ], - 'content' => $lang['strdrop'], - ], - ]; - } else { - /* Browse link */ - $navlinks = [ - 'browse' => [ - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'subject' => 'column', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $tableName, - 'column' => $_REQUEST['column'], - 'return' => 'column', - 'query' => $query, - ], - ], - ], - 'content' => $lang['strbrowse'], - ], - ]; - } - - $misc->printNavLinks($navlinks, 'colproperties-colproperties', get_defined_vars()); - } -} +$colproperty_controller = new \PHPPgAdmin\Controller\ColPropertyController($container); $misc->printHeader($lang['strtables'] . ' - ' . $tableName); $misc->printBody(); if (isset($_REQUEST['view'])) { - doDefault(null, false); + $colproperty_controller->doDefault(null, false); } else { switch ($action) { case 'properties': if (isset($_POST['cancel'])) { - doDefault(); + $colproperty_controller->doDefault(); } else { - doAlter(); + $colproperty_controller->doAlter(); } break; default: - doDefault(); + $colproperty_controller->doDefault(); break; } } diff --git a/src/views/constraints.php b/src/views/constraints.php index 8b28eb85..53ba58d8 100644 --- a/src/views/constraints.php +++ b/src/views/constraints.php @@ -9,601 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Confirm and then actually add a FOREIGN KEY constraint - */ -function addForeignKey($stage, $msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['target'])) { - $_POST['target'] = ''; - } - - switch ($stage) { - case 2: - // Check that they've given at least one source column - if (!isset($_REQUEST['SourceColumnList']) && (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) || sizeof($_POST['IndexColumnList']) == 0)) { - addForeignKey(1, $lang['strfkneedscols']); - } else { - // Copy the IndexColumnList variable from stage 1 - if (isset($_REQUEST['IndexColumnList']) && !isset($_REQUEST['SourceColumnList'])) { - $_REQUEST['SourceColumnList'] = serialize($_REQUEST['IndexColumnList']); - } - - // Initialise variables - if (!isset($_POST['upd_action'])) { - $_POST['upd_action'] = null; - } - - if (!isset($_POST['del_action'])) { - $_POST['del_action'] = null; - } - - if (!isset($_POST['match'])) { - $_POST['match'] = null; - } - - if (!isset($_POST['deferrable'])) { - $_POST['deferrable'] = null; - } - - if (!isset($_POST['initially'])) { - $_POST['initially'] = null; - } - - $_REQUEST['target'] = unserialize($_REQUEST['target']); - - $misc->printTrail('table'); - $misc->printTitle($lang['straddfk'], 'pg.constraint.foreign_key'); - $misc->printMsg($msg); - - // Unserialize target and fetch appropriate table. This is a bit messy - // because the table could be in another schema. - $data->setSchema($_REQUEST['target']['schemaname']); - $attrs = $data->getTableAttributes($_REQUEST['target']['tablename']); - $data->setSchema($_REQUEST['schema']); - - $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); - $selColumns->set_style('width: 15em;'); - - if ($attrs->recordCount() > 0) { - while (!$attrs->EOF) { - $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); - $attrs->moveNext(); - } - } - - $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); - $selIndex->set_style('width: 15em;'); - $selIndex->set_attribute('id', 'IndexColumnList'); - $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); - $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); - $buttonAdd->set_attribute('type', 'button'); - - $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); - $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); - $buttonRemove->set_attribute('type', 'button'); - - echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; - - echo "<table>\n"; - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strfktarget']}</th></tr>"; - echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=data>{$lang['strfkcolumnlist']}</th></tr>\n"; - echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; - echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; - echo "<td class=\"data1\">" . $selIndex->fetch() . "</td></tr>\n"; - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['stractions']}</th></tr>"; - echo "<tr>"; - echo "<td class=\"data1\" colspan=\"3\">\n"; - // ON SELECT actions - echo "{$lang['stronupdate']} <select name=\"upd_action\">"; - foreach ($data->fkactions as $v) { - echo "<option value=\"{$v}\"", ($_POST['upd_action'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - - echo "</select><br />\n"; - - // ON DELETE actions - echo "{$lang['strondelete']} <select name=\"del_action\">"; - foreach ($data->fkactions as $v) { - echo "<option value=\"{$v}\"", ($_POST['del_action'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - - echo "</select><br />\n"; - - // MATCH options - echo "<select name=\"match\">"; - foreach ($data->fkmatches as $v) { - echo "<option value=\"{$v}\"", ($_POST['match'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - - echo "</select><br />\n"; - - // DEFERRABLE options - echo "<select name=\"deferrable\">"; - foreach ($data->fkdeferrable as $v) { - echo "<option value=\"{$v}\"", ($_POST['deferrable'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - - echo "</select><br />\n"; - - // INITIALLY options - echo "<select name=\"initially\">"; - foreach ($data->fkinitial as $v) { - echo "<option value=\"{$v}\"", ($_POST['initially'] == $v) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - - echo "</select>\n"; - echo "</td></tr>\n"; - echo "</table>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_foreign_key\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"target\" value=\"", htmlspecialchars(serialize($_REQUEST['target'])), "\" />\n"; - echo "<input type=\"hidden\" name=\"SourceColumnList\" value=\"", htmlspecialchars($_REQUEST['SourceColumnList']), "\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } - break; - case 3: - // Unserialize target - $_POST['target'] = unserialize($_POST['target']); - - // Check that they've given at least one column - if (isset($_POST['SourceColumnList'])) { - $temp = unserialize($_POST['SourceColumnList']); - } - - if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) - || sizeof($_POST['IndexColumnList']) == 0 || !isset($temp) - || !is_array($temp) || sizeof($temp) == 0) { - addForeignKey(2, $lang['strfkneedscols']); - } else { - $status = $data->addForeignKey($_POST['table'], $_POST['target']['schemaname'], $_POST['target']['tablename'], - unserialize($_POST['SourceColumnList']), $_POST['IndexColumnList'], $_POST['upd_action'], $_POST['del_action'], - $_POST['match'], $_POST['deferrable'], $_POST['initially'], $_POST['name']); - if ($status == 0) { - doDefault($lang['strfkadded']); - } else { - addForeignKey(2, $lang['strfkaddedbad']); - } - - } - break; - default: - $misc->printTrail('table'); - $misc->printTitle($lang['straddfk'], 'pg.constraint.foreign_key'); - $misc->printMsg($msg); - - $attrs = $data->getTableAttributes($_REQUEST['table']); - $tables = $data->getTables(true); - - $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); - $selColumns->set_style('width: 15em;'); - - if ($attrs->recordCount() > 0) { - while (!$attrs->EOF) { - $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); - $attrs->moveNext(); - } - } - - $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); - $selIndex->set_style('width: 15em;'); - $selIndex->set_attribute('id', 'IndexColumnList'); - $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); - $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); - $buttonAdd->set_attribute('type', 'button'); - - $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); - $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); - $buttonRemove->set_attribute('type', 'button'); - - echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; - - echo "<table>\n"; - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strname']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" /></td></tr>\n"; - echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=\"data required\">{$lang['strfkcolumnlist']}</th></tr>\n"; - echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; - echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>\n"; - echo "<td class=data1>" . $selIndex->fetch() . "</td></tr>\n"; - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strfktarget']}</th></tr>"; - echo "<tr>"; - echo "<td class=\"data1\" colspan=\"3\"><select name=\"target\">"; - while (!$tables->EOF) { - $key = ['schemaname' => $tables->fields['nspname'], 'tablename' => $tables->fields['relname']]; - $key = serialize($key); - echo "<option value=\"", htmlspecialchars($key), "\">"; - if ($tables->fields['nspname'] != $_REQUEST['schema']) { - echo htmlspecialchars($tables->fields['nspname']), '.'; - } - echo htmlspecialchars($tables->fields['relname']), "</option>\n"; - $tables->moveNext(); - } - echo "</select>\n"; - echo "</td></tr>"; - echo "</table>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_foreign_key\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - } - -} - -/** - * Confirm and then actually add a PRIMARY KEY or UNIQUE constraint - */ -function addPrimaryOrUniqueKey($type, $confirm, $msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if ($confirm) { - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['tablespace'])) { - $_POST['tablespace'] = ''; - } - - $misc->printTrail('table'); - - switch ($type) { - case 'primary': - $misc->printTitle($lang['straddpk'], 'pg.constraint.primary_key'); - break; - case 'unique': - $misc->printTitle($lang['stradduniq'], 'pg.constraint.unique_key'); - break; - default: - doDefault($lang['strinvalidparam']); - return; - } - - $misc->printMsg($msg); - - $attrs = $data->getTableAttributes($_REQUEST['table']); - // Fetch all tablespaces from the database - if ($data->hasTablespaces()) { - $tablespaces = $data->getTablespaces(); - } - - $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select('TableColumnList', true, 10); - $selColumns->set_style('width: 15em;'); - - if ($attrs->recordCount() > 0) { - while (!$attrs->EOF) { - $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); - $attrs->moveNext(); - } - } - - $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select('IndexColumnList[]', true, 10); - $selIndex->set_style('width: 15em;'); - $selIndex->set_attribute('id', 'IndexColumnList'); - $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button('add', '>>'); - $buttonAdd->set_attribute('onclick', 'buttonPressed(this);'); - $buttonAdd->set_attribute('type', 'button'); - - $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button('remove', '<<'); - $buttonRemove->set_attribute('onclick', 'buttonPressed(this);'); - $buttonRemove->set_attribute('type', 'button'); - - echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"constraints.php\" method=\"post\">\n"; - - echo "<table>\n"; - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strname']}</th></tr>"; - echo "<tr>"; - echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), - "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" /></td></tr>"; - echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th><th class=\"data required\">{$lang['strindexcolumnlist']}</th></tr>\n"; - echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; - echo "<td class=\"data1\" style=\"text-align: center\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; - echo "<td class=data1>" . $selIndex->fetch() . "</td></tr>\n"; - - // Tablespace (if there are any) - if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { - echo "<tr><th class=\"data\" colspan=\"3\">{$lang['strtablespace']}</th></tr>"; - echo "<tr><td class=\"data1\" colspan=\"3\"><select name=\"tablespace\">\n"; - // Always offer the default (empty) option - echo "\t\t\t\t<option value=\"\"", - ($_POST['tablespace'] == '') ? ' selected="selected"' : '', "></option>\n"; - // Display all other tablespaces - while (!$tablespaces->EOF) { - $spcname = htmlspecialchars($tablespaces->fields['spcname']); - echo "\t\t\t\t<option value=\"{$spcname}\"", - ($spcname == $_POST['tablespace']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; - $tablespaces->moveNext(); - } - echo "</select></td></tr>\n"; - } - - echo "</table>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_primary_key\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($type), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - // Default tablespace to empty if it isn't set - if (!isset($_POST['tablespace'])) { - $_POST['tablespace'] = ''; - } - - if ($_POST['type'] == 'primary') { - // Check that they've given at least one column - if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) - || sizeof($_POST['IndexColumnList']) == 0) { - addPrimaryOrUniqueKey($_POST['type'], true, $lang['strpkneedscols']); - } else { - $status = $data->addPrimaryKey($_POST['table'], $_POST['IndexColumnList'], $_POST['name'], $_POST['tablespace']); - if ($status == 0) { - doDefault($lang['strpkadded']); - } else { - addPrimaryOrUniqueKey($_POST['type'], true, $lang['strpkaddedbad']); - } - - } - } elseif ($_POST['type'] == 'unique') { - // Check that they've given at least one column - if (!isset($_POST['IndexColumnList']) || !is_array($_POST['IndexColumnList']) - || sizeof($_POST['IndexColumnList']) == 0) { - addPrimaryOrUniqueKey($_POST['type'], true, $lang['struniqneedscols']); - } else { - $status = $data->addUniqueKey($_POST['table'], $_POST['IndexColumnList'], $_POST['name'], $_POST['tablespace']); - if ($status == 0) { - doDefault($lang['struniqadded']); - } else { - addPrimaryOrUniqueKey($_POST['type'], true, $lang['struniqaddedbad']); - } - - } - } else { - doDefault($lang['strinvalidparam']); - } - - } -} - -/** - * Confirm and then actually add a CHECK constraint - */ -function addCheck($confirm, $msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['definition'])) { - $_POST['definition'] = ''; - } - - if ($confirm) { - $misc->printTrail('table'); - $misc->printTitle($lang['straddcheck'], 'pg.constraint.check'); - $misc->printMsg($msg); - - echo "<form action=\"/views/constraints.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; - echo "<th class=\"data required\">{$lang['strdefinition']}</th></tr>\n"; - - echo "<tr><td class=\"data1\"><input name=\"name\" size=\"24\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" /></td>\n"; - - echo "<td class=\"data1\">(<input name=\"definition\" size=\"64\" value=\"", - htmlspecialchars($_POST['definition']), "\" />)</td></tr>\n"; - echo "</table>\n"; - - echo "<input type=\"hidden\" name=\"action\" value=\"save_add_check\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"submit\" name=\"ok\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - } else { - if (trim($_POST['definition']) == '') { - addCheck(true, $lang['strcheckneedsdefinition']); - } else { - $status = $data->addCheckConstraint($_POST['table'], - $_POST['definition'], $_POST['name']); - if ($status == 0) { - doDefault($lang['strcheckadded']); - } else { - addCheck(true, $lang['strcheckaddedbad']); - } - - } - } -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('constraint'); - $misc->printTitle($lang['strdrop'], 'pg.constraint.drop'); - - echo "<p>", sprintf($lang['strconfdropconstraint'], $misc->printVal($_REQUEST['constraint']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/constraints.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"constraint\" value=\"", htmlspecialchars($_REQUEST['constraint']), "\" />\n"; - echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropConstraint($_POST['constraint'], $_POST['table'], $_POST['type'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strconstraintdropped']); - } else { - doDefault($lang['strconstraintdroppedbad']); - } - - } -} - -/** - * List all the constraints on the table - */ -function doDefault($msg = '') { - global $data, $misc, $lang; - - function cnPre(&$rowdata) { - global $data; - if (is_null($rowdata->fields['consrc'])) { - $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $rowdata->fields['indkey'])); - $rowdata->fields['+definition'] = ($rowdata->fields['contype'] == 'u' ? "UNIQUE (" : "PRIMARY KEY (") . join(',', $atts) . ')'; - } else { - $rowdata->fields['+definition'] = $rowdata->fields['consrc']; - } - } - - $misc->printTrail('table'); - $misc->printTabs('table', 'constraints'); - $misc->printMsg($msg); - - $constraints = $data->getConstraints($_REQUEST['table']); - - $columns = [ - 'constraint' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+definition'), - 'type' => 'pre', - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('constcomment'), - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'table' => $_REQUEST['table'], - 'constraint' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - 'type' => \PHPPgAdmin\Decorators\Decorator::field('contype'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($constraints, $columns, $actions, 'constraints-constraints', $lang['strnoconstraints'], 'cnPre'); - - $navlinks = [ - 'addcheck' => [ - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'action' => 'add_check', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['straddcheck'], - ], - 'adduniq' => [ - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'action' => 'add_unique_key', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['stradduniq'], - ], - 'addpk' => [ - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'action' => 'add_primary_key', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['straddpk'], - ], - 'addfk' => [ - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'action' => 'add_foreign_key', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['straddfk'], - ], - ]; - $misc->printNavLinks($navlinks, 'constraints-constraints', get_defined_vars()); -} +$constraint_controller = new \PHPPgAdmin\Controller\ConstraintController($container); $misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table'] . ' - ' . $lang['strconstraints'], "<script src=\"/js/indexes.js\" type=\"text/javascript\"></script>"); @@ -618,68 +24,68 @@ if ($action == 'add_unique_key' || $action == 'save_add_unique_key' switch ($action) { case 'add_foreign_key': - addForeignKey(1); + $constraint_controller->addForeignKey(1); break; case 'save_add_foreign_key': if (isset($_POST['cancel'])) { - doDefault(); + $constraint_controller->doDefault(); } else { - addForeignKey($_REQUEST['stage']); + $constraint_controller->addForeignKey($_REQUEST['stage']); } break; case 'add_unique_key': - addPrimaryOrUniqueKey('unique', true); + $constraint_controller->addPrimaryOrUniqueKey('unique', true); break; case 'save_add_unique_key': if (isset($_POST['cancel'])) { - doDefault(); + $constraint_controller->doDefault(); } else { - addPrimaryOrUniqueKey('unique', false); + $constraint_controller->addPrimaryOrUniqueKey('unique', false); } break; case 'add_primary_key': - addPrimaryOrUniqueKey('primary', true); + $constraint_controller->addPrimaryOrUniqueKey('primary', true); break; case 'save_add_primary_key': if (isset($_POST['cancel'])) { - doDefault(); + $constraint_controller->doDefault(); } else { - addPrimaryOrUniqueKey('primary', false); + $constraint_controller->addPrimaryOrUniqueKey('primary', false); } break; case 'add_check': - addCheck(true); + $constraint_controller->addCheck(true); break; case 'save_add_check': if (isset($_POST['cancel'])) { - doDefault(); + $constraint_controller->doDefault(); } else { - addCheck(false); + $constraint_controller->addCheck(false); } break; case 'save_create': - doSaveCreate(); + $constraint_controller->doSaveCreate(); break; case 'create': - doCreate(); + $constraint_controller->doCreate(); break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $constraint_controller->doDrop(false); } else { - doDefault(); + $constraint_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $constraint_controller->doDrop(true); break; default: - doDefault(); + $constraint_controller->doDefault(); break; } diff --git a/src/views/conversions.php b/src/views/conversions.php index 810bc936..e96b73a1 100644 --- a/src/views/conversions.php +++ b/src/views/conversions.php @@ -9,59 +9,14 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show default list of conversions in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc, $database; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'conversions'); - $misc->printMsg($msg); - - $conversions = $data->getconversions(); - - $columns = [ - 'conversion' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - ], - 'source_encoding' => [ - 'title' => $lang['strsourceencoding'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('conforencoding'), - ], - 'target_encoding' => [ - 'title' => $lang['strtargetencoding'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('contoencoding'), - ], - 'default' => [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('condefault'), - 'type' => 'yesno', - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('concomment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($conversions, $columns, $actions, 'conversions-conversions', $lang['strnoconversions']); -} +$conversion_controller = new \PHPPgAdmin\Controller\ConversionController($container); $misc->printHeader($lang['strconversions']); $misc->printBody(); switch ($action) { default: - doDefault(); + $conversion_controller->doDefault(); break; } diff --git a/src/views/database.php b/src/views/database.php index 592ca745..05e0dbc7 100755 --- a/src/views/database.php +++ b/src/views/database.php @@ -9,643 +9,16 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -$scripts = ''; - -function _highlight($string, $term) { - return str_replace($term, "<b>{$term}</b>", $string); -} - -/** - * Sends a signal to a process - */ -function doSignal() { - global $data, $lang; - - $status = $data->sendSignal($_REQUEST['pid'], $_REQUEST['signal']); - if ($status == 0) { - doProcesses($lang['strsignalsent']); - } else { - doProcesses($lang['strsignalsentbad']); - } - -} - -/** - * Searches for a named database object - */ -function doFind($confirm = true, $msg = '') { - global $data, $misc; - global $lang, $conf; - - if (!isset($_REQUEST['term'])) { - $_REQUEST['term'] = ''; - } - - if (!isset($_REQUEST['filter'])) { - $_REQUEST['filter'] = ''; - } - - $misc->printTrail('database'); - $misc->printTabs('database', 'find'); - $misc->printMsg($msg); - - echo "<form action=\"/views/database.php\" method=\"post\">\n"; - echo "<p><input name=\"term\" value=\"", htmlspecialchars($_REQUEST['term']), - "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n"; - // Output list of filters. This is complex due to all the 'has' and 'conf' feature possibilities - echo "<select name=\"filter\">\n"; - echo "\t<option value=\"\"", ($_REQUEST['filter'] == '') ? ' selected="selected"' : '', ">{$lang['strallobjects']}</option>\n"; - echo "\t<option value=\"SCHEMA\"", ($_REQUEST['filter'] == 'SCHEMA') ? ' selected="selected"' : '', ">{$lang['strschemas']}</option>\n"; - echo "\t<option value=\"TABLE\"", ($_REQUEST['filter'] == 'TABLE') ? ' selected="selected"' : '', ">{$lang['strtables']}</option>\n"; - echo "\t<option value=\"VIEW\"", ($_REQUEST['filter'] == 'VIEW') ? ' selected="selected"' : '', ">{$lang['strviews']}</option>\n"; - echo "\t<option value=\"SEQUENCE\"", ($_REQUEST['filter'] == 'SEQUENCE') ? ' selected="selected"' : '', ">{$lang['strsequences']}</option>\n"; - echo "\t<option value=\"COLUMN\"", ($_REQUEST['filter'] == 'COLUMN') ? ' selected="selected"' : '', ">{$lang['strcolumns']}</option>\n"; - echo "\t<option value=\"RULE\"", ($_REQUEST['filter'] == 'RULE') ? ' selected="selected"' : '', ">{$lang['strrules']}</option>\n"; - echo "\t<option value=\"INDEX\"", ($_REQUEST['filter'] == 'INDEX') ? ' selected="selected"' : '', ">{$lang['strindexes']}</option>\n"; - echo "\t<option value=\"TRIGGER\"", ($_REQUEST['filter'] == 'TRIGGER') ? ' selected="selected"' : '', ">{$lang['strtriggers']}</option>\n"; - echo "\t<option value=\"CONSTRAINT\"", ($_REQUEST['filter'] == 'CONSTRAINT') ? ' selected="selected"' : '', ">{$lang['strconstraints']}</option>\n"; - echo "\t<option value=\"FUNCTION\"", ($_REQUEST['filter'] == 'FUNCTION') ? ' selected="selected"' : '', ">{$lang['strfunctions']}</option>\n"; - echo "\t<option value=\"DOMAIN\"", ($_REQUEST['filter'] == 'DOMAIN') ? ' selected="selected"' : '', ">{$lang['strdomains']}</option>\n"; - if ($conf['show_advanced']) { - echo "\t<option value=\"AGGREGATE\"", ($_REQUEST['filter'] == 'AGGREGATE') ? ' selected="selected"' : '', ">{$lang['straggregates']}</option>\n"; - echo "\t<option value=\"TYPE\"", ($_REQUEST['filter'] == 'TYPE') ? ' selected="selected"' : '', ">{$lang['strtypes']}</option>\n"; - echo "\t<option value=\"OPERATOR\"", ($_REQUEST['filter'] == 'OPERATOR') ? ' selected="selected"' : '', ">{$lang['stroperators']}</option>\n"; - echo "\t<option value=\"OPCLASS\"", ($_REQUEST['filter'] == 'OPCLASS') ? ' selected="selected"' : '', ">{$lang['stropclasses']}</option>\n"; - echo "\t<option value=\"CONVERSION\"", ($_REQUEST['filter'] == 'CONVERSION') ? ' selected="selected"' : '', ">{$lang['strconversions']}</option>\n"; - echo "\t<option value=\"LANGUAGE\"", ($_REQUEST['filter'] == 'LANGUAGE') ? ' selected="selected"' : '', ">{$lang['strlanguages']}</option>\n"; - } - echo "</select>\n"; - echo "<input type=\"submit\" value=\"{$lang['strfind']}\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"action\" value=\"find\" /></p>\n"; - echo "</form>\n"; - - // Default focus - $misc->setFocus('forms[0].term'); - - // If a search term has been specified, then perform the search - // and display the results, grouped by object type - if ($_REQUEST['term'] != '') { - $rs = $data->findObject($_REQUEST['term'], $_REQUEST['filter']); - if ($rs->recordCount() > 0) { - $curr = ''; - while (!$rs->EOF) { - // Output a new header if the current type has changed, but not if it's just changed the rule type - if ($rs->fields['type'] != $curr) { - // Short-circuit in the case of changing from table rules to view rules; table cols to view cols; - // table constraints to domain constraints - if ($rs->fields['type'] == 'RULEVIEW' && $curr == 'RULETABLE') { - $curr = $rs->fields['type']; - } elseif ($rs->fields['type'] == 'COLUMNVIEW' && $curr == 'COLUMNTABLE') { - $curr = $rs->fields['type']; - } elseif ($rs->fields['type'] == 'CONSTRAINTTABLE' && $curr == 'CONSTRAINTDOMAIN') { - $curr = $rs->fields['type']; - } else { - if ($curr != '') { - echo "</ul>\n"; - } - - $curr = $rs->fields['type']; - echo "<h3>"; - switch ($curr) { - case 'SCHEMA': - echo $lang['strschemas']; - break; - case 'TABLE': - echo $lang['strtables']; - break; - case 'VIEW': - echo $lang['strviews']; - break; - case 'SEQUENCE': - echo $lang['strsequences']; - break; - case 'COLUMNTABLE': - case 'COLUMNVIEW': - echo $lang['strcolumns']; - break; - case 'INDEX': - echo $lang['strindexes']; - break; - case 'CONSTRAINTTABLE': - case 'CONSTRAINTDOMAIN': - echo $lang['strconstraints']; - break; - case 'TRIGGER': - echo $lang['strtriggers']; - break; - case 'RULETABLE': - case 'RULEVIEW': - echo $lang['strrules']; - break; - case 'FUNCTION': - echo $lang['strfunctions']; - break; - case 'TYPE': - echo $lang['strtypes']; - break; - case 'DOMAIN': - echo $lang['strdomains']; - break; - case 'OPERATOR': - echo $lang['stroperators']; - break; - case 'CONVERSION': - echo $lang['strconversions']; - break; - case 'LANGUAGE': - echo $lang['strlanguages']; - break; - case 'AGGREGATE': - echo $lang['straggregates']; - break; - case 'OPCLASS': - echo $lang['stropclasses']; - break; - } - echo "</h3>"; - echo "<ul>\n"; - } - } - - switch ($curr) { - case 'SCHEMA': - echo "<li><a href=\"/redirect/schema?{$misc->href}&schema=", $misc->printVal($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'TABLE': - echo "<li>"; - echo "<a href=\"tables.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/table?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", - urlencode($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'VIEW': - echo "<li>"; - echo "<a href=\"views.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/view?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&view=", - urlencode($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'SEQUENCE': - echo "<li>"; - echo "<a href=\"sequences.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"sequences.php?subject=sequence&action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), - "&sequence=", urlencode($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'COLUMNTABLE': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"tblproperties.php?subject=table&{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"colproperties.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", - urlencode($rs->fields['relname']), "&column=", urlencode($rs->fields['name']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'COLUMNVIEW': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"viewproperties.php?subject=view&{$misc->href}&view=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"colproperties.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&view=", - urlencode($rs->fields['relname']), "&column=", urlencode($rs->fields['name']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'INDEX': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"indexes.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", urlencode($rs->fields['relname']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'CONSTRAINTTABLE': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"constraints.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", - urlencode($rs->fields['relname']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'CONSTRAINTDOMAIN': - echo "<li>"; - echo "<a href=\"domains.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"domains.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&domain=", urlencode($rs->fields['relname']), "\">", - $misc->printVal($rs->fields['relname']), '.', _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'TRIGGER': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"triggers.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&table=", urlencode($rs->fields['relname']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'RULETABLE': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/table?{$misc->href}&table=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"rules.php?subject=table&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&reltype=table&table=", - urlencode($rs->fields['relname']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'RULEVIEW': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"/redirect/view?{$misc->href}&view=", urlencode($rs->fields['relname']), "&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['relname']), "</a>."; - echo "<a href=\"rules.php?subject=view&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&reltype=view&view=", - urlencode($rs->fields['relname']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'FUNCTION': - echo "<li>"; - echo "<a href=\"functions.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"functions.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&function=", - urlencode($rs->fields['name']), "&function_oid=", urlencode($rs->fields['oid']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'TYPE': - echo "<li>"; - echo "<a href=\"types.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"types.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&type=", - urlencode($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'DOMAIN': - echo "<li>"; - echo "<a href=\"domains.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"domains.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&domain=", - urlencode($rs->fields['name']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'OPERATOR': - echo "<li>"; - echo "<a href=\"operators.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"operators.php?action=properties&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "&operator=", - urlencode($rs->fields['name']), "&operator_oid=", urlencode($rs->fields['oid']), "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'CONVERSION': - echo "<li>"; - echo "<a href=\"conversions.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"conversions.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), - "\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'LANGUAGE': - echo "<li><a href=\"languages.php?{$misc->href}\">", _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'AGGREGATE': - echo "<li>"; - echo "<a href=\"aggregates.php?subject=schema&{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"aggregates.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - case 'OPCLASS': - echo "<li>"; - echo "<a href=\"/redirect/schema?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", $misc->printVal($rs->fields['schemaname']), "</a>."; - echo "<a href=\"opclasses.php?{$misc->href}&schema=", urlencode($rs->fields['schemaname']), "\">", - _highlight($misc->printVal($rs->fields['name']), $_REQUEST['term']), "</a></li>\n"; - break; - } - $rs->moveNext(); - } - echo "</ul>\n"; - - echo "<p>", $rs->recordCount(), " ", $lang['strobjects'], "</p>\n"; - } else { - echo "<p>{$lang['strnoobjects']}</p>\n"; - } - - } -} - -/** - * Displays options for database download - */ -function doExport($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('database'); - $misc->printTabs('database', 'export'); - $misc->printMsg($msg); - - echo "<form action=\"/views/dbexport.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; - // Data only - echo "<tr><th class=\"data left\" rowspan=\"2\">"; - echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"d_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; - // Structure only - echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; - echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; - // Structure and data - echo "<tr><th class=\"data left\" rowspan=\"3\">"; - echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"sd_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; - echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; - echo "</table>\n"; - - echo "<h3>{$lang['stroptions']}</h3>\n"; - echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; - echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label>\n"; - // MSIE cannot download gzip in SSL mode - it's just broken - if (!(strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS']))) { - echo "<br /><input type=\"radio\" id=\"output3\" name=\"output\" value=\"gzipped\" /><label for=\"output3\">{$lang['strdownloadgzipped']}</label>\n"; - } - echo "</p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"database\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Show the current status of all database variables - */ -function doVariables() { - global $data, $misc; - global $lang; - - // Fetch the variables from the database - $variables = $data->getVariables(); - $misc->printTrail('database'); - $misc->printTabs('database', 'variables'); - - $columns = [ - 'variable' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - 'value' => [ - 'title' => $lang['strsetting'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('setting'), - ], - ]; - - $actions = []; - - echo $misc->printTable($variables, $columns, $actions, 'database-variables', $lang['strnodata']); -} - -/** - * Show all current database connections and any queries they - * are running. - */ -function doProcesses($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('database'); - $misc->printTabs('database', 'processes'); - $misc->printMsg($msg); - - if (strlen($msg) === 0) { - echo "<br /><a id=\"control\" href=\"\"><img src=\"" . $misc->icon('Refresh') . "\" alt=\"{$lang['strrefresh']}\" title=\"{$lang['strrefresh']}\"/> {$lang['strrefresh']}</a>"; - } - - echo "<div id=\"data_block\">"; - currentProcesses(); - echo "</div>"; -} - -function currentProcesses($isAjax = false) { - global $data, $misc, $lang; - - // Display prepared transactions - if ($data->hasPreparedXacts()) { - echo "<h3>{$lang['strpreparedxacts']}</h3>\n"; - $prep_xacts = $data->getPreparedXacts($_REQUEST['database']); - - $columns = [ - 'transaction' => [ - 'title' => $lang['strxactid'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('transaction'), - ], - 'gid' => [ - 'title' => $lang['strgid'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('gid'), - ], - 'prepared' => [ - 'title' => $lang['strstarttime'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('prepared'), - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('owner'), - ], - ]; - - $actions = []; - - echo $misc->printTable($prep_xacts, $columns, $actions, 'database-processes-preparedxacts', $lang['strnodata']); - } - - // Fetch the processes from the database - echo "<h3>{$lang['strprocesses']}</h3>\n"; - $processes = $data->getProcesses($_REQUEST['database']); - - $columns = [ - 'user' => [ - 'title' => $lang['strusername'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - 'process' => [ - 'title' => $lang['strprocess'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('pid'), - ], - 'blocked' => [ - 'title' => $lang['strblocked'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('waiting'), - ], - 'query' => [ - 'title' => $lang['strsql'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('query'), - ], - 'start_time' => [ - 'title' => $lang['strstarttime'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('query_start'), - ], - ]; - - // Build possible actions for our process list - $columns['actions'] = ['title' => $lang['stractions']]; - - $actions = []; - if ($data->hasUserSignals() || $data->isSuperUser()) { - $actions = [ - 'cancel' => [ - 'content' => $lang['strcancel'], - 'attr' => [ - 'href' => [ - 'url' => 'database.php', - 'urlvars' => [ - 'action' => 'signal', - 'signal' => 'CANCEL', - 'pid' => \PHPPgAdmin\Decorators\Decorator::field('pid'), - ], - ], - ], - ], - 'kill' => [ - 'content' => $lang['strkill'], - 'attr' => [ - 'href' => [ - 'url' => 'database.php', - 'urlvars' => [ - 'action' => 'signal', - 'signal' => 'KILL', - 'pid' => \PHPPgAdmin\Decorators\Decorator::field('pid'), - ], - ], - ], - ], - ]; - - // Remove actions where not supported - if (!$data->hasQueryKill()) { - unset($actions['kill']); - } - - if (!$data->hasQueryCancel()) { - unset($actions['cancel']); - } - - } - - if (count($actions) == 0) { - unset($columns['actions']); - } - - echo $misc->printTable($processes, $columns, $actions, 'database-processes', $lang['strnodata']); - - if ($isAjax) { - exit; - } - -} - -function currentLocks($isAjax = false) { - global $data, $misc, $lang; - - // Get the info from the pg_locks view - $variables = $data->getLocks(); - - $columns = [ - 'namespace' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - 'tablename' => [ - 'title' => $lang['strtablename'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('tablename'), - ], - 'vxid' => [ - 'title' => $lang['strvirtualtransaction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('virtualtransaction'), - ], - 'transactionid' => [ - 'title' => $lang['strtransaction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('transaction'), - ], - 'processid' => [ - 'title' => $lang['strprocessid'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('pid'), - ], - 'mode' => [ - 'title' => $lang['strmode'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('mode'), - ], - 'granted' => [ - 'title' => $lang['strislockheld'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('granted'), - 'type' => 'yesno', - ], - ]; - - if (!$data->hasVirtualTransactionId()) { - unset($columns['vxid']); - } - - $actions = []; - echo $misc->printTable($variables, $columns, $actions, 'database-locks', $lang['strnodata']); - - if ($isAjax) { - exit; - } - -} - -/** - * Show the existing table locks in the current database - */ -function doLocks() { - global $data, $misc; - global $lang; - - $misc->printTrail('database'); - $misc->printTabs('database', 'locks'); - - echo "<br /><a id=\"control\" href=\"\"><img src=\"" . $misc->icon('Refresh') . "\" alt=\"{$lang['strrefresh']}\" title=\"{$lang['strrefresh']}\"/> {$lang['strrefresh']}</a>"; - - echo "<div id=\"data_block\">"; - currentLocks(); - echo "</div>"; -} - -/** - * Allow execution of arbitrary SQL statements on a database - */ -function doSQL() { - global $data, $misc; - global $lang; - - if ((!isset($_SESSION['sqlquery'])) || isset($_REQUEST['new'])) { - $_SESSION['sqlquery'] = ''; - $_REQUEST['paginate'] = 'on'; - } - - $misc->printTrail('database'); - $misc->printTabs('database', 'sql'); - echo "<p>{$lang['strentersql']}</p>\n"; - echo "<form action=\"/views/sql.php\" method=\"post\" enctype=\"multipart/form-data\">\n"; - echo "<p>{$lang['strsql']}<br />\n"; - echo "<textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"query\">", - htmlspecialchars($_SESSION['sqlquery']), "</textarea></p>\n"; - - // Check that file uploads are enabled - if (ini_get('file_uploads')) { - // Don't show upload option if max size of uploads is zero - $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize')); - if (is_double($max_size) && $max_size > 0) { - echo "<p><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />\n"; - echo "<label for=\"script\">{$lang['struploadscript']}</label> <input id=\"script\" name=\"script\" type=\"file\" /></p>\n"; - } - } - - echo "<p><input type=\"checkbox\" id=\"paginate\" name=\"paginate\"", (isset($_REQUEST['paginate']) ? ' checked="checked"' : ''), " /><label for=\"paginate\">{$lang['strpaginate']}</label></p>\n"; - echo "<p><input type=\"submit\" name=\"execute\" accesskey=\"r\" value=\"{$lang['strexecute']}\" />\n"; - echo $misc->form; - echo "<input type=\"reset\" accesskey=\"q\" value=\"{$lang['strreset']}\" /></p>\n"; - echo "</form>\n"; - - // Default focus - $misc->setFocus('forms[0].query'); -} - -require './admin.php'; +$database_controller = new \PHPPgAdmin\Controller\DatabaseController($container); if ($action == 'refresh_locks') { - currentLocks(true); + $database_controller->currentLocks(true); } if ($action == 'refresh_processes') { - currentProcesses(true); + $database_controller->currentProcesses(true); } - +$scripts = ''; /* normal flow */ if ($action == 'locks' or $action == 'processes') { $scripts .= "<script src=\"/js/database.js\" type=\"text/javascript\"></script>"; @@ -672,33 +45,33 @@ $misc->printBody(); switch ($action) { case 'find': if (isset($_REQUEST['term'])) { - doFind(false); + $database_controller->doFind(false); } else { - doFind(true); + $database_controller->doFind(true); } break; case 'sql': - doSQL(); + $database_controller->doSQL(); break; case 'variables': - doVariables(); + $database_controller->doVariables(); break; case 'processes': - doProcesses(); + $database_controller->doProcesses(); break; case 'locks': - doLocks(); + $database_controller->doLocks(); break; case 'export': - doExport(); + $database_controller->doExport(); break; case 'signal': - doSignal(); + $database_controller->doSignal(); break; default: if (adminActions($action, 'database') === false) { - doSQL(); + $database_controller->doSQL(); } break; diff --git a/src/views/dataexport.php b/src/views/dataexport.php index 3fdaa130..0cb2aab2 100644 --- a/src/views/dataexport.php +++ b/src/views/dataexport.php @@ -28,7 +28,7 @@ if (!ini_get('safe_mode')) { if (isset($_REQUEST['what'])) { // Include application functions - $_no_output = true; + $misc->setNoOutput(true); require_once '../lib.inc.php'; switch ($_REQUEST['what']) { @@ -339,7 +339,7 @@ if (isset($_REQUEST['what'])) { $misc->printMsg($msg); } - echo "<form action=\"/views/dataexport.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/dataexport.php\" method=\"post\">\n"; echo "<table>\n"; echo "<tr><th class=\"data\">{$lang['strformat']}:</th><td><select name=\"d_format\">\n"; // COPY and SQL require a table diff --git a/src/views/dbexport.php b/src/views/dbexport.php index 23c54c26..9edd025c 100644 --- a/src/views/dbexport.php +++ b/src/views/dbexport.php @@ -12,9 +12,9 @@ if (!ini_get('safe_mode')) { } // Include application functions -$_no_output = true; -$f_schema = $f_object = ''; +$f_schema = $f_object = ''; require_once '../lib.inc.php'; +$misc->setNoOutput(true); // Are we doing a cluster-wide dump or just a per-database dump $dumpall = ($_REQUEST['subject'] == 'server'); diff --git a/src/views/display.php b/src/views/display.php index d695b929..3db53807 100644 --- a/src/views/display.php +++ b/src/views/display.php @@ -17,7 +17,9 @@ if (!ini_get('safe_mode')) { } // Include application functions -require_once '../lib.inc.php'; +if (!defined('BASE_PATH')) { + require_once '../lib.inc.php'; +} global $conf, $lang; @@ -54,7 +56,7 @@ function doEditRow($confirm, $msg = '') { $fksprops = false; } - echo "<form action=\"/views/display.php\" method=\"post\" id=\"ac_form\">\n"; + echo "<form action=\"/src/views/display.php\" method=\"post\" id=\"ac_form\">\n"; $elements = 0; $error = true; if ($rs->recordCount() == 1 && $attrs->recordCount() > 0) { @@ -218,7 +220,7 @@ function doDelRow($confirm) { $rs = $data->browseRow($_REQUEST['table'], $_REQUEST['key']); - echo "<form action=\"/views/display.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/display.php\" method=\"post\">\n"; echo $misc->form; if ($rs->recordCount() == 1) { diff --git a/src/views/domains.php b/src/views/domains.php index 52e156e3..809356f6 100644 --- a/src/views/domains.php +++ b/src/views/domains.php @@ -9,610 +9,72 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Function to save after altering a domain - */ -function doSaveAlter() { - global $data, $lang; - - $status = $data->alterDomain($_POST['domain'], $_POST['domdefault'], - isset($_POST['domnotnull']), $_POST['domowner']); - if ($status == 0) { - doProperties($lang['strdomainaltered']); - } else { - doAlter($lang['strdomainalteredbad']); - } - -} - -/** - * Allow altering a domain - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('domain'); - $misc->printTitle($lang['stralter'], 'pg.domain.alter'); - $misc->printMsg($msg); - - // Fetch domain info - $domaindata = $data->getDomain($_REQUEST['domain']); - // Fetch all users - $users = $data->getUsers(); - - if ($domaindata->recordCount() > 0) { - if (!isset($_POST['domname'])) { - $_POST['domtype'] = $domaindata->fields['domtype']; - $_POST['domdefault'] = $domaindata->fields['domdef']; - $domaindata->fields['domnotnull'] = $data->phpBool($domaindata->fields['domnotnull']); - if ($domaindata->fields['domnotnull']) { - $_POST['domnotnull'] = 'on'; - } - - $_POST['domowner'] = $domaindata->fields['domowner']; - } - - // Display domain info - echo "<form action=\"/views/domains.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\" style=\"width: 70px\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domname']), "</td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strtype']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domtype']), "</td></tr>\n"; - echo "<tr><th class=\"data left\"><label for=\"domnotnull\">{$lang['strnotnull']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"domnotnull\" name=\"domnotnull\"", (isset($_POST['domnotnull']) ? ' checked="checked"' : ''), " /></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; - echo "<td class=\"data1\"><input name=\"domdefault\" size=\"32\" value=\"", - htmlspecialchars($_POST['domdefault']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\"><select name=\"domowner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['domowner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_alter\" />\n"; - echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Confirm and then actually add a CHECK constraint - */ -function addCheck($confirm, $msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['definition'])) { - $_POST['definition'] = ''; - } - - if ($confirm) { - $misc->printTrail('domain'); - $misc->printTitle($lang['straddcheck'], 'pg.constraint.check'); - $misc->printMsg($msg); - - echo "<form action=\"/views/domains.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; - echo "<th class=\"data required\">{$lang['strdefinition']}</th></tr>\n"; - - echo "<tr><td class=\"data1\"><input name=\"name\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" /></td>\n"; - - echo "<td class=\"data1\">(<input name=\"definition\" size=\"32\" value=\"", - htmlspecialchars($_POST['definition']), "\" />)</td></tr>\n"; - echo "</table>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_add_check\" />\n"; - echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"add\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - } else { - if (trim($_POST['definition']) == '') { - addCheck(true, $lang['strcheckneedsdefinition']); - } else { - $status = $data->addDomainCheckConstraint($_POST['domain'], - $_POST['definition'], $_POST['name']); - if ($status == 0) { - doProperties($lang['strcheckadded']); - } else { - addCheck(true, $lang['strcheckaddedbad']); - } - - } - } -} - -/** - * Show confirmation of drop constraint and perform actual drop - */ -function doDropConstraint($confirm, $msg = '') { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('domain'); - $misc->printTitle($lang['strdrop'], 'pg.constraint.drop'); - $misc->printMsg($msg); - - echo "<p>", sprintf($lang['strconfdropconstraint'], $misc->printVal($_REQUEST['constraint']), - $misc->printVal($_REQUEST['domain'])), "</p>\n"; - echo "<form action=\"/views/domains.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop_con\" />\n"; - echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; - echo "<input type=\"hidden\" name=\"constraint\" value=\"", htmlspecialchars($_REQUEST['constraint']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropDomainConstraint($_POST['domain'], $_POST['constraint'], isset($_POST['cascade'])); - if ($status == 0) { - doProperties($lang['strconstraintdropped']); - } else { - doDropConstraint(true, $lang['strconstraintdroppedbad']); - } - - } - -} - -/** - * Show properties for a domain. Allow manipulating constraints as well. - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('domain'); - $misc->printTitle($lang['strproperties'], 'pg.domain'); - $misc->printMsg($msg); - - $domaindata = $data->getDomain($_REQUEST['domain']); - - if ($domaindata->recordCount() > 0) { - // Show comment if any - if ($domaindata->fields['domcomment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($domaindata->fields['domcomment']), "</p>\n"; - } - - // Display domain info - $domaindata->fields['domnotnull'] = $data->phpBool($domaindata->fields['domnotnull']); - echo "<table>\n"; - echo "<tr><th class=\"data left\" style=\"width: 70px\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strtype']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domtype']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strnotnull']}</th>\n"; - echo "<td class=\"data1\">", ($domaindata->fields['domnotnull'] ? 'NOT NULL' : ''), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domdef']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($domaindata->fields['domowner']), "</td></tr>\n"; - echo "</table>\n"; - - // Display domain constraints - echo "<h3>{$lang['strconstraints']}</h3>\n"; - if ($data->hasDomainConstraints()) { - $domaincons = $data->getDomainConstraints($_REQUEST['domain']); - - $columns = [ - 'name' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('consrc'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'confirm_drop_con', - 'domain' => $_REQUEST['domain'], - 'constraint' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - 'type' => \PHPPgAdmin\Decorators\Decorator::field('contype'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($domaincons, $columns, $actions, 'domains-properties', $lang['strnodata']); - } - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - $navlinks = [ - 'drop' => [ - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'domain' => $_REQUEST['domain'], - ], - ], - ], - 'content' => $lang['strdrop'], - ], - ]; - if ($data->hasAlterDomains()) { - $navlinks['addcheck'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'add_check', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'domain' => $_REQUEST['domain'], - ], - ], - ], - 'content' => $lang['straddcheck'], - ]; - $navlinks['alter'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'alter', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'domain' => $_REQUEST['domain'], - ], - ], - ], - 'content' => $lang['stralter'], - ]; - } - - $misc->printNavLinks($navlinks, 'domains-properties', get_defined_vars()); -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('domain'); - $misc->printTitle($lang['strdrop'], 'pg.domain.drop'); - - echo "<p>", sprintf($lang['strconfdropdomain'], $misc->printVal($_REQUEST['domain'])), "</p>\n"; - echo "<form action=\"/views/domains.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /><label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"domain\" value=\"", htmlspecialchars($_REQUEST['domain']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropDomain($_POST['domain'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strdomaindropped']); - } else { - doDefault($lang['strdomaindroppedbad']); - } - - } - -} - -/** - * Displays a screen where they can enter a new domain - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['domname'])) { - $_POST['domname'] = ''; - } - - if (!isset($_POST['domtype'])) { - $_POST['domtype'] = ''; - } - - if (!isset($_POST['domlength'])) { - $_POST['domlength'] = ''; - } - - if (!isset($_POST['domarray'])) { - $_POST['domarray'] = ''; - } - - if (!isset($_POST['domdefault'])) { - $_POST['domdefault'] = ''; - } - - if (!isset($_POST['domcheck'])) { - $_POST['domcheck'] = ''; - } - - $types = $data->getTypes(true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatedomain'], 'pg.domain.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/domains.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\" style=\"width: 70px\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\"><input name=\"domname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['domname']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strtype']}</th>\n"; - echo "<td class=\"data1\">\n"; - // Output return type list - echo "<select name=\"domtype\">\n"; - while (!$types->EOF) { - echo "<option value=\"", htmlspecialchars($types->fields['typname']), "\"", - ($types->fields['typname'] == $_POST['domtype']) ? ' selected="selected"' : '', ">", - $misc->printVal($types->fields['typname']), "</option>\n"; - $types->moveNext(); - } - echo "</select>\n"; - - // Type length - echo "<input type=\"text\" size=\"4\" name=\"domlength\" value=\"", htmlspecialchars($_POST['domlength']), "\" />"; - - // Output array type selector - echo "<select name=\"domarray\">\n"; - echo "<option value=\"\"", ($_POST['domarray'] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "<option value=\"[]\"", ($_POST['domarray'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "</select></td></tr>\n"; - - echo "<tr><th class=\"data left\"><label for=\"domnotnull\">{$lang['strnotnull']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"domnotnull\" name=\"domnotnull\"", - (isset($_POST['domnotnull']) ? ' checked="checked"' : ''), " /></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; - echo "<td class=\"data1\"><input name=\"domdefault\" size=\"32\" value=\"", - htmlspecialchars($_POST['domdefault']), "\" /></td></tr>\n"; - if ($data->hasDomainConstraints()) { - echo "<tr><th class=\"data left\">{$lang['strconstraints']}</th>\n"; - echo "<td class=\"data1\">CHECK (<input name=\"domcheck\" size=\"32\" value=\"", - htmlspecialchars($_POST['domcheck']), "\" />)</td></tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new domain in the database - */ -function doSaveCreate() { - global $data, $lang; - - if (!isset($_POST['domcheck'])) { - $_POST['domcheck'] = ''; - } - - // Check that they've given a name and a definition - if ($_POST['domname'] == '') { - doCreate($lang['strdomainneedsname']); - } else { - $status = $data->createDomain($_POST['domname'], $_POST['domtype'], $_POST['domlength'], $_POST['domarray'] != '', - isset($_POST['domnotnull']), $_POST['domdefault'], $_POST['domcheck']); - if ($status == 0) { - doDefault($lang['strdomaincreated']); - } else { - doCreate($lang['strdomaincreatedbad']); - } - - } -} - -/** - * Show default list of domains in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'domains'); - $misc->printMsg($msg); - - $domains = $data->getDomains(); - - $columns = [ - 'domain' => [ - 'title' => $lang['strdomain'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domname'), - 'url' => "domains.php?action=properties&{$misc->href}&", - 'vars' => ['domain' => 'domname'], - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domtype'), - ], - 'notnull' => [ - 'title' => $lang['strnotnull'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domnotnull'), - 'type' => 'bool', - 'params' => ['true' => 'NOT NULL', 'false' => ''], - ], - 'default' => [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domdef'), - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domowner'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('domcomment'), - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'alter', - 'domain' => \PHPPgAdmin\Decorators\Decorator::field('domname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'domain' => \PHPPgAdmin\Decorators\Decorator::field('domname'), - ], - ], - ], - ], - ]; - - if (!$data->hasAlterDomains()) { - unset($actions['alter']); - } - - echo $misc->printTable($domains, $columns, $actions, 'domains-domains', $lang['strnodomains']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'domains.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatedomain'], - ], - ]; - $misc->printNavLinks($navlinks, 'domains-domains', get_defined_vars()); -} +$domain_controller = new \PHPPgAdmin\Controller\DomainController($container); $misc->printHeader($lang['strdomains']); $misc->printBody(); switch ($action) { case 'add_check': - addCheck(true); + $domain_controller->addCheck(true); break; case 'save_add_check': if (isset($_POST['cancel'])) { - doProperties(); + $domain_controller->doProperties(); } else { - addCheck(false); + $domain_controller->addCheck(false); } break; case 'drop_con': if (isset($_POST['drop'])) { - doDropConstraint(false); + $domain_controller->doDropConstraint(false); } else { - doProperties(); + $domain_controller->doProperties(); } break; case 'confirm_drop_con': - doDropConstraint(true); + $domain_controller->doDropConstraint(true); break; case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $domain_controller->doDefault(); } else { - doSaveCreate(); + $domain_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $domain_controller->doCreate(); break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $domain_controller->doDrop(false); } else { - doDefault(); + $domain_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $domain_controller->doDrop(true); break; case 'save_alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $domain_controller->doSaveAlter(); } else { - doProperties(); + $domain_controller->doProperties(); } break; case 'alter': - doAlter(); + $domain_controller->doAlter(); break; case 'properties': - doProperties(); + $domain_controller->doProperties(); break; default: - doDefault(); + $domain_controller->doDefault(); break; } diff --git a/src/views/fulltext.php b/src/views/fulltext.php index 299d9362..16959206 100644 --- a/src/views/fulltext.php +++ b/src/views/fulltext.php @@ -9,1072 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'fulltext'); - $misc->printTabs('fulltext', 'ftsconfigs'); - $misc->printMsg($msg); - - $cfgs = $data->getFtsConfigurations(false); - - $columns = [ - 'configuration' => [ - 'title' => $lang['strftsconfig'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('name'), - 'url' => "fulltext.php?action=viewconfig&{$misc->href}&", - 'vars' => ['ftscfg' => 'name'], - ], - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('schema'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'dropconfig', - 'ftscfg' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'alterconfig', - 'ftscfg' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($cfgs, $columns, $actions, 'fulltext-fulltext', $lang['strftsnoconfigs']); - - $navlinks = [ - 'createconf' => [ - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'createconfig', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strftscreateconfig'], - ], - ]; - - $misc->printNavLinks($navlinks, 'fulltext-fulltext', get_defined_vars()); -} - -function doDropConfig($confirm) { - global $data, $data, $misc; - global $lang, $_reload_browser; - - if ($confirm) { - $misc->printTrail('ftscfg'); - $misc->printTitle($lang['strdrop'], 'pg.ftscfg.drop'); - - echo "<p>", sprintf($lang['strconfdropftsconfig'], $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"dropconfig\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_REQUEST['ftscfg']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropFtsConfiguration($_POST['ftscfg'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strftsconfigdropped']); - } else { - doDefault($lang['strftsconfigdroppedbad']); - } - - } - -} - -function doDropDict($confirm) { - global $data, $data, $misc; - global $lang, $_reload_browser; - - if ($confirm) { - $misc->printTrail('ftscfg'); // TODO: change to smth related to dictionary - $misc->printTitle($lang['strdrop'], 'pg.ftsdict.drop'); - - echo "<p>", sprintf($lang['strconfdropftsdict'], $misc->printVal($_REQUEST['ftsdict'])), "</p>\n"; - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"dropdict\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo "<input type=\"hidden\" name=\"ftsdict\" value=\"", htmlspecialchars($_REQUEST['ftsdict']), "\" />\n"; - //echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_REQUEST['ftscfg']), "\" />\n"; - echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewdicts\" /></p>\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropFtsDictionary($_POST['ftsdict'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doViewDicts($lang['strftsdictdropped']); - } else { - doViewDicts($lang['strftsdictdroppedbad']); - } - - } - -} - -/** - * Displays a screen where one can enter a new FTS configuration - */ -function doCreateConfig($msg = '') { - global $data, $misc; - global $lang; - - include_once BASE_PATH . '/classes/Gui.php'; - - $server_info = $misc->getServerInfo(); - - if (!isset($_POST['formName'])) { - $_POST['formName'] = ''; - } - - if (!isset($_POST['formParser'])) { - $_POST['formParser'] = ''; - } - - if (!isset($_POST['formTemplate'])) { - $_POST['formTemplate'] = ''; - } - - if (!isset($_POST['formWithMap'])) { - $_POST['formWithMap'] = ''; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = ''; - } - - // Fetch all FTS configurations from the database - $ftscfgs = $data->getFtsConfigurations(); - // Fetch all FTS parsers from the database - $ftsparsers = $data->getFtsParsers(); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strftscreateconfig'], 'pg.ftscfg.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<table>\n"; - /* conf name */ - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; - - // Template - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftstemplate']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - - $tpls = []; - $tplsel = ''; - while (!$ftscfgs->EOF) { - $data->fieldClean($ftscfgs->fields['schema']); - $data->fieldClean($ftscfgs->fields['name']); - $tplname = $ftscfgs->fields['schema'] . '.' . $ftscfgs->fields['name']; - $tpls[$tplname] = serialize([ - 'name' => $ftscfgs->fields['name'], - 'schema' => $ftscfgs->fields['schema'], - ]); - if ($_POST['formTemplate'] == $tpls[$tplname]) { - $tplsel = htmlspecialchars($tpls[$tplname]); - } - $ftscfgs->moveNext(); - } - echo GUI::printCombo($tpls, 'formTemplate', true, $tplsel, false); - echo "\n\t\t</td>\n\t</tr>\n"; - - // Parser - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsparser']}</th>\n"; - echo "\t\t<td class=\"data1\">\n"; - $ftsparsers_ = []; - $ftsparsel = ''; - while (!$ftsparsers->EOF) { - $data->fieldClean($ftsparsers->fields['schema']); - $data->fieldClean($ftsparsers->fields['name']); - $parsername = $ftsparsers->fields['schema'] . '.' . $ftsparsers->fields['name']; - - $ftsparsers_[$parsername] = serialize([ - 'parser' => $ftsparsers->fields['name'], - 'schema' => $ftsparsers->fields['schema'], - ]); - if ($_POST['formParser'] == $ftsparsers_[$parsername]) { - $ftsparsel = htmlspecialchars($ftsparsers_[$parsername]); - } - $ftsparsers->moveNext(); - } - echo GUI::printCombo($ftsparsers_, 'formParser', true, $ftsparsel, false); - echo "\n\t\t</td>\n\t</tr>\n"; - - // Comment - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"createconfig\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new FTS configuration in the database - */ -function doSaveCreateConfig() { - global $data, $lang, $_reload_browser; - - $err = ''; - // Check that they've given a name - if ($_POST['formName'] == '') { - $err .= "{$lang['strftsconfigneedsname']}<br />"; - } - - if (($_POST['formParser'] != '') && ($_POST['formTemplate'] != '')) { - $err .= "{$lang['strftscantparsercopy']}<br />"; - } - - if ($err != '') { - return doCreateConfig($err); - } - - if ($_POST['formParser'] != '') { - $formParser = unserialize($_POST['formParser']); - } else { - $formParser = ''; - } - - if ($_POST['formTemplate'] != '') { - $formTemplate = unserialize($_POST['formTemplate']); - } else { - $formTemplate = ''; - } - - $status = $data->createFtsConfiguration($_POST['formName'], $formParser, $formTemplate, $_POST['formComment']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strftsconfigcreated']); - } else { - doCreateConfig($lang['strftsconfigcreatedbad']); - } - -} - -/** - * Display a form to permit editing FTS configuration properies. - */ -function doAlterConfig($msg = '') { - global $data, $misc, $lang; - - $misc->printTrail('ftscfg'); - $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); - $misc->printMsg($msg); - - $ftscfg = $data->getFtsConfigurationByName($_REQUEST['ftscfg']); - if ($ftscfg->recordCount() > 0) { - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = $ftscfg->fields['comment']; - } - - if (!isset($_POST['ftscfg'])) { - $_POST['ftscfg'] = $_REQUEST['ftscfg']; - } - - if (!isset($_POST['formName'])) { - $_POST['formName'] = $_REQUEST['ftscfg']; - } - - if (!isset($_POST['formParser'])) { - $_POST['formParser'] = ''; - } - - // Fetch all FTS parsers from the database - $ftsparsers = $data->getFtsParsers(); - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<table>\n"; - - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" />\n"; - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - // Comment - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\"name=\"formComment\">", htmlspecialchars($_POST['formComment']), "</textarea></td>\n"; - echo "\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alterconfig\" />\n"; - echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } -} - -/** - * Save the form submission containing changes to a FTS configuration - */ -function doSaveAlterConfig() { - global $data, $misc, $lang; - - $status = $data->updateFtsConfiguration($_POST['ftscfg'], $_POST['formComment'], $_POST['formName']); - if ($status == 0) { - doDefault($lang['strftsconfigaltered']); - } else { - doAlterConfig($lang['strftsconfigalteredbad']); - } - -} - -/** - * View list of FTS parsers - */ -function doViewParsers($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'fulltext'); - $misc->printTabs('fulltext', 'ftsparsers'); - $misc->printMsg($msg); - - $parsers = $data->getFtsParsers(false); - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('schema'), - ], - 'name' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($parsers, $columns, $actions, 'fulltext-viewparsers', $lang['strftsnoparsers']); - - //TODO: navlink to "create parser" -} - -/** - * View list of FTS dictionaries - */ -function doViewDicts($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'fulltext'); - $misc->printTabs('fulltext', 'ftsdicts'); - $misc->printMsg($msg); - - $dicts = $data->getFtsDictionaries(false); - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('schema'), - ], - 'name' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'dropdict', - 'ftsdict' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'alterdict', - 'ftsdict' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($dicts, $columns, $actions, 'fulltext-viewdicts', $lang['strftsnodicts']); - - $navlinks = [ - 'createdict' => [ - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'createdict', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strftscreatedict'], - ], - ]; - - $misc->printNavLinks($navlinks, 'fulltext-viewdicts', get_defined_vars()); -} - -/** - * View details of FTS configuration given - */ -function doViewConfig($ftscfg, $msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('ftscfg'); - $misc->printTabs('schema', 'fulltext'); - $misc->printTabs('fulltext', 'ftsconfigs'); - $misc->printMsg($msg); - - echo "<h3>{$lang['strftsconfigmap']}</h3>\n"; - - $map = $data->getFtsConfigurationMap($ftscfg); - - $columns = [ - 'name' => [ - 'title' => $lang['strftsmapping'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('name'), - ], - 'dictionaries' => [ - 'title' => $lang['strftsdicts'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('dictionaries'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('description'), - ], - ]; - - $actions = [ - 'drop' => [ - 'multiaction' => 'dropmapping', - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'dropmapping', - 'mapping' => \PHPPgAdmin\Decorators\Decorator::field('name'), - 'ftscfg' => \PHPPgAdmin\Decorators\Decorator::field('cfgname'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'altermapping', - 'mapping' => \PHPPgAdmin\Decorators\Decorator::field('name'), - 'ftscfg' => \PHPPgAdmin\Decorators\Decorator::field('cfgname'), - ], - ], - ], - ], - 'multiactions' => [ - 'keycols' => ['mapping' => 'name'], - 'url' => 'fulltext.php', - 'default' => null, - 'vars' => ['ftscfg' => $ftscfg], - ], - - ]; - - echo $misc->printTable($map, $columns, $actions, 'fulltext-viewconfig', $lang['strftsemptymap']); - - $navlinks = [ - 'addmapping' => [ - 'attr' => [ - 'href' => [ - 'url' => 'fulltext.php', - 'urlvars' => [ - 'action' => 'addmapping', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'ftscfg' => $ftscfg, - ], - ], - ], - 'content' => $lang['strftsaddmapping'], - ], - ]; - - $misc->printNavLinks($navlinks, 'fulltext-viewconfig', get_defined_vars()); -} - -/** - * Displays a screen where one can enter a details of a new FTS dictionary - */ -function doCreateDict($msg = '') { - global $data, $misc; - global $lang; - - include_once BASE_PATH . '/classes/Gui.php'; - - $server_info = $misc->getServerInfo(); - - if (!isset($_POST['formName'])) { - $_POST['formName'] = ''; - } - - if (!isset($_POST['formIsTemplate'])) { - $_POST['formIsTemplate'] = false; - } - - if (!isset($_POST['formTemplate'])) { - $_POST['formTemplate'] = ''; - } - - if (!isset($_POST['formLexize'])) { - $_POST['formLexize'] = ''; - } - - if (!isset($_POST['formInit'])) { - $_POST['formInit'] = ''; - } - - if (!isset($_POST['formOption'])) { - $_POST['formOption'] = ''; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = ''; - } - - // Fetch all FTS dictionaries from the database - $ftstpls = $data->getFtsDictionaryTemplates(); - - $misc->printTrail('schema'); - // TODO: create doc links - $misc->printTitle($lang['strftscreatedict'], 'pg.ftsdict.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" /> ", - "<input type=\"checkbox\" name=\"formIsTemplate\" id=\"formIsTemplate\"", $_POST['formIsTemplate'] ? ' checked="checked" ' : '', " />\n", - "<label for=\"formIsTemplate\">{$lang['strftscreatedicttemplate']}</label></td>\n\t</tr>\n"; - - // Template - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftstemplate']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - $tpls = []; - $tplsel = ''; - while (!$ftstpls->EOF) { - $data->fieldClean($ftstpls->fields['schema']); - $data->fieldClean($ftstpls->fields['name']); - $tplname = $ftstpls->fields['schema'] . '.' . $ftstpls->fields['name']; - $tpls[$tplname] = serialize([ - 'name' => $ftstpls->fields['name'], - 'schema' => $ftstpls->fields['schema'], - ]); - if ($_POST['formTemplate'] == $tpls[$tplname]) { - $tplsel = htmlspecialchars($tpls[$tplname]); - } - $ftstpls->moveNext(); - } - echo GUI::printCombo($tpls, 'formTemplate', true, $tplsel, false); - echo "\n\t\t</td>\n\t</tr>\n"; - - // TODO: what about maxlengths? - // Lexize - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftslexize']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formLexize\" size=\"32\" maxlength=\"1000\" value=\"", - htmlspecialchars($_POST['formLexize']), "\" ", isset($_POST['formIsTemplate']) ? '' : ' disabled="disabled" ', - "/></td>\n\t</tr>\n"; - - // Init - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsinit']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formInit\" size=\"32\" maxlength=\"1000\" value=\"", - htmlspecialchars($_POST['formInit']), "\"", @$_POST['formIsTemplate'] ? '' : ' disabled="disabled" ', - "/></td>\n\t</tr>\n"; - - // Option - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strftsoptionsvalues']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formOption\" size=\"32\" maxlength=\"1000\" value=\"", - htmlspecialchars($_POST['formOption']), "\" /></td>\n\t</tr>\n"; - - // Comment - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"createdict\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</p>\n"; - echo "</form>\n", - "<script type=\"text/javascript\"> - function templateOpts() { - isTpl = document.getElementsByName('formIsTemplate')[0].checked; - document.getElementsByName('formTemplate')[0].disabled = isTpl; - document.getElementsByName('formOption')[0].disabled = isTpl; - document.getElementsByName('formLexize')[0].disabled = !isTpl; - document.getElementsByName('formInit')[0].disabled = !isTpl; - } - - document.getElementsByName('formIsTemplate')[0].onchange = templateOpts; - - templateOpts(); - </script>\n"; -} - -/** - * Actually creates the new FTS dictionary in the database - */ -function doSaveCreateDict() { - global $data, $lang, $_reload_browser; - - // Check that they've given a name - if ($_POST['formName'] == '') { - doCreateDict($lang['strftsdictneedsname']); - } else { - - if (!isset($_POST['formIsTemplate'])) { - $_POST['formIsTemplate'] = false; - } - - if (isset($_POST['formTemplate'])) { - $formTemplate = unserialize($_POST['formTemplate']); - } else { - $formTemplate = ''; - } - - if (!isset($_POST['formLexize'])) { - $_POST['formLexize'] = ''; - } - - if (!isset($_POST['formInit'])) { - $_POST['formInit'] = ''; - } - - if (!isset($_POST['formOption'])) { - $_POST['formOption'] = ''; - } - - $status = $data->createFtsDictionary($_POST['formName'], $_POST['formIsTemplate'], - $formTemplate, $_POST['formLexize'], - $_POST['formInit'], $_POST['formOption'], $_POST['formComment'] - ); - - if ($status == 0) { - $_reload_browser = true; - doViewDicts($lang['strftsdictcreated']); - } else { - doCreateDict($lang['strftsdictcreatedbad']); - } - - } -} - -/** - * Display a form to permit editing FTS dictionary properies. - */ -function doAlterDict($msg = '') { - global $data, $misc, $lang; - - $misc->printTrail('ftscfg'); // TODO: change to smth related to dictionary - $misc->printTitle($lang['stralter'], 'pg.ftsdict.alter'); - $misc->printMsg($msg); - - $ftsdict = $data->getFtsDictionaryByName($_REQUEST['ftsdict']); - if ($ftsdict->recordCount() > 0) { - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = $ftsdict->fields['comment']; - } - - if (!isset($_POST['ftsdict'])) { - $_POST['ftsdict'] = $_REQUEST['ftsdict']; - } - - if (!isset($_POST['formName'])) { - $_POST['formName'] = $_REQUEST['ftsdict']; - } - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<table>\n"; - - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" />\n"; - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - // Comment - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\"name=\"formComment\">", htmlspecialchars($_POST['formComment']), "</textarea></td>\n"; - echo "\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alterdict\" />\n"; - echo "<input type=\"hidden\" name=\"ftsdict\" value=\"", htmlspecialchars($_POST['ftsdict']), "\" />\n"; - echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewdicts\" /></p>\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } -} - -/** - * Save the form submission containing changes to a FTS dictionary - */ -function doSaveAlterDict() { - global $data, $misc, $lang; - - $status = $data->updateFtsDictionary($_POST['ftsdict'], $_POST['formComment'], $_POST['formName']); - if ($status == 0) { - doViewDicts($lang['strftsdictaltered']); - } else { - doAlterDict($lang['strftsdictalteredbad']); - } - -} - -/** - * Show confirmation of drop and perform actual drop of FTS mapping - */ -function doDropMapping($confirm) { - global $data, $misc; - global $lang, $_reload_drop_database; - - if (empty($_REQUEST['mapping']) && empty($_REQUEST['ma'])) { - doDefault($lang['strftsspecifymappingtodrop']); - return; - } - - if (empty($_REQUEST['ftscfg'])) { - doDefault($lang['strftsspecifyconfigtoalter']); - return; - } - - if ($confirm) { - $misc->printTrail('ftscfg'); // TODO: proper breadcrumbs - $misc->printTitle($lang['strdrop'], 'pg.ftscfg.alter'); - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - - // Case of multiaction drop - if (isset($_REQUEST['ma'])) { - - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdropftsmapping'], $misc->printVal($a['mapping']), $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; - printf('<input type="hidden" name="mapping[]" value="%s" />', htmlspecialchars($a['mapping'])); - } - - } else { - echo "<p>", sprintf($lang['strconfdropftsmapping'], $misc->printVal($_REQUEST['mapping']), $misc->printVal($_REQUEST['ftscfg'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"mapping\" value=\"", htmlspecialchars($_REQUEST['mapping']), "\" />\n"; - } - - echo "<input type=\"hidden\" name=\"ftscfg\" value=\"{$_REQUEST['ftscfg']}\" />\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"dropmapping\" />\n"; - echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - // Case of multiaction drop - if (is_array($_REQUEST['mapping'])) { - $status = $data->changeFtsMapping($_REQUEST['ftscfg'], $_REQUEST['mapping'], 'drop'); - if ($status != 0) { - doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdroppedbad']); - return; - } - doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdropped']); - } else { - $status = $data->changeFtsMapping($_REQUEST['ftscfg'], [$_REQUEST['mapping']], 'drop'); - if ($status == 0) { - doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdropped']); - } else { - doViewConfig($_REQUEST['ftscfg'], $lang['strftsmappingdroppedbad']); - } - } - } -} - -function doAlterMapping($msg = '') { - global $data, $misc, $lang; - - $misc->printTrail('ftscfg'); - $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); - $misc->printMsg($msg); - - $ftsdicts = $data->getFtsDictionaries(); - if ($ftsdicts->recordCount() > 0) { - if (!isset($_POST['formMapping'])) { - $_POST['formMapping'] = @$_REQUEST['mapping']; - } - - if (!isset($_POST['formDictionary'])) { - $_POST['formDictionary'] = ''; - } - - if (!isset($_POST['ftscfg'])) { - $_POST['ftscfg'] = $_REQUEST['ftscfg']; - } - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strftsmapping']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - - // Case of multiaction drop - if (isset($_REQUEST['ma'])) { - $ma_mappings = []; - $ma_mappings_names = []; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - printf('<input type="hidden" name="formMapping[]" value="%s" />', htmlspecialchars($a['mapping'])); - $ma_mappings[] = $data->getFtsMappingByName($_POST['ftscfg'], $a['mapping']); - $ma_mappings_names[] = $a['mapping']; - } - echo implode(", ", $ma_mappings_names); - } else { - $mapping = $data->getFtsMappingByName($_POST['ftscfg'], $_POST['formMapping']); - echo $mapping->fields['name']; - echo "<input type=\"hidden\" name=\"formMapping\" value=\"", htmlspecialchars($_POST['formMapping']), "\" />\n"; - } - - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - // Dictionary - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strftsdict']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<select name=\"formDictionary\">\n"; - while (!$ftsdicts->EOF) { - $ftsdict = htmlspecialchars($ftsdicts->fields['name']); - echo "\t\t\t\t<option value=\"{$ftsdict}\"", - ($ftsdict == $_POST['formDictionary'] || $ftsdict == @$mapping->fields['dictionaries'] || $ftsdict == @$ma_mappings[0]->fields['dictionaries']) ? ' selected="selected"' : '', ">{$ftsdict}</option>\n"; - $ftsdicts->moveNext(); - } - - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"altermapping\" />\n"; - echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; - echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; - - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strftsnodictionaries']}</p>\n"; - } -} - -/** - * Save the form submission containing changes to a FTS mapping - */ -function doSaveAlterMapping() { - global $data, $misc, $lang; - - $mappingArray = (is_array($_POST['formMapping']) ? $_POST['formMapping'] : [$_POST['formMapping']]); - $status = $data->changeFtsMapping($_POST['ftscfg'], $mappingArray, 'alter', $_POST['formDictionary']); - if ($status == 0) { - doViewConfig($_POST['ftscfg'], $lang['strftsmappingaltered']); - } else { - doAlterMapping($lang['strftsmappingalteredbad']); - } - -} - -/** - * Show the form to enter parameters of a new FTS mapping - */ -function doAddMapping($msg = '') { - global $data, $misc, $lang; - - $misc->printTrail('ftscfg'); - $misc->printTitle($lang['stralter'], 'pg.ftscfg.alter'); - $misc->printMsg($msg); - - $ftsdicts = $data->getFtsDictionaries(); - if ($ftsdicts->recordCount() > 0) { - if (!isset($_POST['formMapping'])) { - $_POST['formMapping'] = ''; - } - - if (!isset($_POST['formDictionary'])) { - $_POST['formDictionary'] = ''; - } - - if (!isset($_POST['ftscfg'])) { - $_POST['ftscfg'] = $_REQUEST['ftscfg']; - } - - $mappings = $data->getFtsMappings($_POST['ftscfg']); - - echo "<form action=\"/views/fulltext.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strftsmapping']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<select name=\"formMapping\">\n"; - while (!$mappings->EOF) { - $mapping = htmlspecialchars($mappings->fields['name']); - $mapping_desc = htmlspecialchars($mappings->fields['description']); - echo "\t\t\t\t<option value=\"{$mapping}\"", - $mapping == $_POST['formMapping'] ? ' selected="selected"' : '', ">{$mapping}", $mapping_desc ? " - {$mapping_desc}" : "", "</option>\n"; - $mappings->moveNext(); - } - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - // Dictionary - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strftsdict']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<select name=\"formDictionary\">\n"; - while (!$ftsdicts->EOF) { - $ftsdict = htmlspecialchars($ftsdicts->fields['name']); - echo "\t\t\t\t<option value=\"{$ftsdict}\"", - $ftsdict == $_POST['formDictionary'] ? ' selected="selected"' : '', ">{$ftsdict}</option>\n"; - $ftsdicts->moveNext(); - } - - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"addmapping\" />\n"; - echo "<input type=\"hidden\" name=\"ftscfg\" value=\"", htmlspecialchars($_POST['ftscfg']), "\" />\n"; - echo "<input type=\"hidden\" name=\"prev_action\" value=\"viewconfig\" /></p>\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"add\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strftsnodictionaries']}</p>\n"; - } -} - -/** - * Save the form submission containing parameters of a new FTS mapping - */ -function doSaveAddMapping() { - global $data, $misc, $lang; - - $mappingArray = (is_array($_POST['formMapping']) ? $_POST['formMapping'] : [$_POST['formMapping']]); - $status = $data->changeFtsMapping($_POST['ftscfg'], $mappingArray, 'add', $_POST['formDictionary']); - if ($status == 0) { - doViewConfig($_POST['ftscfg'], $lang['strftsmappingadded']); - } else { - doAddMapping($lang['strftsmappingaddedbad']); - } - -} +$fulltext_controller = new \PHPPgAdmin\Controller\FulltextController($container); $misc->printHeader($lang['strschemas']); $misc->printBody(); @@ -1090,40 +25,40 @@ if (isset($_POST['cancel'])) { switch ($action) { case 'createconfig': if (isset($_POST['create'])) { - doSaveCreateConfig(); + $fulltext_controller->doSaveCreateConfig(); } else { - doCreateConfig(); + $fulltext_controller->doCreateConfig(); } break; case 'alterconfig': if (isset($_POST['alter'])) { - doSaveAlterConfig(); + $fulltext_controller->doSaveAlterConfig(); } else { - doAlterConfig(); + $fulltext_controller->doAlterConfig(); } break; case 'dropconfig': if (isset($_POST['drop'])) { - doDropConfig(false); + $fulltext_controller->doDropConfig(false); } else { - doDropConfig(true); + $fulltext_controller->doDropConfig(true); } break; case 'viewconfig': - doViewConfig($_REQUEST['ftscfg']); + $fulltext_controller->doViewConfig($_REQUEST['ftscfg']); break; case 'viewparsers': - doViewParsers(); + $fulltext_controller->doViewParsers(); break; case 'viewdicts': - doViewDicts(); + $fulltext_controller->doViewDicts(); break; case 'createdict': if (isset($_POST['create'])) { - doSaveCreateDict(); + $fulltext_controller->doSaveCreateDict(); } else { doCreateDict(); } @@ -1131,47 +66,47 @@ switch ($action) { break; case 'alterdict': if (isset($_POST['alter'])) { - doSaveAlterDict(); + $fulltext_controller->doSaveAlterDict(); } else { - doAlterDict(); + $fulltext_controller->doAlterDict(); } break; case 'dropdict': if (isset($_POST['drop'])) { - doDropDict(false); + $fulltext_controller->doDropDict(false); } else { - doDropDict(true); + $fulltext_controller->doDropDict(true); } break; case 'dropmapping': if (isset($_POST['drop'])) { - doDropMapping(false); + $fulltext_controller->doDropMapping(false); } else { - doDropMapping(true); + $fulltext_controller->doDropMapping(true); } break; case 'altermapping': if (isset($_POST['alter'])) { - doSaveAlterMapping(); + $fulltext_controller->doSaveAlterMapping(); } else { - doAlterMapping(); + $fulltext_controller->doAlterMapping(); } break; case 'addmapping': if (isset($_POST['add'])) { - doSaveAddMapping(); + $fulltext_controller->doSaveAddMapping(); } else { - doAddMapping(); + $fulltext_controller->doAddMapping(); } break; default: - doDefault(); + $fulltext_controller->doDefault(); break; } diff --git a/src/views/functions.php b/src/views/functions.php index 07fe1d6e..20b85f09 100644 --- a/src/views/functions.php +++ b/src/views/functions.php @@ -9,1062 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Function to save after editing a function - */ -function doSaveEdit() { - global $data, $lang, $misc, $_reload_browser; - - $fnlang = strtolower($_POST['original_lang']); - - if ($fnlang == 'c') { - $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']]; - } else if ($fnlang == 'internal') { - $def = $_POST['formLinkSymbol']; - } else { - $def = $_POST['formDefinition']; - } - if (!$data->hasFunctionAlterSchema()) { - $_POST['formFuncSchema'] = ''; - } - - $status = $data->setFunction($_POST['function_oid'], $_POST['original_function'], $_POST['formFunction'], - $_POST['original_arguments'], $_POST['original_returns'], $def, - $_POST['original_lang'], $_POST['formProperties'], isset($_POST['original_setof']), - $_POST['original_owner'], $_POST['formFuncOwn'], $_POST['original_schema'], - $_POST['formFuncSchema'], isset($_POST['formCost']) ? $_POST['formCost'] : null, - isset($_POST['formRows']) ? $_POST['formRows'] : 0, $_POST['formComment']); - - if ($status == 0) { - // If function has had schema altered, need to change to the new schema - // and reload the browser frame. - if (!empty($_POST['formFuncSchema']) && ($_POST['formFuncSchema'] != $_POST['original_schema'])) { - // Jump them to the new function schema - $misc->setCurrentSchema($_POST['formFuncSchema']); - // Force a browser reload - $_reload_browser = true; - } - doProperties($lang['strfunctionupdated']); - } else { - doEdit($lang['strfunctionupdatedbad']); - } -} - -/** - * Function to allow editing of a Function - */ -function doEdit($msg = '') { - global $data, $misc; - global $lang; - $misc->printTrail('function'); - $misc->printTitle($lang['stralter'], 'pg.function.alter'); - $misc->printMsg($msg); - - $fndata = $data->getFunction($_REQUEST['function_oid']); - - if ($fndata->recordCount() > 0) { - $fndata->fields['proretset'] = $data->phpBool($fndata->fields['proretset']); - - // Initialise variables - if (!isset($_POST['formDefinition'])) { - $_POST['formDefinition'] = $fndata->fields['prosrc']; - } - - if (!isset($_POST['formProperties'])) { - $_POST['formProperties'] = $data->getFunctionProperties($fndata->fields); - } - - if (!isset($_POST['formFunction'])) { - $_POST['formFunction'] = $fndata->fields['proname']; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = $fndata->fields['procomment']; - } - - if (!isset($_POST['formObjectFile'])) { - $_POST['formObjectFile'] = $fndata->fields['probin']; - } - - if (!isset($_POST['formLinkSymbol'])) { - $_POST['formLinkSymbol'] = $fndata->fields['prosrc']; - } - - if (!isset($_POST['formFuncOwn'])) { - $_POST['formFuncOwn'] = $fndata->fields['proowner']; - } - - if (!isset($_POST['formFuncSchema'])) { - $_POST['formFuncSchema'] = $fndata->fields['proschema']; - } - - if ($data->hasFunctionCosting()) { - if (!isset($_POST['formCost'])) { - $_POST['formCost'] = $fndata->fields['procost']; - } - - if (!isset($_POST['formRows'])) { - $_POST['formRows'] = $fndata->fields['prorows']; - } - - } - - // Deal with named parameters - if ($data->hasNamedParams()) { - if (isset($fndata->fields['proallarguments'])) { - $args_arr = $data->phpArray($fndata->fields['proallarguments']); - } else { - $args_arr = explode(', ', $fndata->fields['proarguments']); - } - $names_arr = $data->phpArray($fndata->fields['proargnames']); - $modes_arr = $data->phpArray($fndata->fields['proargmodes']); - $args = ''; - $i = 0; - for ($i = 0; $i < sizeof($args_arr); $i++) { - if ($i != 0) { - $args .= ', '; - } - - if (isset($modes_arr[$i])) { - switch ($modes_arr[$i]) { - case 'i':$args .= " IN "; - break; - case 'o':$args .= " OUT "; - break; - case 'b':$args .= " INOUT "; - break; - case 'v':$args .= " VARIADIC "; - break; - case 't':$args .= " TABLE "; - break; - } - } - if (isset($names_arr[$i]) && $names_arr[$i] != '') { - $data->fieldClean($names_arr[$i]); - $args .= '"' . $names_arr[$i] . '" '; - } - $args .= $args_arr[$i]; - } - } else { - $args = $fndata->fields['proarguments']; - } - - $func_full = $fndata->fields['proname'] . "(" . $fndata->fields['proarguments'] . ")"; - echo "<form action=\"/views/functions.php\" method=\"post\">\n"; - echo "<table style=\"width: 90%\">\n"; - echo "<tr>\n"; - echo "<th class=\"data required\">{$lang['strschema']}</th>\n"; - echo "<th class=\"data required\">{$lang['strfunction']}</th>\n"; - echo "<th class=\"data\">{$lang['strarguments']}</th>\n"; - echo "<th class=\"data required\">{$lang['strreturns']}</th>\n"; - echo "<th class=\"data required\">{$lang['strproglanguage']}</th>\n"; - echo "</tr>\n"; - - echo "<tr>\n"; - echo "<td class=\"data1\">"; - echo "<input type=\"hidden\" name=\"original_schema\" value=\"", htmlspecialchars($fndata->fields['proschema']), "\" />\n"; - if ($data->hasFunctionAlterSchema()) { - $schemas = $data->getSchemas(); - echo "<select name=\"formFuncSchema\">"; - while (!$schemas->EOF) { - $schema = $schemas->fields['nspname']; - echo "<option value=\"", htmlspecialchars($schema), "\"", - ($schema == $_POST['formFuncSchema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; - $schemas->moveNext(); - } - echo "</select>\n"; - } else { - echo $fndata->fields['proschema']; - } - - echo "</td>\n"; - echo "<td class=\"data1\">"; - echo "<input type=\"hidden\" name=\"original_function\" value=\"", htmlspecialchars($fndata->fields['proname']), "\" />\n"; - echo "<input name=\"formFunction\" style=\"width: 100%\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_POST['formFunction']), "\" />"; - echo "</td>\n"; - - echo "<td class=\"data1\">", $misc->printVal($args), "\n"; - echo "<input type=\"hidden\" name=\"original_arguments\" value=\"", htmlspecialchars($args), "\" />\n"; - echo "</td>\n"; - - echo "<td class=\"data1\">"; - if ($fndata->fields['proretset']) { - echo "setof "; - } - - echo $misc->printVal($fndata->fields['proresult']), "\n"; - echo "<input type=\"hidden\" name=\"original_returns\" value=\"", htmlspecialchars($fndata->fields['proresult']), "\" />\n"; - if ($fndata->fields['proretset']) { - echo "<input type=\"hidden\" name=\"original_setof\" value=\"yes\" />\n"; - } - - echo "</td>\n"; - - echo "<td class=\"data1\">", $misc->printVal($fndata->fields['prolanguage']), "\n"; - echo "<input type=\"hidden\" name=\"original_lang\" value=\"", htmlspecialchars($fndata->fields['prolanguage']), "\" />\n"; - echo "</td>\n"; - echo "</tr>\n"; - - $fnlang = strtolower($fndata->fields['prolanguage']); - if ($fnlang == 'c') { - echo "<tr><th class=\"data required\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; - echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formObjectFile\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n"; - echo "<td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; - } else if ($fnlang == 'internal') { - echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"5\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; - } else { - echo "<tr><th class=\"data required\" colspan=\"5\">{$lang['strdefinition']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"5\"><textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", - htmlspecialchars($_POST['formDefinition']), "</textarea></td></tr>\n"; - } - - // Display function comment - echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strcomment']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"5\"><textarea style=\"width:100%;\" name=\"formComment\" rows=\"3\" cols=\"50\">", - htmlspecialchars($_POST['formComment']), "</textarea></td></tr>\n"; - - // Display function cost options - if ($data->hasFunctionCosting()) { - echo "<tr><th class=\"data required\" colspan=\"5\">{$lang['strfunctioncosting']}</th></tr>\n"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" . - htmlspecialchars($_POST['formCost']) . "\" /></td>"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"", - htmlspecialchars($_POST['formRows']), "\"", (!$fndata->fields['proretset']) ? 'disabled' : '', "/></td>"; - } - - // Display function properties - if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { - echo "<tr><th class=\"data\" colspan=\"5\">{$lang['strproperties']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"5\">\n"; - $i = 0; - foreach ($data->funcprops as $k => $v) { - echo "<select name=\"formProperties[{$i}]\">\n"; - foreach ($v as $p) { - echo "<option value=\"", htmlspecialchars($p), "\"", - ($p == $_POST['formProperties'][$i]) ? ' selected="selected"' : '', - ">", $misc->printVal($p), "</option>\n"; - } - echo "</select><br />\n"; - $i++; - } - echo "</td></tr>\n"; - } - - // function owner - if ($data->hasFunctionAlterOwner()) { - $users = $data->getUsers(); - echo "<tr><td class=\"data1\" colspan=\"5\">{$lang['strowner']}: <select name=\"formFuncOwn\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['formFuncOwn']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select>\n"; - echo "<input type=\"hidden\" name=\"original_owner\" value=\"", htmlspecialchars($fndata->fields['proowner']), "\" />\n"; - echo "</td></tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; - echo "<input type=\"hidden\" name=\"function\" value=\"", htmlspecialchars($_REQUEST['function']), "\" />\n"; - echo "<input type=\"hidden\" name=\"function_oid\" value=\"", htmlspecialchars($_REQUEST['function_oid']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Show read only properties of a function - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('function'); - $misc->printTitle($lang['strproperties'], 'pg.function'); - $misc->printMsg($msg); - - $funcdata = $data->getFunction($_REQUEST['function_oid']); - - if ($funcdata->recordCount() > 0) { - // Deal with named parameters - if ($data->hasNamedParams()) { - if (isset($funcdata->fields['proallarguments'])) { - $args_arr = $data->phpArray($funcdata->fields['proallarguments']); - } else { - $args_arr = explode(', ', $funcdata->fields['proarguments']); - } - $names_arr = $data->phpArray($funcdata->fields['proargnames']); - $modes_arr = $data->phpArray($funcdata->fields['proargmodes']); - $args = ''; - $i = 0; - for ($i = 0; $i < sizeof($args_arr); $i++) { - if ($i != 0) { - $args .= ', '; - } - - if (isset($modes_arr[$i])) { - switch ($modes_arr[$i]) { - case 'i':$args .= " IN "; - break; - case 'o':$args .= " OUT "; - break; - case 'b':$args .= " INOUT "; - break; - case 'v':$args .= " VARIADIC "; - break; - case 't':$args .= " TABLE "; - break; - } - } - if (isset($names_arr[$i]) && $names_arr[$i] != '') { - $data->fieldClean($names_arr[$i]); - $args .= '"' . $names_arr[$i] . '" '; - } - $args .= $args_arr[$i]; - } - } else { - $args = $funcdata->fields['proarguments']; - } - - // Show comment if any - if ($funcdata->fields['procomment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($funcdata->fields['procomment']), "</p>\n"; - } - - $funcdata->fields['proretset'] = $data->phpBool($funcdata->fields['proretset']); - $func_full = $funcdata->fields['proname'] . "(" . $funcdata->fields['proarguments'] . ")"; - echo "<table style=\"width: 90%\">\n"; - echo "<tr><th class=\"data\">{$lang['strfunction']}</th>\n"; - echo "<th class=\"data\">{$lang['strarguments']}</th>\n"; - echo "<th class=\"data\">{$lang['strreturns']}</th>\n"; - echo "<th class=\"data\">{$lang['strproglanguage']}</th></tr>\n"; - echo "<tr><td class=\"data1\">", $misc->printVal($funcdata->fields['proname']), "</td>\n"; - echo "<td class=\"data1\">", $misc->printVal($args), "</td>\n"; - echo "<td class=\"data1\">"; - if ($funcdata->fields['proretset']) { - echo "setof "; - } - - echo $misc->printVal($funcdata->fields['proresult']), "</td>\n"; - echo "<td class=\"data1\">", $misc->printVal($funcdata->fields['prolanguage']), "</td></tr>\n"; - - $fnlang = strtolower($funcdata->fields['prolanguage']); - if ($fnlang == 'c') { - echo "<tr><th class=\"data\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; - echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"2\">", $misc->printVal($funcdata->fields['probin']), "</td>\n"; - echo "<td class=\"data1\" colspan=\"2\">", $misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n"; - } else if ($fnlang == 'internal') { - echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\">", $misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n"; - } else { - include_once BASE_PATH . '/src/highlight.php'; - echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strdefinition']}</th></tr>\n"; - // Check to see if we have syntax highlighting for this language - if (isset($data->langmap[$funcdata->fields['prolanguage']])) { - $temp = syntax_highlight(htmlspecialchars($funcdata->fields['prosrc']), $data->langmap[$funcdata->fields['prolanguage']]); - $tag = 'prenoescape'; - } else { - $temp = $funcdata->fields['prosrc']; - $tag = 'pre'; - } - echo "<tr><td class=\"data1\" colspan=\"4\">", $misc->printVal($temp, $tag, ['lineno' => true, 'class' => 'data1']), "</td></tr>\n"; - } - - // Display function cost options - if ($data->hasFunctionCosting()) { - echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strfunctioncosting']}</th></tr>\n"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: ", $misc->printVal($funcdata->fields['procost']), " </td>"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: ", $misc->printVal($funcdata->fields['prorows']), " </td>"; - } - - // Show flags - if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { - // Fetch an array of the function properties - $funcprops = $data->getFunctionProperties($funcdata->fields); - echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strproperties']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\">\n"; - foreach ($funcprops as $v) { - echo $misc->printVal($v), "<br />\n"; - } - echo "</td></tr>\n"; - } - - echo "<tr><td class=\"data1\" colspan=\"5\">{$lang['strowner']}: ", htmlspecialchars($funcdata->fields['proowner']), "\n"; - echo "</td></tr>\n"; - echo "</table>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - $navlinks = [ - 'showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strshowallfunctions'], - ], - 'alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'edit', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'function' => $_REQUEST['function'], - 'function_oid' => $_REQUEST['function_oid'], - ], - ], - ], - 'content' => $lang['stralter'], - ], - 'drop' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'function' => $func_full, - 'function_oid' => $_REQUEST['function_oid'], - ], - ], - ], - 'content' => $lang['strdrop'], - ], - ]; - - $misc->printNavLinks($navlinks, 'functions-properties', get_defined_vars()); -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_browser; - - if (empty($_REQUEST['function']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifyfunctiontodrop']); - exit(); - } - - if ($confirm) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strdrop'], 'pg.function.drop'); - - echo "<form action=\"/views/functions.php\" method=\"post\">\n"; - - //If multi drop - if (isset($_REQUEST['ma'])) { - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdropfunction'], $misc->printVal($a['function'])), "</p>\n"; - echo '<input type="hidden" name="function[]" value="', htmlspecialchars($a['function']), "\" />\n"; - echo "<input type=\"hidden\" name=\"function_oid[]\" value=\"", htmlspecialchars($a['function_oid']), "\" />\n"; - } - } else { - echo "<p>", sprintf($lang['strconfdropfunction'], $misc->printVal($_REQUEST['function'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"function\" value=\"", htmlspecialchars($_REQUEST['function']), "\" />\n"; - echo "<input type=\"hidden\" name=\"function_oid\" value=\"", htmlspecialchars($_REQUEST['function_oid']), "\" />\n"; - } - - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /><label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - if (is_array($_POST['function_oid'])) { - $msg = ''; - $status = $data->beginTransaction(); - if ($status == 0) { - foreach ($_POST['function_oid'] as $k => $s) { - $status = $data->dropFunction($s, isset($_POST['cascade'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $lang['strfunctiondropped']); - } else { - $data->endTransaction(); - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $lang['strfunctiondroppedbad'])); - return; - } - } - } - if ($data->endTransaction() == 0) { - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - doDefault($lang['strfunctiondroppedbad']); - } - - } else { - $status = $data->dropFunction($_POST['function_oid'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strfunctiondropped']); - } else { - doDefault($lang['strfunctiondroppedbad']); - } - } - } - -} - -/** - * Displays a screen where they can enter a new function - */ -function doCreate($msg = '', $szJS = "") { - global $data, $misc; - global $lang; - - $misc->printTrail('schema'); - if (!isset($_POST['formFunction'])) { - $_POST['formFunction'] = ''; - } - - if (!isset($_POST['formArguments'])) { - $_POST['formArguments'] = ''; - } - - if (!isset($_POST['formReturns'])) { - $_POST['formReturns'] = ''; - } - - if (!isset($_POST['formLanguage'])) { - $_POST['formLanguage'] = isset($_REQUEST['language']) ? $_REQUEST['language'] : 'sql'; - } - - if (!isset($_POST['formDefinition'])) { - $_POST['formDefinition'] = ''; - } - - if (!isset($_POST['formObjectFile'])) { - $_POST['formObjectFile'] = ''; - } - - if (!isset($_POST['formLinkSymbol'])) { - $_POST['formLinkSymbol'] = ''; - } - - if (!isset($_POST['formProperties'])) { - $_POST['formProperties'] = $data->defaultprops; - } - - if (!isset($_POST['formSetOf'])) { - $_POST['formSetOf'] = ''; - } - - if (!isset($_POST['formArray'])) { - $_POST['formArray'] = ''; - } - - if (!isset($_POST['formCost'])) { - $_POST['formCost'] = ''; - } - - if (!isset($_POST['formRows'])) { - $_POST['formRows'] = ''; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = ''; - } - - $types = $data->getTypes(true, true, true); - $langs = $data->getLanguages(true); - $fnlang = strtolower($_POST['formLanguage']); - - switch ($fnlang) { - case 'c': - $misc->printTitle($lang['strcreatecfunction'], 'pg.function.create.c'); - break; - case 'internal': - $misc->printTitle($lang['strcreateinternalfunction'], 'pg.function.create.internal'); - break; - default: - $misc->printTitle($lang['strcreateplfunction'], 'pg.function.create.pl'); - break; - } - $misc->printMsg($msg); - - // Create string for return type list - $szTypes = ""; - while (!$types->EOF) { - $szSelected = ""; - if ($types->fields['typname'] == $_POST['formReturns']) { - $szSelected = " selected=\"selected\""; - } - /* this variable is include in the JS code bellow, so we need to ENT_QUOTES */ - $szTypes .= "<option value=\"" . htmlspecialchars($types->fields['typname'], ENT_QUOTES) . "\"{$szSelected}>"; - $szTypes .= htmlspecialchars($types->fields['typname'], ENT_QUOTES) . "</option>"; - $types->moveNext(); - } - - $szFunctionName = "<td class=\"data1\"><input name=\"formFunction\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"" . - htmlspecialchars($_POST['formFunction']) . "\" /></td>"; - - $szArguments = "<td class=\"data1\"><input name=\"formArguments\" style=\"width:100%;\" size=\"16\" value=\"" . - htmlspecialchars($_POST['formArguments']) . "\" /></td>"; - - $szSetOfSelected = ""; - $szNotSetOfSelected = ""; - if ($_POST['formSetOf'] == '') { - $szNotSetOfSelected = " selected=\"selected\""; - } else if ($_POST['formSetOf'] == 'SETOF') { - $szSetOfSelected = " selected=\"selected\""; - } - $szReturns = "<td class=\"data1\" colspan=\"2\">"; - $szReturns .= "<select name=\"formSetOf\">"; - $szReturns .= "<option value=\"\"{$szNotSetOfSelected}></option>"; - $szReturns .= "<option value=\"SETOF\"{$szSetOfSelected}>SETOF</option>"; - $szReturns .= "</select>"; - - $szReturns .= "<select name=\"formReturns\">" . $szTypes . "</select>"; - - // Create string array type selector - - $szArraySelected = ""; - $szNotArraySelected = ""; - if ($_POST['formArray'] == '') { - $szNotArraySelected = " selected=\"selected\""; - } else if ($_POST['formArray'] == '[]') { - $szArraySelected = " selected=\"selected\""; - } - - $szReturns .= "<select name=\"formArray\">"; - $szReturns .= "<option value=\"\"{$szNotArraySelected}></option>"; - $szReturns .= "<option value=\"[]\"{$szArraySelected}>[ ]</option>"; - $szReturns .= "</select>\n</td>"; - - // Create string for language - $szLanguage = "<td class=\"data1\">"; - if ($fnlang == 'c' || $fnlang == 'internal') { - $szLanguage .= $_POST['formLanguage'] . "\n"; - $szLanguage .= "<input type=\"hidden\" name=\"formLanguage\" value=\"{$_POST['formLanguage']}\" />\n"; - } else { - $szLanguage .= "<select name=\"formLanguage\">\n"; - while (!$langs->EOF) { - $szSelected = ''; - if ($langs->fields['lanname'] == $_POST['formLanguage']) { - $szSelected = ' selected="selected"'; - } - if (strtolower($langs->fields['lanname']) != 'c' && strtolower($langs->fields['lanname']) != 'internal') { - $szLanguage .= "<option value=\"" . htmlspecialchars($langs->fields['lanname']) . "\"{$szSelected}>\n" . - $misc->printVal($langs->fields['lanname']) . "</option>"; - } - - $langs->moveNext(); - } - $szLanguage .= "</select>\n"; - } - - $szLanguage .= "</td>"; - $szJSArguments = "<tr><th class=\"data\" colspan=\"7\">{$lang['strarguments']}</th></tr>"; - $arrayModes = ["IN", "OUT", "INOUT"]; - $szModes = "<select name=\"formArgModes[]\" style=\"width:100%;\">"; - foreach ($arrayModes as $pV) { - $szModes .= "<option value=\"{$pV}\">{$pV}</option>"; - } - $szModes .= "</select>"; - $szArgReturns = "<select name=\"formArgArray[]\">"; - $szArgReturns .= "<option value=\"\"></option>"; - $szArgReturns .= "<option value=\"[]\">[]</option>"; - $szArgReturns .= "</select>"; - if (!empty($conf['theme'])) { - $szImgPath = "images/themes/{$conf['theme']}"; - } else { - $szImgPath = "images/themes/default"; - } - if (empty($msg)) { - $szJSTRArg = "<script type=\"text/javascript\" >addArg();</script>\n"; - } else { - $szJSTRArg = ""; - } - $szJSAddTR = "<tr id=\"parent_add_tr\" onclick=\"addArg();\" onmouseover=\"this.style.cursor='pointer'\">\n<td style=\"text-align: right\" colspan=\"6\" class=\"data3\"><table><tr><td class=\"data3\"><img src=\"{$szImgPath}/AddArguments.png\" alt=\"Add Argument\" /></td><td class=\"data3\"><span style=\"font-size: 8pt\">{$lang['strargadd']}</span></td></tr></table></td>\n</tr>\n"; - - echo "<script src=\"/js/functions.js\" type=\"text/javascript\"></script> - <script type=\"text/javascript\"> - //<![CDATA[ - var g_types_select = '<select name=\"formArgType[]\">{$szTypes}</select>{$szArgReturns}'; - var g_modes_select = '{$szModes}'; - var g_name = ''; - var g_lang_strargremove = '", htmlspecialchars($lang["strargremove"], ENT_QUOTES), "'; - var g_lang_strargnoargs = '", htmlspecialchars($lang["strargnoargs"], ENT_QUOTES), "'; - var g_lang_strargenableargs = '", htmlspecialchars($lang["strargenableargs"], ENT_QUOTES), "'; - var g_lang_strargnorowabove = '", htmlspecialchars($lang["strargnorowabove"], ENT_QUOTES), "'; - var g_lang_strargnorowbelow = '", htmlspecialchars($lang["strargnorowbelow"], ENT_QUOTES), "'; - var g_lang_strargremoveconfirm = '", htmlspecialchars($lang["strargremoveconfirm"], ENT_QUOTES), "'; - var g_lang_strargraise = '", htmlspecialchars($lang["strargraise"], ENT_QUOTES), "'; - var g_lang_strarglower = '", htmlspecialchars($lang["strarglower"], ENT_QUOTES), "'; - //]]> - </script> - "; - echo "<form action=\"/views//views/functions.php\" method=\"post\">\n"; - echo "<table><tbody id=\"args_table\">\n"; - echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n"; - echo "<th class=\"data required\" colspan=\"2\">{$lang['strreturns']}</th>\n"; - echo "<th class=\"data required\">{$lang['strproglanguage']}</th></tr>\n"; - echo "<tr>\n"; - echo "{$szFunctionName}\n"; - echo "{$szReturns}\n"; - echo "{$szLanguage}\n"; - echo "</tr>\n"; - echo "{$szJSArguments}\n"; - echo "<tr>\n"; - echo "<th class=\"data required\">{$lang['strargmode']}</th>\n"; - echo "<th class=\"data required\">{$lang['strname']}</th>\n"; - echo "<th class=\"data required\" colspan=\"2\">{$lang['strargtype']}</th>\n"; - echo "</tr>\n"; - echo "{$szJSAddTR}\n"; - - if ($fnlang == 'c') { - echo "<tr><th class=\"data required\" colspan=\"2\">{$lang['strobjectfile']}</th>\n"; - echo "<th class=\"data\" colspan=\"2\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formObjectFile\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n"; - echo "<td class=\"data1\" colspan=\"2\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; - } else if ($fnlang == 'internal') { - echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strlinksymbol']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\"><input type=\"text\" name=\"formLinkSymbol\" style=\"width:100%\" value=\"", - htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n"; - } else { - echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strdefinition']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\"><textarea style=\"width:100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", - htmlspecialchars($_POST['formDefinition']), "</textarea></td></tr>\n"; - } - - // Display function comment - echo "<tr><th class=\"data\" colspan=\"4\">{$lang['strcomment']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\"><textarea style=\"width:100%;\" name=\"formComment\" rows=\"3\" cols=\"50\">", - htmlspecialchars($_POST['formComment']), "</textarea></td></tr>\n"; - - // Display function cost options - if ($data->hasFunctionCosting()) { - echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strfunctioncosting']}</th></tr>\n"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" . - htmlspecialchars($_POST['formCost']) . "\" /></td>"; - echo "<td class=\"data1\" colspan=\"2\">{$lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"" . - htmlspecialchars($_POST['formRows']) . "\" /></td>"; - } - - // Display function properties - if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) { - echo "<tr><th class=\"data required\" colspan=\"4\">{$lang['strproperties']}</th></tr>\n"; - echo "<tr><td class=\"data1\" colspan=\"4\">\n"; - $i = 0; - foreach ($data->funcprops as $k => $v) { - echo "<select name=\"formProperties[{$i}]\">\n"; - foreach ($v as $p) { - echo "<option value=\"", htmlspecialchars($p), "\"", - ($p == $_POST['formProperties'][$i]) ? ' selected="selected"' : '', - ">", $misc->printVal($p), "</option>\n"; - } - echo "</select><br />\n"; - $i++; - } - echo "</td></tr>\n"; - } - echo "</tbody></table>\n"; - echo $szJSTRArg; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - echo $szJS; -} - -/** - * Actually creates the new function in the database - */ -function doSaveCreate() { - global $data, $lang; - - $fnlang = strtolower($_POST['formLanguage']); - - if ($fnlang == 'c') { - $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']]; - } else if ($fnlang == 'internal') { - $def = $_POST['formLinkSymbol']; - } else { - $def = $_POST['formDefinition']; - } - - $szJS = ''; - - echo "<script src=\"/js/functions.js\" type=\"text/javascript\"></script>"; - echo "<script type=\"text/javascript\">" . buildJSData() . '</script>'; - if (!empty($_POST['formArgName'])) { - $szJS = buildJSRows(buildFunctionArguments($_POST)); - } else { - $szJS = "<script type=\"text/javascript\" src=\"/js/functions.js\">noArgsRebuild(addArg());</script>"; - } - - $cost = (isset($_POST['formCost'])) ? $_POST['formCost'] : null; - if ($cost == '' || !is_numeric($cost) || $cost != (int) $cost || $cost < 0) { - $cost = null; - } - - $rows = (isset($_POST['formRows'])) ? $_POST['formRows'] : null; - if ($rows == '' || !is_numeric($rows) || $rows != (int) $rows) { - $rows = null; - } - - // Check that they've given a name and a definition - if ($_POST['formFunction'] == '') { - doCreate($lang['strfunctionneedsname'], $szJS); - } elseif ($fnlang != 'internal' && !$def) { - doCreate($lang['strfunctionneedsdef'], $szJS); - } else { - // Append array symbol to type if chosen - $status = $data->createFunction($_POST['formFunction'], empty($_POST['nojs']) ? buildFunctionArguments($_POST) : $_POST['formArguments'], - $_POST['formReturns'] . $_POST['formArray'], $def, $_POST['formLanguage'], - $_POST['formProperties'], $_POST['formSetOf'] == 'SETOF', - $cost, $rows, $_POST['formComment'], false); - if ($status == 0) { - doDefault($lang['strfunctioncreated']); - } else { - doCreate($lang['strfunctioncreatedbad'], $szJS); - } - } -} - -/** - * Build out the function arguments string - */ -function buildFunctionArguments($arrayVars) { - if (isset($_POST['formArgName'])) { - $arrayArgs = []; - foreach ($arrayVars['formArgName'] as $pK => $pV) { - $arrayArgs[] = $arrayVars['formArgModes'][$pK] . ' ' . trim($pV) . ' ' . trim($arrayVars['formArgType'][$pK]) . $arrayVars['formArgArray'][$pK]; - } - return implode(",", $arrayArgs); - } - return ''; -} - -/** - * Build out JS to re-create table rows for arguments - */ -function buildJSRows($szArgs) { - $arrayModes = ['IN', 'OUT', 'INOUT']; - $arrayArgs = explode(',', $szArgs); - $arrayProperArgs = []; - $nC = 0; - $szReturn = ''; - foreach ($arrayArgs as $pV) { - $arrayWords = explode(' ', $pV); - if (in_array($arrayWords[0], $arrayModes) === true) { - $szMode = $arrayWords[0]; - array_shift($arrayWords); - } - $szArgName = array_shift($arrayWords); - if (strpos($arrayWords[count($arrayWords) - 1], '[]') === false) { - $szArgType = implode(" ", $arrayWords); - $bArgIsArray = "false"; - } else { - $szArgType = str_replace('[]', '', implode(' ', $arrayWords)); - $bArgIsArray = "true"; - } - $arrayProperArgs[] = [$szMode, $szArgName, $szArgType, $bArgIsArray]; - $szReturn .= "<script type=\"text/javascript\">RebuildArgTR('{$szMode}','{$szArgName}','{$szArgType}',new Boolean({$bArgIsArray}));</script>"; - $nC++; - } - return $szReturn; -} - -function buildJSData() { - global $data; - $arrayModes = ['IN', 'OUT', 'INOUT']; - $arrayTypes = $data->getTypes(true, true, true); - $arrayPTypes = []; - $arrayPModes = []; - $szTypes = ''; - - while (!$arrayTypes->EOF) { - $arrayPTypes[] = "'" . $arrayTypes->fields['typname'] . "'"; - $arrayTypes->moveNext(); - } - - foreach ($arrayModes as $pV) { - $arrayPModes[] = "'{$pV}'"; - } - - $szTypes = 'g_main_types = new Array(' . implode(',', $arrayPTypes) . ');'; - $szModes = 'g_main_modes = new Array(' . implode(',', $arrayPModes) . ');'; - return $szTypes . $szModes; -} - -/** - * Show default list of functions in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc, $func; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'functions'); - $misc->printMsg($msg); - - $funcs = $data->getFunctions(); - - $columns = [ - 'function' => [ - 'title' => $lang['strfunction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proproto'), - 'url' => "/redirect/function?action=properties&{$misc->href}&", - 'vars' => ['function' => 'proproto', 'function_oid' => 'prooid'], - ], - 'returns' => [ - 'title' => $lang['strreturns'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proreturns'), - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proowner'), - ], - 'proglanguage' => [ - 'title' => $lang['strproglanguage'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('prolanguage'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('procomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['function' => 'proproto', 'function_oid' => 'prooid'], - 'url' => 'functions.php', - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'edit', - 'function' => \PHPPgAdmin\Decorators\Decorator::field('proproto'), - 'function_oid' => \PHPPgAdmin\Decorators\Decorator::field('prooid'), - ], - ], - ], - ], - 'drop' => [ - 'multiaction' => 'confirm_drop', - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'function' => \PHPPgAdmin\Decorators\Decorator::field('proproto'), - 'function_oid' => \PHPPgAdmin\Decorators\Decorator::field('prooid'), - ], - ], - ], - ], - 'privileges' => [ - 'content' => $lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges.php', - 'urlvars' => [ - 'subject' => 'function', - 'function' => \PHPPgAdmin\Decorators\Decorator::field('proproto'), - 'function_oid' => \PHPPgAdmin\Decorators\Decorator::field('prooid'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($funcs, $columns, $actions, 'functions-functions', $lang['strnofunctions']); - - $navlinks = [ - 'createpl' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateplfunction'], - ], - 'createinternal' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'create', - 'language' => 'internal', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateinternalfunction'], - ], - 'createc' => [ - 'attr' => [ - 'href' => [ - 'url' => 'functions.php', - 'urlvars' => [ - 'action' => 'create', - 'language' => 'C', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatecfunction'], - ], - ]; - - $misc->printNavLinks($navlinks, 'functions-functions', get_defined_vars()); -} +$function_controller = new \PHPPgAdmin\Controller\FunctionController($container); $misc->printHeader($lang['strfunctions']); $misc->printBody(); @@ -1072,42 +17,42 @@ $misc->printBody(); switch ($action) { case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $function_controller->doDefault(); } else { - doSaveCreate(); + $function_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $function_controller->doCreate(); break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $function_controller->doDrop(false); } else { - doDefault(); + $function_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $function_controller->doDrop(true); break; case 'save_edit': if (isset($_POST['cancel'])) { - doDefault(); + $function_controller->doDefault(); } else { - doSaveEdit(); + $function_controller->doSaveEdit(); } break; case 'edit': - doEdit(); + $function_controller->doEdit(); break; case 'properties': - doProperties(); + $function_controller->doProperties(); break; default: - doDefault(); + $function_controller->doDefault(); break; } diff --git a/src/views/groups.php b/src/views/groups.php index 800bc004..b950527e 100644 --- a/src/views/groups.php +++ b/src/views/groups.php @@ -9,348 +9,59 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Add user to a group - */ -function doAddMember() { - global $data, $misc; - global $lang; - - $status = $data->addGroupMember($_REQUEST['group'], $_REQUEST['user']); - if ($status == 0) { - doProperties($lang['strmemberadded']); - } else { - doProperties($lang['strmemberaddedbad']); - } - -} - -/** - * Show confirmation of drop user from group and perform actual drop - */ -function doDropMember($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('group'); - $misc->printTitle($lang['strdropmember'], 'pg.group.alter'); - - echo "<p>", sprintf($lang['strconfdropmember'], $misc->printVal($_REQUEST['user']), $misc->printVal($_REQUEST['group'])), "</p>\n"; - - echo "<form action=\"/views/groups.php\" method=\"post\">\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"action\" value=\"drop_member\" />\n"; - echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; - echo "<input type=\"hidden\" name=\"user\" value=\"", htmlspecialchars($_REQUEST['user']), "\" />\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropGroupMember($_REQUEST['group'], $_REQUEST['user']); - if ($status == 0) { - doProperties($lang['strmemberdropped']); - } else { - doDropMember(true, $lang['strmemberdroppedbad']); - } - - } -} - -/** - * Show read only properties for a group - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['user'])) { - $_POST['user'] = ''; - } - - $misc->printTrail('group'); - $misc->printTitle($lang['strproperties'], 'pg.group'); - $misc->printMsg($msg); - - $groupdata = $data->getGroup($_REQUEST['group']); - $users = $data->getUsers(); - - if ($groupdata->recordCount() > 0) { - $columns = [ - 'members' => [ - 'title' => $lang['strmembers'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'groups.php', - 'urlvars' => [ - 'action' => 'confirm_drop_member', - 'group' => $_REQUEST['group'], - 'user' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($groupdata, $columns, $actions, 'groups-members', $lang['strnousers']); - } - - // Display form for adding a user to the group - echo "<form action=\"/views/groups.php\" method=\"post\">\n"; - echo "<select name=\"user\">"; - while (!$users->EOF) { - $uname = $misc->printVal($users->fields['usename']); - echo "<option value=\"{$uname}\"", - ($uname == $_POST['user']) ? ' selected="selected"' : '', ">{$uname}</option>\n"; - $users->moveNext(); - } - echo "</select>\n"; - echo "<input type=\"submit\" value=\"{$lang['straddmember']}\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"add_member\" />\n"; - echo "</form>\n"; - - $misc->printNavLinks(['showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'groups.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - ], - ], - ], - 'content' => $lang['strshowallgroups'], - ]], 'groups-properties', get_defined_vars()); -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('group'); - $misc->printTitle($lang['strdrop'], 'pg.group.drop'); - - echo "<p>", sprintf($lang['strconfdropgroup'], $misc->printVal($_REQUEST['group'])), "</p>\n"; - - echo "<form action=\"/views/groups.php\" method=\"post\">\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropGroup($_REQUEST['group']); - if ($status == 0) { - doDefault($lang['strgroupdropped']); - } else { - doDefault($lang['strgroupdroppedbad']); - } - - } -} - -/** - * Displays a screen where they can enter a new group - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['members'])) { - $_POST['members'] = []; - } - - // Fetch a list of all users in the cluster - $users = $data->getUsers(); - - $misc->printTrail('server'); - $misc->printTitle($lang['strcreategroup'], 'pg.group.create'); - $misc->printMsg($msg); - - echo "<form action=\"\" method=\"post\">\n"; - echo $misc->form; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input size=\"32\" maxlength=\"{$data->_maxNameLen}\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), "\" /></td>\n\t</tr>\n"; - if ($users->recordCount() > 0) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strmembers']}</th>\n"; - - echo "\t\t<td class=\"data\">\n"; - echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(40, $users->recordCount()), "\">\n"; - while (!$users->EOF) { - $username = $users->fields['usename']; - echo "\t\t\t\t<option value=\"{$username}\"", - (in_array($username, $_POST['members']) ? ' selected="selected"' : ''), ">", $misc->printVal($username), "</option>\n"; - $users->moveNext(); - } - echo "\t\t\t</select>\n"; - echo "\t\t</td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new group in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - if (!isset($_POST['members'])) { - $_POST['members'] = []; - } - - // Check form vars - if (trim($_POST['name']) == '') { - doCreate($lang['strgroupneedsname']); - } else { - $status = $data->createGroup($_POST['name'], $_POST['members']); - if ($status == 0) { - doDefault($lang['strgroupcreated']); - } else { - doCreate($lang['strgroupcreatedbad']); - } - - } -} - -/** - * Show default list of groups in the database - */ -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('server'); - $misc->printTabs('server', 'groups'); - $misc->printMsg($msg); - - $groups = $data->getGroups(); - - $columns = [ - 'group' => [ - 'title' => $lang['strgroup'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('groname'), - 'url' => "groups.php?action=properties&{$misc->href}&", - 'vars' => ['group' => 'groname'], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'groups.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'group' => \PHPPgAdmin\Decorators\Decorator::field('groname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($groups, $columns, $actions, 'groups-properties', $lang['strnogroups']); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'groups.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - ], - ], - ], - 'content' => $lang['strcreategroup'], - ]], 'groups-groups', get_defined_vars()); - -} +$group_controller = new \PHPPgAdmin\Controller\GroupController($container); $misc->printHeader($lang['strgroups']); $misc->printBody(); switch ($action) { case 'add_member': - doAddMember(); + $group_controller->doAddMember(); break; case 'drop_member': if (isset($_REQUEST['drop'])) { - doDropMember(false); + $group_controller->doDropMember(false); } else { - doProperties(); + $group_controller->doProperties(); } break; case 'confirm_drop_member': - doDropMember(true); + $group_controller->doDropMember(true); break; case 'save_create': if (isset($_REQUEST['cancel'])) { - doDefault(); + $group_controller->doDefault(); } else { - doSaveCreate(); + $group_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $group_controller->doCreate(); break; case 'drop': if (isset($_REQUEST['drop'])) { - doDrop(false); + $group_controller->doDrop(false); } else { - doDefault(); + $group_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $group_controller->doDrop(true); break; case 'save_edit': - doSaveEdit(); + $group_controller->doSaveEdit(); break; case 'edit': - doEdit(); + $group_controller->doEdit(); break; case 'properties': - doProperties(); + $group_controller->doProperties(); break; default: - doDefault(); + $group_controller->doDefault(); break; } diff --git a/src/views/help.php b/src/views/help.php index 691438b6..bd02d615 100644 --- a/src/views/help.php +++ b/src/views/help.php @@ -9,81 +9,13 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -function doDefault() { - global $data, $lang; - - if (isset($_REQUEST['help'])) { - $url = $data->getHelp($_REQUEST['help']); - - if (is_array($url)) { - doChoosePage($url); - return; - } - - if ($url) { - header("Location: $url"); - exit; - } - } - - doBrowse($lang['strinvalidhelppage']); -} - -function doBrowse($msg = '') { - global $misc, $data, $lang; - - $misc->printHeader($lang['strhelppagebrowser']); - $misc->printBody(); - - $misc->printTitle($lang['strselecthelppage']); - - echo $misc->printMsg($msg); - - echo "<dl>\n"; - - $pages = $data->getHelpPages(); - foreach ($pages as $page => $dummy) { - echo "<dt>{$page}</dt>\n"; - - $urls = $data->getHelp($page); - if (!is_array($urls)) { - $urls = [$urls]; - } - - foreach ($urls as $url) { - echo "<dd><a href=\"{$url}\">{$url}</a></dd>\n"; - } - } - - echo "</dl>\n"; - - $misc->printFooter(); -} - -function doChoosePage($urls) { - global $misc, $lang; - - $misc->printHeader($lang['strhelppagebrowser']); - $misc->printBody(); - - $misc->printTitle($lang['strselecthelppage']); - - echo "<ul>\n"; - foreach ($urls as $url) { - echo "<li><a href=\"{$url}\">{$url}</a></li>\n"; - } - echo "</ul>\n"; - - $misc->printFooter(); -} +$help_controller = new \PHPPgAdmin\Controller\HelpController($container); switch ($action) { case 'browse': - doBrowse(); + $help_controller->doBrowse(); break; default: - doDefault(); + $help_controller->doDefault(); break; } diff --git a/src/views/history.php b/src/views/history.php index 7eb06219..c7866608 100644 --- a/src/views/history.php +++ b/src/views/history.php @@ -9,225 +9,34 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -function doDefault() { - global $misc, $lang; - - $onchange = "onchange=\"location.href='/views/history.php?server=' + encodeURI(server.options[server.selectedIndex].value) + '&database=' + encodeURI(database.options[database.selectedIndex].value) + '&'\""; - - $misc->printHeader($lang['strhistory']); - - // Bring to the front always - echo "<body onload=\"window.focus();\">\n"; - - echo "<form action=\"/views/history.php\" method=\"post\">\n"; - $misc->printConnection($onchange); - echo "</form><br />"; - - if (!isset($_REQUEST['database'])) { - echo "<p>{$lang['strnodatabaseselected']}</p>\n"; - return; - } - - if (isset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']])) { - - $history = new \PHPPgAdmin\ArrayRecordSet($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]); - - //Kint::dump($history); - $columns = [ - 'query' => [ - 'title' => $lang['strsql'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('query'), - ], - 'paginate' => [ - 'title' => $lang['strpaginate'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('paginate'), - 'type' => 'yesno', - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'run' => [ - 'content' => $lang['strexecute'], - 'attr' => [ - 'href' => [ - 'url' => 'sql.php', - 'urlvars' => [ - 'subject' => 'history', - 'nohistory' => 't', - 'queryid' => \PHPPgAdmin\Decorators\Decorator::field('queryid'), - 'paginate' => \PHPPgAdmin\Decorators\Decorator::field('paginate'), - ], - ], - 'target' => 'detail', - ], - ], - 'remove' => [ - 'content' => $lang['strdelete'], - 'attr' => [ - 'href' => [ - 'url' => 'history.php', - 'urlvars' => [ - 'action' => 'confdelhistory', - 'queryid' => \PHPPgAdmin\Decorators\Decorator::field('queryid'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($history, $columns, $actions, 'history-history', $lang['strnohistory']); - } else { - echo "<p>{$lang['strnohistory']}</p>\n"; - } - - $navlinks = [ - 'refresh' => [ - 'attr' => [ - 'href' => [ - 'url' => 'history.php', - 'urlvars' => [ - 'action' => 'history', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - ], - ], - ], - 'content' => $lang['strrefresh'], - ], - ]; - - if (isset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]) - && count($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']])) { - $navlinks['download'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'history.php', - 'urlvars' => [ - 'action' => 'download', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - ], - ], - ], - 'content' => $lang['strdownload'], - ]; - $navlinks['clear'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'history.php', - 'urlvars' => [ - 'action' => 'confclearhistory', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - ], - ], - ], - 'content' => $lang['strclearhistory'], - ]; - } - - $misc->printNavLinks($navlinks, 'history-history', get_defined_vars()); -} - -function doDelHistory($qid, $confirm) { - global $misc, $lang; - - if ($confirm) { - $misc->printHeader($lang['strhistory']); - - // Bring to the front always - echo "<body onload=\"window.focus();\">\n"; - - echo "<h3>{$lang['strdelhistory']}</h3>\n"; - echo "<p>{$lang['strconfdelhistory']}</p>\n"; - - echo "<pre>", htmlentities($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']][$qid]['query'], ENT_QUOTES, 'UTF-8'), "</pre>"; - echo "<form action=\"/views/history.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"delhistory\" />\n"; - echo "<input type=\"hidden\" name=\"queryid\" value=\"$qid\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - unset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']][$qid]); - } - -} - -function doClearHistory($confirm) { - global $misc, $lang; - - if ($confirm) { - $misc->printHeader($lang['strhistory']); - - // Bring to the front always - echo "<body onload=\"window.focus();\">\n"; - - echo "<h3>{$lang['strclearhistory']}</h3>\n"; - echo "<p>{$lang['strconfclearhistory']}</p>\n"; - - echo "<form action=\"/views/history.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"clearhistory\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - unset($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']]); - } - -} - -function doDownloadHistory() { - header('Content-Type: application/download'); - $datetime = date('YmdHis'); - header("Content-Disposition: attachment; filename=history{$datetime}.sql"); - - foreach ($_SESSION['history'][$_REQUEST['server']][$_REQUEST['database']] as $queries) { - $query = rtrim($queries['query']); - echo $query; - if (substr($query, -1) != ';') { - echo ';'; - } - - echo "\n"; - } - - exit; -} +$history_controller = new \PHPPgAdmin\Controller\HistoryController($container); switch ($action) { case 'confdelhistory': - doDelHistory($_REQUEST['queryid'], true); + $history_controller->doDelHistory($_REQUEST['queryid'], true); break; case 'delhistory': if (isset($_POST['yes'])) { - doDelHistory($_REQUEST['queryid'], false); + $history_controller->doDelHistory($_REQUEST['queryid'], false); } - doDefault(); + $history_controller->doDefault(); break; case 'confclearhistory': - doClearHistory(true); + $history_controller->doClearHistory(true); break; case 'clearhistory': if (isset($_POST['yes'])) { - doClearHistory(false); + $history_controller->doClearHistory(false); } - doDefault(); + $history_controller->doDefault(); break; case 'download': - doDownloadHistory(); + $history_controller->doDownloadHistory(); break; default: - doDefault(); + $history_controller->doDefault(); } // Set the name of the window diff --git a/src/views/indexes.php b/src/views/indexes.php index f5d67711..6677cf70 100644 --- a/src/views/indexes.php +++ b/src/views/indexes.php @@ -9,379 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Show confirmation of cluster index and perform actual cluster - */ -function doClusterIndex($confirm) { - global $data, $misc, $action; - global $lang; - - if ($confirm) { - // Default analyze to on - $_REQUEST['analyze'] = true; - - $misc->printTrail('index'); - $misc->printTitle($lang['strclusterindex'], 'pg.index.cluster'); - - echo "<p>", sprintf($lang['strconfcluster'], $misc->printVal($_REQUEST['index'])), "</p>\n"; - - echo "<form action=\"/views/indexes.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"analyze\" name=\"analyze\"", (isset($_REQUEST['analyze']) ? ' checked="checked"' : ''), " /><label for=\"analyze\">{$lang['stranalyze']}</label></p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"cluster_index\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"cluster\" value=\"{$lang['strclusterindex']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->clusterIndex($_POST['table'], $_POST['index']); - if ($status == 0) { - if (isset($_POST['analyze'])) { - $status = $data->analyzeDB($_POST['table']); - if ($status == 0) { - doDefault($lang['strclusteredgood'] . ' ' . $lang['stranalyzegood']); - } else { - doDefault($lang['stranalyzebad']); - } - - } else { - doDefault($lang['strclusteredgood']); - } - } else { - doDefault($lang['strclusteredbad']); - } - - } - -} - -function doReindex() { - global $data, $lang; - - $status = $data->reindex('INDEX', $_REQUEST['index']); - if ($status == 0) { - doDefault($lang['strreindexgood']); - } else { - doDefault($lang['strreindexbad']); - } - -} - -/** - * Displays a screen where they can enter a new index - */ -function doCreateIndex($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['formIndexName'])) { - $_POST['formIndexName'] = ''; - } - - if (!isset($_POST['formIndexType'])) { - $_POST['formIndexType'] = null; - } - - if (!isset($_POST['formCols'])) { - $_POST['formCols'] = ''; - } - - if (!isset($_POST['formWhere'])) { - $_POST['formWhere'] = ''; - } - - if (!isset($_POST['formSpc'])) { - $_POST['formSpc'] = ''; - } - - $attrs = $data->getTableAttributes($_REQUEST['table']); - // Fetch all tablespaces from the database - if ($data->hasTablespaces()) { - $tablespaces = $data->getTablespaces(); - } - - $misc->printTrail('table'); - $misc->printTitle($lang['strcreateindex'], 'pg.index.create'); - $misc->printMsg($msg); - - $selColumns = new \PHPPgAdmin\XHtml\XHTML_Select("TableColumnList", true, 10); - $selColumns->set_style("width: 10em;"); - - if ($attrs->recordCount() > 0) { - while (!$attrs->EOF) { - $selColumns->add(new \PHPPgAdmin\XHtml\XHTML_Option($attrs->fields['attname'])); - $attrs->moveNext(); - } - } - - $selIndex = new \PHPPgAdmin\XHtml\XHTML_Select("IndexColumnList[]", true, 10); - $selIndex->set_style("width: 10em;"); - $selIndex->set_attribute("id", "IndexColumnList"); - $buttonAdd = new \PHPPgAdmin\XHtml\XHTML_Button("add", ">>"); - $buttonAdd->set_attribute("onclick", "buttonPressed(this);"); - $buttonAdd->set_attribute("type", "button"); - - $buttonRemove = new \PHPPgAdmin\XHtml\XHTML_Button("remove", "<<"); - $buttonRemove->set_attribute("onclick", "buttonPressed(this);"); - $buttonRemove->set_attribute("type", "button"); - - echo "<form onsubmit=\"doSelectAll();\" name=\"formIndex\" action=\"indexes.php\" method=\"post\">\n"; - - echo "<table>\n"; - echo "<tr><th class=\"data required\" colspan=\"3\">{$lang['strindexname']}</th></tr>"; - echo "<tr>"; - echo "<td class=\"data1\" colspan=\"3\"><input type=\"text\" name=\"formIndexName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formIndexName']), "\" /></td></tr>"; - echo "<tr><th class=\"data\">{$lang['strtablecolumnlist']}</th><th class=\"data\"> </th>"; - echo "<th class=\"data required\">{$lang['strindexcolumnlist']}</th></tr>\n"; - echo "<tr><td class=\"data1\">" . $selColumns->fetch() . "</td>\n"; - echo "<td class=\"data1\">" . $buttonRemove->fetch() . $buttonAdd->fetch() . "</td>"; - echo "<td class=\"data1\">" . $selIndex->fetch() . "</td></tr>\n"; - echo "</table>\n"; - - echo "<table> \n"; - echo "<tr>"; - echo "<th class=\"data left required\" scope=\"row\">{$lang['strindextype']}</th>"; - echo "<td class=\"data1\"><select name=\"formIndexType\">"; - foreach ($data->typIndexes as $v) { - echo "<option value=\"", htmlspecialchars($v), "\"", - ($v == $_POST['formIndexType']) ? ' selected="selected"' : '', ">", htmlspecialchars($v), "</option>\n"; - } - echo "</select></td></tr>\n"; - echo "<tr>"; - echo "<th class=\"data left\" scope=\"row\"><label for=\"formUnique\">{$lang['strunique']}</label></th>"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formUnique\" name=\"formUnique\"", (isset($_POST['formUnique']) ? 'checked="checked"' : ''), " /></td>"; - echo "</tr>"; - echo "<tr>"; - echo "<th class=\"data left\" scope=\"row\">{$lang['strwhere']}</th>"; - echo "<td class=\"data1\">(<input name=\"formWhere\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formWhere']), "\" />)</td>"; - echo "</tr>"; - - // Tablespace (if there are any) - if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; - echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formSpc\">\n"; - // Always offer the default (empty) option - echo "\t\t\t\t<option value=\"\"", - ($_POST['formSpc'] == '') ? ' selected="selected"' : '', "></option>\n"; - // Display all other tablespaces - while (!$tablespaces->EOF) { - $spcname = htmlspecialchars($tablespaces->fields['spcname']); - echo "\t\t\t\t<option value=\"{$spcname}\"", - ($spcname == $_POST['formSpc']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; - $tablespaces->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; - } - - if ($data->hasConcurrentIndexBuild()) { - echo "<tr>"; - echo "<th class=\"data left\" scope=\"row\"><label for=\"formConcur\">{$lang['strconcurrently']}</label></th>"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formConcur\" name=\"formConcur\"", (isset($_POST['formConcur']) ? 'checked="checked"' : ''), " /></td>"; - echo "</tr>"; - } - - echo "</table>"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_index\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new index in the database - * @@ Note: this function can't handle columns with commas in them - */ -function doSaveCreateIndex() { - global $data; - global $lang; - - // Handle databases that don't have partial indexes - if (!isset($_POST['formWhere'])) { - $_POST['formWhere'] = ''; - } - - // Default tablespace to null if it isn't set - if (!isset($_POST['formSpc'])) { - $_POST['formSpc'] = null; - } - - // Check that they've given a name and at least one column - if ($_POST['formIndexName'] == '') { - doCreateIndex($lang['strindexneedsname']); - } elseif (!isset($_POST['IndexColumnList']) || $_POST['IndexColumnList'] == '') { - doCreateIndex($lang['strindexneedscols']); - } else { - $status = $data->createIndex($_POST['formIndexName'], $_POST['table'], $_POST['IndexColumnList'], - $_POST['formIndexType'], isset($_POST['formUnique']), $_POST['formWhere'], $_POST['formSpc'], - isset($_POST['formConcur'])); - if ($status == 0) { - doDefault($lang['strindexcreated']); - } else { - doCreateIndex($lang['strindexcreatedbad']); - } - - } -} - -/** - * Show confirmation of drop index and perform actual drop - */ -function doDropIndex($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('index'); - $misc->printTitle($lang['strdrop'], 'pg.index.drop'); - - echo "<p>", sprintf($lang['strconfdropindex'], $misc->printVal($_REQUEST['index'])), "</p>\n"; - - echo "<form action=\"/views/indexes.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop_index\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"index\" value=\"", htmlspecialchars($_REQUEST['index']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropIndex($_POST['index'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strindexdropped']); - } else { - doDefault($lang['strindexdroppedbad']); - } - - } - -} - -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - function indPre(&$rowdata, $actions) { - global $data, $lang; - - if ($data->phpBool($rowdata->fields['indisprimary'])) { - $rowdata->fields['+constraints'] = $lang['strprimarykey']; - $actions['drop']['disable'] = true; - } elseif ($data->phpBool($rowdata->fields['indisunique'])) { - $rowdata->fields['+constraints'] = $lang['struniquekey']; - $actions['drop']['disable'] = true; - } else { - $rowdata->fields['+constraints'] = ''; - } - - return $actions; - } - - $misc->printTrail('table'); - $misc->printTabs('table', 'indexes'); - $misc->printMsg($msg); - - $indexes = $data->getIndexes($_REQUEST['table']); - - $columns = [ - 'index' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('indname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('inddef'), - ], - 'constraints' => [ - 'title' => $lang['strconstraints'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+constraints'), - 'type' => 'verbatim', - 'params' => ['align' => 'center'], - ], - 'clustered' => [ - 'title' => $lang['strclustered'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('indisclustered'), - 'type' => 'yesno', - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('idxcomment'), - ], - ]; - - $actions = [ - 'cluster' => [ - 'content' => $lang['strclusterindex'], - 'attr' => [ - 'href' => [ - 'url' => 'indexes.php', - 'urlvars' => [ - 'action' => 'confirm_cluster_index', - 'table' => $_REQUEST['table'], - 'index' => \PHPPgAdmin\Decorators\Decorator::field('indname'), - ], - ], - ], - ], - 'reindex' => [ - 'content' => $lang['strreindex'], - 'attr' => [ - 'href' => [ - 'url' => 'indexes.php', - 'urlvars' => [ - 'action' => 'reindex', - 'table' => $_REQUEST['table'], - 'index' => \PHPPgAdmin\Decorators\Decorator::field('indname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'indexes.php', - 'urlvars' => [ - 'action' => 'confirm_drop_index', - 'table' => $_REQUEST['table'], - 'index' => \PHPPgAdmin\Decorators\Decorator::field('indname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($indexes, $columns, $actions, 'indexes-indexes', $lang['strnoindexes'], 'indPre'); - - $misc->printNavLinks([ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'indexes.php', - 'urlvars' => [ - 'action' => 'create_index', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strcreateindex'], - ], - ], 'indexes-indexes', get_defined_vars()); -} +$index_controller = new \PHPPgAdmin\Controller\IndexController($container); $misc->printHeader($lang['strindexes'], "<script src=\"/js/indexes.js\" type=\"text/javascript\"></script>"); @@ -394,42 +22,42 @@ if ($action == 'create_index' || $action == 'save_create_index') { switch ($action) { case 'cluster_index': if (isset($_POST['cluster'])) { - doClusterIndex(false); + $index_controller->doClusterIndex(false); } else { - doDefault(); + $index_controller->doDefault(); } break; case 'confirm_cluster_index': - doClusterIndex(true); + $index_controller->doClusterIndex(true); break; case 'reindex': - doReindex(); + $index_controller->doReindex(); break; case 'save_create_index': if (isset($_POST['cancel'])) { - doDefault(); + $index_controller->doDefault(); } else { - doSaveCreateIndex(); + $index_controller->doSaveCreateIndex(); } break; case 'create_index': - doCreateIndex(); + $index_controller->doCreateIndex(); break; case 'drop_index': if (isset($_POST['drop'])) { - doDropIndex(false); + $index_controller->doDropIndex(false); } else { - doDefault(); + $index_controller->doDefault(); } break; case 'confirm_drop_index': - doDropIndex(true); + $index_controller->doDropIndex(true); break; default: - doDefault(); + $index_controller->doDefault(); break; } diff --git a/src/views/info.php b/src/views/info.php index b4ceae3f..ff169072 100644 --- a/src/views/info.php +++ b/src/views/info.php @@ -9,347 +9,14 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * List all the information on the table - */ -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('table'); - $misc->printTabs('table', 'info'); - $misc->printMsg($msg); - - // common params for printVal - $shownull = ['null' => true]; - - // Fetch info - $referrers = $data->getReferrers($_REQUEST['table']); - $parents = $data->getTableParents($_REQUEST['table']); - $children = $data->getTableChildren($_REQUEST['table']); - $tablestatstups = $data->getStatsTableTuples($_REQUEST['table']); - $tablestatsio = $data->getStatsTableIO($_REQUEST['table']); - $indexstatstups = $data->getStatsIndexTuples($_REQUEST['table']); - $indexstatsio = $data->getStatsIndexIO($_REQUEST['table']); - - // Check that there is some info - if (($referrers === -99 || ($referrers !== -99 && $referrers->recordCount() == 0)) - && $parents->recordCount() == 0 && $children->recordCount() == 0 - && ($tablestatstups->recordCount() == 0 && $tablestatsio->recordCount() == 0 - && $indexstatstups->recordCount() == 0 && $indexstatsio->recordCount() == 0)) { - $misc->printMsg($lang['strnoinfo']); - } else { - // Referring foreign tables - if ($referrers !== -99 && $referrers->recordCount() > 0) { - echo "<h3>{$lang['strreferringtables']}</h3>\n"; - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $lang['strtable'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - 'name' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('conname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('consrc'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'constraints.php', - 'urlvars' => [ - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($referrers, $columns, $actions, 'info-referrers', $lang['strnodata']); - } - - // Parent tables - if ($parents->recordCount() > 0) { - echo "<h3>{$lang['strparenttables']}</h3>\n"; - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $lang['strtable'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($parents, $columns, $actions, 'info-parents', $lang['strnodata']); - } - - // Child tables - if ($children->recordCount() > 0) { - echo "<h3>{$lang['strchildtables']}</h3>\n"; - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - 'table' => [ - 'title' => $lang['strtable'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'properties' => [ - 'content' => $lang['strproperties'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($children, $columns, $actions, 'info-children', $lang['strnodata']); - - } - - // Row performance - if ($tablestatstups->recordCount() > 0) { - echo "<h3>{$lang['strrowperf']}</h3>\n"; - - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\" colspan=\"2\">{$lang['strsequential']}</th>\n"; - echo "\t\t<th class=\"data\" colspan=\"2\">{$lang['strindex']}</th>\n"; - echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strrows2']}</th>\n"; - echo "\t</tr>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strread']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strfetch']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strinsert']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strupdate']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strdelete']}</th>\n"; - echo "\t</tr>\n"; - $i = 0; - - while (!$tablestatstups->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['seq_scan'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['seq_tup_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['idx_scan'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['idx_tup_fetch'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_ins'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_upd'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatstups->fields['n_tup_del'], 'int4', $shownull), "</td>\n"; - echo "\t</tr>\n"; - $tablestatstups->movenext(); - $i++; - } - - echo "</table>\n"; - } - - // I/O performance - if ($tablestatsio->recordCount() > 0) { - echo "<h3>{$lang['strioperf']}</h3>\n"; - - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strheap']}</th>\n"; - echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strindex']}</th>\n"; - echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strtoast']}</th>\n"; - echo "\t\t<th class=\"data\" colspan=\"3\">{$lang['strtoastindex']}</th>\n"; - echo "\t</tr>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; - echo "\t</tr>\n"; - $i = 0; - - while (!$tablestatsio->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">\n"; - - $total = $tablestatsio->fields['heap_blks_hit'] + $tablestatsio->fields['heap_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['heap_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['heap_blks_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['heap_blks_hit'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; - - $total = $tablestatsio->fields['idx_blks_hit'] + $tablestatsio->fields['idx_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['idx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['idx_blks_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['idx_blks_hit'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; - - $total = $tablestatsio->fields['toast_blks_hit'] + $tablestatsio->fields['toast_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['toast_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['toast_blks_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['toast_blks_hit'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; - - $total = $tablestatsio->fields['tidx_blks_hit'] + $tablestatsio->fields['tidx_blks_read']; - if ($total > 0) { - $percentage = round(($tablestatsio->fields['tidx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['tidx_blks_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($tablestatsio->fields['tidx_blks_hit'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; - echo "\t</tr>\n"; - $tablestatsio->movenext(); - $i++; - } - - echo "</table>\n"; - } - - // Index row performance - if ($indexstatstups->recordCount() > 0) { - echo "<h3>{$lang['stridxrowperf']}</h3>\n"; - - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strindex']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strscan']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strread']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strfetch']}</th>\n"; - echo "\t</tr>\n"; - $i = 0; - - while (!$indexstatstups->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">\n"; - echo "\t\t<td>", $misc->printVal($indexstatstups->fields['indexrelname']), "</td>\n"; - echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_scan'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_tup_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($indexstatstups->fields['idx_tup_fetch'], 'int4', $shownull), "</td>\n"; - echo "\t</tr>\n"; - $indexstatstups->movenext(); - $i++; - } - - echo "</table>\n"; - } - - // Index I/0 performance - if ($indexstatsio->recordCount() > 0) { - echo "<h3>{$lang['stridxioperf']}</h3>\n"; - - echo "<table>\n"; - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strindex']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strdisk']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strcache']}</th>\n"; - echo "\t\t<th class=\"data\">{$lang['strpercent']}</th>\n"; - echo "\t</tr>\n"; - $i = 0; - - while (!$indexstatsio->EOF) { - $id = (($i % 2) == 0 ? '1' : '2'); - echo "\t<tr class=\"data{$id}\">\n"; - $total = $indexstatsio->fields['idx_blks_hit'] + $indexstatsio->fields['idx_blks_read']; - if ($total > 0) { - $percentage = round(($indexstatsio->fields['idx_blks_hit'] / $total) * 100); - } else { - $percentage = 0; - } - - echo "\t\t<td>", $misc->printVal($indexstatsio->fields['indexrelname']), "</td>\n"; - echo "\t\t<td>", $misc->printVal($indexstatsio->fields['idx_blks_read'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>", $misc->printVal($indexstatsio->fields['idx_blks_hit'], 'int4', $shownull), "</td>\n"; - echo "\t\t<td>({$percentage}{$lang['strpercent']})</td>\n"; - echo "\t</tr>\n"; - $indexstatsio->movenext(); - $i++; - } - - echo "</table>\n"; - } - } -} +$info_controller = new \PHPPgAdmin\Controller\InfoController($container); $misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table'] . ' - ' . $lang['strinfo']); $misc->printBody(); switch ($action) { default: - doDefault(); + $info_controller->doDefault(); break; } diff --git a/src/views/intro.php b/src/views/intro.php index fa92159f..6df90801 100755 --- a/src/views/intro.php +++ b/src/views/intro.php @@ -1,82 +1,19 @@ <?php -/** - * Intro screen - * - * $Id: intro.php,v 1.19 2007/07/12 19:26:22 xzilla Exp $ - */ +if (!defined('BASE_PATH')) { + require_once '../lib.inc.php'; +} -// Include application functions (no db conn) +$intro_controller = new \PHPPgAdmin\Controller\IntroController($container); -function doDefault($container) { +$misc->printHeader($lang['strcasts']); +$misc->printBody(); - $lang = $container->get('lang'); - $misc = $container->get('misc'); - $conf = $container->get('conf'); +switch ($action) { - $appName = $container->get('settings')['appName']; - $appVersion = $container->get('settings')['appVersion']; + default: + $intro_controller->doDefault(); + break; +} - $misc->setNoDBConnection(true); - - $intro_html = $misc->printHeader('', null, false); - - $intro_html .= $misc->printBody(false); - - $intro_html .= $misc->printTrail('root', false); - - $intro_html .= $misc->printTabs('root', 'intro', false); - - $intro_html .= "<h1> $appName $appVersion (PHP " . phpversion() . ')</h1>'; - - $intro_html .= '<form method="get" action="intro.php">'; - $intro_html .= '<table>'; - $intro_html .= '<tr class="data1">'; - $intro_html .= '<th class="data">' . $lang['strlanguage'] . '</th>'; - $intro_html .= '<td>'; - $intro_html .= '<select name="language" onchange="this.form.submit()">'; - - $language = isset($_SESSION['webdbLanguage']) ? $_SESSION['webdbLanguage'] : 'english'; - foreach ($container->get('appLangFiles') as $k => $v) { - $selected = ($k == $language) ? ' selected="selected"' : ''; - $intro_html .= "\t<option value=\"{$k}\"" . $selected . ">{$v}</option>\n"; - } - - $intro_html .= '</select>'; - $intro_html .= '</td>'; - $intro_html .= '</tr>'; - $intro_html .= '<tr class="data2">'; - $intro_html .= '<th class="data">' . $lang['strtheme'] . '</th>'; - $intro_html .= '<td>'; - $intro_html .= '<select name="theme" onchange="this.form.submit()">'; - - foreach ($container->get('appThemes') as $k => $v) { - $selected = ($k == $conf['theme']) ? ' selected="selected"' : ''; - $intro_html .= "\t<option value=\"{$k}\"" . $selected . ">{$v}</option>\n"; - } - - $intro_html .= '</select>'; - $intro_html .= '</td>'; - $intro_html .= '</tr>'; - $intro_html .= '</table>'; - $intro_html .= '<noscript><p><input type="submit" value="' . $lang['stralter'] . '" /></p></noscript>'; - $intro_html .= '</form>'; - - $intro_html .= '<p>' . $lang['strintro'] . '</p>'; - - $intro_html .= '<ul class="intro">'; - $intro_html .= ' <li><a href="http://phppgadmin.sourceforge.net/">' . $lang['strppahome'] . '</a></li>'; - $intro_html .= '<li><a href="' . $lang['strpgsqlhome_url'] . '">' . $lang['strpgsqlhome'] . '</a></li>'; - $intro_html .= '<li><a href="http://sourceforge.net/tracker/?group_id=37132&atid=418980">' . $lang['strreportbug'] . '</a></li>'; - $intro_html .= '<li><a href="' . $lang['strviewfaq_url'] . '">' . $lang['strviewfaq'] . '</a></li>'; - $intro_html .= '<li><a target="_top" href="tests/selenium/selenium-lib/core/TestRunner.html?test=..%2F..%2FTestSuite.php&resultsUrl=..%2FpostResults">Selenium tests</a></li>'; - $intro_html .= '</ul>'; - - if (isset($_GET['language'])) { - $misc->setReloadBrowser(true); - } - - $intro_html .= $misc->printFooter(false); - - return $intro_html; -}
\ No newline at end of file +$misc->printFooter(); diff --git a/src/views/languages.php b/src/views/languages.php index e8d9a85e..200fbb62 100644 --- a/src/views/languages.php +++ b/src/views/languages.php @@ -9,51 +9,14 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show default list of languages in the database - */ -function doDefault($msg = '') { - global $data, $misc, $database; - global $lang; - - $misc->printTrail('database'); - $misc->printTabs('database', 'languages'); - $misc->printMsg($msg); - - $languages = $data->getLanguages(); - - $columns = [ - 'language' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('lanname'), - ], - 'trusted' => [ - 'title' => $lang['strtrusted'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('lanpltrusted'), - 'type' => 'yesno', - ], - 'function' => [ - 'title' => $lang['strfunction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('lanplcallf'), - ], - ]; - - $actions = []; - - echo $misc->printTable($languages, $columns, $actions, 'languages-languages', $lang['strnolanguages']); -} +$lang_controller = new \PHPPgAdmin\Controller\LangController($container); $misc->printHeader($lang['strlanguages']); $misc->printBody(); switch ($action) { default: - doDefault(); + $lang_controller->doDefault(); break; } diff --git a/src/views/opclasses.php b/src/views/opclasses.php index c95c7303..63e5f2fa 100644 --- a/src/views/opclasses.php +++ b/src/views/opclasses.php @@ -9,59 +9,14 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show default list of opclasss in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'opclasses'); - $misc->printMsg($msg); - - $opclasses = $data->getOpClasses(); - - $columns = [ - 'accessmethod' => [ - 'title' => $lang['straccessmethod'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('amname'), - ], - 'opclass' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('opcname'), - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('opcintype'), - ], - 'default' => [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('opcdefault'), - 'type' => 'yesno', - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('opccomment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($opclasses, $columns, $actions, 'opclasses-opclasses', $lang['strnoopclasses']); -} +$opclasses_controller = new \PHPPgAdmin\Controller\OpClassesController($container); $misc->printHeader($lang['stropclasses']); $misc->printBody(); switch ($action) { default: - doDefault(); + $opclasses_controller->doDefault(); break; } diff --git a/src/views/operators.php b/src/views/operators.php index c06e88bc..d6f33f27 100644 --- a/src/views/operators.php +++ b/src/views/operators.php @@ -9,181 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show read only properties for an operator - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('operator'); - $misc->printTitle($lang['strproperties'], 'pg.operator'); - $misc->printMsg($msg); - - $oprdata = $data->getOperator($_REQUEST['operator_oid']); - $oprdata->fields['oprcanhash'] = $data->phpBool($oprdata->fields['oprcanhash']); - - if ($oprdata->recordCount() > 0) { - echo "<table>\n"; - echo "<tr><th class=\"data left\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strleftarg']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprleftname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strrightarg']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrightname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strcommutator']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprcom']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strnegator']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprnegate']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strjoin']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprjoin']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strhashes']}</th>\n"; - echo "<td class=\"data1\">", ($oprdata->fields['oprcanhash']) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; - - /* these field only exists in 8.2 and before in pg_catalog */ - if (isset($oprdata->fields['oprlsortop'])) { - echo "<tr><th class=\"data left\">{$lang['strmerges']}</th>\n"; - echo "<td class=\"data1\">", ($oprdata->fields['oprlsortop'] !== '0' && $oprdata->fields['oprrsortop'] !== '0') ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strrestrict']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrest']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strleftsort']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprlsortop']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strrightsort']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprrsortop']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strlessthan']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprltcmpop']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strgreaterthan']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($oprdata->fields['oprgtcmpop']), "</td></tr>\n"; - } else { - echo "<tr><th class=\"data left\">{$lang['strmerges']}</th>\n"; - echo "<td class=\"data1\">", $data->phpBool($oprdata->fields['oprcanmerge']) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; - } - echo "</table>\n"; - - $misc->printNavLinks([ - 'showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'operators.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strshowalloperators'], - ]], 'operators-properties', get_defined_vars() - ); - } else { - doDefault($lang['strinvalidparam']); - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('operator'); - $misc->printTitle($lang['strdrop'], 'pg.operator.drop'); - - echo "<p>", sprintf($lang['strconfdropoperator'], $misc->printVal($_REQUEST['operator'])), "</p>\n"; - - echo "<form action=\"/views/operators.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"operator\" value=\"", htmlspecialchars($_REQUEST['operator']), "\" />\n"; - echo "<input type=\"hidden\" name=\"operator_oid\" value=\"", htmlspecialchars($_REQUEST['operator_oid']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropOperator($_POST['operator_oid'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['stroperatordropped']); - } else { - doDefault($lang['stroperatordroppedbad']); - } - - } - -} - -/** - * Show default list of operators in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'operators'); - $misc->printMsg($msg); - - $operators = $data->getOperators(); - - $columns = [ - 'operator' => [ - 'title' => $lang['stroperator'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('oprname'), - 'url' => "operators.php?action=properties&{$misc->href}&", - 'vars' => ['operator' => 'oprname', 'operator_oid' => 'oid'], - ], - 'leftarg' => [ - 'title' => $lang['strleftarg'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('oprleftname'), - ], - 'rightarg' => [ - 'title' => $lang['strrightarg'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('oprrightname'), - ], - 'returns' => [ - 'title' => $lang['strreturns'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('resultname'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('oprcomment'), - ], - ]; - - $actions = [ - 'drop' => [ - // 'title' => $lang['strdrop'], - // 'url' => "operators.php?action=confirm_drop&{$misc->href}&", - // 'vars' => array('operator' => 'oprname', 'operator_oid' => 'oid'), - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'operators.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'operator' => \PHPPgAdmin\Decorators\Decorator::field('oprname'), - 'operator_oid' => \PHPPgAdmin\Decorators\Decorator::field('oid'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($operators, $columns, $actions, 'operators-operators', $lang['strnooperators']); - -// TODO operators.php action=create $lang['strcreateoperator'] -} +$operator_controller = new \PHPPgAdmin\Controller\OperatorController($container); $misc->printHeader($lang['stroperators']); $misc->printBody(); @@ -191,9 +17,9 @@ $misc->printBody(); switch ($action) { case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $operator_controller->doDefault(); } else { - doSaveCreate(); + $operator_controller->doSaveCreate(); } break; @@ -202,20 +28,20 @@ switch ($action) { break; case 'drop': if (isset($_POST['cancel'])) { - doDefault(); + $operator_controller->doDefault(); } else { - doDrop(false); + $operator_controller->doDrop(false); } break; case 'confirm_drop': - doDrop(true); + $operator_controller->doDrop(true); break; case 'properties': - doProperties(); + $operator_controller->doProperties(); break; default: - doDefault(); + $operator_controller->doDefault(); break; } diff --git a/src/views/privileges.php b/src/views/privileges.php index f177c279..d0d5be41 100644 --- a/src/views/privileges.php +++ b/src/views/privileges.php @@ -54,7 +54,7 @@ function doAlter($confirm, $mode, $msg = '') { } $misc->printMsg($msg); - echo "<form action=\"/views/privileges.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/privileges.php\" method=\"post\">\n"; echo "<table>\n"; echo "<tr><th class=\"data left\">{$lang['strusers']}</th>\n"; echo "<td class=\"data1\"><select name=\"username[]\" multiple=\"multiple\" size=\"", min(6, $users->recordCount()), "\">\n"; diff --git a/src/views/redirect.php b/src/views/redirect.php deleted file mode 100644 index 16a079f7..00000000 --- a/src/views/redirect.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php - -require_once '../lib.inc.php'; diff --git a/src/views/roles.php b/src/views/roles.php index 3cf68009..92c222da 100644 --- a/src/views/roles.php +++ b/src/views/roles.php @@ -57,7 +57,7 @@ function doCreate($msg = '') { $misc->printTitle($lang['strcreaterole'], 'pg.role.create'); $misc->printMsg($msg); - echo "<form action=\"/views/roles.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/roles.php\" method=\"post\">\n"; echo "<table>\n"; echo "\t<tr>\n\t\t<th class=\"data left required\" style=\"width: 130px\">{$lang['strname']}</th>\n"; echo "\t\t<td class=\"data1\"><input size=\"15\" maxlength=\"{$data->_maxNameLen}\" name=\"formRolename\" value=\"", htmlspecialchars($_POST['formRolename']), "\" /></td>\n\t</tr>\n"; @@ -223,7 +223,7 @@ function doAlter($msg = '') { $_POST['formPassword'] = ''; } - echo "<form action=\"/views/roles.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/roles.php\" method=\"post\">\n"; echo "<table>\n"; echo "\t<tr>\n\t\t<th class=\"data left\" style=\"width: 130px\">{$lang['strname']}</th>\n"; echo "\t\t<td class=\"data1\">", ($canRename ? "<input name=\"formNewRoleName\" size=\"15\" maxlength=\"{$data->_maxNameLen}\" value=\"" . htmlspecialchars($_POST['formNewRoleName']) . "\" />" : $misc->printVal($roledata->fields['rolname'])), "</td>\n\t</tr>\n"; @@ -403,7 +403,7 @@ function doDrop($confirm) { echo "<p>", sprintf($lang['strconfdroprole'], $misc->printVal($_REQUEST['rolename'])), "</p>\n"; - echo "<form action=\"/views/roles.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/roles.php\" method=\"post\">\n"; echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; echo "<input type=\"hidden\" name=\"rolename\" value=\"", htmlspecialchars($_REQUEST['rolename']), "\" />\n"; echo $misc->form; @@ -623,7 +623,7 @@ function doChangePassword($confirm, $msg = '') { $_POST['confirm'] = ''; } - echo "<form action=\"/views/roles.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/roles.php\" method=\"post\">\n"; echo "<table>\n"; echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strpassword']}</th>\n"; echo "\t\t<td><input type=\"password\" name=\"password\" size=\"32\" value=\"", diff --git a/src/views/rules.php b/src/views/rules.php index bc629d24..24186352 100644 --- a/src/views/rules.php +++ b/src/views/rules.php @@ -9,197 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Confirm and then actually create a rule - */ -function createRule($confirm, $msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['name'])) { - $_POST['name'] = ''; - } - - if (!isset($_POST['event'])) { - $_POST['event'] = ''; - } - - if (!isset($_POST['where'])) { - $_POST['where'] = ''; - } - - if (!isset($_POST['type'])) { - $_POST['type'] = 'SOMETHING'; - } - - if (!isset($_POST['raction'])) { - $_POST['raction'] = ''; - } - - if ($confirm) { - $misc->printTrail($_REQUEST['subject']); - $misc->printTitle($lang['strcreaterule'], 'pg.rule.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/rules.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\"><input name=\"name\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strevent']}</th>\n"; - echo "<td class=\"data1\"><select name=\"event\">\n"; - foreach ($data->rule_events as $v) { - echo "<option value=\"{$v}\"", ($v == $_POST['event']) ? ' selected="selected"' : '', - ">{$v}</option>\n"; - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strwhere']}</th>\n"; - echo "<td class=\"data1\"><input name=\"where\" size=\"32\" value=\"", - htmlspecialchars($_POST['where']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left\"><label for=\"instead\">{$lang['strinstead']}</label></th>\n"; - echo "<td class=\"data1\">"; - echo "<input type=\"checkbox\" id=\"instead\" name=\"instead\" ", (isset($_POST['instead'])) ? ' checked="checked"' : '', " />\n"; - echo "</td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['straction']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input type=\"radio\" id=\"type1\" name=\"type\" value=\"NOTHING\"", ($_POST['type'] == 'NOTHING') ? ' checked="checked"' : '', " /> <label for=\"type1\">NOTHING</label><br />\n"; - echo "<input type=\"radio\" name=\"type\" value=\"SOMETHING\"", ($_POST['type'] == 'SOMETHING') ? ' checked="checked"' : '', " />\n"; - echo "(<input name=\"raction\" size=\"32\" value=\"", - htmlspecialchars($_POST['raction']), "\" />)</td></tr>\n"; - echo "</table>\n"; - - echo "<input type=\"hidden\" name=\"action\" value=\"save_create_rule\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"", htmlspecialchars($_REQUEST['subject']), "\" />\n"; - echo "<input type=\"hidden\" name=\"", htmlspecialchars($_REQUEST['subject']), - "\" value=\"", htmlspecialchars($_REQUEST[$_REQUEST['subject']]), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"submit\" name=\"ok\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - } else { - if (trim($_POST['name']) == '') { - createRule(true, $lang['strruleneedsname']); - } else { - $status = $data->createRule($_POST['name'], - $_POST['event'], $_POST[$_POST['subject']], $_POST['where'], - isset($_POST['instead']), $_POST['type'], $_POST['raction']); - if ($status == 0) { - doDefault($lang['strrulecreated']); - } else { - createRule(true, $lang['strrulecreatedbad']); - } - - } - } -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail($_REQUEST['subject']); - $misc->printTitle($lang['strdrop'], 'pg.rule.drop'); - - echo "<p>", sprintf($lang['strconfdroprule'], $misc->printVal($_REQUEST['rule']), - $misc->printVal($_REQUEST[$_REQUEST['reltype']])), "</p>\n"; - - echo "<form action=\"/views/rules.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"", htmlspecialchars($_REQUEST['reltype']), "\" />\n"; - echo "<input type=\"hidden\" name=\"", htmlspecialchars($_REQUEST['reltype']), - "\" value=\"", htmlspecialchars($_REQUEST[$_REQUEST['reltype']]), "\" />\n"; - echo "<input type=\"hidden\" name=\"rule\" value=\"", htmlspecialchars($_REQUEST['rule']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropRule($_POST['rule'], $_POST[$_POST['subject']], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strruledropped']); - } else { - doDefault($lang['strruledroppedbad']); - } - - } - -} - -/** - * List all the rules on the table - */ -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail($_REQUEST['subject']); - $misc->printTabs($_REQUEST['subject'], 'rules'); - $misc->printMsg($msg); - - $rules = $data->getRules($_REQUEST[$_REQUEST['subject']]); - - $columns = [ - 'rule' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('rulename'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('definition'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $subject = urlencode($_REQUEST['subject']); - $object = urlencode($_REQUEST[$_REQUEST['subject']]); - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'rules.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'reltype' => $subject, - $subject => $object, - 'subject' => 'rule', - 'rule' => \PHPPgAdmin\Decorators\Decorator::field('rulename'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($rules, $columns, $actions, 'rules-rules', $lang['strnorules']); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'rules.php', - 'urlvars' => [ - 'action' => 'create_rule', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - $subject => $object, - 'subject' => $subject, - ], - ], - ], - 'content' => $lang['strcreaterule'], - ]], 'rules-rules', get_defined_vars()); -} +$rule_controller = new \PHPPgAdmin\Controller\RuleController($container); // Different header if we're view rules or table rules $misc->printHeader($_REQUEST[$_REQUEST['subject']] . ' - ' . $lang['strrules']); @@ -207,29 +17,29 @@ $misc->printBody(); switch ($action) { case 'create_rule': - createRule(true); + $rule_controller->createRule(true); break; case 'save_create_rule': if (isset($_POST['cancel'])) { - doDefault(); + $rule_controller->doDefault(); } else { - createRule(false); + $rule_controller->createRule(false); } break; case 'drop': if (isset($_POST['yes'])) { - doDrop(false); + $rule_controller->doDrop(false); } else { - doDefault(); + $rule_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $rule_controller->doDrop(true); break; default: - doDefault(); + $rule_controller->doDefault(); break; } diff --git a/src/views/schemas.php b/src/views/schemas.php index 63a84383..8bb271e8 100755 --- a/src/views/schemas.php +++ b/src/views/schemas.php @@ -9,407 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show default list of schemas in the database - */ -function doDefault($msg = '') { - global $data, $misc, $conf; - global $lang; - - $misc->printTrail('database'); - $misc->printTabs('database', 'schemas'); - $misc->printMsg($msg); - - // Check that the DB actually supports schemas - $schemas = $data->getSchemas(); - - $columns = [ - 'schema' => [ - 'title' => $lang['strschema'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - 'url' => "/redirect/schema?{$misc->href}&", - 'vars' => ['schema' => 'nspname'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspowner'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('nspcomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['nsp' => 'nspname'], - 'url' => 'schemas.php', - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'schemas.php', - 'urlvars' => [ - 'action' => 'drop', - 'nsp' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - ], - ], - 'multiaction' => 'drop', - ], - 'privileges' => [ - 'content' => $lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges.php', - 'urlvars' => [ - 'subject' => 'schema', - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'schemas.php', - 'urlvars' => [ - 'action' => 'alter', - 'schema' => \PHPPgAdmin\Decorators\Decorator::field('nspname'), - ], - ], - ], - ], - ]; - - if (!$data->hasAlterSchema()) { - unset($actions['alter']); - } - - echo $misc->printTable($schemas, $columns, $actions, 'schemas-schemas', $lang['strnoschemas']); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'schemas.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - ], - ], - ], - 'content' => $lang['strcreateschema'], - ]], 'schemas-schemas', get_defined_vars()); -} - -/** - * Displays a screen where they can enter a new schema - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - $server_info = $misc->getServerInfo(); - - if (!isset($_POST['formName'])) { - $_POST['formName'] = ''; - } - - if (!isset($_POST['formAuth'])) { - $_POST['formAuth'] = $server_info['username']; - } - - if (!isset($_POST['formSpc'])) { - $_POST['formSpc'] = ''; - } - - if (!isset($_POST['formComment'])) { - $_POST['formComment'] = ''; - } - - // Fetch all users from the database - $users = $data->getUsers(); - - $misc->printTrail('database'); - $misc->printTitle($lang['strcreateschema'], 'pg.schema.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/schemas.php\" method=\"post\">\n"; - echo "<table style=\"width: 100%\">\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n"; - // Owner - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formAuth\">\n"; - while (!$users->EOF) { - $uname = htmlspecialchars($users->fields['usename']); - echo "\t\t\t\t<option value=\"{$uname}\"", - ($uname == $_POST['formAuth']) ? ' selected="selected"' : '', ">{$uname}</option>\n"; - $users->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"create\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new schema in the database - */ -function doSaveCreate() { - global $data, $lang, $_reload_browser; - - // Check that they've given a name - if ($_POST['formName'] == '') { - doCreate($lang['strschemaneedsname']); - } else { - $status = $data->createSchema($_POST['formName'], $_POST['formAuth'], $_POST['formComment']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strschemacreated']); - } else { - doCreate($lang['strschemacreatedbad']); - } - - } -} - -/** - * Display a form to permit editing schema properies. - * TODO: permit changing owner - */ -function doAlter($msg = '') { - global $data, $misc, $lang; - - $misc->printTrail('schema'); - $misc->printTitle($lang['stralter'], 'pg.schema.alter'); - $misc->printMsg($msg); - - $schema = $data->getSchemaByName($_REQUEST['schema']); - if ($schema->recordCount() > 0) { - if (!isset($_POST['comment'])) { - $_POST['comment'] = $schema->fields['nspcomment']; - } - - if (!isset($_POST['schema'])) { - $_POST['schema'] = $_REQUEST['schema']; - } - - if (!isset($_POST['name'])) { - $_POST['name'] = $_REQUEST['schema']; - } - - if (!isset($_POST['owner'])) { - $_POST['owner'] = $schema->fields['ownername']; - } - - echo "<form action=\"/views/schemas.php\" method=\"post\">\n"; - echo "<table>\n"; - - echo "\t<tr>\n"; - echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data1\">"; - echo "\t\t\t<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" />\n"; - echo "\t\t</td>\n"; - echo "\t</tr>\n"; - - if ($data->hasAlterSchemaOwner()) { - $users = $data->getUsers(); - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data2\"><select name=\"owner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - } else { - echo "<input name=\"owner\" value=\"{$_POST['owner']}\" type=\"hidden\" />"; - } - - echo "\t<tr>\n"; - echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\" name=\"comment\">", htmlspecialchars($_POST['comment']), "</textarea></td>\n"; - echo "\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo "<input type=\"hidden\" name=\"schema\" value=\"", htmlspecialchars($_POST['schema']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } -} - -/** - * Save the form submission containing changes to a schema - */ -function doSaveAlter($msg = '') { - global $data, $misc, $lang, $_reload_browser; - - $status = $data->updateSchema($_POST['schema'], $_POST['comment'], $_POST['name'], $_POST['owner']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strschemaaltered']); - } else { - doAlter($lang['strschemaalteredbad']); - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_browser; - - if (empty($_REQUEST['nsp']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifyschematodrop']); - exit(); - } - - if ($confirm) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strdrop'], 'pg.schema.drop'); - - echo "<form action=\"/views/schemas.php\" method=\"post\">\n"; - //If multi drop - if (isset($_REQUEST['ma'])) { - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo '<p>', sprintf($lang['strconfdropschema'], $misc->printVal($a['nsp'])), "</p>\n"; - echo '<input type="hidden" name="nsp[]" value="', htmlspecialchars($a['nsp']), "\" />\n"; - } - } else { - echo "<p>", sprintf($lang['strconfdropschema'], $misc->printVal($_REQUEST['nsp'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"nsp\" value=\"", htmlspecialchars($_REQUEST['nsp']), "\" />\n"; - } - - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - if (is_array($_POST['nsp'])) { - $msg = ''; - $status = $data->beginTransaction(); - if ($status == 0) { - foreach ($_POST['nsp'] as $s) { - $status = $data->dropSchema($s, isset($_POST['cascade'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadropped']); - } else { - $data->endTransaction(); - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadroppedbad'])); - return; - } - } - } - if ($data->endTransaction() == 0) { - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - doDefault($lang['strschemadroppedbad']); - } - - } else { - $status = $data->dropSchema($_POST['nsp'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strschemadropped']); - } else { - doDefault($lang['strschemadroppedbad']); - } - - } - } -} - -/** - * Displays options for database download - */ -function doExport($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'export'); - $misc->printMsg($msg); - - echo "<form action=\"/views/dbexport.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; - // Data only - echo "<tr><th class=\"data left\" rowspan=\"2\">"; - echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"d_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; - // Structure only - echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; - echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; - // Structure and data - echo "<tr><th class=\"data left\" rowspan=\"3\">"; - echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"sd_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; - echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; - echo "</table>\n"; - - echo "<h3>{$lang['stroptions']}</h3>\n"; - echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; - echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label>\n"; - // MSIE cannot download gzip in SSL mode - it's just broken - if (!(strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS']))) { - echo "<br /><input type=\"radio\" id=\"output3\" name=\"output\" value=\"gzipped\" /><label for=\"output3\">{$lang['strdownloadgzipped']}</label>\n"; - } - echo "</p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"schema\" />\n"; - echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n"; - echo "<input type=\"hidden\" name=\"schema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; - echo "</form>\n"; -} +$schema_controller = new \PHPPgAdmin\Controller\SchemaController($container); $misc->printHeader($lang['strschemas']); $misc->printBody(); @@ -421,33 +21,33 @@ if (isset($_POST['cancel'])) { switch ($action) { case 'create': if (isset($_POST['create'])) { - doSaveCreate(); + $schema_controller->doSaveCreate(); } else { - doCreate(); + $schema_controller->doCreate(); } break; case 'alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $schema_controller->doSaveAlter(); } else { - doAlter(); + $schema_controller->doAlter(); } break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $schema_controller->doDrop(false); } else { - doDrop(true); + $schema_controller->doDrop(true); } break; case 'export': - doExport(); + $schema_controller->doExport(); break; default: - doDefault(); + $schema_controller->doDefault(); break; } diff --git a/src/views/sequences.php b/src/views/sequences.php index 12850784..63ef6d1a 100644 --- a/src/views/sequences.php +++ b/src/views/sequences.php @@ -9,715 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Display list of all sequences in the database/schema - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'sequences'); - $misc->printMsg($msg); - - // Get all sequences - $sequences = $data->getSequences(); - - $columns = [ - 'sequence' => [ - 'title' => $lang['strsequence'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('seqname'), - 'url' => "sequences.php?action=properties&{$misc->href}&", - 'vars' => ['sequence' => 'seqname'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('seqowner'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('seqcomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['sequence' => 'seqname'], - 'url' => 'sequences.php', - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'subject' => 'sequence', - 'sequence' => \PHPPgAdmin\Decorators\Decorator::field('seqname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'sequence' => \PHPPgAdmin\Decorators\Decorator::field('seqname'), - ], - ], - ], - 'multiaction' => 'confirm_drop', - ], - 'privileges' => [ - 'content' => $lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges.php', - 'urlvars' => [ - 'subject' => 'sequence', - 'sequence' => \PHPPgAdmin\Decorators\Decorator::field('seqname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($sequences, $columns, $actions, 'sequences-sequences', $lang['strnosequences']); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatesequence'], - ]], 'sequences-sequences', get_defined_vars()); -} - -/** - * Display the properties of a sequence - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('sequence'); - $misc->printTitle($lang['strproperties'], 'pg.sequence'); - $misc->printMsg($msg); - - // Fetch the sequence information - $sequence = $data->getSequence($_REQUEST['sequence']); - - if (is_object($sequence) && $sequence->recordCount() > 0) { - $sequence->fields['is_cycled'] = $data->phpBool($sequence->fields['is_cycled']); - $sequence->fields['is_called'] = $data->phpBool($sequence->fields['is_called']); - - // Show comment if any - if ($sequence->fields['seqcomment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($sequence->fields['seqcomment']), "</p>\n"; - } - - echo "<table border=\"0\">"; - echo "<tr><th class=\"data\">{$lang['strname']}</th>"; - if ($data->hasAlterSequenceStart()) { - echo "<th class=\"data\">{$lang['strstartvalue']}</th>"; - } - echo "<th class=\"data\">{$lang['strlastvalue']}</th>"; - echo "<th class=\"data\">{$lang['strincrementby']}</th>"; - echo "<th class=\"data\">{$lang['strmaxvalue']}</th>"; - echo "<th class=\"data\">{$lang['strminvalue']}</th>"; - echo "<th class=\"data\">{$lang['strcachevalue']}</th>"; - echo "<th class=\"data\">{$lang['strlogcount']}</th>"; - echo "<th class=\"data\">{$lang['strcancycle']}</th>"; - echo "<th class=\"data\">{$lang['striscalled']}</th></tr>"; - echo "<tr>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['seqname']), "</td>"; - if ($data->hasAlterSequenceStart()) { - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['start_value']), "</td>"; - } - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['last_value']), "</td>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['increment_by']), "</td>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['max_value']), "</td>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['min_value']), "</td>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['cache_value']), "</td>"; - echo "<td class=\"data1\">", $misc->printVal($sequence->fields['log_cnt']), "</td>"; - echo "<td class=\"data1\">", ($sequence->fields['is_cycled'] ? $lang['stryes'] : $lang['strno']), "</td>"; - echo "<td class=\"data1\">", ($sequence->fields['is_called'] ? $lang['stryes'] : $lang['strno']), "</td>"; - echo "</tr>"; - echo "</table>"; - - $navlinks = [ - 'alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'sequence' => $sequence->fields['seqname'], - ], - ], - ], - 'content' => $lang['stralter'], - ], - 'setval' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'confirm_setval', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'sequence' => $sequence->fields['seqname'], - ], - ], - ], - 'content' => $lang['strsetval'], - ], - 'nextval' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'nextval', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'sequence' => $sequence->fields['seqname'], - ], - ], - ], - 'content' => $lang['strnextval'], - ], - 'restart' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'restart', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'sequence' => $sequence->fields['seqname'], - ], - ], - ], - 'content' => $lang['strrestart'], - ], - 'reset' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'action' => 'reset', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'sequence' => $sequence->fields['seqname'], - ], - ], - ], - 'content' => $lang['strreset'], - ], - 'showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'sequences.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strshowallsequences'], - ], - ]; - - if (!$data->hasAlterSequenceStart()) { - unset($navlinks['restart']); - } - - $misc->printNavLinks($navlinks, 'sequences-properties', get_defined_vars()); - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Drop a sequence - */ -function doDrop($confirm, $msg = '') { - global $data, $misc; - global $lang; - - if (empty($_REQUEST['sequence']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifysequencetodrop']); - exit(); - } - - if ($confirm) { - $misc->printTrail('sequence'); - $misc->printTitle($lang['strdrop'], 'pg.sequence.drop'); - $misc->printMsg($msg); - - echo "<form action=\"/views/sequences.php\" method=\"post\">\n"; - - //If multi drop - if (isset($_REQUEST['ma'])) { - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdropsequence'], $misc->printVal($a['sequence'])), "</p>\n"; - printf('<input type="hidden" name="sequence[]" value="%s" />', htmlspecialchars($a['sequence'])); - } - } else { - echo "<p>", sprintf($lang['strconfdropsequence'], $misc->printVal($_REQUEST['sequence'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; - } - - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - if (is_array($_POST['sequence'])) { - $msg = ''; - $status = $data->beginTransaction(); - if ($status == 0) { - foreach ($_POST['sequence'] as $s) { - $status = $data->dropSequence($s, isset($_POST['cascade'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strsequencedropped']); - } else { - $data->endTransaction(); - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strsequencedroppedbad'])); - return; - } - } - } - if ($data->endTransaction() == 0) { - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - doDefault($lang['strsequencedroppedbad']); - } - - } else { - $status = $data->dropSequence($_POST['sequence'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strsequencedropped']); - } else { - doDrop(true, $lang['strsequencedroppedbad']); - } - - } - } -} - -/** - * Displays a screen where they can enter a new sequence - */ -function doCreateSequence($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['formSequenceName'])) { - $_POST['formSequenceName'] = ''; - } - - if (!isset($_POST['formIncrement'])) { - $_POST['formIncrement'] = ''; - } - - if (!isset($_POST['formMinValue'])) { - $_POST['formMinValue'] = ''; - } - - if (!isset($_POST['formMaxValue'])) { - $_POST['formMaxValue'] = ''; - } - - if (!isset($_POST['formStartValue'])) { - $_POST['formStartValue'] = ''; - } - - if (!isset($_POST['formCacheValue'])) { - $_POST['formCacheValue'] = ''; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatesequence'], 'pg.sequence.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/sequences.php\" method=\"post\">\n"; - echo "<table>\n"; - - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formSequenceName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['formSequenceName']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strincrementby']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formIncrement\" size=\"5\" value=\"", - htmlspecialchars($_POST['formIncrement']), "\" /> </td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strminvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formMinValue\" size=\"5\" value=\"", - htmlspecialchars($_POST['formMinValue']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strmaxvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formMaxValue\" size=\"5\" value=\"", - htmlspecialchars($_POST['formMaxValue']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strstartvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formStartValue\" size=\"5\" value=\"", - htmlspecialchars($_POST['formStartValue']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strcachevalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formCacheValue\" size=\"5\" value=\"", - htmlspecialchars($_POST['formCacheValue']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\"><label for=\"formCycledValue\">{$lang['strcancycle']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formCycledValue\" name=\"formCycledValue\" ", - (isset($_POST['formCycledValue']) ? ' checked="checked"' : ''), " /></td></tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_sequence\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new sequence in the database - */ -function doSaveCreateSequence() { - global $data; - global $lang; - - // Check that they've given a name and at least one column - if ($_POST['formSequenceName'] == '') { - doCreateSequence($lang['strsequenceneedsname']); - } else { - $status = $data->createSequence($_POST['formSequenceName'], - $_POST['formIncrement'], $_POST['formMinValue'], - $_POST['formMaxValue'], $_POST['formStartValue'], - $_POST['formCacheValue'], isset($_POST['formCycledValue'])); - if ($status == 0) { - doDefault($lang['strsequencecreated']); - } else { - doCreateSequence($lang['strsequencecreatedbad']); - } - } -} - -/** - * Restarts a sequence - */ -function doRestart() { - global $data; - global $lang; - - $status = $data->restartSequence($_REQUEST['sequence']); - if ($status == 0) { - doProperties($lang['strsequencerestart']); - } else { - doProperties($lang['strsequencerestartbad']); - } - -} - -/** - * Resets a sequence - */ -function doReset() { - global $data; - global $lang; - - $status = $data->resetSequence($_REQUEST['sequence']); - if ($status == 0) { - doProperties($lang['strsequencereset']); - } else { - doProperties($lang['strsequenceresetbad']); - } - -} - -/** - * Set Nextval of a sequence - */ -function doNextval() { - global $data; - global $lang; - - $status = $data->nextvalSequence($_REQUEST['sequence']); - if ($status == 0) { - doProperties($lang['strsequencenextval']); - } else { - doProperties($lang['strsequencenextvalbad']); - } - -} - -/** - * Function to save after 'setval'ing a sequence - */ -function doSaveSetval() { - global $data, $lang, $_reload_browser; - - $status = $data->setvalSequence($_POST['sequence'], $_POST['nextvalue']); - if ($status == 0) { - doProperties($lang['strsequencesetval']); - } else { - doProperties($lang['strsequencesetvalbad']); - } - -} - -/** - * Function to allow 'setval'ing of a sequence - */ -function doSetval($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('sequence'); - $misc->printTitle($lang['strsetval'], 'pg.sequence'); - $misc->printMsg($msg); - - // Fetch the sequence information - $sequence = $data->getSequence($_REQUEST['sequence']); - - if (is_object($sequence) && $sequence->recordCount() > 0) { - echo "<form action=\"/views/sequences.php\" method=\"post\">\n"; - echo "<table border=\"0\">"; - echo "<tr><th class=\"data left required\">{$lang['strlastvalue']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"nextvalue\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - $misc->printVal($sequence->fields['last_value']), "\" /></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"setval\" />\n"; - echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"setval\" value=\"{$lang['strsetval']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Function to save after altering a sequence - */ -function doSaveAlter() { - global $data, $lang, $_reload_browser, $misc; - - if (!isset($_POST['owner'])) { - $_POST['owner'] = null; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = null; - } - - if (!isset($_POST['formIncrement'])) { - $_POST['formIncrement'] = null; - } - - if (!isset($_POST['formMinValue'])) { - $_POST['formMinValue'] = null; - } - - if (!isset($_POST['formMaxValue'])) { - $_POST['formMaxValue'] = null; - } - - if (!isset($_POST['formStartValue'])) { - $_POST['formStartValue'] = null; - } - - if (!isset($_POST['formRestartValue'])) { - $_POST['formRestartValue'] = null; - } - - if (!isset($_POST['formCacheValue'])) { - $_POST['formCacheValue'] = null; - } - - if (!isset($_POST['formCycledValue'])) { - $_POST['formCycledValue'] = null; - } - - $status = $data->alterSequence($_POST['sequence'], $_POST['name'], $_POST['comment'], $_POST['owner'], - $_POST['newschema'], $_POST['formIncrement'], $_POST['formMinValue'], $_POST['formMaxValue'], - $_POST['formRestartValue'], $_POST['formCacheValue'], isset($_POST['formCycledValue']), $_POST['formStartValue']); - - if ($status == 0) { - if ($_POST['sequence'] != $_POST['name']) { - // Jump them to the new view name - $_REQUEST['sequence'] = $_POST['name']; - // Force a browser reload - $_reload_browser = true; - } - if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { - // Jump them to the new sequence schema - $misc->setCurrentSchema($_POST['newschema']); - $_reload_browser = true; - } - doProperties($lang['strsequencealtered']); - } else { - doProperties($lang['strsequencealteredbad']); - } - -} - -/** - * Function to allow altering of a sequence - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('sequence'); - $misc->printTitle($lang['stralter'], 'pg.sequence.alter'); - $misc->printMsg($msg); - - // Fetch the sequence information - $sequence = $data->getSequence($_REQUEST['sequence']); - - if (is_object($sequence) && $sequence->recordCount() > 0) { - if (!isset($_POST['name'])) { - $_POST['name'] = $_REQUEST['sequence']; - } - - if (!isset($_POST['comment'])) { - $_POST['comment'] = $sequence->fields['seqcomment']; - } - - if (!isset($_POST['owner'])) { - $_POST['owner'] = $sequence->fields['seqowner']; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = $sequence->fields['nspname']; - } - - // Handle Checkbox Value - $sequence->fields['is_cycled'] = $data->phpBool($sequence->fields['is_cycled']); - if ($sequence->fields['is_cycled']) { - $_POST['formCycledValue'] = 'on'; - } - - echo "<form action=\"/views/sequences.php\" method=\"post\">\n"; - echo "<table>\n"; - - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; - - if ($data->isSuperUser()) { - // Fetch all users - $users = $data->getUsers(); - - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\"><select name=\"owner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - } - - if ($data->hasAlterSequenceSchema()) { - $schemas = $data->getSchemas(); - echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; - echo "<td class=\"data1\"><select name=\"newschema\">"; - while (!$schemas->EOF) { - $schema = $schemas->fields['nspname']; - echo "<option value=\"", htmlspecialchars($schema), "\"", - ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; - $schemas->moveNext(); - } - echo "</select></td></tr>\n"; - } - - echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", - htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; - - if ($data->hasAlterSequenceStart()) { - echo "<tr><th class=\"data left\">{$lang['strstartvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formStartValue\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['start_value']), "\" /></td></tr>\n"; - } - - echo "<tr><th class=\"data left\">{$lang['strrestartvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formRestartValue\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['last_value']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strincrementby']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formIncrement\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['increment_by']), "\" /> </td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strmaxvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formMaxValue\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['max_value']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strminvalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formMinValue\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['min_value']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\">{$lang['strcachevalue']}</th>\n"; - echo "<td class=\"data1\"><input name=\"formCacheValue\" size=\"5\" value=\"", - htmlspecialchars($sequence->fields['cache_value']), "\" /></td></tr>\n"; - - echo "<tr><th class=\"data left\"><label for=\"formCycledValue\">{$lang['strcancycle']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"formCycledValue\" name=\"formCycledValue\" ", - (isset($_POST['formCycledValue']) ? ' checked="checked"' : ''), " /></td></tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"sequence\" value=\"", htmlspecialchars($_REQUEST['sequence']), "\" />\n"; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} +$sequence_controller = new \PHPPgAdmin\Controller\SequenceController($container); // Print header $misc->printHeader($lang['strsequences']); @@ -725,63 +17,63 @@ $misc->printBody(); switch ($action) { case 'create': - doCreateSequence(); + $sequence_controller->doCreateSequence(); break; case 'save_create_sequence': if (isset($_POST['create'])) { - doSaveCreateSequence(); + $sequence_controller->doSaveCreateSequence(); } else { - doDefault(); + $sequence_controller->doDefault(); } break; case 'properties': - doProperties(); + $sequence_controller->doProperties(); break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $sequence_controller->doDrop(false); } else { - doDefault(); + $sequence_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $sequence_controller->doDrop(true); break; case 'restart': - doRestart(); + $sequence_controller->doRestart(); break; case 'reset': - doReset(); + $sequence_controller->doReset(); break; case 'nextval': - doNextval(); + $sequence_controller->doNextval(); break; case 'setval': if (isset($_POST['setval'])) { - doSaveSetval(); + $sequence_controller->doSaveSetval(); } else { - doDefault(); + $sequence_controller->doDefault(); } break; case 'confirm_setval': - doSetval(); + $sequence_controller->doSetval(); break; case 'alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $sequence_controller->doSaveAlter(); } else { - doDefault(); + $sequence_controller->doDefault(); } break; case 'confirm_alter': - doAlter(); + $sequence_controller->doAlter(); break; default: - doDefault(); + $sequence_controller->doDefault(); break; } diff --git a/src/views/sqledit.php b/src/views/sqledit.php index 184e5587..2fa2854e 100644 --- a/src/views/sqledit.php +++ b/src/views/sqledit.php @@ -108,7 +108,7 @@ function doDefault($container) { $default_html = $misc->printTabs($misc->getNavTabs('popup'), 'sql', false); - $default_html .= '<form action="/views/sql.php" method="post" enctype="multipart/form-data" class="sqlform" id="sqlform" target="detail">'; + $default_html .= '<form action="/src/views/sql.php" method="post" enctype="multipart/form-data" class="sqlform" id="sqlform" target="detail">'; $default_html .= "\n"; $default_html .= _printConnection($container, 'sql'); diff --git a/src/views/tables.php b/src/views/tables.php index 19189bcc..2e21f5b7 100644 --- a/src/views/tables.php +++ b/src/views/tables.php @@ -9,1009 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Displays a screen where they can enter a new table - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - $default_with_oids = $data->getDefaultWithOid(); - if ($default_with_oids == 'off') { - $_REQUEST['withoutoids'] = 'on'; - } - - } - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['fields'])) { - $_REQUEST['fields'] = ''; - } - - if (!isset($_REQUEST['tblcomment'])) { - $_REQUEST['tblcomment'] = ''; - } - - if (!isset($_REQUEST['spcname'])) { - $_REQUEST['spcname'] = ''; - } - - switch ($_REQUEST['stage']) { - case 1: - // Fetch all tablespaces from the database - if ($data->hasTablespaces()) { - $tablespaces = $data->getTablespaces(); - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumcols']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['stroptions']}</th>\n"; - echo "\t\t<td class=\"data\"><label for=\"withoutoids\"><input type=\"checkbox\" id=\"withoutoids\" name=\"withoutoids\"", isset($_REQUEST['withoutoids']) ? ' checked="checked"' : '', " />WITHOUT OIDS</label></td>\n\t</tr>\n"; - - // Tablespace (if there are any) - if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; - echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"spcname\">\n"; - // Always offer the default (empty) option - echo "\t\t\t\t<option value=\"\"", - ($_REQUEST['spcname'] == '') ? ' selected="selected"' : '', "></option>\n"; - // Display all other tablespaces - while (!$tablespaces->EOF) { - $spcname = htmlspecialchars($tablespaces->fields['spcname']); - echo "\t\t\t\t<option value=\"{$spcname}\"", - ($tablespaces->fields['spcname'] == $_REQUEST['spcname']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; - $tablespaces->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; - } - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"tblcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['tblcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - case 2: - global $lang; - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreate($lang['strtableneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) { - $_REQUEST['stage'] = 1; - doCreate($lang['strtableneedscols']); - return; - } - - $types = $data->getTypes(true, false, true); - $types_for_js = []; - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); - $misc->printMsg($msg); - - echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strcolumn']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>"; - echo "<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strnotnull']}</th>"; - echo "<th class=\"data\">{$lang['struniquekey']}</th><th class=\"data\">{$lang['strprimarykey']}</th>"; - echo "<th class=\"data\">{$lang['strdefault']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n"; - - for ($i = 0; $i < $_REQUEST['fields']; $i++) { - if (!isset($_REQUEST['field'][$i])) { - $_REQUEST['field'][$i] = ''; - } - - if (!isset($_REQUEST['length'][$i])) { - $_REQUEST['length'][$i] = ''; - } - - if (!isset($_REQUEST['default'][$i])) { - $_REQUEST['default'][$i] = ''; - } - - if (!isset($_REQUEST['colcomment'][$i])) { - $_REQUEST['colcomment'][$i] = ''; - } - - echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; - echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n"; - echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\" id=\"types{$i}\" onchange=\"checkLengths(this.options[this.selectedIndex].value,{$i});\">\n"; - // Output any "magic" types - foreach ($data->extraTypes as $v) { - $types_for_js[strtolower($v)] = 1; - echo "\t\t\t\t<option value=\"", htmlspecialchars($v), "\"", - (isset($_REQUEST['type'][$i]) && $v == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", - $misc->printVal($v), "</option>\n"; - } - $types->moveFirst(); - while (!$types->EOF) { - $typname = $types->fields['typname']; - $types_for_js[$typname] = 1; - echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"", - (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", - $misc->printVal($typname), "</option>\n"; - $types->moveNext(); - } - echo "\t\t\t</select>\n\t\t\n"; - if ($i == 0) { - // only define js types array once - $predefined_size_types = array_intersect($data->predefined_size_types, array_keys($types_for_js)); - $escaped_predef_types = []; // the JS escaped array elements - foreach ($predefined_size_types as $value) { - $escaped_predef_types[] = "'{$value}'"; - } - echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");</script>\n\t</td>"; - } - - // Output array type selector - echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n"; - echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "\t\t\t</select>\n\t\t</td>\n"; - - echo "\t\t<td><input name=\"length[{$i}]\" id=\"lengths{$i}\" size=\"10\" value=\"", - htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n"; - echo "\t\t<td><input type=\"checkbox\" name=\"notnull[{$i}]\"", (isset($_REQUEST['notnull'][$i])) ? ' checked="checked"' : '', " /></td>\n"; - echo "\t\t<td style=\"text-align: center\"><input type=\"checkbox\" name=\"uniquekey[{$i}]\"" - . (isset($_REQUEST['uniquekey'][$i]) ? ' checked="checked"' : '') . " /></td>\n"; - echo "\t\t<td style=\"text-align: center\"><input type=\"checkbox\" name=\"primarykey[{$i}]\" " - . (isset($_REQUEST['primarykey'][$i]) ? ' checked="checked"' : '') - . " /></td>\n"; - echo "\t\t<td><input name=\"default[{$i}]\" size=\"20\" value=\"", - htmlspecialchars($_REQUEST['default'][$i]), "\" /></td>\n"; - echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"", - htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /> - <script type=\"text/javascript\">checkLengths(document.getElementById('types{$i}').value,{$i});</script> - </td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n"; - if (isset($_REQUEST['withoutoids'])) { - echo "<input type=\"hidden\" name=\"withoutoids\" value=\"true\" />\n"; - } - echo "<input type=\"hidden\" name=\"tblcomment\" value=\"", htmlspecialchars($_REQUEST['tblcomment']), "\" />\n"; - if (isset($_REQUEST['spcname'])) { - echo "<input type=\"hidden\" name=\"spcname\" value=\"", htmlspecialchars($_REQUEST['spcname']), "\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 3: - global $data, $lang, $_reload_browser; - - if (!isset($_REQUEST['notnull'])) { - $_REQUEST['notnull'] = []; - } - - if (!isset($_REQUEST['uniquekey'])) { - $_REQUEST['uniquekey'] = []; - } - - if (!isset($_REQUEST['primarykey'])) { - $_REQUEST['primarykey'] = []; - } - - if (!isset($_REQUEST['length'])) { - $_REQUEST['length'] = []; - } - - // Default tablespace to null if it isn't set - if (!isset($_REQUEST['spcname'])) { - $_REQUEST['spcname'] = null; - } - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreate($lang['strtableneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) { - $_REQUEST['stage'] = 1; - doCreate($lang['strtableneedscols']); - return; - } - - $status = $data->createTable($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'], - $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['notnull'], $_REQUEST['default'], - isset($_REQUEST['withoutoids']), $_REQUEST['colcomment'], $_REQUEST['tblcomment'], $_REQUEST['spcname'], - $_REQUEST['uniquekey'], $_REQUEST['primarykey']); - - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strtablecreated']); - } elseif ($status == -1) { - $_REQUEST['stage'] = 2; - doCreate($lang['strtableneedsfield']); - return; - } else { - $_REQUEST['stage'] = 2; - doCreate($lang['strtablecreatedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Dsiplay a screen where user can create a table from an existing one. - * We don't have to check if pg supports schema cause create table like - * is available under pg 7.4+ which has schema. - */ -function doCreateLike($confirm, $msg = '') { - global $data, $misc, $lang; - - if (!$confirm) { - - include_once BASE_PATH . '/classes/Gui.php'; - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['like'])) { - $_REQUEST['like'] = ''; - } - - if (!isset($_REQUEST['tablespace'])) { - $_REQUEST['tablespace'] = ''; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatetable'], 'pg.table.create'); - $misc->printMsg($msg); - - $tbltmp = $data->getTables(true); - $tbltmp = $tbltmp->getArray(); - - $tables = []; - $tblsel = ''; - foreach ($tbltmp as $a) { - $data->fieldClean($a['nspname']); - $data->fieldClean($a['relname']); - $tables["\"{$a['nspname']}\".\"{$a['relname']}\""] = serialize(['schema' => $a['nspname'], 'table' => $a['relname']]); - if ($_REQUEST['like'] == $tables["\"{$a['nspname']}\".\"{$a['relname']}\""]) { - $tblsel = htmlspecialchars($tables["\"{$a['nspname']}\".\"{$a['relname']}\""]); - } - - } - - unset($tbltmp); - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - echo "<table>\n\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strcreatetablelikeparent']}</th>\n"; - echo "\t\t<td class=\"data\">"; - echo GUI::printCombo($tables, 'like', true, $tblsel, false); - echo "</td>\n\t</tr>\n"; - if ($data->hasTablespaces()) { - $tblsp_ = $data->getTablespaces(); - if ($tblsp_->recordCount() > 0) { - $tblsp_ = $tblsp_->getArray(); - $tblsp = []; - foreach ($tblsp_ as $a) { - $tblsp[$a['spcname']] = $a['spcname']; - } - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; - echo "\t\t<td class=\"data\">"; - echo GUI::printCombo($tblsp, 'tablespace', true, $_REQUEST['tablespace'], false); - echo "</td>\n\t</tr>\n"; - } - } - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['stroptions']}</th>\n\t\t<td class=\"data\">"; - echo "<label for=\"withdefaults\"><input type=\"checkbox\" id=\"withdefaults\" name=\"withdefaults\"", - isset($_REQUEST['withdefaults']) ? ' checked="checked"' : '', - "/>{$lang['strcreatelikewithdefaults']}</label>"; - if ($data->hasCreateTableLikeWithConstraints()) { - echo "<br /><label for=\"withconstraints\"><input type=\"checkbox\" id=\"withconstraints\" name=\"withconstraints\"", - isset($_REQUEST['withconstraints']) ? ' checked="checked"' : '', - "/>{$lang['strcreatelikewithconstraints']}</label>"; - } - if ($data->hasCreateTableLikeWithIndexes()) { - echo "<br /><label for=\"withindexes\"><input type=\"checkbox\" id=\"withindexes\" name=\"withindexes\"", - isset($_REQUEST['withindexes']) ? ' checked="checked"' : '', - "/>{$lang['strcreatelikewithindexes']}</label>"; - } - echo "</td>\n\t</tr>\n"; - echo "</table>"; - - echo "<input type=\"hidden\" name=\"action\" value=\"confcreatelike\" />\n"; - echo $misc->form; - echo "<p><input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - global $_reload_browser; - - if (trim($_REQUEST['name']) == '') { - doCreateLike(false, $lang['strtableneedsname']); - return; - } - if (trim($_REQUEST['like']) == '') { - doCreateLike(false, $lang['strtablelikeneedslike']); - return; - } - - if (!isset($_REQUEST['tablespace'])) { - $_REQUEST['tablespace'] = ''; - } - - $status = $data->createTableLike($_REQUEST['name'], unserialize($_REQUEST['like']), isset($_REQUEST['withdefaults']), - isset($_REQUEST['withconstraints']), isset($_REQUEST['withindexes']), $_REQUEST['tablespace']); - - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strtablecreated']); - } else { - doCreateLike(false, $lang['strtablecreatedbad']); - return; - } - } -} - -/** - * Ask for select parameters and perform select - */ -function doSelectRows($confirm, $msg = '') { - global $data, $misc, $_no_output; - global $lang; - - if ($confirm) { - $misc->printTrail('table'); - $misc->printTabs('table', 'select'); - $misc->printMsg($msg); - - $attrs = $data->getTableAttributes($_REQUEST['table']); - - echo "<form action=\"/views/tables.php\" method=\"post\" id=\"selectform\">\n"; - if ($attrs->recordCount() > 0) { - // JavaScript for select all feature - echo "<script type=\"text/javascript\">\n"; - echo "//<![CDATA[\n"; - echo " function selectAll() {\n"; - echo " for (var i=0; i<document.getElementById('selectform').elements.length; i++) {\n"; - echo " var e = document.getElementById('selectform').elements[i];\n"; - echo " if (e.name.indexOf('show') == 0) e.checked = document.getElementById('selectform').selectall.checked;\n"; - echo " }\n"; - echo " }\n"; - echo "//]]>\n"; - echo "</script>\n"; - - echo "<table>\n"; - - // Output table header - echo "<tr><th class=\"data\">{$lang['strshow']}</th><th class=\"data\">{$lang['strcolumn']}</th>"; - echo "<th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['stroperator']}</th>"; - echo "<th class=\"data\">{$lang['strvalue']}</th></tr>"; - - $i = 0; - while (!$attrs->EOF) { - $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); - // Set up default value if there isn't one already - if (!isset($_REQUEST['values'][$attrs->fields['attname']])) { - $_REQUEST['values'][$attrs->fields['attname']] = null; - } - - if (!isset($_REQUEST['ops'][$attrs->fields['attname']])) { - $_REQUEST['ops'][$attrs->fields['attname']] = null; - } - - // Continue drawing row - $id = (($i % 2) == 0 ? '1' : '2'); - echo "<tr class=\"data{$id}\">\n"; - echo "<td style=\"white-space:nowrap;\">"; - echo "<input type=\"checkbox\" name=\"show[", htmlspecialchars($attrs->fields['attname']), "]\"", - isset($_REQUEST['show'][$attrs->fields['attname']]) ? ' checked="checked"' : '', " /></td>"; - echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; - echo "<td style=\"white-space:nowrap;\">", $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])), "</td>"; - echo "<td style=\"white-space:nowrap;\">"; - echo "<select name=\"ops[{$attrs->fields['attname']}]\">\n"; - foreach (array_keys($data->selectOps) as $v) { - echo "<option value=\"", htmlspecialchars($v), "\"", ($v == $_REQUEST['ops'][$attrs->fields['attname']]) ? ' selected="selected"' : '', - ">", htmlspecialchars($v), "</option>\n"; - } - echo "</select>\n</td>\n"; - echo "<td style=\"white-space:nowrap;\">", $data->printField("values[{$attrs->fields['attname']}]", - $_REQUEST['values'][$attrs->fields['attname']], $attrs->fields['type']), "</td>"; - echo "</tr>\n"; - $i++; - $attrs->moveNext(); - } - // Select all checkbox - echo "<tr><td colspan=\"5\"><input type=\"checkbox\" id=\"selectall\" name=\"selectall\" accesskey=\"a\" onclick=\"javascript:selectAll()\" /><label for=\"selectall\">{$lang['strselectallfields']}</label></td>"; - echo "</tr></table>\n"; - } else { - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } - - echo "<p><input type=\"hidden\" name=\"action\" value=\"selectrows\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"select\" accesskey=\"r\" value=\"{$lang['strselect']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - if (!isset($_POST['show'])) { - $_POST['show'] = []; - } - - if (!isset($_POST['values'])) { - $_POST['values'] = []; - } - - if (!isset($_POST['nulls'])) { - $_POST['nulls'] = []; - } - - // Verify that they haven't supplied a value for unary operators - foreach ($_POST['ops'] as $k => $v) { - if ($data->selectOps[$v] == 'p' && $_POST['values'][$k] != '') { - doSelectRows(true, $lang['strselectunary']); - return; - } - } - - if (sizeof($_POST['show']) == 0) { - doSelectRows(true, $lang['strselectneedscol']); - } else { - // Generate query SQL - $query = $data->getSelectSQL($_REQUEST['table'], array_keys($_POST['show']), - $_POST['values'], $_POST['ops']); - $_REQUEST['query'] = $query; - $_REQUEST['return'] = 'selectrows'; - - $_no_output = true; - include './display.php'; - exit; - } - } -} - -/** - * Ask for insert parameters and then actually insert row - */ -function doInsertRow($confirm, $msg = '') { - global $data, $misc, $conf; - global $lang; - - if ($confirm) { - $misc->printTrail('table'); - $misc->printTabs('table', 'insert'); - - $misc->printMsg($msg); - - $attrs = $data->getTableAttributes($_REQUEST['table']); - - if (($conf['autocomplete'] != 'disable')) { - $fksprops = $misc->getAutocompleteFKProperties($_REQUEST['table']); - if ($fksprops !== false) { - echo $fksprops['code']; - } - - } else { - $fksprops = false; - } - - echo "<form action=\"/views/tables.php\" method=\"post\" id=\"ac_form\">\n"; - if ($attrs->recordCount() > 0) { - echo "<table>\n"; - - // Output table header - echo "<tr><th class=\"data\">{$lang['strcolumn']}</th><th class=\"data\">{$lang['strtype']}</th>"; - echo "<th class=\"data\">{$lang['strformat']}</th>"; - echo "<th class=\"data\">{$lang['strnull']}</th><th class=\"data\">{$lang['strvalue']}</th></tr>"; - - $i = 0; - $fields = []; - while (!$attrs->EOF) { - $fields[$attrs->fields['attnum']] = $attrs->fields['attname']; - $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); - // Set up default value if there isn't one already - if (!isset($_REQUEST['values'][$attrs->fields['attnum']])) { - $_REQUEST['values'][$attrs->fields['attnum']] = $attrs->fields['adsrc']; - } - - // Default format to 'VALUE' if there is no default, - // otherwise default to 'EXPRESSION' - if (!isset($_REQUEST['format'][$attrs->fields['attnum']])) { - $_REQUEST['format'][$attrs->fields['attnum']] = ($attrs->fields['adsrc'] === null) ? 'VALUE' : 'EXPRESSION'; - } - - // Continue drawing row - $id = (($i % 2) == 0 ? '1' : '2'); - echo "<tr class=\"data{$id}\">\n"; - echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; - echo "<td style=\"white-space:nowrap;\">\n"; - echo $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])); - echo "<input type=\"hidden\" name=\"types[{$attrs->fields['attnum']}]\" value=\"", - htmlspecialchars($attrs->fields['type']), "\" /></td>"; - echo "<td style=\"white-space:nowrap;\">\n"; - echo "<select name=\"format[{$attrs->fields['attnum']}]\">\n"; - echo "<option value=\"VALUE\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'VALUE') ? ' selected="selected"' : '', ">{$lang['strvalue']}</option>\n"; - echo "<option value=\"EXPRESSION\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'EXPRESSION') ? ' selected="selected"' : '', ">{$lang['strexpression']}</option>\n"; - echo "</select>\n</td>\n"; - echo "<td style=\"white-space:nowrap;\">"; - // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS) - if (!$attrs->fields['attnotnull']) { - echo "<label><span><input type=\"checkbox\" name=\"nulls[{$attrs->fields['attnum']}]\"", - isset($_REQUEST['nulls'][$attrs->fields['attnum']]) ? ' checked="checked"' : '', " /></span></label></td>"; - } else { - echo " </td>"; - } - echo "<td id=\"row_att_{$attrs->fields['attnum']}\" style=\"white-space:nowrap;\">"; - if (($fksprops !== false) && isset($fksprops['byfield'][$attrs->fields['attnum']])) { - echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], 'fktype' /*force FK*/, - [ - 'id' => "attr_{$attrs->fields['attnum']}", - 'autocomplete' => 'off', - ] - ); - } else { - echo $data->printField("values[{$attrs->fields['attnum']}]", $_REQUEST['values'][$attrs->fields['attnum']], $attrs->fields['type']); - } - echo "</td>\n"; - echo "</tr>\n"; - $i++; - $attrs->moveNext(); - } - echo "</table>\n"; - - if (!isset($_SESSION['counter'])) {$_SESSION['counter'] = 0;} - - echo "<input type=\"hidden\" name=\"action\" value=\"insertrow\" />\n"; - echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlentities(serialize($fields), ENT_QUOTES, 'UTF-8'), "\" />\n"; - echo "<input type=\"hidden\" name=\"protection_counter\" value=\"" . $_SESSION['counter'] . "\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<p><input type=\"submit\" name=\"insert\" value=\"{$lang['strinsert']}\" />\n"; - echo "<input type=\"submit\" name=\"insertandrepeat\" accesskey=\"r\" value=\"{$lang['strinsertandrepeat']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - - if ($fksprops !== false) { - if ($conf['autocomplete'] != 'default off') { - echo "<input type=\"checkbox\" id=\"no_ac\" value=\"1\" checked=\"checked\" /><label for=\"no_ac\">{$lang['strac']}</label>\n"; - } else { - echo "<input type=\"checkbox\" id=\"no_ac\" value=\"0\" /><label for=\"no_ac\">{$lang['strac']}</label>\n"; - } - - } - echo "</p>\n"; - } else { - echo "<p>{$lang['strnofieldsforinsert']}</p>\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - } - echo $misc->form; - echo "</form>\n"; - } else { - if (!isset($_POST['values'])) { - $_POST['values'] = []; - } - - if (!isset($_POST['nulls'])) { - $_POST['nulls'] = []; - } - - $_POST['fields'] = unserialize(htmlspecialchars_decode($_POST['fields'], ENT_QUOTES)); - - if ($_SESSION['counter']++ == $_POST['protection_counter']) { - $status = $data->insertRow($_POST['table'], $_POST['fields'], $_POST['values'], - $_POST['nulls'], $_POST['format'], $_POST['types']); - if ($status == 0) { - if (isset($_POST['insert'])) { - doDefault($lang['strrowinserted']); - } else { - $_REQUEST['values'] = []; - $_REQUEST['nulls'] = []; - doInsertRow(true, $lang['strrowinserted']); - } - } else { - doInsertRow(true, $lang['strrowinsertedbad']); - } - - } else { - doInsertRow(true, $lang['strrowduplicate']); - } - - } - -} - -/** - * Show confirmation of empty and perform actual empty - */ -function doEmpty($confirm) { - global $data, $misc; - global $lang; - - if (empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletoempty']); - exit(); - } - - if ($confirm) { - if (isset($_REQUEST['ma'])) { - $misc->printTrail('schema'); - $misc->printTitle($lang['strempty'], 'pg.table.empty'); - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfemptytable'], $misc->printVal($a['table'])), "</p>\n"; - printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table'])); - } - } // END mutli empty - else { - $misc->printTrail('table'); - $misc->printTitle($lang['strempty'], 'pg.table.empty'); - - echo "<p>", sprintf($lang['strconfemptytable'], $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - } // END not mutli empty - - echo "<input type=\"hidden\" name=\"action\" value=\"empty\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"empty\" value=\"{$lang['strempty']}\" /> <input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END if confirm - else { - // Do Empty - if (is_array($_REQUEST['table'])) { - $msg = ''; - foreach ($_REQUEST['table'] as $t) { - $status = $data->emptyTable($t); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtableemptied']); - } else { - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtableemptiedbad'])); - return; - } - } - doDefault($msg); - } // END mutli empty - else { - $status = $data->emptyTable($_POST['table']); - if ($status == 0) { - doDefault($lang['strtableemptied']); - } else { - doDefault($lang['strtableemptiedbad']); - } - - } // END not mutli empty - } // END do Empty -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_browser; - - if (empty($_REQUEST['table']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifytabletodrop']); - exit(); - } - - if ($confirm) { - //If multi drop - if (isset($_REQUEST['ma'])) { - - $misc->printTrail('schema'); - $misc->printTitle($lang['strdrop'], 'pg.table.drop'); - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdroptable'], $misc->printVal($a['table'])), "</p>\n"; - printf('<input type="hidden" name="table[]" value="%s" />', htmlspecialchars($a['table'])); - } - } else { - - $misc->printTrail('table'); - $misc->printTitle($lang['strdrop'], 'pg.table.drop'); - - echo "<p>", sprintf($lang['strconfdroptable'], $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/tables.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - } // END if multi drop - - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } // END confirm - else { - //If multi drop - if (is_array($_REQUEST['table'])) { - $msg = ''; - $status = $data->beginTransaction(); - if ($status == 0) { - foreach ($_REQUEST['table'] as $t) { - $status = $data->dropTable($t, isset($_POST['cascade'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtabledropped']); - } else { - $data->endTransaction(); - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($t, ENT_QUOTES, 'UTF-8'), $lang['strtabledroppedbad'])); - return; - } - } - } - if ($data->endTransaction() == 0) { - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - doDefault($lang['strtabledroppedbad']); - } - - } else { - $status = $data->dropTable($_POST['table'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strtabledropped']); - } else { - doDefault($lang['strtabledroppedbad']); - } - - } - } // END DROP -} // END Function - -/** - * Show default list of tables in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc, $data; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'tables'); - $misc->printMsg($msg); - - $tables = $data->getTables(); - - $columns = [ - 'table' => [ - 'title' => $lang['strtable'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - 'url' => "/redirect/table?{$misc->href}&", - 'vars' => ['table' => 'relname'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relowner'), - ], - 'tablespace' => [ - 'title' => $lang['strtablespace'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('tablespace'), - ], - 'tuples' => [ - 'title' => $lang['strestimatedrowcount'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('reltuples'), - 'type' => 'numeric', - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relcomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['table' => 'relname'], - 'url' => 'tables.php', - 'default' => 'analyze', - ], - 'browse' => [ - 'content' => $lang['strbrowse'], - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'subject' => 'table', - 'return' => 'table', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'select' => [ - 'content' => $lang['strselect'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confselectrows', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'insert' => [ - 'content' => $lang['strinsert'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confinsertrow', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'empty' => [ - 'multiaction' => 'confirm_empty', - 'content' => $lang['strempty'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_empty', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'drop' => [ - 'multiaction' => 'confirm_drop', - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'vacuum' => [ - 'multiaction' => 'confirm_vacuum', - 'content' => $lang['strvacuum'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_vacuum', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'analyze' => [ - 'multiaction' => 'confirm_analyze', - 'content' => $lang['stranalyze'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_analyze', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'reindex' => [ - 'multiaction' => 'confirm_reindex', - 'content' => $lang['strreindex'], - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_reindex', - 'table' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - //'cluster' TODO ? - ]; - - if (!$data->hasTablespaces()) { - unset($columns['tablespace']); - } - - echo $misc->printTable($tables, $columns, $actions, 'tables-tables', $lang['strnotables']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatetable'], - ], - ]; - - if (($tables->recordCount() > 0) && $data->hasCreateTableLike()) { - $navlinks['createlike'] = [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'createlike', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatetablelike'], - ]; - } - $misc->printNavLinks($navlinks, 'tables-tables', get_defined_vars()); -} - -require './admin.php'; +$table_controller = new \PHPPgAdmin\Controller\TableController($container); $misc->printHeader($lang['strtables']); $misc->printBody(); @@ -1019,70 +17,70 @@ $misc->printBody(); switch ($action) { case 'create': if (isset($_POST['cancel'])) { - doDefault(); + $table_controller->doDefault(); } else { - doCreate(); + $table_controller->doCreate(); } break; case 'createlike': - doCreateLike(false); + $table_controller->doCreateLike(false); break; case 'confcreatelike': if (isset($_POST['cancel'])) { - doDefault(); + $table_controller->doDefault(); } else { - doCreateLike(true); + $table_controller->doCreateLike(true); } break; case 'selectrows': if (!isset($_POST['cancel'])) { - doSelectRows(false); + $table_controller->doSelectRows(false); } else { - doDefault(); + $table_controller->doDefault(); } break; case 'confselectrows': - doSelectRows(true); + $table_controller->doSelectRows(true); break; case 'insertrow': if (!isset($_POST['cancel'])) { - doInsertRow(false); + $table_controller->doInsertRow(false); } else { - doDefault(); + $table_controller->doDefault(); } break; case 'confinsertrow': - doInsertRow(true); + $table_controller->doInsertRow(true); break; case 'empty': if (isset($_POST['empty'])) { - doEmpty(false); + $table_controller->doEmpty(false); } else { - doDefault(); + $table_controller->doDefault(); } break; case 'confirm_empty': - doEmpty(true); + $table_controller->doEmpty(true); break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $table_controller->doDrop(false); } else { - doDefault(); + $table_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $table_controller->doDrop(true); break; default: - if (adminActions($action, 'table') === false) { - doDefault(); + if ($table_controller->adminActions($action, 'table') === false) { + $table_controller->doDefault(); } break; diff --git a/src/views/tablespaces.php b/src/views/tablespaces.php index 10590d33..0ec0af61 100755 --- a/src/views/tablespaces.php +++ b/src/views/tablespaces.php @@ -44,7 +44,7 @@ function doAlter($msg = '') { $_POST['comment'] = ($data->hasSharedComments()) ? $tablespace->fields['spccomment'] : ''; } - echo "<form action=\"/views/tablespaces.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/tablespaces.php\" method=\"post\">\n"; echo $misc->form; echo "<table>\n"; echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; @@ -116,7 +116,7 @@ function doDrop($confirm) { echo "<p>", sprintf($lang['strconfdroptablespace'], $misc->printVal($_REQUEST['tablespace'])), "</p>\n"; - echo "<form action=\"/views/tablespaces.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/tablespaces.php\" method=\"post\">\n"; echo $misc->form; echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; echo "<input type=\"hidden\" name=\"tablespace\" value=\"", htmlspecialchars($_REQUEST['tablespace']), "\" />\n"; @@ -166,7 +166,7 @@ function doCreate($msg = '') { $misc->printTitle($lang['strcreatetablespace'], 'pg.tablespace.create'); $misc->printMsg($msg); - echo "<form action=\"/views/tablespaces.php\" method=\"post\">\n"; + echo "<form action=\"/src/views/tablespaces.php\" method=\"post\">\n"; echo $misc->form; echo "<table>\n"; echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; diff --git a/src/views/tblproperties.php b/src/views/tblproperties.php index b5169a12..0aa6fd54 100644 --- a/src/views/tblproperties.php +++ b/src/views/tblproperties.php @@ -9,750 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Function to save after altering a table - */ -function doSaveAlter() { - global $data, $lang, $_reload_browser, $misc; - - // For databases that don't allow owner change - if (!isset($_POST['owner'])) { - $_POST['owner'] = ''; - } - - // Default tablespace to null if it isn't set - if (!isset($_POST['tablespace'])) { - $_POST['tablespace'] = null; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = null; - } - - $status = $data->alterTable($_POST['table'], $_POST['name'], $_POST['owner'], $_POST['newschema'], $_POST['comment'], $_POST['tablespace']); - if ($status == 0) { - // If table has been renamed, need to change to the new name and - // reload the browser frame. - if ($_POST['table'] != $_POST['name']) { - // Jump them to the new table name - $_REQUEST['table'] = $_POST['name']; - // Force a browser reload - $_reload_browser = true; - } - // If schema has changed, need to change to the new schema and reload the browser - if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { - // Jump them to the new sequence schema - $misc->setCurrentSchema($_POST['newschema']); - $_reload_browser = true; - } - doDefault($lang['strtablealtered']); - } else { - doAlter($lang['strtablealteredbad']); - } - -} - -/** - * Function to allow altering of a table - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('table'); - $misc->printTitle($lang['stralter'], 'pg.table.alter'); - $misc->printMsg($msg); - - // Fetch table info - $table = $data->getTable($_REQUEST['table']); - // Fetch all users - $users = $data->getUsers(); - // Fetch all tablespaces from the database - if ($data->hasTablespaces()) { - $tablespaces = $data->getTablespaces(true); - } - - if ($table->recordCount() > 0) { - - if (!isset($_POST['name'])) { - $_POST['name'] = $table->fields['relname']; - } - - if (!isset($_POST['owner'])) { - $_POST['owner'] = $table->fields['relowner']; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = $table->fields['nspname']; - } - - if (!isset($_POST['comment'])) { - $_POST['comment'] = $table->fields['relcomment']; - } - - if ($data->hasTablespaces() && !isset($_POST['tablespace'])) { - $_POST['tablespace'] = $table->fields['tablespace']; - } - - echo "<form action=\"/views/tblproperties.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name'], ENT_QUOTES), "\" /></td></tr>\n"; - - if ($data->isSuperUser()) { - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\"><select name=\"owner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - } - - if ($data->hasAlterTableSchema()) { - $schemas = $data->getSchemas(); - echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; - echo "<td class=\"data1\"><select name=\"newschema\">"; - while (!$schemas->EOF) { - $schema = $schemas->fields['nspname']; - echo "<option value=\"", htmlspecialchars($schema), "\"", - ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; - $schemas->moveNext(); - } - echo "</select></td></tr>\n"; - } - - // Tablespace (if there are any) - if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) { - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strtablespace']}</th>\n"; - echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"tablespace\">\n"; - // Always offer the default (empty) option - echo "\t\t\t\t<option value=\"\"", - ($_POST['tablespace'] == '') ? ' selected="selected"' : '', "></option>\n"; - // Display all other tablespaces - while (!$tablespaces->EOF) { - $spcname = htmlspecialchars($tablespaces->fields['spcname']); - echo "\t\t\t\t<option value=\"{$spcname}\"", - ($spcname == $_POST['tablespace']) ? ' selected="selected"' : '', ">{$spcname}</option>\n"; - $tablespaces->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n"; - } - - echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", - htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -function doExport($msg = '') { - global $data, $misc; - global $lang; - - // Determine whether or not the table has an object ID - $hasID = $data->hasObjectID($_REQUEST['table']); - - $misc->printTrail('table'); - $misc->printTabs('table', 'export'); - $misc->printMsg($msg); - - echo "<form action=\"/views/dataexport.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; - // Data only - echo "<tr><th class=\"data left\" rowspan=\"", ($hasID) ? 2 : 1, "\">"; - echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"d_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "<option value=\"csv\">CSV</option>\n"; - echo "<option value=\"tab\">{$lang['strtabbed']}</option>\n"; - echo "<option value=\"html\">XHTML</option>\n"; - echo "<option value=\"xml\">XML</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - if ($hasID) { - echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n"; - } - // Structure only - echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; - echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; - // Structure and data - echo "<tr><th class=\"data left\" rowspan=\"", ($hasID) ? 3 : 2, "\">"; - echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"sd_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; - if ($hasID) { - echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n"; - } - echo "</table>\n"; - - echo "<h3>{$lang['stroptions']}</h3>\n"; - echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; - echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; - echo "</form>\n"; -} - -function doImport($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('table'); - $misc->printTabs('table', 'import'); - $misc->printMsg($msg); - - // Check that file uploads are enabled - if (ini_get('file_uploads')) { - // Don't show upload option if max size of uploads is zero - $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize')); - if (is_double($max_size) && $max_size > 0) { - echo "<form action=\"/views/dataimport.php\" method=\"post\" enctype=\"multipart/form-data\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strformat']}</th>\n"; - echo "\t\t<td><select name=\"format\">\n"; - echo "\t\t\t<option value=\"auto\">{$lang['strauto']}</option>\n"; - echo "\t\t\t<option value=\"csv\">CSV</option>\n"; - echo "\t\t\t<option value=\"tab\">{$lang['strtabbed']}</option>\n"; - if (function_exists('xml_parser_create')) { - echo "\t\t\t<option value=\"xml\">XML</option>\n"; - } - echo "\t\t</select></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strallowednulls']}</th>\n"; - echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$lang['strbackslashn']}</label><br />\n"; - echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />\n"; - echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$lang['stremptystring']}</label></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strfile']}</th>\n"; - echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />"; - echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"import\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strimport']}\" /></p>\n"; - echo "</form>\n"; - } - } else { - echo "<p>{$lang['strnouploads']}</p>\n"; - } - -} - -/** - * Displays a screen where they can add a column - */ -function doAddColumn($msg = '') { - global $data, $misc, $_reload_browser; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - switch ($_REQUEST['stage']) { - case 1: - // Set variable defaults - if (!isset($_POST['field'])) { - $_POST['field'] = ''; - } - - if (!isset($_POST['type'])) { - $_POST['type'] = ''; - } - - if (!isset($_POST['array'])) { - $_POST['array'] = ''; - } - - if (!isset($_POST['length'])) { - $_POST['length'] = ''; - } - - if (!isset($_POST['default'])) { - $_POST['default'] = ''; - } - - if (!isset($_POST['comment'])) { - $_POST['comment'] = ''; - } - - // Fetch all available types - $types = $data->getTypes(true, false, true); - $types_for_js = []; - - $misc->printTrail('table'); - $misc->printTitle($lang['straddcolumn'], 'pg.column.add'); - $misc->printMsg($msg); - - echo "<script src=\"/js/tables.js\" type=\"text/javascript\"></script>"; - echo "<form action=\"/views/tblproperties.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "<tr><th class=\"data required\">{$lang['strname']}</th>\n<th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>\n"; - echo "<th class=\"data\">{$lang['strlength']}</th>\n"; - if ($data->hasCreateFieldWithConstraints()) { - echo "<th class=\"data\">{$lang['strnotnull']}</th>\n<th class=\"data\">{$lang['strdefault']}</th>\n"; - } - - echo "<th class=\"data\">{$lang['strcomment']}</th></tr>\n"; - - echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['field']), "\" /></td>\n"; - echo "<td><select name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">\n"; - // Output any "magic" types. This came in with the alter column type so we'll check that - if ($data->hasMagicTypes()) { - foreach ($data->extraTypes as $v) { - $types_for_js[] = strtolower($v); - echo "\t<option value=\"", htmlspecialchars($v), "\"", - ($v == $_POST['type']) ? ' selected="selected"' : '', ">", - $misc->printVal($v), "</option>\n"; - } - } - while (!$types->EOF) { - $typname = $types->fields['typname']; - $types_for_js[] = $typname; - echo "\t<option value=\"", htmlspecialchars($typname), "\"", ($typname == $_POST['type']) ? ' selected="selected"' : '', ">", - $misc->printVal($typname), "</option>\n"; - $types->moveNext(); - } - echo "</select></td>\n"; - - // Output array type selector - echo "<td><select name=\"array\">\n"; - echo "\t<option value=\"\"", ($_POST['array'] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "\t<option value=\"[]\"", ($_POST['array'] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "</select></td>\n"; - $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js); - $escaped_predef_types = []; // the JS escaped array elements - foreach ($predefined_size_types as $value) { - $escaped_predef_types[] = "'{$value}'"; - } - - echo "<td><input name=\"length\" id=\"lengths\" size=\"8\" value=\"", - htmlspecialchars($_POST['length']), "\" /></td>\n"; - // Support for adding column with not null and default - if ($data->hasCreateFieldWithConstraints()) { - echo "<td><input type=\"checkbox\" name=\"notnull\"", - (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', " /></td>\n"; - echo "<td><input name=\"default\" size=\"20\" value=\"", - htmlspecialchars($_POST['default']), "\" /></td>\n"; - } - echo "<td><input name=\"comment\" size=\"40\" value=\"", - htmlspecialchars($_POST['comment']), "\" /></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"add_column\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - if (!$data->hasCreateFieldWithConstraints()) { - echo "<input type=\"hidden\" name=\"default\" value=\"\" />\n"; - } - echo "<input type=\"submit\" value=\"{$lang['stradd']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - echo "<script type=\"text/javascript\">predefined_lengths = new Array(" . implode(",", $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>\n"; - break; - case 2: - // Check inputs - if (trim($_POST['field']) == '') { - $_REQUEST['stage'] = 1; - doAddColumn($lang['strcolneedsname']); - return; - } - if (!isset($_POST['length'])) { - $_POST['length'] = ''; - } - - $status = $data->addColumn($_POST['table'], $_POST['field'], - $_POST['type'], $_POST['array'] != '', $_POST['length'], isset($_POST['notnull']), - $_POST['default'], $_POST['comment']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strcolumnadded']); - } else { - $_REQUEST['stage'] = 1; - doAddColumn($lang['strcolumnaddedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Show confirmation of drop column and perform actual drop - */ -function doDrop($confirm) { - global $data, $database, $misc, $_reload_browser; - global $lang; - - if ($confirm) { - $misc->printTrail('column'); - $misc->printTitle($lang['strdrop'], 'pg.column.drop'); - - echo "<p>", sprintf($lang['strconfdropcolumn'], $misc->printVal($_REQUEST['column']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/tblproperties.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\"> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropColumn($_POST['table'], $_POST['column'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strcolumndropped']); - } else { - doDefault($lang['strcolumndroppedbad']); - } - - } - -} - -/** - * Show default list of columns in the table - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - function attPre(&$rowdata, $actions) { - global $data; - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - $attname = $rowdata->fields['attname']; - $table = $_REQUEST['table']; - $data->fieldClean($attname); - $data->fieldClean($table); - - $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\" - FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\""; - - return $actions; - } - - $misc->printTrail('table'); - $misc->printTabs('table', 'columns'); - $misc->printMsg($msg); - - // Get table - $tdata = $data->getTable($_REQUEST['table']); - // Get columns - $attrs = $data->getTableAttributes($_REQUEST['table']); - // Get constraints keys - $ck = $data->getConstraintsWithFields($_REQUEST['table']); - - // Show comment if any - if ($tdata->fields['relcomment'] !== null) { - echo '<p class="comment">', $misc->printVal($tdata->fields['relcomment']), "</p>\n"; - } - - $columns = [ - 'column' => [ - 'title' => $lang['strcolumn'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - 'url' => "colproperties.php?subject=column&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", - 'vars' => ['column' => 'attname'], - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+type'), - ], - 'notnull' => [ - 'title' => $lang['strnotnull'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attnotnull'), - 'type' => 'bool', - 'params' => ['true' => 'NOT NULL', 'false' => ''], - ], - 'default' => [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('adsrc'), - ], - 'keyprop' => [ - 'title' => $lang['strconstraints'], - 'class' => 'constraint_cell', - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - 'type' => 'callback', - 'params' => [ - 'function' => 'cstrRender', - 'keys' => $ck->getArray(), - ], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - function cstrRender($s, $p) { - global $misc, $data; - - $str = ''; - foreach ($p['keys'] as $k => $c) { - - if (is_null($p['keys'][$k]['consrc'])) { - $atts = $data->getAttributeNames($_REQUEST['table'], explode(' ', $p['keys'][$k]['indkey'])); - $c['consrc'] = ($c['contype'] == 'u' ? "UNIQUE (" : "PRIMARY KEY (") . join(',', $atts) . ')'; - } - - if ($c['p_field'] == $s) { - switch ($c['contype']) { - case 'p': - $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . - $misc->icon('PrimaryKey') . '" alt="[pk]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; - break; - case 'f': - $str .= '<a href="tblproperties.php?' . $misc->href . "&table=" . urlencode($c['f_table']) . "&schema=" . urlencode($c['f_schema']) . "\"><img src=\"" . - $misc->icon('ForeignKey') . '" alt="[fk]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; - break; - case 'u': - $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . - $misc->icon('UniqueConstraint') . '" alt="[uniq]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; - break; - case 'c': - $str .= '<a href="constraints.php?' . $misc->href . "&table=" . urlencode($c['p_table']) . "&schema=" . urlencode($c['p_schema']) . "\"><img src=\"" . - $misc->icon('CheckConstraint') . '" alt="[check]" title="' . htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8') . '" /></a>'; - } - } - - } - - return $str; - } - - $actions = [ - 'browse' => [ - 'title' => $lang['strbrowse'], - 'url' => "display.php?{$misc->href}&subject=column&return=table&table=" . urlencode($_REQUEST['table']) . '&', - 'vars' => ['column' => 'attname'], - ], - 'alter' => [ - 'title' => $lang['stralter'], - 'url' => "colproperties.php?action=properties&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", - 'vars' => ['column' => 'attname'], - ], - 'privileges' => [ - 'title' => $lang['strprivileges'], - 'url' => "privileges.php?subject=column&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", - 'vars' => ['column' => 'attname'], - ], - 'drop' => [ - 'title' => $lang['strdrop'], - 'url' => "tblproperties.php?action=confirm_drop&{$misc->href}&table=" . urlencode($_REQUEST['table']) . "&", - 'vars' => ['column' => 'attname'], - ], - ]; - - $actions = [ - 'browse' => [ - 'content' => $lang['strbrowse'], - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'table' => $_REQUEST['table'], - 'subject' => 'column', - 'return' => 'table', - 'column' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - ], - ], - ], - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'colproperties.php', - 'urlvars' => [ - 'subject' => 'column', - 'action' => 'properties', - 'table' => $_REQUEST['table'], - 'column' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - ], - ], - ], - 'privileges' => [ - 'content' => $lang['strprivileges'], - 'attr' => [ - 'href' => [ - 'url' => 'privileges.php', - 'urlvars' => [ - 'subject' => 'column', - 'table' => $_REQUEST['table'], - 'column' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'subject' => 'column', - 'action' => 'confirm_drop', - 'table' => $_REQUEST['table'], - 'column' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', null, 'attPre'); - - $navlinks = [ - 'browse' => [ - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - 'subject' => 'table', - 'return' => 'table', - ], - ], - ], - 'content' => $lang['strbrowse'], - ], - 'select' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confselectrows', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strselect'], - ], - 'insert' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confinsertrow', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strinsert'], - ], - 'empty' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_empty', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strempty'], - ], - 'drop' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tables.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strdrop'], - ], - 'addcolumn' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'action' => 'add_column', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['straddcolumn'], - ], - 'alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'tblproperties.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['stralter'], - ], - ]; - $misc->printNavLinks($navlinks, - 'tblproperties-tblproperties' - , get_defined_vars() - ); - -} +$tableproperty_controller = new \PHPPgAdmin\Controller\TablePropertyController($container); $misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table']); $misc->printBody(); @@ -760,53 +17,51 @@ $misc->printBody(); switch ($action) { case 'alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $tableproperty_controller->doSaveAlter(); } else { - doDefault(); + $tableproperty_controller->doDefault(); } break; case 'confirm_alter': - doAlter(); + $tableproperty_controller->doAlter(); break; case 'import': - doImport(); + $tableproperty_controller->doImport(); break; case 'export': - doExport(); + $tableproperty_controller->doExport(); break; case 'add_column': if (isset($_POST['cancel'])) { - doDefault(); + $tableproperty_controller->doDefault(); } else { - doAddColumn(); + $tableproperty_controller->doAddColumn(); } break; case 'properties': if (isset($_POST['cancel'])) { - doDefault(); + $tableproperty_controller->doDefault(); } else { - doProperties(); + $tableproperty_controller->doProperties(); } break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $tableproperty_controller->doDrop(false); } else { - doDefault(); + $tableproperty_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $tableproperty_controller->doDrop(true); break; default: - doDefault(); + $tableproperty_controller->doDefault(); break; } $misc->printFooter(); - -?> diff --git a/src/views/triggers.php b/src/views/triggers.php index 441b2d62..53b916e2 100644 --- a/src/views/triggers.php +++ b/src/views/triggers.php @@ -9,385 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Function to save after altering a trigger - */ -function doSaveAlter() { - global $data, $lang; - - $status = $data->alterTrigger($_POST['table'], $_POST['trigger'], $_POST['name']); - if ($status == 0) { - doDefault($lang['strtriggeraltered']); - } else { - doAlter($lang['strtriggeralteredbad']); - } - -} - -/** - * Function to allow altering of a trigger - */ -function doAlter($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('trigger'); - $misc->printTitle($lang['stralter'], 'pg.trigger.alter'); - $misc->printMsg($msg); - - $triggerdata = $data->getTrigger($_REQUEST['table'], $_REQUEST['trigger']); - - if ($triggerdata->recordCount() > 0) { - - if (!isset($_POST['name'])) { - $_POST['name'] = $triggerdata->fields['tgname']; - } - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" />\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['strok']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strdrop'], 'pg.trigger.drop'); - - echo "<p>", sprintf($lang['strconfdroptrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->dropTrigger($_POST['trigger'], $_POST['table'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strtriggerdropped']); - } else { - doDefault($lang['strtriggerdroppedbad']); - } - - } - -} - -/** - * Show confirmation of enable trigger and perform enabling the trigger - */ -function doEnable($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strenable'], 'pg.table.alter'); - - echo "<p>", sprintf($lang['strconfenabletrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"enable\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->enableTrigger($_POST['trigger'], $_POST['table']); - if ($status == 0) { - doDefault($lang['strtriggerenabled']); - } else { - doDefault($lang['strtriggerenabledbad']); - } - - } - -} - -/** - * Show confirmation of disable trigger and perform disabling the trigger - */ -function doDisable($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('trigger'); - $misc->printTitle($lang['strdisable'], 'pg.table.alter'); - - echo "<p>", sprintf($lang['strconfdisabletrigger'], $misc->printVal($_REQUEST['trigger']), - $misc->printVal($_REQUEST['table'])), "</p>\n"; - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"disable\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo "<input type=\"hidden\" name=\"trigger\" value=\"", htmlspecialchars($_REQUEST['trigger']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"yes\" value=\"{$lang['stryes']}\" />\n"; - echo "<input type=\"submit\" name=\"no\" value=\"{$lang['strno']}\" />\n"; - echo "</form>\n"; - } else { - $status = $data->disableTrigger($_POST['trigger'], $_POST['table']); - if ($status == 0) { - doDefault($lang['strtriggerdisabled']); - } else { - doDefault($lang['strtriggerdisabledbad']); - } - - } - -} - -/** - * Let them create s.th. - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('table'); - $misc->printTitle($lang['strcreatetrigger'], 'pg.trigger.create'); - $misc->printMsg($msg); - - // Get all the functions that can be used in triggers - $funcs = $data->getTriggerFunctions(); - if ($funcs->recordCount() == 0) { - doDefault($lang['strnofunctions']); - return; - } - - /* Populate functions */ - $sel0 = new \PHPPgAdmin\XHtml\XHTML_Select('formFunction'); - while (!$funcs->EOF) { - $sel0->add(new \PHPPgAdmin\XHtml\XHTML_Option($funcs->fields['proname'])); - $funcs->moveNext(); - } - - /* Populate times */ - $sel1 = new \PHPPgAdmin\XHtml\XHTML_Select('formExecTime'); - $sel1->set_data($data->triggerExecTimes); - - /* Populate events */ - $sel2 = new \PHPPgAdmin\XHtml\XHTML_Select('formEvent'); - $sel2->set_data($data->triggerEvents); - - /* Populate occurences */ - $sel3 = new \PHPPgAdmin\XHtml\XHTML_Select('formFrequency'); - $sel3->set_data($data->triggerFrequency); - - echo "<form action=\"/views/triggers.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr>\n"; - echo " <th class=\"data\">{$lang['strname']}</th>\n"; - echo " <th class=\"data\">{$lang['strwhen']}</th>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <td class=\"data1\"> <input type=\"text\" name=\"formTriggerName\" size=\"32\" /></td>\n"; - echo " <td class=\"data1\"> ", $sel1->fetch(), "</td>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <th class=\"data\">{$lang['strevent']}</th>\n"; - echo " <th class=\"data\">{$lang['strforeach']}</th>\n"; - echo "</tr>\n"; - echo "<tr>\n"; - echo " <td class=\"data1\"> ", $sel2->fetch(), "</td>\n"; - echo " <td class=\"data1\"> ", $sel3->fetch(), "</td>\n"; - echo "</tr>\n"; - echo "<tr><th class=\"data\"> {$lang['strfunction']}</th>\n"; - echo "<th class=\"data\"> {$lang['strarguments']}</th></tr>\n"; - echo "<tr><td class=\"data1\">", $sel0->fetch(), "</td>\n"; - echo "<td class=\"data1\">(<input type=\"text\" name=\"formTriggerArgs\" size=\"32\" />)</td>\n"; - echo "</tr></table>\n"; - echo "<p><input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n"; - echo $misc->form; - echo "</form>\n"; -} - -/** - * Actually creates the new trigger in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - // Check that they've given a name and a definition - - if ($_POST['formFunction'] == '') { - doCreate($lang['strtriggerneedsfunc']); - } elseif ($_POST['formTriggerName'] == '') { - doCreate($lang['strtriggerneedsname']); - } elseif ($_POST['formEvent'] == '') { - doCreate(); - } else { - $status = $data->createTrigger($_POST['formTriggerName'], $_POST['table'], - $_POST['formFunction'], $_POST['formExecTime'], $_POST['formEvent'], - $_POST['formFrequency'], $_POST['formTriggerArgs']); - if ($status == 0) { - doDefault($lang['strtriggercreated']); - } else { - doCreate($lang['strtriggercreatedbad']); - } - - } -} - -/** - * List all the triggers on the table - */ -function doDefault($msg = '') { - global $data, $misc, $database; - global $lang; - - function tgPre(&$rowdata, $actions) { - global $data; - // toggle enable/disable trigger per trigger - if (!$data->phpBool($rowdata->fields["tgenabled"])) { - unset($actions['disable']); - } else { - unset($actions['enable']); - } - - return $actions; - } - - $misc->printTrail('table'); - $misc->printTabs('table', 'triggers'); - $misc->printMsg($msg); - - $triggers = $data->getTriggers($_REQUEST['table']); - - $columns = [ - 'trigger' => [ - 'title' => $lang['strname'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('tgname'), - ], - 'definition' => [ - 'title' => $lang['strdefinition'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('tgdef'), - ], - 'function' => [ - 'title' => $lang['strfunction'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('proproto'), - 'url' => "functions.php?action=properties&server={$_REQUEST['server']}&database={$_REQUEST['database']}&", - 'vars' => [ - 'schema' => 'pronamespace', - 'function' => 'proproto', - 'function_oid' => 'prooid', - ], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'table' => $_REQUEST['table'], - 'trigger' => \PHPPgAdmin\Decorators\Decorator::field('tgname'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'table' => $_REQUEST['table'], - 'trigger' => \PHPPgAdmin\Decorators\Decorator::field('tgname'), - ], - ], - ], - ], - ]; - if ($data->hasDisableTriggers()) { - $actions['enable'] = [ - 'content' => $lang['strenable'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_enable', - 'table' => $_REQUEST['table'], - 'trigger' => \PHPPgAdmin\Decorators\Decorator::field('tgname'), - ], - ], - ], - ]; - $actions['disable'] = [ - 'content' => $lang['strdisable'], - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'confirm_disable', - 'table' => $_REQUEST['table'], - 'trigger' => \PHPPgAdmin\Decorators\Decorator::field('tgname'), - ], - ], - ], - ]; - } - - echo $misc->printTable($triggers, $columns, $actions, 'triggers-triggers', $lang['strnotriggers'], 'tgPre'); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'triggers.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'table' => $_REQUEST['table'], - ], - ], - ], - 'content' => $lang['strcreatetrigger'], - ]], 'triggers-triggers', get_defined_vars()); -} +$trigger_controller = new \PHPPgAdmin\Controller\TriggerController($container); $misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table'] . ' - ' . $lang['strtriggers']); $misc->printBody(); @@ -395,61 +17,61 @@ $misc->printBody(); switch ($action) { case 'alter': if (isset($_POST['alter'])) { - doSaveAlter(); + $trigger_controller->doSaveAlter(); } else { - doDefault(); + $trigger_controller->doDefault(); } break; case 'confirm_alter': - doAlter(); + $trigger_controller->doAlter(); break; case 'confirm_enable': - doEnable(true); + $trigger_controller->doEnable(true); break; case 'confirm_disable': - doDisable(true); + $trigger_controller->doDisable(true); break; case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $trigger_controller->doDefault(); } else { - doSaveCreate(); + $trigger_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $trigger_controller->doCreate(); break; case 'drop': if (isset($_POST['yes'])) { - doDrop(false); + $trigger_controller->doDrop(false); } else { - doDefault(); + $trigger_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $trigger_controller->doDrop(true); break; case 'enable': if (isset($_POST['yes'])) { - doEnable(false); + $trigger_controller->doEnable(false); } else { - doDefault(); + $trigger_controller->doDefault(); } break; case 'disable': if (isset($_POST['yes'])) { - doDisable(false); + $trigger_controller->doDisable(false); } else { - doDefault(); + $trigger_controller->doDefault(); } break; default: - doDefault(); + $trigger_controller->doDefault(); break; } diff --git a/src/views/types.php b/src/views/types.php index a7047b8e..81e24dba 100644 --- a/src/views/types.php +++ b/src/views/types.php @@ -9,707 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Show read only properties for a type - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - // Get type (using base name) - $typedata = $data->getType($_REQUEST['type']); - - $misc->printTrail('type'); - $misc->printTitle($lang['strproperties'], 'pg.type'); - $misc->printMsg($msg); - - function attPre(&$rowdata) { - global $data; - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - } - - if ($typedata->recordCount() > 0) { - $vals = false; - switch ($typedata->fields['typtype']) { - case 'c': - $attrs = $data->getTableAttributes($_REQUEST['type']); - - $columns = [ - 'field' => [ - 'title' => $lang['strfield'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+type'), - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - $actions = []; - - echo $misc->printTable($attrs, $columns, $actions, 'types-properties', null, 'attPre'); - - break; - case 'e': - $vals = $data->getEnumValues($typedata->fields['typname']); - default: - $byval = $data->phpBool($typedata->fields['typbyval']); - echo "<table>\n"; - echo "<tr><th class=\"data left\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typname']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strinputfn']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typin']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['stroutputfn']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typout']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strlength']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typlen']), "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strpassbyval']}</th>\n"; - echo "<td class=\"data1\">", ($byval) ? $lang['stryes'] : $lang['strno'], "</td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; - echo "<td class=\"data1\">", $misc->printVal($typedata->fields['typalign']), "</td></tr>\n"; - if ($data->hasEnumTypes() && $vals) { - $vals = $vals->getArray(); - $nbVals = count($vals); - echo "<tr>\n\t<th class=\"data left\" rowspan=\"$nbVals\">{$lang['strenumvalues']}</th>\n"; - echo "<td class=\"data2\">{$vals[0]['enumval']}</td></tr>\n"; - for ($i = 1; $i < $nbVals; $i++) { - echo "<td class=\"data", 2 - ($i % 2), "\">{$vals[$i]['enumval']}</td></tr>\n"; - } - - } - echo "</table>\n"; - } - - $misc->printNavLinks(['showall' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strshowalltypes'], - ]], 'types-properties', get_defined_vars()); - } else { - doDefault($lang['strinvalidparam']); - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('type'); - $misc->printTitle($lang['strdrop'], 'pg.type.drop'); - - echo "<p>", sprintf($lang['strconfdroptype'], $misc->printVal($_REQUEST['type'])), "</p>\n"; - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"type\" value=\"", htmlspecialchars($_REQUEST['type']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropType($_POST['type'], isset($_POST['cascade'])); - if ($status == 0) { - doDefault($lang['strtypedropped']); - } else { - doDefault($lang['strtypedroppedbad']); - } - - } - -} - -/** - * Displays a screen where they can enter a new composite type - */ -function doCreateComposite($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['fields'])) { - $_REQUEST['fields'] = ''; - } - - if (!isset($_REQUEST['typcomment'])) { - $_REQUEST['typcomment'] = ''; - } - - switch ($_REQUEST['stage']) { - case 1: - $misc->printTrail('type'); - $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumfields']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>\n"; - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - case 2: - global $lang; - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedscols']); - return; - } - - $types = $data->getTypes(true, false, true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatecomptype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$lang['strtype']}</th>"; - echo "<th class=\"data\">{$lang['strlength']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>\n"; - - for ($i = 0; $i < $_REQUEST['fields']; $i++) { - if (!isset($_REQUEST['field'][$i])) { - $_REQUEST['field'][$i] = ''; - } - - if (!isset($_REQUEST['length'][$i])) { - $_REQUEST['length'][$i] = ''; - } - - if (!isset($_REQUEST['colcomment'][$i])) { - $_REQUEST['colcomment'][$i] = ''; - } - - echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; - echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['field'][$i]), "\" /></td>\n"; - echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">\n"; - $types->moveFirst(); - while (!$types->EOF) { - $typname = $types->fields['typname']; - echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), "\"", - (isset($_REQUEST['type'][$i]) && $typname == $_REQUEST['type'][$i]) ? ' selected="selected"' : '', ">", - $misc->printVal($typname), "</option>\n"; - $types->moveNext(); - } - echo "\t\t\t</select>\n\t\t</td>\n"; - - // Output array type selector - echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">\n"; - echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', "></option>\n"; - echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', ">[ ]</option>\n"; - echo "\t\t\t</select>\n\t\t</td>\n"; - - echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"", - htmlspecialchars($_REQUEST['length'][$i]), "\" /></td>\n"; - echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"", - htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_comp\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlspecialchars($_REQUEST['fields']), "\" />\n"; - echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 3: - global $data, $lang; - - // Check inputs - $fields = trim($_REQUEST['fields']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedsname']); - return; - } elseif ($fields == '' || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) { - $_REQUEST['stage'] = 1; - doCreateComposite($lang['strtypeneedscols']); - return; - } - - $status = $data->createCompositeType($_REQUEST['name'], $_REQUEST['fields'], $_REQUEST['field'], - $_REQUEST['type'], $_REQUEST['array'], $_REQUEST['length'], $_REQUEST['colcomment'], - $_REQUEST['typcomment']); - - if ($status == 0) { - doDefault($lang['strtypecreated']); - } elseif ($status == -1) { - $_REQUEST['stage'] = 2; - doCreateComposite($lang['strtypeneedsfield']); - return; - } else { - $_REQUEST['stage'] = 2; - doCreateComposite($lang['strtypecreatedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Displays a screen where they can enter a new enum type - */ -function doCreateEnum($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - if (!isset($_REQUEST['name'])) { - $_REQUEST['name'] = ''; - } - - if (!isset($_REQUEST['values'])) { - $_REQUEST['values'] = ''; - } - - if (!isset($_REQUEST['typcomment'])) { - $_REQUEST['typcomment'] = ''; - } - - switch ($_REQUEST['stage']) { - case 1: - $misc->printTrail('type'); - $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strnumvalues']}</th>\n"; - echo "\t\t<td class=\"data\"><input name=\"values\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['values']), "\" /></td>\n\t</tr>\n"; - - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>\n"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - break; - case 2: - global $lang; - - // Check inputs - $values = trim($_REQUEST['values']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsname']); - return; - } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values < 1) { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsvals']); - return; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateenumtype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - - // Output table header - echo "<table>\n"; - echo "\t<tr><th colspan=\"2\" class=\"data required\">{$lang['strvalue']}</th></tr>\n"; - - for ($i = 0; $i < $_REQUEST['values']; $i++) { - if (!isset($_REQUEST['value'][$i])) { - $_REQUEST['value'][$i] = ''; - } - - echo "\t<tr>\n\t\t<td>", $i + 1, ". </td>\n"; - echo "\t\t<td><input name=\"value[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['value'][$i]), "\" /></td>\n\t</tr>\n"; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"create_enum\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"3\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"name\" value=\"", htmlspecialchars($_REQUEST['name']), "\" />\n"; - echo "<input type=\"hidden\" name=\"values\" value=\"", htmlspecialchars($_REQUEST['values']), "\" />\n"; - echo "<input type=\"hidden\" name=\"typcomment\" value=\"", htmlspecialchars($_REQUEST['typcomment']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 3: - global $data, $lang; - - // Check inputs - $values = trim($_REQUEST['values']); - if (trim($_REQUEST['name']) == '') { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsname']); - return; - } elseif ($values == '' || !is_numeric($values) || $values != (int) $values || $values <= 0) { - $_REQUEST['stage'] = 1; - doCreateEnum($lang['strtypeneedsvals']); - return; - } - - $status = $data->createEnumType($_REQUEST['name'], $_REQUEST['value'], $_REQUEST['typcomment']); - - if ($status == 0) { - doDefault($lang['strtypecreated']); - } elseif ($status == -1) { - $_REQUEST['stage'] = 2; - doCreateEnum($lang['strtypeneedsvalue']); - return; - } else { - $_REQUEST['stage'] = 2; - doCreateEnum($lang['strtypecreatedbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -/** - * Displays a screen where they can enter a new type - */ -function doCreate($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_POST['typname'])) { - $_POST['typname'] = ''; - } - - if (!isset($_POST['typin'])) { - $_POST['typin'] = ''; - } - - if (!isset($_POST['typout'])) { - $_POST['typout'] = ''; - } - - if (!isset($_POST['typlen'])) { - $_POST['typlen'] = ''; - } - - if (!isset($_POST['typdef'])) { - $_POST['typdef'] = ''; - } - - if (!isset($_POST['typelem'])) { - $_POST['typelem'] = ''; - } - - if (!isset($_POST['typdelim'])) { - $_POST['typdelim'] = ''; - } - - if (!isset($_POST['typalign'])) { - $_POST['typalign'] = $data->typAlignDef; - } - - if (!isset($_POST['typstorage'])) { - $_POST['typstorage'] = $data->typStorageDef; - } - - // Retrieve all functions and types in the database - $funcs = $data->getFunctions(true); - $types = $data->getTypes(true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreatetype'], 'pg.type.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/types.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['typname']), "\" /></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['strinputfn']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typin\">"; - while (!$funcs->EOF) { - $proname = htmlspecialchars($funcs->fields['proname']); - echo "<option value=\"{$proname}\"", - ($proname == $_POST['typin']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; - $funcs->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left required\">{$lang['stroutputfn']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typout\">"; - $funcs->moveFirst(); - while (!$funcs->EOF) { - $proname = htmlspecialchars($funcs->fields['proname']); - echo "<option value=\"{$proname}\"", - ($proname == $_POST['typout']) ? ' selected="selected"' : '', ">{$proname}</option>\n"; - $funcs->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left" . (version_compare($data->major_version, '7.4', '<') ? ' required' : '') . "\">{$lang['strlength']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typlen\" size=\"8\" value=\"", - htmlspecialchars($_POST['typlen']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['strdefault']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typdef\" size=\"8\" value=\"", - htmlspecialchars($_POST['typdef']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['strelement']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typelem\">"; - echo "<option value=\"\"></option>\n"; - while (!$types->EOF) { - $currname = htmlspecialchars($types->fields['typname']); - echo "<option value=\"{$currname}\"", - ($currname == $_POST['typelem']) ? ' selected="selected"' : '', ">{$currname}</option>\n"; - $types->moveNext(); - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strdelimiter']}</th>\n"; - echo "<td class=\"data1\"><input name=\"typdelim\" size=\"1\" maxlength=\"1\" value=\"", - htmlspecialchars($_POST['typdelim']), "\" /></td></tr>"; - echo "<tr><th class=\"data left\"><label for=\"typbyval\">{$lang['strpassbyval']}</label></th>\n"; - echo "<td class=\"data1\"><input type=\"checkbox\" id=\"typbyval\" name=\"typbyval\"", - isset($_POST['typbyval']) ? ' checked="checked"' : '', " /></td></tr>"; - echo "<tr><th class=\"data left\">{$lang['stralignment']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typalign\">"; - foreach ($data->typAligns as $v) { - echo "<option value=\"{$v}\"", - ($v == $_POST['typalign']) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - echo "</select></td></tr>\n"; - echo "<tr><th class=\"data left\">{$lang['strstorage']}</th>\n"; - echo "<td class=\"data1\"><select name=\"typstorage\">"; - foreach ($data->typStorages as $v) { - echo "<option value=\"{$v}\"", - ($v == $_POST['typstorage']) ? ' selected="selected"' : '', ">{$v}</option>\n"; - } - echo "</select></td></tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new type in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - // Check that they've given a name and a length. - // Note: We're assuming they've given in and out functions here - // which might be unwise... - if ($_POST['typname'] == '') { - doCreate($lang['strtypeneedsname']); - } elseif ($_POST['typlen'] == '') { - doCreate($lang['strtypeneedslen']); - } else { - $status = $data->createType( - $_POST['typname'], - $_POST['typin'], - $_POST['typout'], - $_POST['typlen'], - $_POST['typdef'], - $_POST['typelem'], - $_POST['typdelim'], - isset($_POST['typbyval']), - $_POST['typalign'], - $_POST['typstorage'] - ); - if ($status == 0) { - doDefault($lang['strtypecreated']); - } else { - doCreate($lang['strtypecreatedbad']); - } - - } -} - -/** - * Show default list of types in the database - */ -function doDefault($msg = '') { - global $data, $conf, $misc; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'types'); - $misc->printMsg($msg); - - $types = $data->getTypes(); - - $columns = [ - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('typname'), - 'url' => "types.php?action=properties&{$misc->href}&", - 'vars' => ['type' => 'basename'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('typowner'), - ], - 'flavour' => [ - 'title' => $lang['strflavor'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('typtype'), - 'type' => 'verbatim', - 'params' => [ - 'map' => [ - 'b' => $lang['strbasetype'], - 'c' => $lang['strcompositetype'], - 'd' => $lang['strdomain'], - 'p' => $lang['strpseudotype'], - 'e' => $lang['strenum'], - ], - 'align' => 'center', - ], - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('typcomment'), - ], - ]; - - if (!isset($types->fields['typtype'])) { - unset($columns['flavour']); - } - - $actions = [ - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'type' => \PHPPgAdmin\Decorators\Decorator::field('basename'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($types, $columns, $actions, 'types-types', $lang['strnotypes']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatetype'], - ], - 'createcomp' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create_comp', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreatecomptype'], - ], - 'createenum' => [ - 'attr' => [ - 'href' => [ - 'url' => 'types.php', - 'urlvars' => [ - 'action' => 'create_enum', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateenumtype'], - ], - ]; - - if (!$data->hasEnumTypes()) { - unset($navlinks['enum']); - } - - $misc->printNavLinks($navlinks, 'types-types', get_defined_vars()); -} +$type_controller = new \PHPPgAdmin\Controller\TypeController($container); $misc->printHeader($lang['strtypes']); $misc->printBody(); @@ -717,47 +17,47 @@ $misc->printBody(); switch ($action) { case 'create_comp': if (isset($_POST['cancel'])) { - doDefault(); + $type_controller->doDefault(); } else { - doCreateComposite(); + $type_controller->doCreateComposite(); } break; case 'create_enum': if (isset($_POST['cancel'])) { - doDefault(); + $type_controller->doDefault(); } else { - doCreateEnum(); + $type_controller->doCreateEnum(); } break; case 'save_create': if (isset($_POST['cancel'])) { - doDefault(); + $type_controller->doDefault(); } else { - doSaveCreate(); + $type_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $type_controller->doCreate(); break; case 'drop': if (isset($_POST['cancel'])) { - doDefault(); + $type_controller->doDefault(); } else { - doDrop(false); + $type_controller->doDrop(false); } break; case 'confirm_drop': - doDrop(true); + $type_controller->doDrop(true); break; case 'properties': - doProperties(); + $type_controller->doProperties(); break; default: - doDefault(); + $type_controller->doDefault(); break; } diff --git a/src/views/users.php b/src/views/users.php index 75733e9e..8fa40d25 100644 --- a/src/views/users.php +++ b/src/views/users.php @@ -9,408 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * If a user is not a superuser, then we have an 'account management' page - * where they can change their password, etc. We don't prevent them from - * messing with the URL to gain access to other user admin stuff, because - * the PostgreSQL permissions will prevent them changing anything anyway. - */ -function doAccount($msg = '') { - global $data, $misc; - global $lang; - - $server_info = $misc->getServerInfo(); - - $userdata = $data->getUser($server_info['username']); - $_REQUEST['user'] = $server_info['username']; - - $misc->printTrail('user'); - $misc->printTabs('server', 'account'); - $misc->printMsg($msg); - - if ($userdata->recordCount() > 0) { - $userdata->fields['usesuper'] = $data->phpBool($userdata->fields['usesuper']); - $userdata->fields['usecreatedb'] = $data->phpBool($userdata->fields['usecreatedb']); - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strusername']}</th><th class=\"data\">{$lang['strsuper']}</th><th class=\"data\">{$lang['strcreatedb']}</th><th class=\"data\">{$lang['strexpires']}</th>"; - echo "<th class=\"data\">{$lang['strsessiondefaults']}</th>"; - echo "</tr>\n"; - echo "<tr>\n\t<td class=\"data1\">", $misc->printVal($userdata->fields['usename']), "</td>\n"; - echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['usesuper'], 'yesno'), "</td>\n"; - echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['usecreatedb'], 'yesno'), "</td>\n"; - echo "\t<td class=\"data1\">", ($userdata->fields['useexpires'] == 'infinity' || is_null($userdata->fields['useexpires']) ? $lang['strnever'] : $misc->printVal($userdata->fields['useexpires'])), "</td>\n"; - echo "\t<td class=\"data1\">", $misc->printVal($userdata->fields['useconfig']), "</td>\n"; - echo "</tr>\n</table>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - $misc->printNavLinks(['changepassword' => [ - 'attr' => [ - 'href' => [ - 'url' => 'users.php', - 'urlvars' => [ - 'action' => 'confchangepassword', - 'server' => $_REQUEST['server'], - ], - ], - ], - 'content' => $lang['strchangepassword'], - ]], 'users-account', get_defined_vars()); -} - -/** - * Show confirmation of change password and actually change password - */ -function doChangePassword($confirm, $msg = '') { - global $data, $misc; - global $lang, $conf; - - $server_info = $misc->getServerInfo(); - - if ($confirm) { - $_REQUEST['user'] = $server_info['username']; - $misc->printTrail('user'); - $misc->printTitle($lang['strchangepassword'], 'pg.user.alter'); - $misc->printMsg($msg); - - if (!isset($_POST['password'])) { - $_POST['password'] = ''; - } - - if (!isset($_POST['confirm'])) { - $_POST['confirm'] = ''; - } - - echo "<form action=\"/views/users.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strpassword']}</th>\n"; - echo "\t\t<td><input type=\"password\" name=\"password\" size=\"32\" value=\"", - htmlspecialchars($_POST['password']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strconfirm']}</th>\n"; - echo "\t\t<td><input type=\"password\" name=\"confirm\" size=\"32\" value=\"\" /></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"changepassword\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"ok\" value=\"{$lang['strok']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</p></form>\n"; - } else { - // Check that password is minimum length - if (strlen($_POST['password']) < $conf['min_password_length']) { - doChangePassword(true, $lang['strpasswordshort']); - } - - // Check that password matches confirmation password - elseif ($_POST['password'] != $_POST['confirm']) { - doChangePassword(true, $lang['strpasswordconfirm']); - } else { - $status = $data->changePassword($server_info['username'], - $_POST['password']); - if ($status == 0) { - doAccount($lang['strpasswordchanged']); - } else { - doAccount($lang['strpasswordchangedbad']); - } - - } - } -} - -/** - * Function to allow editing of a user - */ -function doEdit($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('user'); - $misc->printTitle($lang['stralter'], 'pg.user.alter'); - $misc->printMsg($msg); - - $userdata = $data->getUser($_REQUEST['username']); - - if ($userdata->recordCount() > 0) { - $server_info = $misc->getServerInfo(); - $canRename = $data->hasUserRename() && ($_REQUEST['username'] != $server_info['username']); - $userdata->fields['usesuper'] = $data->phpBool($userdata->fields['usesuper']); - $userdata->fields['usecreatedb'] = $data->phpBool($userdata->fields['usecreatedb']); - - if (!isset($_POST['formExpires'])) { - if ($canRename) { - $_POST['newname'] = $userdata->fields['usename']; - } - - if ($userdata->fields['usesuper']) { - $_POST['formSuper'] = ''; - } - - if ($userdata->fields['usecreatedb']) { - $_POST['formCreateDB'] = ''; - } - - $_POST['formExpires'] = $userdata->fields['useexpires'] == 'infinity' ? '' : $userdata->fields['useexpires']; - $_POST['formPassword'] = ''; - } - - echo "<form action=\"/views/users.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strusername']}</th>\n"; - echo "\t\t<td class=\"data1\">", ($canRename ? "<input name=\"newname\" size=\"15\" maxlength=\"{$data->_maxNameLen}\" value=\"" . htmlspecialchars($_POST['newname']) . "\" />" : $misc->printVal($userdata->fields['usename'])), "</td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$lang['strsuper']}</label></th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"", - (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$lang['strcreatedb']}</label></th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"", - (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strexpires']}</th>\n"; - echo "\t\t<td class=\"data1\"><input size=\"16\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strpassword']}</th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"16\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strconfirm']}</th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"password\" size=\"16\" name=\"formConfirm\" value=\"\" /></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; - echo "<input type=\"hidden\" name=\"username\" value=\"", htmlspecialchars($_REQUEST['username']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Function to save after editing a user - */ -function doSaveEdit() { - global $data, $lang; - - // Check name and password - if (isset($_POST['newname']) && $_POST['newname'] == '') { - doEdit($lang['struserneedsname']); - } else if ($_POST['formPassword'] != $_POST['formConfirm']) { - doEdit($lang['strpasswordconfirm']); - } else { - if (isset($_POST['newname'])) { - $status = $data->setRenameUser($_POST['username'], $_POST['formPassword'], isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires'], $_POST['newname']); - } else { - $status = $data->setUser($_POST['username'], $_POST['formPassword'], isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires']); - } - - if ($status == 0) { - doDefault($lang['struserupdated']); - } else { - doEdit($lang['struserupdatedbad']); - } - - } -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang; - - if ($confirm) { - $misc->printTrail('user'); - $misc->printTitle($lang['strdrop'], 'pg.user.drop'); - - echo "<p>", sprintf($lang['strconfdropuser'], $misc->printVal($_REQUEST['username'])), "</p>\n"; - - echo "<form action=\"/views/users.php\" method=\"post\">\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - echo "<input type=\"hidden\" name=\"username\" value=\"", htmlspecialchars($_REQUEST['username']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - $status = $data->dropUser($_REQUEST['username']); - if ($status == 0) { - doDefault($lang['struserdropped']); - } else { - doDefault($lang['struserdroppedbad']); - } - - } -} - -/** - * Displays a screen where they can enter a new user - */ -function doCreate($msg = '') { - global $data, $misc, $username; - global $lang; - - if (!isset($_POST['formUsername'])) { - $_POST['formUsername'] = ''; - } - - if (!isset($_POST['formPassword'])) { - $_POST['formPassword'] = ''; - } - - if (!isset($_POST['formConfirm'])) { - $_POST['formConfirm'] = ''; - } - - if (!isset($_POST['formExpires'])) { - $_POST['formExpires'] = ''; - } - - $misc->printTrail('server'); - $misc->printTitle($lang['strcreateuser'], 'pg.user.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/users.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strusername']}</th>\n"; - echo "\t\t<td class=\"data1\"><input size=\"15\" maxlength=\"{$data->_maxNameLen}\" name=\"formUsername\" value=\"", htmlspecialchars($_POST['formUsername']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strpassword']}</th>\n"; - echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formPassword\" value=\"", htmlspecialchars($_POST['formPassword']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strconfirm']}</th>\n"; - echo "\t\t<td class=\"data1\"><input size=\"15\" type=\"password\" name=\"formConfirm\" value=\"", htmlspecialchars($_POST['formConfirm']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formSuper\">{$lang['strsuper']}</label></th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formSuper\" name=\"formSuper\"", - (isset($_POST['formSuper'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\"><label for=\"formCreateDB\">{$lang['strcreatedb']}</label></th>\n"; - echo "\t\t<td class=\"data1\"><input type=\"checkbox\" id=\"formCreateDB\" name=\"formCreateDB\"", - (isset($_POST['formCreateDB'])) ? ' checked="checked"' : '', " /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strexpires']}</th>\n"; - echo "\t\t<td class=\"data1\"><input size=\"30\" name=\"formExpires\" value=\"", htmlspecialchars($_POST['formExpires']), "\" /></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new user in the database - */ -function doSaveCreate() { - global $data; - global $lang; - - // Check data - if ($_POST['formUsername'] == '') { - doCreate($lang['struserneedsname']); - } else if ($_POST['formPassword'] != $_POST['formConfirm']) { - doCreate($lang['strpasswordconfirm']); - } else { - $status = $data->createUser($_POST['formUsername'], $_POST['formPassword'], - isset($_POST['formCreateDB']), isset($_POST['formSuper']), $_POST['formExpires'], []); - if ($status == 0) { - doDefault($lang['strusercreated']); - } else { - doCreate($lang['strusercreatedbad']); - } - - } -} - -/** - * Show default list of users in the database - */ -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - function renderUseExpires($val) { - global $lang; - return $val == 'infinity' ? $lang['strnever'] : htmlspecialchars($val); - } - - $misc->printTrail('server'); - $misc->printTabs('server', 'users'); - $misc->printMsg($msg); - - $users = $data->getUsers(); - - $columns = [ - 'user' => [ - 'title' => $lang['strusername'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - 'superuser' => [ - 'title' => $lang['strsuper'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usesuper'), - 'type' => 'yesno', - ], - 'createdb' => [ - 'title' => $lang['strcreatedb'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('usecreatedb'), - 'type' => 'yesno', - ], - 'expires' => [ - 'title' => $lang['strexpires'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('useexpires'), - 'type' => 'callback', - 'params' => ['function' => 'renderUseExpires', 'null' => $lang['strnever']], - ], - 'defaults' => [ - 'title' => $lang['strsessiondefaults'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('useconfig'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'users.php', - 'urlvars' => [ - 'action' => 'edit', - 'username' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - ], - ], - ], - 'drop' => [ - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'users.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'username' => \PHPPgAdmin\Decorators\Decorator::field('usename'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($users, $columns, $actions, 'users-users', $lang['strnousers']); - - $misc->printNavLinks(['create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'users.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - ], - ], - ], - 'content' => $lang['strcreateuser'], - ]], 'users-users', get_defined_vars()); - -} +$user_controller = new \PHPPgAdmin\Controller\UserController($container); $misc->printHeader($lang['strusers']); $misc->printBody(); @@ -418,53 +17,53 @@ $misc->printBody(); switch ($action) { case 'changepassword': if (isset($_REQUEST['ok'])) { - doChangePassword(false); + $user_controller->doChangePassword(false); } else { - doAccount(); + $user_controller->doAccount(); } break; case 'confchangepassword': - doChangePassword(true); + $user_controller->doChangePassword(true); break; case 'account': - doAccount(); + $user_controller->doAccount(); break; case 'save_create': if (isset($_REQUEST['cancel'])) { - doDefault(); + $user_controller->doDefault(); } else { - doSaveCreate(); + $user_controller->doSaveCreate(); } break; case 'create': - doCreate(); + $user_controller->doCreate(); break; case 'drop': if (isset($_REQUEST['cancel'])) { - doDefault(); + $user_controller->doDefault(); } else { - doDrop(false); + $user_controller->doDrop(false); } break; case 'confirm_drop': - doDrop(true); + $user_controller->doDrop(true); break; case 'save_edit': if (isset($_REQUEST['cancel'])) { - doDefault(); + $user_controller->doDefault(); } else { - doSaveEdit(); + $user_controller->doSaveEdit(); } break; case 'edit': - doEdit(); + $user_controller->doEdit(); break; default: - doDefault(); + $user_controller->doDefault(); break; } diff --git a/src/views/viewproperties.php b/src/views/viewproperties.php index c9f87e81..4148854c 100755 --- a/src/views/viewproperties.php +++ b/src/views/viewproperties.php @@ -9,503 +9,7 @@ // Include application functions require_once '../lib.inc.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; - -/** - * Function to save after editing a view - */ -function doSaveEdit() { - global $data, $lang; - - $status = $data->setView($_POST['view'], $_POST['formDefinition'], $_POST['formComment']); - if ($status == 0) { - doDefinition($lang['strviewupdated']); - } else { - doEdit($lang['strviewupdatedbad']); - } - -} - -/** - * Function to allow editing of a view - */ -function doEdit($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('view'); - $misc->printTitle($lang['stredit'], 'pg.view.alter'); - $misc->printMsg($msg); - - $viewdata = $data->getView($_REQUEST['view']); - - if ($viewdata->recordCount() > 0) { - - if (!isset($_POST['formDefinition'])) { - $_POST['formDefinition'] = $viewdata->fields['vwdefinition']; - $_POST['formComment'] = $viewdata->fields['relcomment']; - } - - echo "<form action=\"/views/viewproperties.php\" method=\"post\">\n"; - echo "<table style=\"width: 100%\">\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strdefinition']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea style=\"width: 100%;\" rows=\"20\" cols=\"50\" name=\"formDefinition\">", - htmlspecialchars($_POST['formDefinition']), "</textarea></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea rows=\"3\" cols=\"32\" name=\"formComment\">", - htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n"; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - -} - -/** - * Allow the dumping of the data "in" a view - * NOTE:: PostgreSQL doesn't currently support dumping the data in a view - * so I have disabled the data related parts for now. In the future - * we should allow it conditionally if it becomes supported. This is - * a SMOP since it is based on pg_dump version not backend version. - */ -function doExport($msg = '') { - global $data, $misc; - global $lang; - - $misc->printTrail('view'); - $misc->printTabs('view', 'export'); - $misc->printMsg($msg); - - echo "<form action=\"/views/dataexport.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n"; - // Data only - echo "<!--\n"; - echo "<tr><th class=\"data left\">"; - echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"d_format\" >\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "<option value=\"csv\">CSV</option>\n"; - echo "<option value=\"tab\">{$lang['strtabbed']}</option>\n"; - echo "<option value=\"html\">XHTML</option>\n"; - echo "<option value=\"xml\">XML</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "-->\n"; - - // Structure only - echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" checked=\"checked\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n"; - echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n"; - // Structure and data - echo "<!--\n"; - echo "<tr><th class=\"data left\" rowspan=\"2\">"; - echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n"; - echo "<td>{$lang['strformat']}</td>\n"; - echo "<td><select name=\"sd_format\">\n"; - echo "<option value=\"copy\">COPY</option>\n"; - echo "<option value=\"sql\">SQL</option>\n"; - echo "</select>\n</td>\n</tr>\n"; - echo "<td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n"; - echo "-->\n"; - echo "</table>\n"; - - echo "<h3>{$lang['stroptions']}</h3>\n"; - echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n"; - echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label></p>\n"; - - echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n"; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Show definition for a view - */ -function doDefinition($msg = '') { - global $data, $misc; - global $lang; - - // Get view - $vdata = $data->getView($_REQUEST['view']); - - $misc->printTrail('view'); - $misc->printTabs('view', 'definition'); - $misc->printMsg($msg); - - if ($vdata->recordCount() > 0) { - // Show comment if any - if ($vdata->fields['relcomment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($vdata->fields['relcomment']), "</p>\n"; - } - - echo "<table style=\"width: 100%\">\n"; - echo "<tr><th class=\"data\">{$lang['strdefinition']}</th></tr>\n"; - echo "<tr><td class=\"data1\">", $misc->printVal($vdata->fields['vwdefinition']), "</td></tr>\n"; - echo "</table>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - $misc->printNavLinks(['alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'viewproperties.php', - 'urlvars' => [ - 'action' => 'edit', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $_REQUEST['view'], - ], - ], - ], - 'content' => $lang['stralter'], - ]], 'viewproperties-definition', get_defined_vars()); -} - -/** - * Displays a screen where they can alter a column in a view - */ -function doProperties($msg = '') { - global $data, $misc; - global $lang; - - if (!isset($_REQUEST['stage'])) { - $_REQUEST['stage'] = 1; - } - - switch ($_REQUEST['stage']) { - case 1: - global $lang; - - $misc->printTrail('column'); - $misc->printTitle($lang['stralter'], 'pg.column.alter'); - $misc->printMsg($msg); - - echo "<form action=\"/views/viewproperties.php\" method=\"post\">\n"; - - // Output view header - echo "<table>\n"; - echo "<tr><th class=\"data required\">{$lang['strname']}</th><th class=\"data required\">{$lang['strtype']}</th>"; - echo "<th class=\"data\">{$lang['strdefault']}</th><th class=\"data\">{$lang['strcomment']}</th></tr>"; - - $column = $data->getTableAttributes($_REQUEST['view'], $_REQUEST['column']); - - if (!isset($_REQUEST['default'])) { - $_REQUEST['field'] = $column->fields['attname']; - $_REQUEST['default'] = $_REQUEST['olddefault'] = $column->fields['adsrc']; - $_REQUEST['comment'] = $column->fields['comment']; - } - - echo "<tr><td><input name=\"field\" size=\"32\" value=\"", - htmlspecialchars($_REQUEST['field']), "\" /></td>"; - - echo "<td>", $misc->printVal($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "</td>"; - echo "<td><input name=\"default\" size=\"20\" value=\"", - htmlspecialchars($_REQUEST['default']), "\" /></td>"; - echo "<td><input name=\"comment\" size=\"32\" value=\"", - htmlspecialchars($_REQUEST['comment']), "\" /></td>"; - - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"properties\" />\n"; - echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n"; - echo $misc->form; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - echo "<input type=\"hidden\" name=\"column\" value=\"", htmlspecialchars($_REQUEST['column']), "\" />\n"; - echo "<input type=\"hidden\" name=\"olddefault\" value=\"", htmlspecialchars($_REQUEST['olddefault']), "\" />\n"; - echo "<input type=\"submit\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - - break; - case 2: - global $data, $lang; - - // Check inputs - if (trim($_REQUEST['field']) == '') { - $_REQUEST['stage'] = 1; - doProperties($lang['strcolneedsname']); - return; - } - - // Alter the view column - $status = $data->alterColumn($_REQUEST['view'], $_REQUEST['column'], $_REQUEST['field'], - false, false, $_REQUEST['default'], $_REQUEST['olddefault'], - '', '', '', '', $_REQUEST['comment']); - if ($status == 0) { - doDefault($lang['strcolumnaltered']); - } else { - $_REQUEST['stage'] = 1; - doProperties($lang['strcolumnalteredbad']); - return; - } - break; - default: - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } -} - -function doAlter($confirm = false, $msg = '') { - if ($confirm) { - global $data, $misc, $lang; - - $misc->printTrail('view'); - $misc->printTitle($lang['stralter'], 'pg.view.alter'); - $misc->printMsg($msg); - - // Fetch view info - $view = $data->getView($_REQUEST['view']); - - if ($view->recordCount() > 0) { - if (!isset($_POST['name'])) { - $_POST['name'] = $view->fields['relname']; - } - - if (!isset($_POST['owner'])) { - $_POST['owner'] = $view->fields['relowner']; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = $view->fields['nspname']; - } - - if (!isset($_POST['comment'])) { - $_POST['comment'] = $view->fields['relcomment']; - } - - echo "<form action=\"/views/viewproperties.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_POST['name']), "\" /></td></tr>\n"; - - if ($data->isSuperUser()) { - - // Fetch all users - $users = $data->getUsers(); - - echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n"; - echo "<td class=\"data1\"><select name=\"owner\">"; - while (!$users->EOF) { - $uname = $users->fields['usename']; - echo "<option value=\"", htmlspecialchars($uname), "\"", - ($uname == $_POST['owner']) ? ' selected="selected"' : '', ">", htmlspecialchars($uname), "</option>\n"; - $users->moveNext(); - } - echo "</select></td></tr>\n"; - } - - if ($data->hasAlterTableSchema()) { - $schemas = $data->getSchemas(); - echo "<tr><th class=\"data left required\">{$lang['strschema']}</th>\n"; - echo "<td class=\"data1\"><select name=\"newschema\">"; - while (!$schemas->EOF) { - $schema = $schemas->fields['nspname']; - echo "<option value=\"", htmlspecialchars($schema), "\"", - ($schema == $_POST['newschema']) ? ' selected="selected"' : '', ">", htmlspecialchars($schema), "</option>\n"; - $schemas->moveNext(); - } - echo "</select></td></tr>\n"; - } - - echo "<tr><th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "<td class=\"data1\">"; - echo "<textarea rows=\"3\" cols=\"32\" name=\"comment\">", - htmlspecialchars($_POST['comment']), "</textarea></td></tr>\n"; - echo "</table>\n"; - echo "<input type=\"hidden\" name=\"action\" value=\"alter\" />\n"; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - echo $misc->form; - echo "<p><input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - echo "<p>{$lang['strnodata']}</p>\n"; - } - - } else { - global $data, $lang, $_reload_browser, $misc; - - // For databases that don't allow owner change - if (!isset($_POST['owner'])) { - $_POST['owner'] = ''; - } - - if (!isset($_POST['newschema'])) { - $_POST['newschema'] = null; - } - - $status = $data->alterView($_POST['view'], $_POST['name'], $_POST['owner'], $_POST['newschema'], $_POST['comment']); - if ($status == 0) { - // If view has been renamed, need to change to the new name and - // reload the browser frame. - if ($_POST['view'] != $_POST['name']) { - // Jump them to the new view name - $_REQUEST['view'] = $_POST['name']; - // Force a browser reload - $_reload_browser = true; - } - // If schema has changed, need to change to the new schema and reload the browser - if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) { - // Jump them to the new sequence schema - $misc->setCurrentSchema($_POST['newschema']); - $_reload_browser = true; - } - doDefault($lang['strviewaltered']); - } else { - doAlter(true, $lang['strviewalteredbad']); - } - - } -} - -/** - * Show view definition and virtual columns - */ -function doDefault($msg = '') { - global $data, $misc; - global $lang; - - function attPre(&$rowdata) { - global $data; - $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']); - } - - $misc->printTrail('view'); - $misc->printTabs('view', 'columns'); - $misc->printMsg($msg); - - // Get view - $vdata = $data->getView($_REQUEST['view']); - // Get columns (using same method for getting a view) - $attrs = $data->getTableAttributes($_REQUEST['view']); - - // Show comment if any - if ($vdata->fields['relcomment'] !== null) { - echo "<p class=\"comment\">", $misc->printVal($vdata->fields['relcomment']), "</p>\n"; - } - - $columns = [ - 'column' => [ - 'title' => $lang['strcolumn'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - 'url' => "colproperties.php?subject=column&{$misc->href}&view=" . urlencode($_REQUEST['view']) . "&", - 'vars' => ['column' => 'attname'], - ], - 'type' => [ - 'title' => $lang['strtype'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('+type'), - ], - 'default' => [ - 'title' => $lang['strdefault'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('adsrc'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('comment'), - ], - ]; - - $actions = [ - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'viewproperties.php', - 'urlvars' => [ - 'action' => 'properties', - 'view' => $_REQUEST['view'], - 'column' => \PHPPgAdmin\Decorators\Decorator::field('attname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($attrs, $columns, $actions, 'viewproperties-viewproperties', null, 'attPre'); - - echo "<br />\n"; - - $navlinks = [ - 'browse' => [ - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $_REQUEST['view'], - 'subject' => 'view', - 'return' => 'view', - ], - ], - ], - 'content' => $lang['strbrowse'], - ], - 'select' => [ - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'confselectrows', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $_REQUEST['view'], - ], - ], - ], - 'content' => $lang['strselect'], - ], - 'drop' => [ - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $_REQUEST['view'], - ], - ], - ], - 'content' => $lang['strdrop'], - ], - 'alter' => [ - 'attr' => [ - 'href' => [ - 'url' => 'viewproperties.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - 'view' => $_REQUEST['view'], - ], - ], - ], - 'content' => $lang['stralter'], - ], - ]; - - $misc->printNavLinks($navlinks, 'viewproperties-viewproperties', get_defined_vars()); -} +$viewproperty_controller = new \PHPPgAdmin\Controller\ViewPropertyController($container); $misc->printHeader($lang['strviews'] . ' - ' . $_REQUEST['view']); $misc->printBody(); @@ -513,34 +17,34 @@ $misc->printBody(); switch ($action) { case 'save_edit': if (isset($_POST['cancel'])) { - doDefinition(); + $viewproperty_controller->doDefinition(); } else { - doSaveEdit(); + $viewproperty_controller->doSaveEdit(); } break; case 'edit': - doEdit(); + $viewproperty_controller->doEdit(); break; case 'export': - doExport(); + $viewproperty_controller->doExport(); break; case 'definition': - doDefinition(); + $viewproperty_controller->doDefinition(); break; case 'properties': if (isset($_POST['cancel'])) { - doDefault(); + $viewproperty_controller->doDefault(); } else { - doProperties(); + $viewproperty_controller->doProperties(); } break; case 'alter': if (isset($_POST['alter'])) { - doAlter(false); + $viewproperty_controller->doAlter(false); } else { - doDefault(); + $viewproperty_controller->doDefault(); } break; @@ -549,17 +53,17 @@ switch ($action) { break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $viewproperty_controller->doDrop(false); } else { - doDefault(); + $viewproperty_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $viewproperty_controller->doDrop(true); break; default: - doDefault(); + $viewproperty_controller->doDefault(); break; } diff --git a/src/views/views.php b/src/views/views.php index 8a8a25e1..e2d62965 100644 --- a/src/views/views.php +++ b/src/views/views.php @@ -8,734 +8,8 @@ // Include application functions require_once '../lib.inc.php'; -include_once '../classes/Gui.php'; -$action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : ''; -if (!isset($msg)) { - $msg = ''; -} - -/** - * Ask for select parameters and perform select - */ -function doSelectRows($confirm, $msg = '') { - global $data, $misc, $_no_output; - global $lang; - - if ($confirm) { - $misc->printTrail('view'); - $misc->printTabs('view', 'select'); - $misc->printMsg($msg); - - $attrs = $data->getTableAttributes($_REQUEST['view']); - - echo "<form action=\"/views/views.php\" method=\"post\" id=\"selectform\">\n"; - if ($attrs->recordCount() > 0) { - // JavaScript for select all feature - echo "<script type=\"text/javascript\">\n"; - echo "//<![CDATA[\n"; - echo " function selectAll() {\n"; - echo " for (var i=0; i<document.getElementById('selectform').elements.length; i++) {\n"; - echo " var e = document.getElementById('selectform').elements[i];\n"; - echo " if (e.name.indexOf('show') == 0) e.checked = document.getElementById('selectform').selectall.checked;\n"; - echo " }\n"; - echo " }\n"; - echo "//]]>\n"; - echo "</script>\n"; - - echo "<table>\n"; - - // Output table header - echo "<tr><th class=\"data\">{$lang['strshow']}</th><th class=\"data\">{$lang['strcolumn']}</th>"; - echo "<th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['stroperator']}</th>"; - echo "<th class=\"data\">{$lang['strvalue']}</th></tr>"; - - $i = 0; - while (!$attrs->EOF) { - $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']); - // Set up default value if there isn't one already - if (!isset($_REQUEST['values'][$attrs->fields['attname']])) { - $_REQUEST['values'][$attrs->fields['attname']] = null; - } - - if (!isset($_REQUEST['ops'][$attrs->fields['attname']])) { - $_REQUEST['ops'][$attrs->fields['attname']] = null; - } - - // Continue drawing row - $id = (($i % 2) == 0 ? '1' : '2'); - echo "<tr class=\"data{$id}\">\n"; - echo "<td style=\"white-space:nowrap;\">"; - echo "<input type=\"checkbox\" name=\"show[", htmlspecialchars($attrs->fields['attname']), "]\"", - isset($_REQUEST['show'][$attrs->fields['attname']]) ? ' checked="checked"' : '', " /></td>"; - echo "<td style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>"; - echo "<td style=\"white-space:nowrap;\">", $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])), "</td>"; - echo "<td style=\"white-space:nowrap;\">"; - echo "<select name=\"ops[{$attrs->fields['attname']}]\">\n"; - foreach (array_keys($data->selectOps) as $v) { - echo "<option value=\"", htmlspecialchars($v), "\"", ($v == $_REQUEST['ops'][$attrs->fields['attname']]) ? ' selected="selected"' : '', - ">", htmlspecialchars($v), "</option>\n"; - } - echo "</select></td>\n"; - echo "<td style=\"white-space:nowrap;\">", $data->printField("values[{$attrs->fields['attname']}]", - $_REQUEST['values'][$attrs->fields['attname']], $attrs->fields['type']), "</td>"; - echo "</tr>\n"; - $i++; - $attrs->moveNext(); - } - // Select all checkbox - echo "<tr><td colspan=\"5\"><input type=\"checkbox\" id=\"selectall\" name=\"selectall\" accesskey=\"a\" onclick=\"javascript:selectAll()\" /><label for=\"selectall\">{$lang['strselectallfields']}</label></td></tr>"; - echo "</table>\n"; - } else { - echo "<p>{$lang['strinvalidparam']}</p>\n"; - } - - echo "<p><input type=\"hidden\" name=\"action\" value=\"selectrows\" />\n"; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" name=\"select\" accesskey=\"r\" value=\"{$lang['strselect']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } else { - if (!isset($_POST['show'])) { - $_POST['show'] = []; - } - - if (!isset($_POST['values'])) { - $_POST['values'] = []; - } - - if (!isset($_POST['nulls'])) { - $_POST['nulls'] = []; - } - - // Verify that they haven't supplied a value for unary operators - foreach ($_POST['ops'] as $k => $v) { - if ($data->selectOps[$v] == 'p' && $_POST['values'][$k] != '') { - doSelectRows(true, $lang['strselectunary']); - return; - } - } - - if (sizeof($_POST['show']) == 0) { - doSelectRows(true, $lang['strselectneedscol']); - } else { - // Generate query SQL - $query = $data->getSelectSQL($_REQUEST['view'], array_keys($_POST['show']), - $_POST['values'], $_POST['ops']); - $_REQUEST['query'] = $query; - $_REQUEST['return'] = "schema"; - $_no_output = true; - include './display.php'; - exit; - } - } - -} - -/** - * Show confirmation of drop and perform actual drop - */ -function doDrop($confirm) { - global $data, $misc; - global $lang, $_reload_browser; - - if (empty($_REQUEST['view']) && empty($_REQUEST['ma'])) { - doDefault($lang['strspecifyviewtodrop']); - exit(); - } - - if ($confirm) { - $misc->printTrail('view'); - $misc->printTitle($lang['strdrop'], 'pg.view.drop'); - - echo "<form action=\"/views/views.php\" method=\"post\">\n"; - - //If multi drop - if (isset($_REQUEST['ma'])) { - foreach ($_REQUEST['ma'] as $v) { - $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES)); - echo "<p>", sprintf($lang['strconfdropview'], $misc->printVal($a['view'])), "</p>\n"; - echo '<input type="hidden" name="view[]" value="', htmlspecialchars($a['view']), "\" />\n"; - } - } else { - echo "<p>", sprintf($lang['strconfdropview'], $misc->printVal($_REQUEST['view'])), "</p>\n"; - echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n"; - } - - echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n"; - - echo $misc->form; - echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n"; - echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n"; - echo "</form>\n"; - } else { - if (is_array($_POST['view'])) { - $msg = ''; - $status = $data->beginTransaction(); - if ($status == 0) { - foreach ($_POST['view'] as $s) { - $status = $data->dropView($s, isset($_POST['cascade'])); - if ($status == 0) { - $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdropped']); - } else { - $data->endTransaction(); - doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdroppedbad'])); - return; - } - } - } - if ($data->endTransaction() == 0) { - // Everything went fine, back to the Default page.... - $_reload_browser = true; - doDefault($msg); - } else { - doDefault($lang['strviewdroppedbad']); - } - - } else { - $status = $data->dropView($_POST['view'], isset($_POST['cascade'])); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strviewdropped']); - } else { - doDefault($lang['strviewdroppedbad']); - } - - } - } - -} - -/** - * Sets up choices for table linkage, and which fields to select for the view we're creating - */ -function doSetParamsCreate($msg = '') { - global $data, $misc; - global $lang; - - // Check that they've chosen tables for the view definition - if (!isset($_POST['formTables'])) { - doWizardCreate($lang['strviewneedsdef']); - } else { - // Initialise variables - if (!isset($_REQUEST['formView'])) { - $_REQUEST['formView'] = ''; - } - - if (!isset($_REQUEST['formComment'])) { - $_REQUEST['formComment'] = ''; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateviewwiz'], 'pg.view.create'); - $misc->printMsg($msg); - - $tblCount = sizeof($_POST['formTables']); - //unserialize our schema/table information and store in arrSelTables - for ($i = 0; $i < $tblCount; $i++) { - $arrSelTables[] = unserialize($_POST['formTables'][$i]); - } - - $linkCount = $tblCount; - - //get linking keys - $rsLinkKeys = $data->getLinkingKeys($arrSelTables); - $linkCount = $rsLinkKeys->recordCount() > $tblCount ? $rsLinkKeys->recordCount() : $tblCount; - - $arrFields = []; //array that will hold all our table/field names - - //if we have schemas we need to specify the correct schema for each table we're retrieiving - //with getTableAttributes - $curSchema = $data->_schema; - for ($i = 0; $i < $tblCount; $i++) { - if ($data->_schema != $arrSelTables[$i]['schemaname']) { - $data->setSchema($arrSelTables[$i]['schemaname']); - } - - $attrs = $data->getTableAttributes($arrSelTables[$i]['tablename']); - while (!$attrs->EOF) { - $arrFields["{$arrSelTables[$i]['schemaname']}.{$arrSelTables[$i]['tablename']}.{$attrs->fields['attname']}"] = serialize([ - 'schemaname' => $arrSelTables[$i]['schemaname'], - 'tablename' => $arrSelTables[$i]['tablename'], - 'fieldname' => $attrs->fields['attname']] - ); - $attrs->moveNext(); - } - - $data->setSchema($curSchema); - } - asort($arrFields); - - echo "<form action=\"/views/views.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strviewname']}</th></tr>"; - echo "<tr>\n<td class=\"data1\">\n"; - // View name - echo "<input name=\"formView\" value=\"", htmlspecialchars($_REQUEST['formView']), "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n"; - echo "</td>\n</tr>\n"; - echo "<tr><th class=\"data\">{$lang['strcomment']}</th></tr>"; - echo "<tr>\n<td class=\"data1\">\n"; - // View comments - echo "<textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['formComment']), "</textarea>\n"; - echo "</td>\n</tr>\n"; - echo "</table>\n"; - - // Output selector for fields to be retrieved from view - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strcolumns']}</th></tr>"; - echo "<tr>\n<td class=\"data1\">\n"; - echo GUI::printCombo($arrFields, 'formFields[]', false, '', true); - echo "</td>\n</tr>"; - echo "<tr><td><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth1\" value=\"rename\" /><label for=\"dblFldMeth1\">{$lang['strrenamedupfields']}</label>"; - echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth2\" value=\"drop\" /><label for=\"dblFldMeth2\">{$lang['strdropdupfields']}</label>"; - echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth3\" value=\"\" checked=\"checked\" /><label for=\"dblFldMeth3\">{$lang['strerrordupfields']}</label></td></tr></table><br />"; - - // Output the Linking keys combo boxes - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>"; - $rowClass = 'data1'; - for ($i = 0; $i < $linkCount; $i++) { - // Initialise variables - if (!isset($formLink[$i]['operator'])) { - $formLink[$i]['operator'] = 'INNER JOIN'; - } - - echo "<tr>\n<td class=\"$rowClass\">\n"; - - if (!$rsLinkKeys->EOF) { - $curLeftLink = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['p_schema'], 'tablename' => $rsLinkKeys->fields['p_table'], 'fieldname' => $rsLinkKeys->fields['p_field']])); - $curRightLink = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['f_schema'], 'tablename' => $rsLinkKeys->fields['f_table'], 'fieldname' => $rsLinkKeys->fields['f_field']])); - $rsLinkKeys->moveNext(); - } else { - $curLeftLink = ''; - $curRightLink = ''; - } - - echo GUI::printCombo($arrFields, "formLink[$i][leftlink]", true, $curLeftLink, false); - echo GUI::printCombo($data->joinOps, "formLink[$i][operator]", true, $formLink[$i]['operator']); - echo GUI::printCombo($arrFields, "formLink[$i][rightlink]", true, $curRightLink, false); - echo "</td>\n</tr>\n"; - $rowClass = $rowClass == 'data1' ? 'data2' : 'data1'; - } - echo "</table>\n<br />\n"; - - // Build list of available operators (infix only) - $arrOperators = []; - foreach ($data->selectOps as $k => $v) { - if ($v == 'i') { - $arrOperators[$k] = $k; - } - - } - - // Output additional conditions, note that this portion of the wizard treats the right hand side as literal values - //(not as database objects) so field names will be treated as strings, use the above linking keys section to perform joins - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strviewconditions']}</th></tr>"; - $rowClass = 'data1'; - for ($i = 0; $i < $linkCount; $i++) { - echo "<tr>\n<td class=\"$rowClass\">\n"; - echo GUI::printCombo($arrFields, "formCondition[$i][field]"); - echo GUI::printCombo($arrOperators, "formCondition[$i][operator]", false, false); - echo "<input type=\"text\" name=\"formCondition[$i][txt]\" />\n"; - echo "</td>\n</tr>\n"; - $rowClass = $rowClass == 'data1' ? 'data2' : 'data1'; - } - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_wiz\" />\n"; - - foreach ($arrSelTables as $curTable) { - echo "<input type=\"hidden\" name=\"formTables[]\" value=\"" . htmlspecialchars(serialize($curTable)) . "\" />\n"; - } - - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; - } -} - -/** - * Display a wizard where they can enter a new view - */ -function doWizardCreate($msg = '') { - global $data, $misc; - global $lang; - - $tables = $data->getTables(true); - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateviewwiz'], 'pg.view.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/views.php\" method=\"post\">\n"; - echo "<table>\n"; - echo "<tr><th class=\"data\">{$lang['strtables']}</th></tr>"; - echo "<tr>\n<td class=\"data1\">\n"; - - $arrTables = []; - while (!$tables->EOF) { - $arrTmp = []; - $arrTmp['schemaname'] = $tables->fields['nspname']; - $arrTmp['tablename'] = $tables->fields['relname']; - $arrTables[$tables->fields['nspname'] . '.' . $tables->fields['relname']] = serialize($arrTmp); - $tables->moveNext(); - } - echo GUI::printCombo($arrTables, 'formTables[]', false, '', true); - - echo "</td>\n</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"set_params_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Displays a screen where they can enter a new view - */ -function doCreate($msg = '') { - global $data, $misc, $conf; - global $lang; - - if (!isset($_REQUEST['formView'])) { - $_REQUEST['formView'] = ''; - } - - if (!isset($_REQUEST['formDefinition'])) { - if (isset($_SESSION['sqlquery'])) { - $_REQUEST['formDefinition'] = $_SESSION['sqlquery']; - } else { - $_REQUEST['formDefinition'] = 'SELECT '; - } - - } - if (!isset($_REQUEST['formComment'])) { - $_REQUEST['formComment'] = ''; - } - - $misc->printTrail('schema'); - $misc->printTitle($lang['strcreateview'], 'pg.view.create'); - $misc->printMsg($msg); - - echo "<form action=\"/views/views.php\" method=\"post\">\n"; - echo "<table style=\"width: 100%\">\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n"; - echo "\t<td class=\"data1\"><input name=\"formView\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", - htmlspecialchars($_REQUEST['formView']), "\" /></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strdefinition']}</th>\n"; - echo "\t<td class=\"data1\"><textarea style=\"width:100%;\" rows=\"10\" cols=\"50\" name=\"formDefinition\">", - htmlspecialchars($_REQUEST['formDefinition']), "</textarea></td>\n\t</tr>\n"; - echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n"; - echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">", - htmlspecialchars($_REQUEST['formComment']), "</textarea></td>\n\t</tr>\n"; - echo "</table>\n"; - echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n"; - echo $misc->form; - echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n"; - echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n"; - echo "</form>\n"; -} - -/** - * Actually creates the new view in the database - */ -function doSaveCreate() { - global $data, $lang, $_reload_browser; - - // Check that they've given a name and a definition - if ($_POST['formView'] == '') { - doCreate($lang['strviewneedsname']); - } elseif ($_POST['formDefinition'] == '') { - doCreate($lang['strviewneedsdef']); - } else { - $status = $data->createView($_POST['formView'], $_POST['formDefinition'], false, $_POST['formComment']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strviewcreated']); - } else { - doCreate($lang['strviewcreatedbad']); - } - - } -} - -/** - * Actually creates the new wizard view in the database - */ -function doSaveCreateWiz() { - global $data, $lang, $_reload_browser; - - // Check that they've given a name and fields they want to select - - if (!strlen($_POST['formView'])) { - doSetParamsCreate($lang['strviewneedsname']); - } else if (!isset($_POST['formFields']) || !count($_POST['formFields'])) { - doSetParamsCreate($lang['strviewneedsfields']); - } else { - $selFields = ''; - - if (!empty($_POST['dblFldMeth'])) { - $tmpHsh = []; - } - - foreach ($_POST['formFields'] as $curField) { - $arrTmp = unserialize($curField); - $data->fieldArrayClean($arrTmp); - if (!empty($_POST['dblFldMeth'])) { - // doublon control - if (empty($tmpHsh[$arrTmp['fieldname']])) { - // field does not exist - $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", "; - $tmpHsh[$arrTmp['fieldname']] = 1; - } else if ($_POST['dblFldMeth'] == 'rename') { - // field exist and must be renamed - $tmpHsh[$arrTmp['fieldname']]++; - $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" AS \"{$arrTmp['schemaname']}_{$arrTmp['tablename']}_{$arrTmp['fieldname']}{$tmpHsh[$arrTmp['fieldname']]}\", "; - } - /* field already exist, just ignore this one */ - } else { - // no doublon control - $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", "; - } - } - - $selFields = substr($selFields, 0, -2); - unset($arrTmp, $tmpHsh); - $linkFields = ''; - - // If we have links, out put the JOIN ... ON statements - if (is_array($_POST['formLink'])) { - // Filter out invalid/blank entries for our links - $arrLinks = []; - foreach ($_POST['formLink'] as $curLink) { - if (strlen($curLink['leftlink']) && strlen($curLink['rightlink']) && strlen($curLink['operator'])) { - $arrLinks[] = $curLink; - } - } - // We must perform some magic to make sure that we have a valid join order - $count = sizeof($arrLinks); - $arrJoined = []; - $arrUsedTbls = []; - - // If we have at least one join condition, output it - if ($count > 0) { - $j = 0; - while ($j < $count) { - foreach ($arrLinks as $curLink) { - - $arrLeftLink = unserialize($curLink['leftlink']); - $arrRightLink = unserialize($curLink['rightlink']); - $data->fieldArrayClean($arrLeftLink); - $data->fieldArrayClean($arrRightLink); - - $tbl1 = "\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\""; - $tbl2 = "\"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\""; - - if ((!in_array($curLink, $arrJoined) && in_array($tbl1, $arrUsedTbls)) || !count($arrJoined)) { - - // Make sure for multi-column foreign keys that we use a table alias tables joined to more than once - // This can (and should be) more optimized for multi-column foreign keys - $adj_tbl2 = in_array($tbl2, $arrUsedTbls) ? "$tbl2 AS alias_ppa_" . mktime() : $tbl2; - - $linkFields .= strlen($linkFields) ? "{$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") " - : "$tbl1 {$curLink['operator']} $adj_tbl2 ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") "; - - $arrJoined[] = $curLink; - if (!in_array($tbl1, $arrUsedTbls)) { - $arrUsedTbls[] = $tbl1; - } - - if (!in_array($tbl2, $arrUsedTbls)) { - $arrUsedTbls[] = $tbl2; - } - - } - } - $j++; - } - } - } - - //if linkfields has no length then either _POST['formLink'] was not set, or there were no join conditions - //just select from all seleted tables - a cartesian join do a - if (!strlen($linkFields)) { - foreach ($_POST['formTables'] as $curTable) { - $arrTmp = unserialize($curTable); - $data->fieldArrayClean($arrTmp); - $linkFields .= strlen($linkFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\""; - } - } - - $addConditions = ''; - if (is_array($_POST['formCondition'])) { - foreach ($_POST['formCondition'] as $curCondition) { - if (strlen($curCondition['field']) && strlen($curCondition['txt'])) { - $arrTmp = unserialize($curCondition['field']); - $data->fieldArrayClean($arrTmp); - $addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' " - : " \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' "; - } - } - } - - $viewQuery = "SELECT $selFields FROM $linkFields "; - - //add where from additional conditions - if (strlen($addConditions)) { - $viewQuery .= ' WHERE ' . $addConditions; - } - - $status = $data->createView($_POST['formView'], $viewQuery, false, $_POST['formComment']); - if ($status == 0) { - $_reload_browser = true; - doDefault($lang['strviewcreated']); - } else { - doSetParamsCreate($lang['strviewcreatedbad']); - } - - } -} - -/** - * Show default list of views in the database - */ -function doDefault($msg = '') { - global $data, $misc, $conf; - global $lang; - - $misc->printTrail('schema'); - $misc->printTabs('schema', 'views'); - $misc->printMsg($msg); - - $views = $data->getViews(); - - $columns = [ - 'view' => [ - 'title' => $lang['strview'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - 'url' => "/redirect/view?{$misc->href}&", - 'vars' => ['view' => 'relname'], - ], - 'owner' => [ - 'title' => $lang['strowner'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relowner'), - ], - 'actions' => [ - 'title' => $lang['stractions'], - ], - 'comment' => [ - 'title' => $lang['strcomment'], - 'field' => \PHPPgAdmin\Decorators\Decorator::field('relcomment'), - ], - ]; - - $actions = [ - 'multiactions' => [ - 'keycols' => ['view' => 'relname'], - 'url' => 'views.php', - ], - 'browse' => [ - 'content' => $lang['strbrowse'], - 'attr' => [ - 'href' => [ - 'url' => 'display.php', - 'urlvars' => [ - 'action' => 'confselectrows', - 'subject' => 'view', - 'return' => 'schema', - 'view' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'select' => [ - 'content' => $lang['strselect'], - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'confselectrows', - 'view' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - -// Insert is possible if the relevant rule for the view has been created. - // 'insert' => array( - // 'title' => $lang['strinsert'], - // 'url' => "views.php?action=confinsertrow&{$misc->href}&", - // 'vars' => array('view' => 'relname'), - // ), - - 'alter' => [ - 'content' => $lang['stralter'], - 'attr' => [ - 'href' => [ - 'url' => 'viewproperties.php', - 'urlvars' => [ - 'action' => 'confirm_alter', - 'view' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - 'drop' => [ - 'multiaction' => 'confirm_drop', - 'content' => $lang['strdrop'], - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'confirm_drop', - 'view' => \PHPPgAdmin\Decorators\Decorator::field('relname'), - ], - ], - ], - ], - ]; - - echo $misc->printTable($views, $columns, $actions, 'views-views', $lang['strnoviews']); - - $navlinks = [ - 'create' => [ - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateview'], - ], - 'createwiz' => [ - 'attr' => [ - 'href' => [ - 'url' => 'views.php', - 'urlvars' => [ - 'action' => 'wiz_create', - 'server' => $_REQUEST['server'], - 'database' => $_REQUEST['database'], - 'schema' => $_REQUEST['schema'], - ], - ], - ], - 'content' => $lang['strcreateviewwiz'], - ], - ]; - $misc->printNavLinks($navlinks, 'views-views', get_defined_vars()); - -} +$view_controller = new \PHPPgAdmin\Controller\ViewController($container); $misc->printHeader($lang['strviews']); $misc->printBody(); @@ -743,20 +17,20 @@ $misc->printBody(); switch ($action) { case 'selectrows': if (!isset($_REQUEST['cancel'])) { - doSelectRows(false); + $view_controller->doSelectRows(false); } else { - doDefault(); + $view_controller->doDefault(); } break; case 'confselectrows': - doSelectRows(true); + $view_controller->doSelectRows(true); break; case 'save_create_wiz': if (isset($_REQUEST['cancel'])) { - doDefault(); + $view_controller->doDefault(); } else { - doSaveCreateWiz(); + $view_controller->doSaveCreateWiz(); } break; @@ -765,17 +39,17 @@ switch ($action) { break; case 'set_params_create': if (isset($_POST['cancel'])) { - doDefault(); + $view_controller->doDefault(); } else { - doSetParamsCreate(); + $view_controller->doSetParamsCreate(); } break; case 'save_create': if (isset($_REQUEST['cancel'])) { - doDefault(); + $view_controller->doDefault(); } else { - doSaveCreate(); + $view_controller->doSaveCreate(); } break; @@ -784,17 +58,17 @@ switch ($action) { break; case 'drop': if (isset($_POST['drop'])) { - doDrop(false); + $view_controller->doDrop(false); } else { - doDefault(); + $view_controller->doDefault(); } break; case 'confirm_drop': - doDrop(true); + $view_controller->doDrop(true); break; default: - doDefault(); + $view_controller->doDefault(); break; } diff --git a/templates/home.twig b/templates/home.twig index 7e61a78d..ae3f8997 100644 --- a/templates/home.twig +++ b/templates/home.twig @@ -7,10 +7,10 @@ <frameset cols="{{cols}}"> {% if rtl == true %} - <frame src="/src/views/intro" name="detail" id="detail" frameborder="0" /> + <frame src="/src/views/intro.php" name="detail" id="detail" frameborder="0" /> <frame src="/tree/browser" name="browser" id="browser" frameborder="0" /> {% else %} <frame src="/tree/browser" name="browser" id="browser" frameborder="0" /> - <frame src="/src/views/intro" name="detail" id="detail" frameborder="0" /> {% endif %} + <frame src="/src/views/intro.php" name="detail" id="detail" frameborder="0" /> {% endif %} <noframes> |