diff --git a/composer.json b/composer.json index e49450cca..430f489dc 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ "@dev:lint:phpcs" ], "dev:lint:php": "parallel-lint --exclude vendor .", - "dev:lint:phpcs": "phpcs -d memory_limit=256M src/ autoload.php all_db.php all_db_export.php alter_db.php alter_role.php browser.php create_db.php create_role.php drop_db.php drop_role.php history.php history_clear.php history_delete.php history_download.php index.php intro.php login.php logout.php roles.php server-logout.php servers.php servers-tree.php sqledit.php", + "dev:lint:phpcs": "phpcs -d memory_limit=256M src/ autoload.php all_db.php all_db_export.php alter_db.php alter_role.php browser.php create_db.php create_role.php dbexport.php drop_db.php drop_role.php history.php history_clear.php history_delete.php history_download.php index.php intro.php login.php logout.php roles.php server-logout.php servers.php servers-tree.php sqledit.php", "dev:test": [ "@dev:test:acceptance" ], diff --git a/composer.lock b/composer.lock index e64011f72..cdb3a3956 100644 --- a/composer.lock +++ b/composer.lock @@ -288,16 +288,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.1", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "24dd4de28d2e3988b311751ac49e684d783e2345" + "reference": "58751048de17bae71c5aa0d13cb19d79bca26391" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345", - "reference": "24dd4de28d2e3988b311751ac49e684d783e2345", + "url": "https://api.github.com/repos/symfony/yaml/zipball/58751048de17bae71c5aa0d13cb19d79bca26391", + "reference": "58751048de17bae71c5aa0d13cb19d79bca26391", "shasum": "" }, "require": { @@ -340,7 +340,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.1" + "source": "https://github.com/symfony/yaml/tree/v7.4.6" }, "funding": [ { @@ -360,7 +360,7 @@ "type": "tidelift" } ], - "time": "2025-12-04T18:11:45+00:00" + "time": "2026-02-09T09:33:46+00:00" } ], "packages-dev": [ @@ -449,16 +449,16 @@ }, { "name": "captainhook/captainhook", - "version": "5.28.3", + "version": "5.28.5", "source": { "type": "git", "url": "https://github.com/captainhook-git/captainhook.git", - "reference": "5d35b249f3843ef36ead119f4347e649278ad6d8" + "reference": "2a7316bf4ba4c3b11b3544c063788622d3520ee1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/captainhook-git/captainhook/zipball/5d35b249f3843ef36ead119f4347e649278ad6d8", - "reference": "5d35b249f3843ef36ead119f4347e649278ad6d8", + "url": "https://api.github.com/repos/captainhook-git/captainhook/zipball/2a7316bf4ba4c3b11b3544c063788622d3520ee1", + "reference": "2a7316bf4ba4c3b11b3544c063788622d3520ee1", "shasum": "" }, "require": { @@ -521,7 +521,7 @@ ], "support": { "issues": "https://github.com/captainhook-git/captainhook/issues", - "source": "https://github.com/captainhook-git/captainhook/tree/5.28.3" + "source": "https://github.com/captainhook-git/captainhook/tree/5.28.5" }, "funding": [ { @@ -529,7 +529,7 @@ "type": "github" } ], - "time": "2026-02-16T14:08:58+00:00" + "time": "2026-02-28T08:59:22+00:00" }, { "name": "captainhook/hook-installer", @@ -5310,32 +5310,32 @@ }, { "name": "slevomat/coding-standard", - "version": "8.27.1", + "version": "8.28.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "29bdaee8b65e7ed2b8e702b01852edba8bae1769" + "reference": "0cd4b30cc1037eca54091c188d260d570e61770c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/29bdaee8b65e7ed2b8e702b01852edba8bae1769", - "reference": "29bdaee8b65e7ed2b8e702b01852edba8bae1769", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/0cd4b30cc1037eca54091c188d260d570e61770c", + "reference": "0cd4b30cc1037eca54091c188d260d570e61770c", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.2.0", "php": "^7.4 || ^8.0", - "phpstan/phpdoc-parser": "^2.3.1", + "phpstan/phpdoc-parser": "^2.3.2", "squizlabs/php_codesniffer": "^4.0.1" }, "require-dev": { - "phing/phing": "3.0.1|3.1.1", + "phing/phing": "3.0.1|3.1.2", "php-parallel-lint/php-parallel-lint": "1.4.0", - "phpstan/phpstan": "2.1.37", - "phpstan/phpstan-deprecation-rules": "2.0.3", - "phpstan/phpstan-phpunit": "2.0.12", - "phpstan/phpstan-strict-rules": "2.0.7", - "phpunit/phpunit": "9.6.31|10.5.60|11.4.4|11.5.49|12.5.7" + "phpstan/phpstan": "2.1.40", + "phpstan/phpstan-deprecation-rules": "2.0.4", + "phpstan/phpstan-phpunit": "2.0.16", + "phpstan/phpstan-strict-rules": "2.0.10", + "phpunit/phpunit": "9.6.34|10.5.63|11.4.4|11.5.50|12.5.14" }, "type": "phpcodesniffer-standard", "extra": { @@ -5359,7 +5359,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.27.1" + "source": "https://github.com/slevomat/coding-standard/tree/8.28.0" }, "funding": [ { @@ -5371,7 +5371,7 @@ "type": "tidelift" } ], - "time": "2026-01-25T15:57:07+00:00" + "time": "2026-02-23T21:35:24+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -5579,16 +5579,16 @@ }, { "name": "symfony/config", - "version": "v7.4.4", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "4275b53b8ab0cf37f48bf273dc2285c8178efdfb" + "reference": "9400e2f9226b3b64ebb0a8ae967ae84e54e39640" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/4275b53b8ab0cf37f48bf273dc2285c8178efdfb", - "reference": "4275b53b8ab0cf37f48bf273dc2285c8178efdfb", + "url": "https://api.github.com/repos/symfony/config/zipball/9400e2f9226b3b64ebb0a8ae967ae84e54e39640", + "reference": "9400e2f9226b3b64ebb0a8ae967ae84e54e39640", "shasum": "" }, "require": { @@ -5634,7 +5634,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.4" + "source": "https://github.com/symfony/config/tree/v7.4.6" }, "funding": [ { @@ -5654,20 +5654,20 @@ "type": "tidelift" } ], - "time": "2026-01-13T11:36:38+00:00" + "time": "2026-02-25T16:50:00+00:00" }, { "name": "symfony/console", - "version": "v7.4.4", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894" + "reference": "6d643a93b47398599124022eb24d97c153c12f27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894", - "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894", + "url": "https://api.github.com/repos/symfony/console/zipball/6d643a93b47398599124022eb24d97c153c12f27", + "reference": "6d643a93b47398599124022eb24d97c153c12f27", "shasum": "" }, "require": { @@ -5732,7 +5732,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.4" + "source": "https://github.com/symfony/console/tree/v7.4.6" }, "funding": [ { @@ -5752,20 +5752,20 @@ "type": "tidelift" } ], - "time": "2026-01-13T11:36:38+00:00" + "time": "2026-02-25T17:02:47+00:00" }, { "name": "symfony/css-selector", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135" + "reference": "2e7c52c647b406e2107dd867db424a4dbac91864" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/ab862f478513e7ca2fe9ec117a6f01a8da6e1135", - "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/2e7c52c647b406e2107dd867db424a4dbac91864", + "reference": "2e7c52c647b406e2107dd867db424a4dbac91864", "shasum": "" }, "require": { @@ -5801,7 +5801,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.0" + "source": "https://github.com/symfony/css-selector/tree/v7.4.6" }, "funding": [ { @@ -5821,20 +5821,20 @@ "type": "tidelift" } ], - "time": "2025-10-30T13:39:42+00:00" + "time": "2026-02-17T07:53:42+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.5", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "76a02cddca45a5254479ad68f9fa274ead0a7ef2" + "reference": "a3f7d594ca53a34a7d39ae683fbca09408b0c598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/76a02cddca45a5254479ad68f9fa274ead0a7ef2", - "reference": "76a02cddca45a5254479ad68f9fa274ead0a7ef2", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a3f7d594ca53a34a7d39ae683fbca09408b0c598", + "reference": "a3f7d594ca53a34a7d39ae683fbca09408b0c598", "shasum": "" }, "require": { @@ -5885,7 +5885,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.5" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.6" }, "funding": [ { @@ -5905,20 +5905,20 @@ "type": "tidelift" } ], - "time": "2026-01-27T16:16:02+00:00" + "time": "2026-02-25T16:50:00+00:00" }, { "name": "symfony/dom-crawler", - "version": "v7.4.4", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "71fd6a82fc357c8b5de22f78b228acfc43dee965" + "reference": "487ba8fa43da9a8e6503fe939b45ecd96875410e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/71fd6a82fc357c8b5de22f78b228acfc43dee965", - "reference": "71fd6a82fc357c8b5de22f78b228acfc43dee965", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/487ba8fa43da9a8e6503fe939b45ecd96875410e", + "reference": "487ba8fa43da9a8e6503fe939b45ecd96875410e", "shasum": "" }, "require": { @@ -5957,7 +5957,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.4.4" + "source": "https://github.com/symfony/dom-crawler/tree/v7.4.6" }, "funding": [ { @@ -5977,7 +5977,7 @@ "type": "tidelift" } ], - "time": "2026-01-05T08:47:25+00:00" + "time": "2026-02-17T07:53:42+00:00" }, { "name": "symfony/event-dispatcher", @@ -6142,16 +6142,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "d551b38811096d0be9c4691d406991b47c0c630a" + "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", - "reference": "d551b38811096d0be9c4691d406991b47c0c630a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3ebc794fa5315e59fd122561623c2e2e4280538e", + "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e", "shasum": "" }, "require": { @@ -6188,7 +6188,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.0" + "source": "https://github.com/symfony/filesystem/tree/v7.4.6" }, "funding": [ { @@ -6208,20 +6208,20 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-02-25T16:50:00+00:00" }, { "name": "symfony/finder", - "version": "v7.4.5", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb" + "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ad4daa7c38668dcb031e63bc99ea9bd42196a2cb", - "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb", + "url": "https://api.github.com/repos/symfony/finder/zipball/8655bf1076b7a3a346cb11413ffdabff50c7ffcf", + "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf", "shasum": "" }, "require": { @@ -6256,7 +6256,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.4.5" + "source": "https://github.com/symfony/finder/tree/v7.4.6" }, "funding": [ { @@ -6276,7 +6276,7 @@ "type": "tidelift" } ], - "time": "2026-01-26T15:07:59+00:00" + "time": "2026-01-29T09:40:50+00:00" }, { "name": "symfony/polyfill-intl-grapheme", @@ -6768,16 +6768,16 @@ }, { "name": "symfony/string", - "version": "v7.4.4", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f" + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/1c4b10461bf2ec27537b5f36105337262f5f5d6f", - "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f", + "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", "shasum": "" }, "require": { @@ -6835,7 +6835,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.4" + "source": "https://github.com/symfony/string/tree/v7.4.6" }, "funding": [ { @@ -6855,20 +6855,20 @@ "type": "tidelift" } ], - "time": "2026-01-12T10:54:30+00:00" + "time": "2026-02-09T09:33:46+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.4.4", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "0e4769b46a0c3c62390d124635ce59f66874b282" + "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e4769b46a0c3c62390d124635ce59f66874b282", - "reference": "0e4769b46a0c3c62390d124635ce59f66874b282", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/045321c440ac18347b136c63d2e9bf28a2dc0291", + "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291", "shasum": "" }, "require": { @@ -6922,7 +6922,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.4.4" + "source": "https://github.com/symfony/var-dumper/tree/v7.4.6" }, "funding": [ { @@ -6942,7 +6942,7 @@ "type": "tidelift" } ], - "time": "2026-01-01T22:13:48+00:00" + "time": "2026-02-15T10:53:20+00:00" }, { "name": "symfony/var-exporter", @@ -7175,5 +7175,5 @@ "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/dbexport.php b/dbexport.php index c854d88db..b10d2dae1 100644 --- a/dbexport.php +++ b/dbexport.php @@ -1,148 +1,10 @@ isDumpEnabled($dumpall)) { - $server_info = $misc->getServerInfo(); - - // Get the path of the pg_dump/pg_dumpall executable - $exe = $misc->escapeShellCmd($server_info[$dumpall ? 'pg_dumpall_path' : 'pg_dump_path']); - - // Obtain the pg_dump version number and check if the path is good - $version = array(); - preg_match("/(\d+(?:\.\d+)?)(?:\.\d+)?.*$/", exec($exe . " --version"), $version); - - if (empty($version)) { - if ($dumpall) { - printf($lang['strbadpgdumpallpath'], $server_info['pg_dumpall_path']); - } else { - printf($lang['strbadpgdumppath'], $server_info['pg_dump_path']); - } - exit; - } - - // Make it do a download, if necessary - switch ($_REQUEST['output']) { - case 'show': - header('Content-Type: text/plain'); - break; - case 'download': - // Set headers. MSIE is totally broken for SSL downloading, so - // we need to have it download in-place as plain text - if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) { - header('Content-Type: text/plain'); - } else { - header('Content-Type: application/download'); - header('Content-Disposition: attachment; filename=dump.sql'); - } - break; - case 'gzipped': - // MSIE in SSL mode cannot do this - it should never get to this point - header('Content-Type: application/download'); - header('Content-Disposition: attachment; filename=dump.sql.gz'); - break; - } - - // Set environmental variables that pg_dump uses - putenv('PGPASSWORD=' . $server_info['password']); - putenv('PGUSER=' . $server_info['username']); - $hostname = $server_info['host']; - if ($hostname !== null && $hostname != '') { - putenv('PGHOST=' . $hostname); - } - $port = $server_info['port']; - if ($port !== null && $port != '') { - putenv('PGPORT=' . $port); - } - - // Build command for executing pg_dump. - $cmd = $exe; - - // we are PG 7.4+, so we always have a schema - if (isset($_REQUEST['schema'])) { - $f_schema = $_REQUEST['schema']; - $f_schema = $data->fieldClean($f_schema); - } - - // Check for a specified table/view - switch ($_REQUEST['subject']) { - case 'schema': - // This currently works for 8.2+ (due to the orthoganl -t -n issue introduced then) - $cmd .= " -n " . $misc->escapeShellArg("\"{$f_schema}\""); - break; - case 'table': - case 'view': - $f_object = $_REQUEST[$_REQUEST['subject']]; - $f_object = $data->fieldClean($f_object); - - // Starting in 8.2, -n and -t are orthogonal, so we now schema qualify - // the table name in the -t argument and quote both identifiers - if (((float) $version[1]) >= 8.2) { - $cmd .= " -t " . $misc->escapeShellArg("\"{$f_schema}\".\"{$f_object}\""); - } else { - // If we are 7.4 or higher, assume they are using 7.4 pg_dump and - // set dump schema as well. Also, mixed case dumping has been fixed - // then.. - $cmd .= " -t " . $misc->escapeShellArg($f_object) - . " -n " . $misc->escapeShellArg($f_schema); - } - } - - // Check for GZIP compression specified - if ($_REQUEST['output'] == 'gzipped' && !$dumpall) { - $cmd .= " -Z 9"; - } - - switch ($_REQUEST['what']) { - case 'dataonly': - $cmd .= ' -a'; - if ($_REQUEST['d_format'] == 'sql') { - $cmd .= ' --inserts'; - } elseif (isset($_REQUEST['d_oids'])) { - $cmd .= ' -o'; - } - break; - case 'structureonly': - $cmd .= ' -s'; - if (isset($_REQUEST['s_clean'])) { - $cmd .= ' -c'; - } - break; - case 'structureanddata': - if ($_REQUEST['sd_format'] == 'sql') { - $cmd .= ' --inserts'; - } elseif (isset($_REQUEST['sd_oids'])) { - $cmd .= ' -o'; - } - if (isset($_REQUEST['sd_clean'])) { - $cmd .= ' -c'; - } - break; - } - - if (!$dumpall) { - putenv('PGDATABASE=' . $_REQUEST['database']); - } - - // Execute command and return the output to the screen - passthru($cmd); -} +$website = new DbExport(); +echo $website->buildHtmlString(); diff --git a/locale/ca_ES/LC_MESSAGES/messages.mo b/locale/ca_ES/LC_MESSAGES/messages.mo index 7514cf2bc..3b7fa8cfe 100644 Binary files a/locale/ca_ES/LC_MESSAGES/messages.mo and b/locale/ca_ES/LC_MESSAGES/messages.mo differ diff --git a/locale/ca_ES/LC_MESSAGES/messages.po b/locale/ca_ES/LC_MESSAGES/messages.po index 35cff7338..4c31b2084 100644 --- a/locale/ca_ES/LC_MESSAGES/messages.po +++ b/locale/ca_ES/LC_MESSAGES/messages.po @@ -540,10 +540,10 @@ msgstr "Intent de connexió amb un paràmetre del servidor invàlid, possiblemen msgid "strnoserversupplied" msgstr "No s'ha proporcionat cap servidor!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Error d'exportació: Fallada en l'execució de pg_dump (path definit a conf/config.inc.php : %s ). Sisplau, arregli el path en la configuració." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Error d'exportació: Fallada en l'execució de pg_dumpall (path definit a conf/config.inc.php : %s ). Sisplau, arregli el path en la configuració." msgid "strconnectionfail" diff --git a/locale/cs_CZ/LC_MESSAGES/messages.mo b/locale/cs_CZ/LC_MESSAGES/messages.mo index 4cb814ab8..54e58166d 100644 Binary files a/locale/cs_CZ/LC_MESSAGES/messages.mo and b/locale/cs_CZ/LC_MESSAGES/messages.mo differ diff --git a/locale/cs_CZ/LC_MESSAGES/messages.po b/locale/cs_CZ/LC_MESSAGES/messages.po index f1c120115..6f46c0643 100644 --- a/locale/cs_CZ/LC_MESSAGES/messages.po +++ b/locale/cs_CZ/LC_MESSAGES/messages.po @@ -540,10 +540,10 @@ msgstr "Pokus o připojení s neplatnými parametry serveru, možná se někdo s msgid "strnoserversupplied" msgstr "Není nabízen žádný server!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Chyba při exportu: Nezdařilo se spustit pg_dump (s cestou danou ve vašem conf/config.inc.php: %s). Opravte prosím cestu ve svém nastavení a zkuste to znovu." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Chyba při exportu: Nezdařilo se spustit pg_dumpall (s cestou danou ve vašem conf/config.inc.php: %s). Opravte prosím cestu ve svém nastavení a zkuste to znovu." msgid "strconnectionfail" diff --git a/locale/en_US/LC_MESSAGES/messages.mo b/locale/en_US/LC_MESSAGES/messages.mo index 3c49d9319..fb8888d0a 100644 Binary files a/locale/en_US/LC_MESSAGES/messages.mo and b/locale/en_US/LC_MESSAGES/messages.mo differ diff --git a/locale/en_US/LC_MESSAGES/messages.po b/locale/en_US/LC_MESSAGES/messages.po index 4d13a566d..5beb03c37 100644 --- a/locale/en_US/LC_MESSAGES/messages.po +++ b/locale/en_US/LC_MESSAGES/messages.po @@ -610,10 +610,12 @@ msgstr "Attempt to connect with invalid server parameter, possibly someone is tr msgid "strnoserversupplied" msgstr "No server supplied!" -msgid "strbadpgdumppath" +# original: "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." -msgid "strbadpgdumpallpath" +# original: "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgid "strconnectionfail" diff --git a/locale/es_ES/LC_MESSAGES/messages.mo b/locale/es_ES/LC_MESSAGES/messages.mo index 365fa4475..3a415ddb9 100644 Binary files a/locale/es_ES/LC_MESSAGES/messages.mo and b/locale/es_ES/LC_MESSAGES/messages.mo differ diff --git a/locale/es_ES/LC_MESSAGES/messages.po b/locale/es_ES/LC_MESSAGES/messages.po index d66ff0e35..056f9a902 100644 --- a/locale/es_ES/LC_MESSAGES/messages.po +++ b/locale/es_ES/LC_MESSAGES/messages.po @@ -543,10 +543,10 @@ msgstr "Intento de conexión al servidor con un parámetro inválido. Posiblemen msgid "strnoserversupplied" msgstr "No se suministró un servidor" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Error de exportación: Falló la ejecución de execute pg_dump (según la ruta dada en conf/config.inc.php : %s). Por favor, arregla esta ruta en tu configuración y vuelve a iniciar sesión." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Error de exportación: Falló la ejecución de pg_dumpall (según la ruta dada en conf/config.inc.php : %s). Por favor, arregla esta ruta en tu configuración y vuelve a iniciar sesión." msgid "strconnectionfail" diff --git a/locale/fr_FR/LC_MESSAGES/messages.mo b/locale/fr_FR/LC_MESSAGES/messages.mo index e277913ad..9f53e8497 100644 Binary files a/locale/fr_FR/LC_MESSAGES/messages.mo and b/locale/fr_FR/LC_MESSAGES/messages.mo differ diff --git a/locale/fr_FR/LC_MESSAGES/messages.po b/locale/fr_FR/LC_MESSAGES/messages.po index 07c03baa1..0df112f1a 100644 --- a/locale/fr_FR/LC_MESSAGES/messages.po +++ b/locale/fr_FR/LC_MESSAGES/messages.po @@ -549,10 +549,10 @@ msgstr "Tentative de connexion avec un serveur invalide, il est possible que que msgid "strnoserversupplied" msgstr "Aucun serveur fournis !" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Erreur d'export : n'a pu exécuter pg_dump (chemin indiqué dans votre conf/config.inc.php : %s). Merci de corriger le chemin dans votre configuration et de vous reconnecter." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Erreur d'export : n'a pu exécuter pg_dumpall (chemin indiqué dans votre conf/config.inc.php : %s). Merci de corriger le chemin dans votre configuration et de vous reconnecter." msgid "strconnectionfail" diff --git a/locale/gl_ES/LC_MESSAGES/messages.mo b/locale/gl_ES/LC_MESSAGES/messages.mo index bf6d2f1e8..60e6aa46b 100644 Binary files a/locale/gl_ES/LC_MESSAGES/messages.mo and b/locale/gl_ES/LC_MESSAGES/messages.mo differ diff --git a/locale/gl_ES/LC_MESSAGES/messages.po b/locale/gl_ES/LC_MESSAGES/messages.po index 383012cbd..f96672577 100644 --- a/locale/gl_ES/LC_MESSAGES/messages.po +++ b/locale/gl_ES/LC_MESSAGES/messages.po @@ -540,10 +540,10 @@ msgstr "Produciuse un intento de conexión cun servidor non permitido como pará msgid "strnoserversupplied" msgstr "Non se forneceu ningún servidor!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Produciuse un erro ao exportar: non se conseguiu executar pg_dump (a ruta indicada no seu ficheiro «conf/config.inc.php» é «%s»). Cambie a ruta no ficheiro de configuración e volva intentalo." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Produciuse un erro ao exportar: non se conseguiu executar pg_dumpall (a ruta indicada no seu ficheiro «conf/config.inc.php» é «%s»). Cambie a ruta no ficheiro de configuración e volva intentalo." msgid "strconnectionfail" diff --git a/locale/hu_HU/LC_MESSAGES/messages.mo b/locale/hu_HU/LC_MESSAGES/messages.mo index f20c57c69..98fade7b4 100644 Binary files a/locale/hu_HU/LC_MESSAGES/messages.mo and b/locale/hu_HU/LC_MESSAGES/messages.mo differ diff --git a/locale/hu_HU/LC_MESSAGES/messages.po b/locale/hu_HU/LC_MESSAGES/messages.po index 3a475dcdc..b3ea0db08 100644 --- a/locale/hu_HU/LC_MESSAGES/messages.po +++ b/locale/hu_HU/LC_MESSAGES/messages.po @@ -540,10 +540,10 @@ msgstr "Érvénytelen kiszolgáló paraméterrel próbáltak csatlakozni. Lehet, msgid "strnoserversupplied" msgstr "Nincs megadva kiszolgáló!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Kiviteli hiba: Elbukott a pg_dump végrehajtása (conf/config.inc.php fájlban megadott ösvény: %s). Kérem, javítsa ki ezt a beállításban, és ismételjen." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Kiviteli hiba: Elbukott a pg_dumpall végrehajtása (conf/config.inc.php fájlban megadott ösvény: %s). Kérem, javítsa ki ezt a beállításban, és ismételjen." msgid "strconnectionfail" diff --git a/locale/lt_LT/LC_MESSAGES/messages.mo b/locale/lt_LT/LC_MESSAGES/messages.mo index c133ddf2d..535a0d45a 100644 Binary files a/locale/lt_LT/LC_MESSAGES/messages.mo and b/locale/lt_LT/LC_MESSAGES/messages.mo differ diff --git a/locale/lt_LT/LC_MESSAGES/messages.po b/locale/lt_LT/LC_MESSAGES/messages.po index d363fdc9b..f24c7c6b1 100644 --- a/locale/lt_LT/LC_MESSAGES/messages.po +++ b/locale/lt_LT/LC_MESSAGES/messages.po @@ -555,10 +555,10 @@ msgstr "Bandymas prisijungti su negaliojančiu serverio parametru, galbūt kas n msgid "strnoserversupplied" msgstr "Nenurodytas serveris!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Eksportavimo klaida: nepavyko įvykdyti pg_dump (pateiktas kelias Jūsų conf/config.inc.php : %s). Pataisykite šį kelią savo konfigūracijoje ir prisijunkite iš naujo." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Eksportavimo klaida: nepavyko įvykdyti pg_dumpall (pateiktas kelias Jūsų conf/config.inc.php : %s). Pataisykite šį kelią savo konfigūracijoje ir prisijunkite iš naujo." msgid "strconnectionfail" diff --git a/locale/pt_BR/LC_MESSAGES/messages.mo b/locale/pt_BR/LC_MESSAGES/messages.mo index ffe9d4a43..73ce697a2 100644 Binary files a/locale/pt_BR/LC_MESSAGES/messages.mo and b/locale/pt_BR/LC_MESSAGES/messages.mo differ diff --git a/locale/pt_BR/LC_MESSAGES/messages.po b/locale/pt_BR/LC_MESSAGES/messages.po index 4f50d5048..00ad59621 100644 --- a/locale/pt_BR/LC_MESSAGES/messages.po +++ b/locale/pt_BR/LC_MESSAGES/messages.po @@ -537,10 +537,10 @@ msgstr "Tentativa de conectar com um parâmetro de servidor inválido, possivelm msgid "strnoserversupplied" msgstr "Nenhum servidor informado!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Erro de exportação: Falha ao executar pg_dump (caminho apontado no seu conf/config.inc.php : %s). Por favor, ajuste este diretório na sua configuração e relogue no sistema." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Erro de exportação: Falha ao executar pg_dumpall (caminho apontado no seu conf/config.inc.php : %s). Por favor, este diretório na sua configuração e relogue no sistema." msgid "strconnectionfail" diff --git a/locale/ru_RU/LC_MESSAGES/messages.mo b/locale/ru_RU/LC_MESSAGES/messages.mo index a316d5be3..25ebf5832 100644 Binary files a/locale/ru_RU/LC_MESSAGES/messages.mo and b/locale/ru_RU/LC_MESSAGES/messages.mo differ diff --git a/locale/ru_RU/LC_MESSAGES/messages.po b/locale/ru_RU/LC_MESSAGES/messages.po index 7a186822f..c317548ac 100644 --- a/locale/ru_RU/LC_MESSAGES/messages.po +++ b/locale/ru_RU/LC_MESSAGES/messages.po @@ -537,10 +537,10 @@ msgstr "Попытка соединения с некорректным знач msgid "strnoserversupplied" msgstr "Значение параметра \"сервер\" не представлено!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Ошибка экспорта: Невозможно выполнить pg_dump (указанный в conf/config.inc.php путь: %s). Пожалуйста, исправте этот путь в конфигурации и заново войдите в систему." -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "Ошибка экспорта: Невозможно выполнить pg_dumpall (указанный в conf/config.inc.php путь: %s). Пожалуйста, исправте этот путь в конфигурации и заново войдите в систему." msgid "strconnectionfail" diff --git a/locale/zh_CN/LC_MESSAGES/messages.mo b/locale/zh_CN/LC_MESSAGES/messages.mo index a08f63322..4a9a44df0 100644 Binary files a/locale/zh_CN/LC_MESSAGES/messages.mo and b/locale/zh_CN/LC_MESSAGES/messages.mo differ diff --git a/locale/zh_CN/LC_MESSAGES/messages.po b/locale/zh_CN/LC_MESSAGES/messages.po index c84994502..b0a49406c 100644 --- a/locale/zh_CN/LC_MESSAGES/messages.po +++ b/locale/zh_CN/LC_MESSAGES/messages.po @@ -540,10 +540,10 @@ msgstr "尝试用无效的服务器参数连接,可能有人正尝试攻击你 msgid "strnoserversupplied" msgstr "没有选择数据库!" -msgid "strbadpgdumppath" +msgid "Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "导出错误:在 conf/config.inc.php 中指定的路径 %s 下执行pg_dump失败。请在配置中修改路径并重新登录。" -msgid "strbadpgdumpallpath" +msgid "Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s). Please, fix this path in your configuration and relog." msgstr "导出错误:在 conf/config.inc.php 中指定的路径 %s 下执行pg_dumpall失败。请在配置中修改路径并重新登录。" msgid "strconnectionfail" diff --git a/phpcs.xml b/phpcs.xml index 8565ec375..f72953f6c 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -49,7 +49,7 @@ - + @@ -81,7 +81,14 @@ - + + + + + + + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 533b3968d..6ad539d4d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -11,6 +11,7 @@ parameters: - browser.php - create_db.php - create_role.php + - dbexport.php - drop_db.php - drop_role.php - history.php diff --git a/src/Application/Exceptions/FileNotFoundException.php b/src/Application/Exceptions/FileNotFoundException.php new file mode 100644 index 000000000..db4898ede --- /dev/null +++ b/src/Application/Exceptions/FileNotFoundException.php @@ -0,0 +1,9 @@ +id()) { + return $server; + } + } + + return null; + } + public static function leftWidth(): int { $conf = self::tryGetConfigFileData(); @@ -234,22 +250,6 @@ public static function locale(): string return self::$data['locale']; } - /** - * @param string $serverId Server ID in the format host:port:sslmode - */ - public static function getServerById(string $serverId): ?Server - { - $servers = self::getServers(); - - foreach ($servers as $server) { - if ($serverId === $server->id()) { - return $server; - } - } - - return null; - } - public static function ownedOnly(): bool { $conf = self::tryGetConfigFileData(); diff --git a/src/DDD/Entities/Server.php b/src/DDD/Entities/Server.php index e4bb5966f..0a90be47f 100644 --- a/src/DDD/Entities/Server.php +++ b/src/DDD/Entities/Server.php @@ -80,6 +80,28 @@ public static function fromArray(array $input): self ); } + public function tryGetPgDumpFilename(bool $all): ?Filename + { + $pgDumpFilename = $all + ? $this->PgDumpAllPath + : $this->PgDumpPath; + + if (!file_exists((string)$pgDumpFilename)) { + return null; + } + + $pregMatchResult = preg_match( + "/(\d+(?:\.\d+)?)(?:\.\d+)?.*$/", + exec($pgDumpFilename . " --version") ?: '', + ); + + if (!$pregMatchResult) { + return null; + } + + return $pgDumpFilename; + } + public function id(): string { return (string)$this->host . ':' . $this->port->Value . ':' . $this->sslMode->value; diff --git a/src/Website/DbExport.php b/src/Website/DbExport.php new file mode 100644 index 000000000..9f99bcdc4 --- /dev/null +++ b/src/Website/DbExport.php @@ -0,0 +1,217 @@ +handlePostRequest(); + } + } + + private function applyCompressSpecificCommandArguments(string $command, bool $dumpAll): string + { + $output = RequestParameter::getString('output') ?? ''; + + if ($output === 'gzipped' && !$dumpAll) { + $command .= " -Z 9"; + } + + return $command; + } + + private function applySubjectSpecificCommandArguments(string $command, string $subject): string + { + $schema = RequestParameter::getString('schema') ?? ''; + + if ($subject === 'schema') { + $command .= " -n " . escapeshellarg("\"{$schema}\""); + } elseif ($subject === 'table' || $subject === 'view') { + $object = RequestParameter::getString($subject); + $command .= " -t " . escapeshellarg("\"{$schema}\".\"{$object}\""); + } + + return $command; + } + + private function applyWhatSpecificCommandArguments(string $command): string + { + $what = RequestParameter::getString('what'); + + switch ($what) { + case 'dataonly': + $command .= ' -a'; + + $dFormat = RequestParameter::getString('d_format'); + $dOids = RequestParameter::getString('d_oids'); + + if ($dFormat === 'sql') { + $command .= ' --inserts'; + } elseif (isset($dOids)) { + $command .= ' -o'; + } + + break; + + case 'structureonly': + $command .= ' -s'; + + $sClean = RequestParameter::getString('s_clean'); + + if (isset($sClean)) { + $command .= ' -c'; + } + + break; + + case 'structureanddata': + $sdFormat = RequestParameter::getString('sd_format'); + $sdOids = RequestParameter::getString('sd_oids'); + $sdClean = RequestParameter::getString('sd_clean'); + + if ($sdFormat === 'sql') { + $command .= ' --inserts'; + } elseif (isset($sdOids)) { + $command .= ' -o'; + } + + if (isset($sdClean)) { + $command .= ' -c'; + } + + break; + + default: + break; + } + + return $command; + } + + private function buildCommand(): string + { + $subject = RequestParameter::getString('subject') ?? ''; + $dumpAll = ($subject === 'server'); + $dumpFilename = $this->ensurePgDumpFilenameExists($dumpAll); + + $command = escapeshellcmd((string)$dumpFilename); + $command = $this->applySubjectSpecificCommandArguments($command, $subject); + $command = $this->applyCompressSpecificCommandArguments($command, $dumpAll); + $command = $this->applyWhatSpecificCommandArguments($command); + + return $command; + } + + private function ensurePgDumpFilenameExists(bool $all): Filename + { + $serverId = RequestParameter::getString('server') ?? ''; + $server = Config::getServerById($serverId); + + if (is_null($server)) { + throw new ServerNotFoundException("No Server for server ($serverId) found."); + } + + $dumpFilename = $server->tryGetPgDumpFilename($all); + + if (is_null($dumpFilename)) { + $errorMessageFormat = _( + 'Export error: Failed to execute pg_dump (given path in your conf/config.inc.php : %s).' + . ' Please, fix this path in your configuration and relog.', + ); + + if ($all) { + $errorMessageFormat = _( + 'Export error: Failed to execute pg_dumpall (given path in your conf/config.inc.php : %s).' + . ' Please, fix this path in your configuration and relog.', + ); + } + + throw new FileNotFoundException(sprintf($errorMessageFormat, (string)$dumpFilename)); + } + + return $dumpFilename; + } + + private function handlePostRequest(): never + { + $this->setEnvironmentVariables(); + $this->setHttpHeaders(); + + passthru($this->buildCommand()); + die; + } + + private function setEnvironmentVariables(): void + { + $serverId = RequestParameter::getString('server') ?? ''; + $serverSession = ServerSession::fromServerId($serverId, Config::getServers()); + + if (is_null($serverSession)) { + throw new ServerSessionNotFoundException("No ServerSession for server ($serverId) found."); + } + + putenv('PGPASSWORD=' . $serverSession->Password); + putenv('PGUSER=' . $serverSession->Username); + putenv('PGPORT=' . $serverSession->Port->Value); + + $host = (string)$serverSession->Host; + + if ($host !== '') { + putenv('PGHOST=' . $host); + } + + $subject = RequestParameter::getString('subject') ?? ''; + $dumpAll = ($subject === 'server'); + + if ($dumpAll) { + return; + } + + $database = RequestParameter::getString('database') ?? ''; + putenv('PGDATABASE=' . $database); + } + + private function setHttpHeaders(): void + { + if (headers_sent()) { + return; + } + + $output = RequestParameter::getString('output') ?? ''; + + $contentType = match ($output) { + 'download' => 'application/download', + 'gzipped' => 'application/download', + 'show' => 'text/plain', + default => 'text/plain', + }; + $contentDisposition = match ($output) { + 'download' => 'attachment; filename=dump.sql', + 'gzipped' => 'attachment; filename=dump.sql.gz', + default => '', + }; + + header("Content-Type: $contentType"); + + if ($contentDisposition !== '') { + header("Content-Disposition: $contentDisposition"); + } + } +}