Compare commits

...

353 Commits

Author SHA1 Message Date
10b20c0745 Merge pull request #944 from cytopia/release/v3.0.0-beta-0.3
Release/v3.0.0 beta 0.3
2023-01-03 01:32:23 +01:00
1c2143095a Update PHP modules 2023-01-02 23:31:26 +01:00
22ed5edc4e Intranet: be more clear about watcherd restart 2023-01-02 23:29:02 +01:00
9d23981173 Pin PHP image 2023-01-02 23:28:45 +01:00
6fa4d4a386 Refs #919 Added host.docker.internal to connect to host system 2023-01-02 12:40:26 +01:00
51a127dda3 Update PHP image 2023-01-02 11:29:40 +01:00
76c6467806 Docs: Update available PHP exts 2023-01-02 00:33:09 +01:00
617241ce42 Fixup README 2023-01-01 15:19:26 +01:00
2fa1641bc2 Fix shellcheck 2023-01-01 15:17:49 +01:00
de8d40822c Adjust Readme 2023-01-01 14:37:28 +01:00
b773fcd1b7 Adjust tests 2022-12-31 09:18:02 +01:00
7c461870f0 Remove obsolete entries 2022-12-31 08:55:40 +01:00
ecb674f859 Update CHANGELOG 2022-12-31 08:19:41 +01:00
8e39202fc9 Update HTTPD server 2022-12-31 08:19:29 +01:00
8c81bcc1a1 Fix TLD_SUFFIX section in env_example 2022-12-31 07:05:23 +01:00
8a1a720e8c Show PHP 8.3 link in support section 2022-12-31 07:01:12 +01:00
fb173e0ed6 Intranet vhost: vhost table width jumping 2022-12-31 06:58:37 +01:00
9f54138567 Intranet index: vhost table width jumping 2022-12-31 06:52:23 +01:00
364f4aa3a6 Syntax highlighting for httpd configs 2022-12-31 06:47:59 +01:00
c7c2b4f2cb Update CHANGELOG 2022-12-31 06:05:51 +01:00
0b561dfdd2 Intranet: Show wscat version 2022-12-31 06:05:19 +01:00
794e3d8961 Intranet vhosts.php b64 encode modal html targets 2022-12-31 05:56:07 +01:00
a84e18be67 Use TLD_SUFFIX=dvl.to which always points to 127.0.0.1 2022-12-31 05:44:25 +01:00
894706ab09 Docs: Show available tools per version in README.md 2022-12-31 05:26:31 +01:00
448054bece Intranet: vhost overview now shows listening ports 2022-12-31 05:23:49 +01:00
e18bfd3f4f Intranet: vhosts.php Use modals to show config 2022-12-31 05:20:32 +01:00
d1894b3eb2 Refs #798 Added ctype_xdigit check around hexdec 2022-12-31 03:33:09 +01:00
7f3b45b387 Update REAMDE 2022-12-30 14:21:39 +01:00
81c9bb0a93 Merge pull request #943 from cytopia/release/v3.0.0-beta-0.2
Release/v3.0.0 beta 0.2
2022-12-27 15:28:16 +01:00
cb07f319de Pin HTTPD server 2022-12-27 13:00:21 +01:00
cca1744145 Bump version date 2022-12-27 12:52:19 +01:00
9fc97586e6 Intranet: show local daemons if netstat is available 2022-12-27 12:28:42 +01:00
2db5ffff6b Pin PHP versions 2022-12-27 12:26:47 +01:00
0dc1b9cafb Intranet: Make vhost page less jumpy 2022-12-27 12:24:28 +01:00
b05f4240f3 Update vhost-gen templates 2022-12-27 02:58:40 +01:00
e18e923d87 Update Changelog 2022-12-26 23:01:57 +01:00
c6e1192429 Disable linkcheck2, works locally, breaks on CI 2022-12-26 23:01:34 +01:00
634b9af7e5 Intranet vhost page: accept HTTP 426 for project gathering 2022-12-26 22:59:13 +01:00
a1fa5724e8 Update vhost-gen templates 2022-12-26 16:03:05 +01:00
a786eb64b0 Update CHANGELOG 2022-12-26 14:51:25 +01:00
01d2f4afed Remove autostart mounts from compose override php images 2022-12-26 14:51:03 +01:00
873abc6c4c Update docker images 2022-12-26 14:50:37 +01:00
1ba3cd399c Intranet: Reverse Proxy/Websockets do not need a htdocs directory 2022-12-26 14:13:36 +01:00
299b765652 Websock: Allow HTTP 426 for DNS check (Upgrade) 2022-12-26 14:13:01 +01:00
6819619d8a Merge pull request #942 from cytopia/release/v3.0.0-beta-0.1
🎅🎄🎁
2022-12-25 20:42:06 +01:00
3ffb360c51 Update check-config.sh 2022-12-25 18:41:26 +01:00
025b45c48c Fix IPv6 handling 2022-12-25 18:11:25 +01:00
10571f7b51 Intranet: Show backend type on vhost page 2022-12-25 18:06:35 +01:00
ffba5d61b7 Remove obsolete mod/ directory 2022-12-25 17:40:02 +01:00
200f6ce0b1 Fix volume paths in php-multi compose files 2022-12-25 17:38:40 +01:00
8b0788b403 Add PHP version number to README files in cfg/ dir 2022-12-25 17:37:58 +01:00
dfda00d78a Pinned HTTPD images 2022-12-25 16:48:46 +01:00
98f05d7570 Updated UPDATING.md 2022-12-25 16:48:32 +01:00
a560926315 Removed obsolete supervisorctl config section 2022-12-25 16:48:15 +01:00
e60aa4e465 Remove obsolete points from README 2022-12-25 15:59:57 +01:00
d5858da3e0 Fix indentation 2022-12-25 15:42:10 +01:00
c64c4553d7 Remove obsolete mounts from docker-compose 2022-12-25 15:41:21 +01:00
55f0447ce1 Add some colored output for logs in C&C 2022-12-25 15:40:45 +01:00
0e3b963df2 Do not rely on external supervisord.conf for C&C web interface 2022-12-24 13:28:51 +01:00
0964c7bdd9 Fix hostnames in CHANGELOG 2022-12-24 13:01:58 +01:00
3b1c0b25a5 docs: fix bind links 2022-12-23 23:03:13 +01:00
32c7beda22 Fix magento install guide links 2022-12-23 22:56:36 +01:00
794bf0c27c Atom no longer available 2022-12-23 22:52:56 +01:00
e51f34c1ae Fix wrong link in docs 2022-12-23 22:28:43 +01:00
6b80453b92 Docs announce 2022-12-23 21:42:45 +01:00
6fa03e6961 Fix env var names in docs 2022-12-23 21:07:34 +01:00
e3b7c2d4db Adjust check-config.sh 2022-12-23 20:01:44 +01:00
2b4bf59a40 Add missing mariadb config directories 2022-12-23 19:59:14 +01:00
ee5988507e Update CHANGELOG 2022-12-23 19:45:20 +01:00
d354d84165 Update intranet and docker-compose 2022-12-23 19:37:50 +01:00
f2c0372618 Update DNS server to latest version 2022-12-23 19:36:10 +01:00
a35216fdfb Add Docker Compose Override File for Multi PHP versions 2022-12-23 19:35:54 +01:00
2828e837d9 Merge pull request #910 from minhchu/support-meilisearch
Add support for meilisearch
2022-12-20 10:46:40 +01:00
685e09f76b Merge branch 'master' into support-meilisearch 2022-12-20 00:03:23 +01:00
04c0e27ebf Merge pull request #920 from Cleancookie/master
shell.sh to fall back to docker compose (no dash)
2022-12-20 00:02:56 +01:00
7645068258 Merge branch 'master' into master 2022-12-18 23:31:03 +01:00
b5566c1c52 Merge pull request #941 from cytopia/release/v2.4.0
Release/v2.4.0
2022-12-18 22:56:34 +01:00
826859a1cd Merge branch 'master' into release/v2.4.0 2022-12-18 18:00:44 +01:00
71064a7296 Update CHANGELOG 2022-12-18 15:50:47 +01:00
f2088d63a7 Disable Drupal test due to removed drush 2022-12-18 15:49:28 +01:00
8b70a01a16 Update CHANGELOG and version 2022-12-18 15:05:54 +01:00
a5f28e80c3 Switching to Discord 2022-12-18 14:45:40 +01:00
48e7133825 Intranet: Improved installed tools overview 2022-12-18 14:38:19 +01:00
2e33d991b7 Fixed PostgreSQL database overview in intranet 2022-12-18 14:37:05 +01:00
8227605036 Refs #940, #936, #934, #930 Update PHP versions 2022-12-18 14:35:51 +01:00
565a5c7427 Updated MySQL versions 2022-12-18 14:34:12 +01:00
eb5ecc836c Merge branch 'cytopia:master' into support-meilisearch 2022-12-16 11:59:28 +07:00
c165fd2ba0 Merge pull request #904 from mmcev106/large-email-support
Delayed message body loading
2022-12-13 10:35:28 +01:00
d2d1ddfb63 PHP 5.3 fix 2022-12-12 13:54:33 -06:00
f7c58ddbc4 Fixed email unit test 2022-12-12 10:38:31 -06:00
8bde34caaf Merge branch 'master' into master 2022-12-11 14:20:50 +01:00
441adbb66d Merge branch 'master' into support-meilisearch 2022-12-11 14:14:50 +01:00
b5a6c0e6ad Merge branch 'master' into large-email-support 2022-12-11 06:24:22 +01:00
ca56dff442 Merge pull request #935 from cytopia/release/v2.3.0
WIP: Release v2.3.0
2022-12-04 13:31:13 +01:00
7c941000c8 Updated CHANGELOG 2022-12-04 11:17:51 +01:00
dbfd086227 Use latest docker-mysql images 2022-12-04 11:15:36 +01:00
895558209e Adjusted release date 2022-12-04 10:56:50 +01:00
b6512388d7 Added recent MariaDB, Redis and PGSQL versions 2022-12-04 10:56:07 +01:00
5cce2a8a89 Make phpPgAdmin work with PgSQL 15 2022-12-04 10:38:28 +01:00
b00b1e77b9 Disable CakePHP integration tests 2022-12-04 04:42:43 +01:00
f2cca91dd1 Update CHANGELOG 2022-12-02 15:37:57 +01:00
b600f9866a Update docker-compose 2022-12-02 15:37:57 +01:00
aae28e7d6d Update CHANGELOG and version 2022-12-02 15:37:56 +01:00
fe59793304 Fix script to fetch PHP modules 2022-12-02 15:37:56 +01:00
e8a6fe51e7 shell.sh now falls back to docker compose (no dash) 2022-11-30 13:57:58 +00:00
c5da81b83b Merge pull request #931 from alexaandrov/fix-rabbit-docs
Fix rabbit container name typo in docs
2022-11-19 15:13:34 +01:00
503667a8da Fix rabbit container name typo in docs 2022-11-12 23:33:57 +03:00
315fb9e3c4 Merge pull request #927 from kenjis/add-setup-codeigniter4
docs: add "Setup CodeIgniter4"
2022-10-28 13:52:33 +02:00
fc28e32b0c Add "Setup CodeIgniter4" 2022-10-26 20:50:27 +09:00
180eac149b Merge pull request #926 from boodaah71/patch-1
fix typo
2022-10-21 13:41:01 +02:00
dfb6eaec69 Merge branch 'master' into patch-1 2022-10-21 13:40:54 +02:00
248cf5ba5f Merge pull request #928 from kenjis/fix-docs-setup-codeigniter
docs: fix CodeIgniter3 docs link
2022-10-21 13:40:27 +02:00
07df58f13a Merge branch 'master' into fix-docs-setup-codeigniter 2022-10-21 13:40:15 +02:00
3bffa62456 Merge pull request #925 from vikas5914/patch-1
Fix: Using ${var} in strings is deprecated, use {$var} instead
2022-10-21 13:38:47 +02:00
59205dc888 docs: fix CodeIgniter3 docs link 2022-10-19 13:32:12 +09:00
63437650ee fix typo
The word 'than' is used for comparisons. The word 'then' is used for sequence of events.
2022-10-18 13:00:50 -04:00
a11419e82e Fix: Using ${var} in strings is deprecated, use {$var} instead 2022-10-13 22:44:48 +05:30
fb64b0bd31 Add docs for Meilisearch 2022-08-01 00:29:03 +07:00
12e613188e Add support for meilisearch 2022-07-31 01:06:13 +07:00
234bdd6419 Delayed message body loading 2022-06-20 15:13:20 -05:00
6a04527456 Merge pull request #902 from rafaelstz/patch-1
Fixing Magento 2 doc link
2022-06-02 10:44:54 +02:00
0bb019b8a8 Fixing Magento 2 doc link 2022-06-01 15:20:59 -04:00
d3492e4acc Merge pull request #897 from ahberg/master
Add custom vhost-gen yml files into gitignore
2022-05-13 17:59:36 +02:00
4418b305de Add custom vhost-gen .yml files to .gitignore 2022-05-13 17:28:10 +02:00
933a1c65e1 Merge pull request #896 from cytopia/cytopia-patch-1
Update bug_report.yml
2022-05-02 10:03:52 +02:00
cabb7b07aa Update bug_report.yml 2022-05-02 10:02:23 +02:00
97751fad37 Merge pull request #893 from jakeparis/master
Add docs about .local on MacOS
2022-04-24 10:23:14 +02:00
81d896fa93 Fix whitespace 2022-04-22 10:02:17 -04:00
270cb45726 Updated docs about .local on MacOS
See #892
2022-04-22 09:59:57 -04:00
26cbb63f00 Merge pull request #891 from cytopia/release/v2.2.0
Devilbox Release v2.2.0
2022-04-14 18:02:52 +02:00
daefd0f927 Add announcement in docs 2022-04-14 12:05:39 +02:00
44d1f0162f Add PHP-FPM community image to intranet credits 2022-04-14 11:42:07 +02:00
59619ca9c1 Update project files 2022-04-14 11:29:13 +02:00
a6c45353bd Adding PHP-FPM community images 2022-04-14 11:28:54 +02:00
575782af55 Merge pull request #890 from cytopia/release/v2.1.1
Release v2.1.1
2022-04-08 10:48:44 +02:00
56d2ab39b4 Used tagged PHP images (auto-updating)instead early release branch one 2022-04-07 22:05:20 +02:00
c29741d119 Merge pull request #889 from cytopia/release/v2.1.0
Release v2.1.0
2022-04-06 09:29:14 +02:00
6e2f6ca181 Use intermediate images 2022-04-05 23:15:12 +02:00
7e85b8e609 Update project files 2022-04-05 23:15:01 +02:00
02f6876a21 Make Devilbox arm64 compatible 2022-04-03 13:39:56 +02:00
a5396c2213 Merge pull request #888 from cytopia/issue-bug-report
fine-tune bug report
2022-04-01 06:22:08 +02:00
eb9cb0254f fine-tune bug report 2022-04-01 06:21:44 +02:00
f054b22957 Merge pull request #887 from cytopia/bug-report
Refine bug report
2022-04-01 06:16:50 +02:00
aed9a96dfc Refine bug report 2022-04-01 06:16:34 +02:00
7a13143b4f Merge pull request #886 from cytopia/issue-template-bug
Adjust templates
2022-04-01 06:04:11 +02:00
887202db65 Adjust templates 2022-04-01 06:03:53 +02:00
4fb67be0bd Merge pull request #885 from cytopia/fix-templates
Enhance issue templates
2022-04-01 05:48:27 +02:00
14bba0a140 Enhance issue templates 2022-04-01 05:47:58 +02:00
6c2b42cbc7 Merge pull request #884 from cytopia/github-issues
Adjust issue templates
2022-04-01 05:20:25 +02:00
19619394e3 Adjust issue templates 2022-04-01 05:19:42 +02:00
66fe7e355d Merge pull request #883 from cytopia/repository-organization
Repository organization
2022-04-01 05:04:03 +02:00
ec1e5861ce Add new GitHub issue templates 2022-04-01 05:02:23 +02:00
fb48e5e85a Ensure to run CI tests only for specific purposes 2022-04-01 05:01:29 +02:00
49190e4c36 Merge pull request #881 from MrCrayon/master
Add note about MDEV-27937 MariaDB bug
2022-04-01 02:07:44 +02:00
c3da7facb4 Update docs/support/troubleshooting.rst 2022-03-31 12:39:38 +02:00
d375244920 Add note about MDEV-27937 MariaDB bug
I prefer to write code than documentation and I am not native speaker so feel free to suggest or make changes.

https://jira.mariadb.org/browse/MDEV-27937

Closes #870
2022-03-31 05:34:52 +02:00
1b5522b6fa Merge branch 'master' of https://github.com/MrCrayon/devilbox 2022-03-31 05:32:52 +02:00
68541d76ad Merge pull request #880 from cytopia/release/v2.0.0
Release/v2.0.0
2022-03-28 20:44:37 +02:00
96610c756b Update project files 2022-03-28 17:13:11 +02:00
7799740525 Added .env variable HTTPD_FLAVOUR to decide between Debian or Alpine for HTTP server 2022-03-28 17:10:51 +02:00
8e8991896a Remove failing services in CI 2022-03-28 17:10:50 +02:00
cbdabb2f97 Add exceptions for PHP CI to use older PGSQL versions 2022-03-28 17:10:50 +02:00
d45a336d65 Removed CI for MongoDB 2.8 and MongoDB 3.0 due to segfault 2022-03-28 17:10:50 +02:00
49b919534a Give more startup-time for CI tests 2022-03-28 17:10:49 +02:00
0159d2a60b Ensure CI tests run on bash shell 2022-03-28 17:10:49 +02:00
ac07995595 Adjust version according to breaking changes 2022-03-28 17:10:48 +02:00
4f0542b756 Add breaking changes info to CHANGELOG 2022-03-28 17:10:48 +02:00
052be908aa Add new CI status badges 2022-03-28 17:10:47 +02:00
a714821dea Use tiny Alpine version of Bind container 2022-03-28 17:10:47 +02:00
579ae15bcc Add exceptions for PHP CI to use older PGSQL versions 2022-03-28 17:10:46 +02:00
f632cc247f Fix Release version in CHANELOG 2022-03-28 17:10:46 +02:00
fbef67daac Rename workflows 2022-03-28 17:10:46 +02:00
a5e0a54c5f Reorganize integration tests 2022-03-28 17:10:45 +02:00
71c73f7fb3 Test re-usable workflows 2022-03-28 17:10:36 +02:00
52689f435a Colorize test outputs 2022-03-28 17:10:35 +02:00
3678a6799c Fix PGSQL versions in CI 2022-03-28 17:10:34 +02:00
014d9103db Added CakePHP integration tests for PHP 8+ 2022-03-28 17:10:33 +02:00
6acac7d8de Fix CI script to detect PHP version 2022-03-28 17:10:33 +02:00
9ac4b7399f Fix postgresql volume definitions 2022-03-28 17:10:33 +02:00
e3dfa7cc09 Bump version 2022-03-28 17:10:32 +02:00
6c03253313 Changed default server versions to have arm64 support 2022-03-28 17:10:32 +02:00
19a65b3da4 Merge pull request #877 from discorgento/fix/DOCS-xdebug3
Fix/docs xdebug3
2022-03-27 04:42:27 +02:00
95a0109004 DOCS-xdebug3 vscode linux config 2022-03-24 18:39:20 -03:00
0c26a6c319 Merge pull request #1 from cytopia/master
update
2022-03-24 13:50:28 -03:00
ad66ef3dc5 Merge pull request #871 from cytopia/release/v1.11.0
Release/v1.11.0
2022-03-22 21:46:18 +01:00
907d6797ca Re-enable testing wordpress for PHP 8.0 and PHP 8.1 2022-03-22 15:17:20 +01:00
708253ebd9 Add support section 2022-03-22 15:16:31 +01:00
fe3c90f117 Fixes #867 Adminer 4.8.1 CSS issues 2022-03-22 10:54:08 +01:00
8666ca68bc Fix CI test output for Adminer Mongo 2022-03-22 10:51:01 +01:00
91da7d3f5b Refs #837 Update phpmyadmin to 5.1.3 2022-03-22 10:26:48 +01:00
5804546be4 Fix shellcheck errors for CI tests 2022-03-22 09:23:40 +01:00
39aae0501c Add MariaDB 10.8 to CI tests 2022-03-22 01:40:51 +01:00
eadafcf6ba Updated project files 2022-03-22 01:33:13 +01:00
7f3d37e606 Updated bind image 2022-03-22 01:26:05 +01:00
c87f18fe78 Update PHP-FPM images 2022-03-22 01:25:18 +01:00
d4b0be9ac4 Be more verbose during test startup 2022-03-18 15:00:45 +01:00
218ed79e14 Fixed array definition for PHP < 5.4 2022-03-18 15:00:04 +01:00
6a98ee4109 Update project files 2022-03-18 14:04:02 +01:00
d6337ccb51 #844 Update docs for HTTP/2 settings 2022-03-18 13:24:37 +01:00
4945ca2ccd Update README 2022-03-18 13:13:45 +01:00
ace31c89ed Fixes #854 pidof issue for rsyslog on arm64 2022-03-18 13:12:20 +01:00
81d2f7d02b Fixes #844 Allow to globally enable/disable HTTP/2 2022-03-18 13:10:12 +01:00
1bb408f16b Make PHP 8.1 the default 2022-03-18 13:09:25 +01:00
c3f213b779 Merge tag 'v1.10.5' of https://github.com/cytopia/devilbox
Release v1.10.5
2022-03-17 04:25:24 +01:00
4e10d85de6 Make MariaDB 10.6 the default 2022-03-16 17:31:02 +01:00
349fa0ec73 Merge pull request #869 from cytopia/release/v1.10.5
Release/v1.10.5
2022-03-16 16:40:25 +01:00
4b3cc3f1e8 Update project files 2022-03-16 14:33:13 +01:00
be73b353eb Use updated version of mysql 2022-03-16 14:31:16 +01:00
a45748e1aa Use updated version of bind 2022-03-16 14:27:57 +01:00
31103f0040 Merge pull request #865 from cytopia/release/v1.10.4
Release v1.10.4
2022-02-15 16:11:49 +01:00
bdad47617c Adjust CI email test 2022-02-15 12:25:28 +01:00
52a42623bb Updated CHANGELOG 2022-02-15 12:10:04 +01:00
75f1d7f471 Made vhost error message more verbose 2022-02-15 12:09:20 +01:00
03eb46da99 Changed Intranet mail tester to using POST instead of GET for larger body size 2022-02-15 12:08:27 +01:00
dd85f5b1bb Fixed SSL-Cache Mutex on M1 CPU 2022-02-15 12:06:52 +01:00
fca58c22c6 Merge pull request #864 from cytopia/release/v1.10.3
Release v1.10.3
2022-02-04 19:13:08 +01:00
830549a905 Update README 2022-02-04 12:47:03 +01:00
015d66052e Adjust CHANGELOG 2022-02-04 11:05:05 +01:00
82a1d7c881 Adjust release date 2022-02-04 11:04:02 +01:00
7d346463c7 Adjust smoke tests 2022-02-04 11:03:00 +01:00
ae780388dc Update PHP images 2022-02-03 20:34:01 +01:00
422af8e916 Added missing mariadb entries into gitignore 2022-02-03 10:16:11 +01:00
3d3f716121 Added PHP 8.2 2022-02-03 10:15:54 +01:00
928d5a2475 Updated get-modules tests 2022-02-03 10:01:56 +01:00
9b37e3a307 Updated project files 2022-02-03 10:01:28 +01:00
682eaf82ee Merge pull request #863 from cytopia/release/v1.10.2
Release v1.10.2
2022-02-02 18:57:11 +01:00
38b96b7a08 Updated project files 2022-02-02 11:41:20 +01:00
94bf3c9dcf Updated PHP images 2022-02-02 11:40:50 +01:00
9272bfec92 Merge pull request #861 from cytopia/release/v1.10.1
Release v1.10.1
2022-01-30 20:20:53 +01:00
d57e72bc75 Update project files 2022-01-30 14:28:50 +01:00
bbc6a661ed Fixes #754 Be able to delete emails from control center 2022-01-30 14:27:08 +01:00
2ea5ff59e0 Fxies #830 Evaluate MASS_VHOST_SSL_GEN env var 2022-01-30 13:59:43 +01:00
ba6fd1e554 Merge pull request #860 from cytopia/release/v1.10.0
Release v1.10.0
2022-01-28 08:36:08 +01:00
fe67bdf6bb Harden CI tests 2022-01-27 17:30:00 +01:00
4a9c0b6d9f Update HTTPD images 2022-01-27 14:49:57 +01:00
855d98d895 Add Docker volumes for MariaDB 10.6 and 10.7 2022-01-27 12:37:47 +01:00
01b0ecdf20 Fixes #807 description in env-example 2022-01-27 08:41:55 +01:00
fe9e6264d9 Update PHP modules in README 2022-01-27 08:30:41 +01:00
55bb37c53b Update project files 2022-01-27 08:23:19 +01:00
a6894b7793 Add MariaDB conf anbd log dirs 2022-01-27 08:21:44 +01:00
0daa62cc02 Update comment about PHP 8.0 and 8.1 stability 2022-01-27 08:17:32 +01:00
38942fa168 Added MariaDB 10.6 and MariaDB 10.7 2022-01-27 08:15:46 +01:00
a0246b7a0e Update HTTPD images 2022-01-27 08:11:28 +01:00
b17f4600f4 Update PHP images 2022-01-27 08:11:12 +01:00
5f465abd61 Merge pull request #851 from felixmosh/fix-850
fix: show utf-8 mail body properly
2022-01-26 12:08:04 +01:00
61246b5151 Merge branch 'master' into fix-850 2022-01-26 10:01:31 +01:00
ca90af0fb0 Merge pull request #859 from cytopia/release/v1.9.3
Release v1.9.3
2022-01-25 20:14:49 +01:00
7bd6b34698 Update project files 2022-01-25 10:06:22 +01:00
2677422250 Update PHP images 2022-01-24 19:29:54 +01:00
200000cb5b Ensure documentation passes CI checks 2022-01-24 15:23:41 +01:00
8560267fdc Update MySQL Docker Images 2022-01-24 14:39:10 +01:00
8c13144d3e Update available PHP modules 2022-01-24 09:27:31 +01:00
2f8fc59dd9 Ensure PHP code is compatible to legacy versions 2022-01-24 09:15:52 +01:00
d9fb88058f Updated PHP Docker Images to 0.129 2022-01-24 08:39:23 +01:00
4c15e191a0 Merge branch 'master' into fix-850 2022-01-23 13:36:19 +01:00
249b132e58 Merge pull request #832 from Ernestopheles/patch-1
Update setup-auto-dns.rst
2022-01-23 13:35:44 +01:00
6e34d3b263 Merge pull request #843 from ericvanjohnson/patch-1
Update add-project-dns-entry-on-win.rst (grammar correction)
2022-01-23 13:33:17 +01:00
68bd88d304 Merge branch 'master' into patch-1 2022-01-23 13:32:39 +01:00
bfb4769e85 fix: show utf-8 mail body properly 2021-11-07 15:56:54 +02:00
23a6aed10d Merge pull request #817 from ulin-evgeny/patch
Fixed typos
2021-10-15 11:48:42 +02:00
0dfd63d7f9 Merge branch 'master' into patch 2021-10-15 11:48:31 +02:00
3804a3b6f3 Merge pull request #842 from ericp-mrel/fix-redis-args-parsing
Fix redis args parsing for password
2021-10-15 11:47:49 +02:00
9cfc69e5bb Update add-project-dns-entry-on-win.rst 2021-10-13 04:48:52 -07:00
56555e87a5 Adjust redis args regex to allow optional quotes. 2021-10-12 10:44:44 -05:00
5e90a3a35d Use preg_match_all to get redis password from args
This should fix the issue where preg_split was being used and would cause an error if the redis args variable didn't contain the --requirepass string and the WebGUI wouldn't load as a result.
2021-10-12 09:42:04 -05:00
54e17f5ec5 Update setup-auto-dns.rst
For me it has been unclear if prot 53 may not be in use in cobination to 127.0.0.1 or generally.
2021-08-24 17:48:52 +02:00
b5d19264de Fixed typos 2021-06-20 05:07:19 +03:00
f6bbdc72fd Merge pull request #814 from cytopia/release/v1.9.2
Release v1.9.2
2021-06-04 13:06:36 +02:00
2f9ba2e30a Release v1.9.2 2021-06-04 10:32:46 +02:00
fa0c8f5632 Merge pull request #787 from merlijnvanlent/master
Ability to view emails within the intranet dashboard.
2021-05-21 15:31:13 +02:00
64330b5b12 Merge branch 'master' into master 2021-05-21 10:50:26 +02:00
872340e14b Merge pull request #806 from Agnohendrix/patch-1
XDebug 3.0 Linux Docs
2021-05-21 10:48:21 +02:00
5eb2ee8ca0 Merge branch 'master' into master 2021-05-20 16:28:02 +02:00
aff86a6b15 Merge branch 'master' into patch-1 2021-05-20 15:48:25 +02:00
fb51eece98 Merge pull request #777 from cytopia/release/v1.9.1
Devilbox Release v1.9.1
2021-05-20 14:51:02 +02:00
6c438bb434 Updated Adminer to 4.8.1 2021-05-20 10:52:49 +02:00
9935780588 Update README 2021-05-20 00:12:10 +02:00
20cba7d773 Update CHANGELOG 2021-05-20 00:03:16 +02:00
353fa53d29 Updated php images to 0.125 2021-05-19 22:59:42 +02:00
f28e1ee4a4 Enable mysql binlog by default 2021-05-19 19:04:22 +02:00
fb390ac429 gitignore php-ini 8.1 dir 2021-05-19 19:03:56 +02:00
867327a8c3 Update project files 2021-05-19 16:06:53 +02:00
8ffd65a905 Upgrade sphinx deprecations 2021-05-19 16:05:45 +02:00
5a4574edb8 Remove Travis CI 2021-05-19 16:05:44 +02:00
dc350b00b5 Update CHANGELOG date 2021-05-19 16:05:43 +02:00
f4d492ea98 Update release date 2021-05-19 16:05:42 +02:00
c40c43c4ea Exclude shellcheck rule 2021-05-19 16:05:41 +02:00
d0585bb174 Update documentation 2021-05-19 16:05:40 +02:00
0b9d18cdf4 Adjust enabled PHP modules 2021-05-19 16:05:33 +02:00
ba42717f01 Update CHANGELOG 2021-05-19 16:05:29 +02:00
b4c3de9195 Update PHP images to 0.124 2021-05-19 16:05:25 +02:00
a0423ebd02 Adjust xdebug CI tests 2021-05-19 16:05:21 +02:00
06c2a7ac51 Update Available PHP modules in README 2021-05-19 16:05:17 +02:00
543e373b91 Added PHP Xdebug info page for intranet 2021-05-19 16:05:14 +02:00
3d0154f987 Docs: smaller headlines for PHP modules 2021-05-19 16:05:10 +02:00
715c6b3c83 Adjusted Xdebug 3.0 defaults 2021-05-19 16:05:06 +02:00
d8e728a6a4 Merge pull request #802 from llaville/patch-intranet
Patch intranet to fix issue 801
2021-05-19 16:04:34 +02:00
1d41fb025c Merge branch 'master' into patch-intranet 2021-05-19 16:01:18 +02:00
af98125279 Merge branch 'master' into patch-1 2021-05-18 08:39:16 +02:00
ab761eedba Merge pull request #783 from mhodge13/master
Kibana 6.6 and above uses ELASTICSEARCH_HOSTS
2021-05-17 20:36:00 +02:00
0058e0bd61 Merge branch 'master' into master 2021-05-17 20:34:25 +02:00
2dd3ec9dd0 Merge pull request #781 from kovacbb/patch-1
Update enable-varnish.rst
2021-05-17 20:33:47 +02:00
7f294735e7 Fixed wrong push 2021-05-05 15:55:44 +02:00
a07b3442f1 Updated XDebug Linux documentation for XDebug 3.0 2021-05-05 15:50:46 +02:00
db1be81471 Update compose/docker-compose.override.yml-elk 2021-04-19 18:10:43 +02:00
d5e463db60 Update compose/docker-compose.override.yml-all 2021-04-19 18:10:36 +02:00
83c0c672d4 avoid PHP Fatal Error when pgsql PHP module is not available 2021-04-19 17:27:20 +02:00
af68fb65f2 avoid PHP Fatal Error when mysqli PHP module is not available 2021-04-19 17:25:56 +02:00
f6c273d6c4 avoid PHP Fatal Error when memcache PHP modules are not available 2021-04-19 17:24:11 +02:00
46f5c48ba0 avoid PHP Fatal Error when redis PHP module is not available 2021-04-19 17:21:47 +02:00
6c18e8f112 avoid PHP Fatal Error when mongo PHP modules are not available 2021-04-19 17:20:00 +02:00
6807b83e6b typo error fixed in memcached info panel 2021-04-19 14:29:43 +00:00
01fb99ec1a Added custom shadowdom element to view emails
WIthout the styling leaking into the global styling.
2021-02-21 14:40:16 +01:00
56342426b3 Kibana 6.6 and above uses ELASTICSEARCH_HOSTS 2021-02-11 08:48:18 -06:00
87e710050f Update enable-varnish.rst
fix small typo
2021-02-04 22:49:29 +01:00
cdfb55ec2d Merge pull request #771 from alikon/patch-1
xdebug v3 info panel
2020-12-21 10:14:40 +01:00
7cad84f527 Update .devilbox/www/htdocs/xdebug.php
Co-authored-by: cytopia <cytopia@everythingcli.org>
2020-12-21 08:24:46 +01:00
e65685b604 with header and footer 2020-12-18 17:16:28 +01:00
7e08261602 moved to Info 2020-12-18 14:07:46 +01:00
30d23f0f6f move to Info 2020-12-18 14:06:57 +01:00
b5fca3f842 moved on Info 2020-12-18 14:06:38 +01:00
dd529d0a1a xdebug 3 info panel 2020-12-18 12:59:49 +01:00
a6863c5ceb xdebug v3 info panel 2020-12-18 12:58:17 +01:00
6dba0ce963 Merge pull request #766 from BrookeDot/patch-1
Capitalize p in WordPress
2020-12-13 17:17:36 +01:00
201925e0b2 Merge branch 'master' into patch-1 2020-12-13 13:07:31 +01:00
ffee650e60 Merge pull request #765 from cytopia/release/v1.9.0
Devilbox Release v1.9.0
2020-12-13 13:03:01 +01:00
59738601b2 Capitalize p in WordPress
This is a simple edit to capitalize the p in WordPress throughout this document
2020-12-12 16:37:03 -08:00
50ae11f95f Retry network tasks 2020-12-12 19:13:31 +01:00
09b8803f21 Adjust test and examples according to Xdebug 3.0 2020-12-12 19:04:35 +01:00
75aa5139e2 Sort correctly when updating modules 2020-12-12 18:14:15 +01:00
f9b4a9d9f4 Fix lint job 2020-12-12 17:54:32 +01:00
0151167635 Devilbox Release v1.9.0 2020-12-12 17:53:36 +01:00
9c6711c948 Update php images 2020-12-12 17:53:32 +01:00
22f5c945ef Fixes #761 missing varnish config env var 2020-12-12 17:53:28 +01:00
1b768425b2 Added checks for TLD_SUFFIX in check-config.sh 2020-12-12 17:53:24 +01:00
a05f3eea47 Merge pull request #760 from avierr/patch-1
Updated docs for Mac SSL
2020-12-01 19:12:20 +01:00
e3c1e18ae3 Update for Mac 2020-12-01 16:46:29 +00:00
a78bccfd33 Merge pull request #757 from cytopia/release/v1.8.3
Release v1.8.3
2020-11-22 17:08:56 +01:00
2679acc569 Fix symlink handling with watcherd 2020-11-22 14:36:13 +01:00
6b18f7b71d CI: wordpress: increase retries and be more verbose 2020-11-22 12:40:02 +01:00
df6ee3fb36 Intranet: show custom Httpd configuration files 2020-11-22 11:54:56 +01:00
fda37efc64 Check supervisor configs with check-config.sh 2020-11-22 11:13:04 +01:00
e9281c9b40 Bump versions 2020-11-22 10:57:37 +01:00
dfd3e27882 Fixes #753 handle symlinks with watcherd 2020-11-22 10:57:06 +01:00
8e7069f893 Fixes #692 Add custom supervisor configs 2020-11-22 10:56:08 +01:00
c96f740c39 check-config.sh: debug mode 2020-11-20 15:15:45 +01:00
fe54bbf714 check-config: custom configs 2020-11-20 15:09:21 +01:00
9660c37937 check-config.sh: verify LOCAL_LISTEN_ADDR 2020-11-20 14:46:29 +01:00
0d6ecf23e3 check-config.sh: check customizations 2020-11-20 14:35:53 +01:00
3a2dacf748 Fix shellcheck for check-config 2020-11-20 13:37:09 +01:00
467fc03640 Validate htdocs dir in check-config 2020-11-20 13:18:19 +01:00
7480eb4e08 Add project checks 2020-11-20 13:06:06 +01:00
f348fa7814 Fixes #751 check-config output duplication 2020-11-17 12:51:15 +01:00
4488 changed files with 301101 additions and 376379 deletions

4
.devilbox/cfg/mysql.cnf Normal file
View File

@ -0,0 +1,4 @@
[mysqld]
server_id = 1
log_bin = "mysql-bin"
sync_binlog = 0

View File

@ -13,8 +13,8 @@ error_reporting(-1);
putenv('RES_OPTIONS=retrans:1 retry:1 timeout:1 attempts:1');
$DEVILBOX_VERSION = 'v1.8.2';
$DEVILBOX_DATE = '2020-11-14';
$DEVILBOX_VERSION = 'v3.0.0-beta-0.3';
$DEVILBOX_DATE = '2023-01-02';
$DEVILBOX_API_PAGE = 'devilbox-api/status.json';
//
@ -127,15 +127,27 @@ function loadClass($class) {
break;
case 'Redis':
// Check if redis is using a password
$REDIS_ROOT_PASSWORD = '';
$_REDIS_ARGS = loadClass('Helper')->getEnv('REDIS_ARGS');
$_REDIS_PASS = preg_split("/--requirepass\s+/", $_REDIS_ARGS);
if (is_array($_REDIS_PASS) && count($_REDIS_PASS)) {
// In case the option is specified multiple times, use the last effective one.
$_REDIS_PASS = $_REDIS_PASS[count($_REDIS_PASS)-1];
/*
* This pattern will match optional quoted string, 'my password' or "my password"
* or if there aren't any quotes, it will match up until the next space.
*/
$_REDIS_PASS = array();
preg_match_all('/--requirepass\s+("|\')?(?(1)(.*)|([^\s]*))(?(1)\1|)/', $_REDIS_ARGS, $_REDIS_PASS, PREG_SET_ORDER);
if (! empty($_REDIS_PASS)) {
/*
* In case the option is specified multiple times, use the last effective one.
*
* preg_match_all returns a multi-dimensional array, the first level array is in order of which was matched first,
* and the password string is either matched in group 2 or group 3 which is always the end of the sub-array.
*/
$_REDIS_PASS = end(end($_REDIS_PASS));
if (strlen($_REDIS_PASS) > 0) {
$REDIS_ROOT_PASSWORD = $_REDIS_PASS;
}

View File

@ -36,31 +36,32 @@ if (loadClass('Helper')->isLoggedIn()) {
//
else if (isset($_GET['software'])) {
$no = '<span class="text-danger">not installed</span>';
$no_mod = '<span class="text-warning">PHP module not loaded</span>';
$software = array();
if ($_GET['software'] == 'composer') {
if ($_GET['software'] == 'angular_cli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getAngularCliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'asgardcms_installer') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getAsgardCmsInstallerVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'codeception') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getCodeceptionVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'composer') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getComposerVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'drupalc') {
else if ($_GET['software'] == 'deployer') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getDrupalConsoleVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'drush7') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getDrushVersion(7)) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'drush8') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getDrushVersion(8)) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'drush9') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getDrushVersion(9)) !== false) ? $version : $no
$_GET['software'] => (($version = loadClass('Php')->getDeployerVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'git') {
@ -68,9 +69,24 @@ if (loadClass('Helper')->isLoggedIn()) {
$_GET['software'] => (($version = loadClass('Php')->getGitVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'laravel') {
else if ($_GET['software'] == 'grunt_cli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getLaravelVersion()) !== false) ? $version : $no
$_GET['software'] => (($version = loadClass('Php')->getGruntCliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'gulp') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getGulpVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'laravel_installer') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getLaravelInstallerVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'laravel_lumen') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getLaravelLumenVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'mds') {
@ -78,6 +94,11 @@ if (loadClass('Helper')->isLoggedIn()) {
$_GET['software'] => (($version = loadClass('Php')->getMdsVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'mupdf_tools') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getMupdfToolsVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'node') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getNodeVersion()) !== false) ? $version : $no
@ -88,20 +109,56 @@ if (loadClass('Helper')->isLoggedIn()) {
$_GET['software'] => (($version = loadClass('Php')->getNpmVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'phalcon') {
else if ($_GET['software'] == 'phalcon_devtools') {
if (!extension_loaded('phalcon')) {
echo json_encode(array(
$_GET['software'] => $no_mod
));
} else {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getPhalconDevtoolsVersion()) !== false) ? $version : $no
));
}
}
else if ($_GET['software'] == 'phpunit') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getPhalconVersion()) !== false) ? $version : $no
$_GET['software'] => (($version = loadClass('Php')->getPhpunitVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'symfony') {
else if ($_GET['software'] == 'stylelint') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getSymfonyVersion()) !== false) ? $version : $no
$_GET['software'] => (($version = loadClass('Php')->getStylelintVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'symfony_cli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getSymfonyCliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'vue_cli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getVueCliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'webpack_cli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getWebpackCliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'wpcli') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getWpcliVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'wscat') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getWscatVersion()) !== false) ? $version : $no
));
}
else if ($_GET['software'] == 'yarn') {
echo json_encode(array(
$_GET['software'] => (($version = loadClass('Php')->getYarnVersion()) !== false) ? $version : $no
));
} else {
echo json_encode(array($_GET['software'] => 'unknown software'));
}

View File

@ -0,0 +1,179 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<?php
// TODO: This is currently a temporary hack to talk to supervisor on the HTTPD server
function run_supervisor_command($command) {
$supervisor_config_file = '/tmp/supervisorctl.conf';
$port = getenv('SVCTL_LISTEN_PORT');
$user = getenv('SVCTL_USER');
$pass = getenv('SVCTL_PASS');
$content = "[supervisorctl]\n";
$content .= "serverurl=http://httpd:" . $port . "\n";
$content .= "username=" . $user . "\n";
$content .= "password=" . $pass . "\n";
$fp = fopen($supervisor_config_file, 'w');
fwrite($fp, $content);
fclose($fp);
return loadClass('Helper')->exec('supervisorctl -c ' . $supervisor_config_file . ' ' . $command);
}
?>
<?php if ( isset($_POST['watcherd']) && $_POST['watcherd'] == 'reload' ) {
run_supervisor_command('restart watcherd');
sleep(1);
loadClass('Helper')->redirect('/cnc.php');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(true); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>Command & Control</h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<?php
$status_w = run_supervisor_command('status watcherd');
$status_h = run_supervisor_command('status httpd');
$words = preg_split("/\s+/", $status_w);
$data_w = array(
'name' => isset($words[0]) ? $words[0] : '',
'state' => isset($words[1]) ? $words[1] : '',
'pid' => isset($words[3]) ? preg_replace('/,$/', '', $words[3]) : '',
'uptime' => isset($words[5]) ? $words[5] : '',
);
$words = preg_split("/\s+/", $status_h);
$data_h = array(
'name' => isset($words[0]) ? $words[0] : '',
'state' => isset($words[1]) ? $words[1] : '',
'pid' => isset($words[3]) ? preg_replace('/,$/', '', $words[3]) : '',
'uptime' => isset($words[5]) ? $words[5] : '',
);
?>
<h3>Daemon overview</h3><br/>
<p>If you made any changes to vhost settings (vhost-gen templates or backend configuration) or to the webserver configuration itself, you can trigger a manual reload of <code>watcherd</code> here to apply them. No need to restart the Docker Compose stack.</p>
<table class="table table-striped">
<thead class="thead-inverse">
<tr>
<th>Daemon</th>
<th>Status</th>
<th>Pid</th>
<th>Uptime</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><?php echo $data_w['name']; ?></td>
<td><?php echo $data_w['state']; ?></td>
<td><?php echo $data_w['pid']; ?></td>
<td><?php echo $data_w['uptime']; ?></td>
<td><form method="post"><button type="submit" name="watcherd" value="reload" class="btn btn-primary">Reload</button></form></td>
</tr>
<tr>
<td><?php echo $data_h['name']; ?></td>
<td><?php echo $data_h['state']; ?></td>
<td><?php echo $data_h['pid']; ?></td>
<td><?php echo $data_h['uptime']; ?></td>
<td></td>
</tr>
</tbody>
</table>
<br/>
<br/>
<h3>watcherd stderr</h3>
<br/>
<?php
$output = run_supervisor_command('tail -1000000 watcherd stderr');
echo '<pre>';
foreach(preg_split("/((\r?\n)|(\r\n?))/", $output) as $line) {
if ( strpos($line, "[ERR]") !== false ) {
echo '<span style="color: #ff0000">' . $line . '</span>';
} else if ( strpos($line, "[emerg]") !== false ) {
echo '<span style="color: #ff0000">' . $line . '</span>';
} else if ( strpos($line, "Syntax error") !== false ) {
echo '<span style="color: #ff0000">' . $line . '</span>';
} else if ( strpos($line, "[WARN]") !== false ) {
echo '<span style="color: #ccaa00">' . $line . '</span>';
} else {
echo $line;
}
echo "\n";
}
echo '</pre>';
?>
<h3>watcherd stdout</h3>
<br/>
<?php
$output = run_supervisor_command('tail -1000000 watcherd');
echo '<pre>';
foreach(preg_split("/((\r?\n)|(\r\n?))/", $output) as $line) {
$pos_info = strpos($line, "[INFO]");
$pos_ok = strpos($line, "[OK]");
if ( $pos_ok !== false ) {
echo '<span style="color: #669a00"><strong>' . $line . '</strong></span>';
} else if ( $pos_info !== false && $pos_info == 0 ) {
echo '<span style="color: #0088cd">' . $line . '</span>';
} else {
echo $line;
}
echo "\n";
}
echo '</pre>';
?>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
<script>
$(function() {
$('.subject').click(function() {
const id = ($(this).attr('id'));
const row = $('#mail-'+id);
row.toggle();
const bodyElement = row.find('.email-body')[0];
if(bodyElement.shadowRoot !== null){
// We've already fetched the message content.
return;
}
bodyElement.attachShadow({ mode: 'open' });
bodyElement.shadowRoot.innerHTML = 'Loading...';
$.get('?get-body=' + id, function(response){
response = JSON.parse(response);
row.find('.raw-email-body').html(response.raw);
const body = response.body;
if(body === null){
row.find('.alert').show();
}
else{
bodyElement.shadowRoot.innerHTML = body;
}
})
})
// Handler for .ready() called.
});
</script>
</body>
</html>

View File

@ -0,0 +1,62 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>Httpd custom configs</h1>
<br/>
<br/>
<p>Shows your currently custom configuration files applied to the Httpd container.</p>
<div class="row">
<div class="col-md-12">
<?php $vHosts = loadClass('Httpd')->getVirtualHosts(); ?>
<?php $custom = false; ?>
<?php foreach ($vHosts as $vHost): ?>
<?php if (($vhostGen = loadClass('Httpd')->getVhostgenTemplatePath($vHost['name'])) !== false): ?>
<?php $custom = true; ?>
<?php endif; ?>
<?php endforeach; ?>
<?php if ($custom): ?>
<table class="table table-striped">
<thead class="thead-inverse">
<tr>
<th>Project</th>
<th>Host</th>
<th>Container</th>
<th>Files</th>
</tr>
</thead>
<tbody>
<?php foreach ($vHosts as $vHost): ?>
<?php if (($vhostGen = loadClass('Httpd')->getVhostgenTemplatePath($vHost['name'])) !== false): ?>
<tr>
<th><?php echo $vHost['domain']; ?></th>
<td><?php echo loadClass('Helper')->getEnv('HOST_PATH_HTTPD_DATADIR').'/'.$vHost['name'].'/'.loadClass('Helper')->getEnv('HTTPD_TEMPLATE_DIR');?></td>
<td><?php echo dirname($vhostGen); ?></td>
<td><code><?php echo basename($vhostGen); ?></code></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>No custom configurations applied.</p>
<?php endif; ?>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

View File

@ -0,0 +1,126 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>PHP custom configs</h1>
<br/>
<br/>
<p>Shows your currently custom configuration files applied to the PHP-FPM container.</p>
<div class="row">
<div class="col-md-12">
<table class="table table-striped">
<thead class="thead-inverse">
<tr>
<th>Section</th>
<th>Host</th>
<th>Container</th>
<th>Files</th>
</tr>
</thead>
<tbody>
<tr>
<th>Supervisord</th>
<td>supervisor/</td>
<td>/etc/supervisor/custom.d/</td>
<td>
<?php
$files = glob('/etc/supervisor/custom.d/*.conf');
if ($files) {
foreach ($files as $file) {
echo '<code>'.basename($file). '</code><br/>';
}
} else {
echo 'No custom files';
}
?>
</td>
</tr>
<tr>
<th>Autostart (global)</th>
<td>autostart/</td>
<td>/startup.2.d/</td>
<td>
<?php
$files = glob('/startup.2.d/*.sh');
if ($files) {
foreach ($files as $file) {
echo '<code>'.basename($file). '</code><br/>';
}
} else {
echo 'No custom files';
}
?>
</td>
</tr>
<tr>
<th>Autostart (version)</th>
<td>cfg/php-startup-<?php echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;?>/</td>
<td>/startup.1.d/</td>
<td>
<?php
$files = glob('/startup.1.d/*.sh');
if ($files) {
foreach ($files as $file) {
echo '<code>'.basename($file). '</code><br/>';
}
} else {
echo 'No custom files';
}
?>
</td>
</tr>
<tr>
<th>PHP-FPM</th>
<td>cfg/php-fpm-<?php echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;?>/</td>
<td>/etc/php-fpm-custom.d/</td>
<td>
<?php
$files = glob('/etc/php-fpm-custom.d/*.conf');
if ($files) {
foreach ($files as $file) {
echo '<code>'.basename($file). '</code><br/>';
}
} else {
echo 'No custom files';
}
?>
</td>
</tr>
<tr>
<th>PHP</th>
<td>cfg/php-ini-<?php echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;?>/</td>
<td>/etc/php-custom.d/</td>
<td>
<?php
$files = glob('/etc/php-custom.d/*.ini');
if ($files) {
foreach ($files as $file) {
echo '<code>'.basename($file). '</code><br/>';
}
} else {
echo 'No custom files';
}
?>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

View File

@ -334,10 +334,121 @@ $HEALTH_PERCENT = 100 - ceil(100 * $HEALTH_FAILS / $HEALTH_TOTAL);
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12 col-margin">
<div class="dash-box">
<div class="dash-box-head"><i class="fa fa-info-circle" aria-hidden="true"></i> PHP Container Setup</div>
<div class="dash-box-head"><i class="fa fa-info-circle" aria-hidden="true"></i> Available CLI Tools</div>
<div class="dash-box-body">
<p><small>You can also enter the php container via <code style="background-color:#3d3d3d;">./shell.sh</code> and use the following cli tools:</small></p>
<table class="table table-striped table-hover table-bordered table-sm font-small">
<thead class="thead-inverse">
<tr>
<th colspan="2">Tools</th>
</tr>
</thead>
<tbody>
<tr>
<th style="width: 50%;">Angular Cli</th>
<td id="app_angular_cli"></td>
</tr>
<tr>
<th>AsgardCMS Installer</th>
<td id="app_asgardcms_installer"></td>
</tr>
<tr>
<th>Codeception</th>
<td id="app_codeception"></td>
</tr>
<tr>
<th>Composer</th>
<td id="app_composer"></td>
</tr>
<tr>
<th>Deployer</th>
<td id="app_deployer"></td>
</tr>
<tr>
<th>Git</th>
<td id="app_git"></td>
</tr>
<tr>
<th>Grunt Cli</th>
<td id="app_grunt_cli"></td>
</tr>
<tr>
<th>Gulp</th>
<td id="app_gulp"></td>
</tr>
<tr>
<th>Laravel Installer</th>
<td id="app_laravel_installer"></td>
</tr>
<tr>
<th>Laravel Lumen</th>
<td id="app_laravel_lumen"></td>
</tr>
<tr>
<th>Mupdf Tools</th>
<td id="app_mupdf_tools"></td>
</tr>
<tr>
<th>mysqldump-secure</th>
<td id="app_mds"></td>
</tr>
<tr>
<th>Node</th>
<td id="app_node"></td>
</tr>
<tr>
<th>Npm</th>
<td id="app_npm"></td>
</tr>
<tr>
<th>Phalcon Devtools</th>
<td id="app_phalcon_devtools"></td>
</tr>
<tr>
<th>Phpunit</th>
<td id="app_phpunit"></td>
</tr>
<tr>
<th>Stylelint</th>
<td id="app_stylelint"></td>
</tr>
<tr>
<th>Symfony Cli</th>
<td id="app_symfony_cli"></td>
</tr>
<tr>
<th>Vue Cli</th>
<td id="app_vue_cli"></td>
</tr>
<tr>
<th>Webpack Cli</th>
<td id="app_webpack_cli"></td>
</tr>
<tr>
<th>Wordpress Cli</th>
<td id="app_wpcli"></td>
</tr>
<tr>
<th>Wscat</th>
<td id="app_wscat"></td>
</tr>
<tr>
<th>Yarn</th>
<td id="app_yarn"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12 offset-lg-4 offset-md-0 offset-sm-0 col-margin">
<div class="dash-box">
<div class="dash-box-head"><i class="fa fa-info-circle" aria-hidden="true"></i> PHP Container Status</div>
<div class="dash-box-body">
<p><small>You have made the following base configuration to the Devilbox:</small></p>
<table class="table table-striped table-hover table-bordered table-sm font-small">
<p><small>You can also enter the php container and work from inside. The following is available inside the container:</small></p>
<thead class="thead-inverse">
<tr>
<th colspan="2">Settings</th>
@ -374,78 +485,7 @@ $HEALTH_PERCENT = 100 - ceil(100 * $HEALTH_FAILS / $HEALTH_TOTAL);
</tr>
</tbody>
</table>
<table class="table table-striped table-hover table-bordered table-sm font-small">
<thead class="thead-inverse">
<tr>
<th colspan="2">Tools</th>
</tr>
</thead>
<tbody>
<tr>
<th>composer</th>
<td id="app_composer"></td>
</tr>
<tr>
<th>drupal-console</th>
<td id="app_drupalc"></td>
</tr>
<tr>
<th>drush7</th>
<td id="app_drush7"></td>
</tr>
<tr>
<th>drush8</th>
<td id="app_drush8"></td>
</tr>
<tr>
<th>drush9</th>
<td id="app_drush9"></td>
</tr>
<tr>
<th>git</th>
<td id="app_git"></td>
</tr>
<tr>
<th>Laravel installer</th>
<td id="app_laravel"></td>
</tr>
<tr>
<th>mysqldump-secure</th>
<td id="app_mds"></td>
</tr>
<tr>
<th>node</th>
<td id="app_node"></td>
</tr>
<tr>
<th>npm</th>
<td id="app_npm"></td>
</tr>
<tr>
<th>Phalcon devtools</th>
<td id="app_phalcon"></td>
</tr>
<tr>
<th>Symfony installer</th>
<td id="app_symfony"></td>
</tr>
<tr>
<th>Wordpress cli</th>
<td id="app_wpcli"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12 offset-lg-4 offset-md-0 offset-sm-0 col-margin">
<div class="dash-box">
<div class="dash-box-head"><i class="fa fa-info-circle" aria-hidden="true"></i> PHP Container Status</div>
<div class="dash-box-body">
<p><small>The PHP Docker can connect to the following services via the specified hostnames and IP addresses.</small></p>
<p><small>The PHP container can connect to the following services via the specified hostnames and IP addresses.</small></p>
<table class="table table-striped table-hover table-bordered table-sm font-small">
<thead class="thead-inverse">
<tr>
@ -913,19 +953,29 @@ $HEALTH_PERCENT = 100 - ceil(100 * $HEALTH_FAILS / $HEALTH_TOTAL);
xhttp.open('GET', '_ajax_callback.php?software='+app, true);
xhttp.send();
}
updateVersions('angular_cli');
updateVersions('asgardcms_installer');
updateVersions('codeception');
updateVersions('composer');
updateVersions('drupalc');
updateVersions('drush7');
updateVersions('drush8');
updateVersions('drush9');
updateVersions('deployer');
updateVersions('git');
updateVersions('laravel');
updateVersions('grunt_cli');
updateVersions('gulp');
updateVersions('laravel_installer');
updateVersions('laravel_lumen');
updateVersions('mds');
updateVersions('mupdf_tools');
updateVersions('node');
updateVersions('npm');
updateVersions('phalcon');
updateVersions('symfony');
updateVersions('phalcon_devtools');
updateVersions('phpunit');
updateVersions('stylelint');
updateVersions('symfony_cli');
updateVersions('vue_cli');
updateVersions('webpack_cli');
updateVersions('wpcli');
updateVersions('wscat');
updateVersions('yarn');
})();
</script>
</body>

View File

@ -19,7 +19,7 @@
<div class="col-md-12">
<?php if (!loadClass('Memcd')->isAvailable()): ?>
<p>Memcahed container is not running.</p>
<p>Memcached container is not running.</p>
<?php else: ?>
<?php foreach (loadClass('Memcd')->getInfo() as $srv => $data): ?>
<h2><?php echo $srv; ?></h2>

View File

@ -1,66 +0,0 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<?php
if (!isset($_GET['name'])) {
loadClass('Helper')->redirect('/vhosts.php');
}
if (!strlen($_GET['name'])) {
loadClass('Helper')->redirect('/vhosts.php');
}
$vhost = $_GET['name'];
$found = false;
$vhosts = loadClass('Httpd')->getVirtualHosts();
foreach ($vhosts as $v) {
if ($vhost == $v['name']) {
$found = true;
break;
}
}
// Be safe before using outputs
$vhost = htmlentities($vhost);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(true); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>vhost-gen: <?php echo $vhost;?></h1>
<br/>
<br/>
<div class="row">
<div class="col-md-12">
<?php if (!$found): ?>
<p>The Virtual Host "<?php echo $vhost; ?>" does not exist.</p>
<?php else: ?>
<?php $tpl = loadClass('Httpd')->getVhostgenTemplatePath($vhost); ?>
<?php if (!$tpl): ?>
<p>No custom vhost-gen configuration found for "<?php echo $vhost; ?>".</p>
<?php else: ?>
<p>Note: If the resulting virtual host config does not reflect the vhost-gen template changes, you will need to restart the Devilbox.</p>
<a href="/vhosts.php"><i class="fa fa-chevron-left" aria-hidden="true"></i> Overview</a><br/>
<br/><h3>virtual host config</h3><br/>
<a title="Virtual host: <?php echo $vhost;?>.conf" target="_blank" href="/vhost.d/<?php echo $vhost;?>.conf">
<i class="fa fa-external-link" aria-hidden="true"></i> <?php echo $vhost;?>.conf
</a>
<br/><br/><h3>vhost-gen config</h3><br/>
<code><?php echo $tpl; ?></code><br/><br/>
<?php $lines = file($tpl); ?>
<pre style="border: 1px solid black; padding:5px;"><code><?php foreach ($lines as $line): ?><?php echo $line; ?><?php endforeach; ?></code></pre>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

View File

@ -0,0 +1,32 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<div class="row">
<div class="col-md-12">
<style>
body {width: 100% !important;}
</style>
<?php if (($version = phpversion('xdebug')) === false): ?>
<p><code>xdebug</code> module is not enabled.</p>
<?php elseif (!function_exists('xdebug_info')): ?>
<p>Xdebug info only available with <code>xdebug 3.x.x</code> or greater. Your version is <code>xdebug <?php echo $version;?></code></p>
<?php else:?>
<?php xdebug_info(); ?>
<?php endif; ?>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

View File

@ -5,10 +5,10 @@
//
// $_POST submit for sending a test email
//
if (isset($_GET['email']) && isset($_GET['subject']) && isset($_GET['message'])) {
$mail = $_GET['email'];
$subj = $_GET['subject'];
$mess = $_GET['message'];
if (isset($_POST['email']) && isset($_POST['subject']) && isset($_POST['message'])) {
$mail = $_POST['email'];
$subj = $_POST['subject'];
$mess = $_POST['message'];
if (! mail($mail, $subj, $mess)) {
loadClass('Logger')->error('Could not send mail to: '.$mail.' | subject: '.$subj);
}
@ -24,6 +24,39 @@ require $VEN_DIR . DIRECTORY_SEPARATOR . 'Mail' . DIRECTORY_SEPARATOR .'mimeDeco
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Mail.php';
require $LIB_DIR . DIRECTORY_SEPARATOR . 'Sort.php';
if (isset($_GET['get-body']) && is_numeric($_GET['get-body'])) {
$messageNumber = $_GET['get-body'];
$MyMbox = new \devilbox\Mail('/var/mail/devilbox');
$message = $MyMbox->getMessage($messageNumber-1);
$structure = $message['decoded'];
$body = null;
if (isset($structure->body)) {
$body = $structure->body;
}
elseif(isset($structure->parts[1]->body)) {
$body = $structure->parts[1]->body;
}
elseif(isset($structure->parts[0]->body)) {
$body = $structure->parts[0]->body;
}
exit(json_encode(array(
'raw' => htmlentities($message['raw']),
'body' => $body,
)));
}
if (isset($_GET['delete']) && is_numeric($_GET['delete'])) {
$message = $_GET['delete'];
$MyMbox = new \devilbox\Mail('/var/mail/devilbox');
$MyMbox->delete($message);
header('Location: /mail.php');
exit();
}
//
// Setup Sort/Order
//
@ -108,7 +141,7 @@ $messages = $MyMbox->get($sortOrderArr);
<div class="row">
<div class="col-md-12">
<form class="form-inline">
<form method="post" class="form-inline">
<div class="form-group">
<label class="sr-only" for="exampleInputEmail1">Email to</label>
<input name="email" type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter to email">
@ -121,7 +154,7 @@ $messages = $MyMbox->get($sortOrderArr);
<div class="form-group">
<label class="sr-only" for="exampleInputEmail3">Message</label>
<input name="message" type="text" class="form-control" id="exampleInputEmail3" placeholder="Message">
<textarea name="message" rows="1" class="form-control" id="exampleInputEmail3" placeholder="Message"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Email</button>
@ -152,6 +185,7 @@ $messages = $MyMbox->get($sortOrderArr);
<th>From <?php echo $orderFrom;?></th>
<th>To <?php echo $orderTo;?></th>
<th>Subject <?php echo $orderSubj;?></th>
<th>Action</th>
</tr>
</thead>
<tbody>
@ -169,25 +203,19 @@ $messages = $MyMbox->get($sortOrderArr);
<td><?php echo htmlentities($structure->headers['from']);?></td>
<td><?php echo htmlentities($structure->headers['x-original-to']);?></td>
<td><?php echo htmlentities($structure->headers['subject']);?></td>
<td><a href="/mail.php?delete=<?php echo $data['num']-1;?>" title="Delete Email"><i class="fa fa-trash"></i></a></td>
</tr>
<tr></tr>
<tr id="mail-<?php echo $data['num'];?>" style="display:none">
<td></td>
<td colspan="4">
<?php if (isset($structure->body)): ?>
<?php echo htmlentities($structure->body) ?>
<?php elseif(isset($structure->parts[1]->body)): ?>
<?php echo htmlentities($structure->parts[1]->body) ?>
<?php elseif(isset($structure->parts[0]->body)): ?>
<?php echo htmlentities($structure->parts[0]->body) ?>
<?php else: ?>
<?php echo '<div class="alert alert-warning" role="alert">
No valid body found
</div>' ?>
<?php endif; ?>
<td colspan="5">
<div class="email-body"></div>
<div class="alert alert-warning" role="alert" style="display:none">
No valid body found
</div>
<hr>
<p><a class="btn btn-primary" data-toggle="collapse" href="#email-<?php echo $data['num'];?>" aria-expanded="false" aria-controls="email-<?php echo $data['num'];?>">Raw source</a></p>
<div class="collapse" id="email-<?php echo $data['num'];?>"><pre><?php echo $message;?></pre></div>
<div class="collapse" id="email-<?php echo $data['num'];?>"><pre class="raw-email-body"></pre></div>
</td>
</tr>
<?php endforeach; ?>
@ -205,11 +233,31 @@ $messages = $MyMbox->get($sortOrderArr);
<?php echo loadClass('Html')->getFooter(); ?>
<script>
$(function() {
$('.subject').each(function() {
$(this).click(function() {
var id = ($(this).attr('id'));
$('#mail-'+id).toggle();
$('.subject').click(function() {
const id = ($(this).attr('id'));
const row = $('#mail-'+id);
row.toggle();
const bodyElement = row.find('.email-body')[0];
if(bodyElement.shadowRoot !== null){
// We've already fetched the message content.
return;
}
bodyElement.attachShadow({ mode: 'open' });
bodyElement.shadowRoot.innerHTML = 'Loading...';
$.get('?get-body=' + id, function(response){
response = JSON.parse(response);
row.find('.raw-email-body').html(response.raw);
const body = response.body;
if(body === null){
row.find('.alert').show();
}
else{
bodyElement.shadowRoot.innerHTML = body;
}
})
})
// Handler for .ready() called.

View File

@ -55,13 +55,13 @@ class OpCacheService
'debounce_rate' => 250
];
private function __construct($options = [])
private function __construct($options = array())
{
$this->options = array_merge($this->defaults, $options);
$this->data = $this->compileState();
}
public static function init($options = [])
public static function init($options = array())
{
$self = new self($options);
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
@ -150,7 +150,7 @@ class OpCacheService
$status = opcache_get_status();
$config = opcache_get_configuration();
$files = [];
$files = array();
if (!empty($status['scripts']) && $this->getOption('allow_filelist')) {
uasort($status['scripts'], function($a, $b) {
return $a['hits'] < $b['hits'];
@ -192,7 +192,7 @@ class OpCacheService
]
);
$directives = [];
$directives = array();
ksort($config['directives']);
foreach ($config['directives'] as $k => $v) {
$directives[] = ['k' => $k, 'v' => $v];

View File

@ -0,0 +1,203 @@
<?php require '../config.php'; ?>
<?php loadClass('Helper')->authPage(); ?>
<!DOCTYPE html>
<html lang="en">
<head>
<?php echo loadClass('Html')->getHead(true); ?>
</head>
<body>
<?php echo loadClass('Html')->getNavbar(); ?>
<div class="container">
<h1>Support</h1>
<br/>
<p>I am currently the sole creator and maintainer of the Devilbox and all of its required projects.<br/>If you find this useful or if it makes your daily programming life easier, consider donating to keep this project alive.</p>
<ul>
<li><a target="_blank" href="https://github.com/sponsors/cytopia"><strong>GitHub sponsorship</strong></a></li>
<li><a target="_blank" href="https://opencollective.com/devilbox"><strong>Open Collective</strong></a></li>
<li><a target="_blank" href="https://www.patreon.com/devilbox"><strong>Patreon</strong></a></li>
</ul>
<br/>
<div class="row">
<div class="col-md-6">
<h2>Core projects</h2>
<p>The following core projects were created and are maintained in order to make the Devilbox work.</p>
<table class="table table-striped ">
<thead class="thead-inverse ">
<tr>
<th>Repository</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/devilbox">devilbox</a></td>
<td>The Devilbox</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.2">docker-php-fpm-5.2</a></td>
<td>Legacy PHP 5.2 base images (<code>amd64</code> and <code>i386</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.3">docker-php-fpm-5.3</a></td>
<td>Legacy PHP 5.3 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.4">docker-php-fpm-5.4</a></td>
<td>Legacy PHP 5.4 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-5.5">docker-php-fpm-5.5</a></td>
<td>Legacy PHP 5.5 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.0">docker-php-fpm-8.0</a></td>
<td>PHP 8.0 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.1">docker-php-fpm-8.1</a></td>
<td>PHP 8.1 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.2">docker-php-fpm-8.2</a></td>
<td>PHP 8.2 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-8.3">docker-php-fpm-8.3</a></td>
<td>PHP 8.3 base images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm">docker-php-fpm</a></td>
<td>PHP-FPM Devilbox images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-fpm-community">docker-php-fpm-community</a></td>
<td>PHP-FPM Community images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-mysql">docker-mysql</a></td>
<td>MySQL, MariaDB and PerconaDB images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-apache-2.2">docker-apache-2.2</a></td>
<td>Apache 2.2 images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-apache-2.4">docker-apache-2.4</a></td>
<td>Apache 2.4 images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-nginx-stable">docker-nginx-stable</a></td>
<td>Nginx stable images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-nginx-mainline">docker-nginx-mainline</a></td>
<td>Nginx mainline images (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-haproxy">docker-haproxy</a></td>
<td>HA Proxy image</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-ngrok">docker-ngrok</a></td>
<td>Ngrok image (<code>amd64</code> and <code>arm64</code>)</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-varnish">docker-varnish</a></td>
<td>Varnish image</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-python-flask">docker-python-flask</a></td>
<td>Python Flask image</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<h2>Supporting projects</h2>
<p>The following supporting projects were created and are maintained in order to keep the Devilbox eco system running.</p>
<table class="table table-striped ">
<thead class="thead-inverse ">
<tr>
<th>Repository</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/cert-gen">cert-gen</a></td>
<td>CA and cert generation tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/vhost-gen">vhost-gen</a></td>
<td>HTTPD agnostic vhost creation tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/watcherd">watcherd</a></td>
<td>OS agnostic filesystem change poller tool</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/makefiles">makefiles</a></td>
<td>Unified build Makefiles</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/github-actions">github-actions</a></td>
<td>Re-usable GitHub Action Workflows</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/shell-command-retry-action">shell-command-retry</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-tag-action">docker-tag</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/git-ref-matrix-action">git-ref-matrix</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/upload-artifact-verify-action">upload-artifact-verify</a></td>
<td>GitHub Action</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-python-sphinx">docker-python-sphinx</a></td>
<td>Dockerized Sphinx documentation builder</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/xdebug">xdebug</a></td>
<td>IP addr alias MacOS plist for Xdebug</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-ansible">docker-ansible</a></td>
<td>Ansible images for PHP-FPM Dockerfile creation</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/linkcheck">linkcheck</a></td>
<td>Broken linkchecker for documentation</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/cytopia/docker-linkcheck">docker-linkcheck</a></td>
<td>Dockerized version of linkcheck</td>
</tr>
<tr>
<td><i class="fa fa-github-alt" aria-hidden="true"></i> <a target="_blank" href="https://github.com/devilbox/docker-php-1.99s">docker-php-1.99s</a></td>
<td>Just for the lulz</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><!-- /.container -->
<?php echo loadClass('Html')->getFooter(); ?>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,458 +0,0 @@
phpMyAdmin - ChangeLog
======================
5.0.4 (2020-10-15)
- issue #16245 Fix failed Zoom search clears existing values
- issue Fixed a PHP error when reporting a particular JS error
- issue #16326 Fixed latitude and longitude swap for geometries in edit mode
- issue #16032 Fix CREATE TABLE not being tracked when auto tracking is enabled
- issue #16397 Fix compatibility problems with older PHP versions (also issue #16399)
- issue #16396 Fix broken two-factor authentication
5.0.3 (2020-10-09)
- issue #15983 Require twig ^2.9
- issue Fix option to import files locally appearing as not available
- issue #16048 Fix to allow NULL as a default bit value
- issue #16062 Fix "htmlspecialchars() expects parameter 1 to be string, null given" on Export xml
- issue #16078 Fix no charts in monitor when using a decimal separator ","
- issue #16041 Fix IN(...) clause doesn't permit multiple values on "Search" page
- issue #14411 Support double tap to edit on mobile
- issue #16043 Fix php error "Use of undefined constant MYSQLI_TYPE_JSON" when using the mysqlnd extension
- issue #14611 Fix fatal JS error on index creation after using Enter key to submit the form
- issue #16012 Set "axis-order" to swap lon and lat on MySQL >= 8.1
- issue #16104 Fixed overwriting a bookmarked query causes a PHP fatal error
- issue Fix typo in a condition in the Sql class
- issue #15996 Fix local setup doc links pointing to a wrong location
- issue #16093 Fix error importing utf-8 with bom sql file
- issue #16089 2FA UX enhancement: autofocus 2FA input
- issue #16127 Fix table column description PHP error when ['DisableIS'] = true;
- issue #16130 Fix local documentation links display when a PHP extension is missing
- issue Fix some twig code deprecations for php 8
- issue Fix ENUM and SET display when editing procedures and functions
- issue Keep full query state on "auto refresh" process list
- issue Keep columns order on "auto refresh" process list
- issue Fixed editing a failed query from the error message
- issue #16166 Fix the alter user privileges query to make it MySQL 8.0.11+ compatible
- issue Fix copy table to another database when the nbr of DBs is > $cfg['MaxDbList']
- issue #16157 Fix relations of tables having spaces or special chars not showing in the Designer
- issue #16052 Fix a very rare JS error occuring on mousemove event
- issue #16162 Make a foreign key link clickable in a new tab after the value was saved and replaced
- issue #16163 Fixed a PHP notice "Undefined index: column_info" on views
- issue #14478 Fix the data stream when exporting data in file mode
- issue #16184 Fix templates/ directory not found error
- issue #16184 Remove chdir logic to fix PHP fatal error "Uncaught TypeError: chdir()"
- issue Support for Twig 3
- issue Allow phpmyadmin/twig-i18n-extension ^3.0
- issue #16201 Trim spaces for integer values in table search
- issue #16076 Fixed cannot edit or export TIMESTAMP column with default CURRENT_TIMESTAMP in MySQL >= 8.0.13
- issue #16226 Fix error 500 after copying a table
- issue #16222 Fixed can't use the search page when the table name has special characters
- issue #16248 Fix zoom search is not performing input validation on INT columns
- issue #16248 Fix javascript error when typing in INT fields on zoom search page
- issue Fix type errors when using saved searches
- issue #16261 Fix missing headings on modals of "User Accounts -> Export"
- issue #16146 Fixed sorting did not keep the selector of number of rows
- issue #16194 Fixed SQL query does not appear in case of editing view where definer is not you on MySQL 8
- issue #16255 Fix tinyint(1) shown as INT on Search page
- issue #16256 Fix "Warning: error_reporting() has been disabled for security reasons" on php 7.x
- issue #15367 Fix "Change or reconfigure primary server" link
- issue #15367 Fix first replica links, start, stop, ignore links
- issue #16058 Add "PMA_single_signon_HMAC_secret" for signon auths to make special links work and udate examples
- issue #16269 Support ReCaptcha v2 checkbox width "$cfg['CaptchaMethod'] = 'checkbox';"
- issue #14644 Use Doctum instead of Sami
- issue #16086 Fix "Browse" headings shift when scrolling
- issue #15328 Fix no message after import of zipped shapefile without php-zip
- issue #14326 Fix PHP error when exporting without php-zip
- issue #16318 Fix Profiling doesn't sum the number of calls
- issue #16319 Fixed a Russian translation mistake on search results total text
- issue #15634 Only use session_set_cookie_params once on PHP >= 7.3.0 versions for single signon auth
- issue #14698 Fixed database named as 'New' (language variable) causes PHP fatal error
- issue #16355 Make textareas both sides resizable
- issue #16366 Fix column definition form not showing default value
- issue #16342 Fixed multi-table query (db_multi_table_query.php) alias show the same alias for all columns
- issue #15109 Fixed using ST_GeomFromText + GUI on insert throws an error
- issue #16325 Fixed editing Geometry data throws error on using the GUI
- issue [security] Fix XSS vulnerability with the transformation feature (PMASA-2020-5)
- issue [security] Fix SQL injection vulnerability with search feature (PMASA-2020-6)
5.0.2 (2020-03-20)
- issue Fixed deprecation warning "implode(): Passing glue string after array is deprecated." function on export page
- issue #15767 Fixed can not copy user account since 5.0 - "error #1133"
- issue #15772 Fixed error code 500 during pagination of the tables in a database
- issue #16009 Fix php error "Trying to access array offset on value of type null" on column distinct values feature
- issue #15741 Fix fatal javascript error on clicking "Pick from Central Columns"
- issue #15773 Fixed a view named "views" adds an expand button
- issue #15432 Fixed names of the pages in the designer should be unique
- issue #14310 Fixed column selector "See more" removes "Preview SQL" and "Save" area
- issue Fixed wrong jQuery function call in table search page
- issue #15761 Fix uncaught TypeError when using "$cfg['ServerDefault'] = 0;"
- issue #15780 Fixed unexpected UI of action links (text only mode)
- issue #15674 Replace twig/extensions with phpmyadmin/twig-i18n-extension
- issue #15799 Change location of profiling state documentation to fix column ordering
- issue #15720 Fix designer adding all available tables to a designer page after adding a new relationship
- issue #15791 Replace facebook/webdriver by php-webdriver/webdriver
- issue #15802 Removed SET AUTOCOMMIT=0 from SQL export
- issue #15818 Fix table borders missing on theme original since 5.0.0
- issue #13864 Fix ENUM's radiobuttons reset on "Continue insertion with" changes
- issue #15811 Fixed browse foreign values doesn't show a modal with grid edit
- issue #15817 Fix "new table" layout issue on original theme
- issue #15798 Fixed not needed prompt before abandoning changes on SQL tab after only changing a checkbox
- issue #15833 Fix php TypeError when submitting unchanged data
- issue Fix php notice "Trying to access array offset on value of type bool" on Designer
- issue #13326 Added integer validations on search page
- issue #15200 Fixed server-side HTTPS detection misses support for Forwarded HTTP Extension (RFC 7239)
- issue #15831 Fixed DB names starting with "b" being cut off in <option>, User account page
- issue #15850 Fixed display content from "information_schema.PROCESSLIST"
- issue #15836 Fixed "has no type" error on export and import pages for "Chinese traditional" users
- issue #15863 Fixed designer move menu icon not changing directions and tables menu list resize button
- issue #15854 Fixed black borders for full screen mode on Designer
- issue #15899 Fix "Uncaught TypeError: mb_strtoupper()" on the relational view of a view
- issue Fixed some php uncaught errors and notices on user missing extension
- issue #15926 Fixed PhpMyAdmin\Core::getRealSize('8000M') returns a float instead of an int
- issue #15410 Fixed auto increment reset issue where the last value of AI was saved an could destroy the "good" value
- issue #15187 Fixed editing a row and using 'insert as new row' uses primary key 0 instead of NULL
- issue #15877 Fixed php error "preg_match() expects parameter 2 to be string, null given" on some specific tables
- issue #15795 Fix broken link on "MySQL said" error message
- issue #15781 Fix illegal string offset error on structure page of 'information_schema' database
- issue #15745 Fix version 5.0.1 suggests 4.9.4 as latest stable version
- issue #15958 Fix uncaught TypeError when sorting database tables by size or by rows
- issue #15830 Fix strftime issue on windows for Japanese users on "Structure" tab
- issue Windows testsuite fixes
- issue #15879 Added missing CSS class on "simulate query" button
- issue #15401 Fixed php notice "Undefined index HMAC_secret" for users upgrading phpMyAdmin without a log-out
- issue #15810 Fixed unexpected heading on add a new procedure, trigger, function, routine modals
- issue #15970 Removed wrong html a tag on "Replication status" header
- issue Add missing css classes on some buttons
- issue #15937 Make modals draggability/expand (down) work after a screen zoom change
- issue Fix php notice "Undefined index: on_delete" while creating a foreign key
- issue #15876 Fixed select "IN (...)" is a simple select instead of a multiple select
- issue Fix maxlength for User and Host on replication add user form
- issue #15282 Fixed MySQL 8.0 password syntax error when creating a replication user
- issue #15986 Fixed php fatal error "Uncaught TypeError: array_flip() expects parameter 1 to be array, null given"
- issue Fixed php fatal error "Uncaught TypeError: htmlspecialchars() expects parameter 1 to be string, int given"
- issue Support phpunit 9.0
- issue Fix error in NavigationTree where $key might be sent as an int instead of a str to urlencode
- issue #16022 Fix uncaught TypeError on browse foreigners
- issue Fix failure if relational display field value is NULL - "Display column for relationships"
- issue #16033 Remove vendor bin files from non source version of phpMyAdmin
- issue #15898 [security] Fix escape tbl_storage_engine argument used on tbl_create.php
- issue #15224 Don't fire keyboard shortcuts while SQL query area is focused (on a mobile for example)
- issue [security] Fix SQL injection with certain usernames (PMASA-2020-2)
- issue [security] Fix SQL injection in particular search situations (PMASA-2020-3)
- issue [security] Fix SQL injection and XSS flaw (PMASA-2020-4)
- issue Deprecate "options" for the external transformation; options must now be hard-coded along with the program name directly in the file.
5.0.1 (2020-01-07)
- issue #15719 Fixed error 500 when browsing a table when $cfg['LimitChars'] used a string and not an int value
- issue #14936 Fixed display NULL on numeric fields has showing empty string since 5.0.0
- issue #15722 Fix get Database structure fails with PHP error on replicated server
- issue #15723 Fix can't browse certain tables since 5.0.0 update
- issue Prevent line wrap in DB structure size column
- issue Remove extra line break from downloaded blob content
- issue #15725 Fixed error 500 when exporting - set time limit when $cfg['ExecTimeLimit'] used a string and not an int value
- issue #15726 Fixed double delete icons on enum editor
- issue #15717 Fixed warning popup not dissapearing on table stucture when using actions without any column selection
- issue #15693 Fixed focus of active tab is lost by clicking refresh option on browse tab
- issue #15734 Fix Uncaught TypeError: http_build_query() in setup
- issue Fix double slash in path when $cfg['TempDir'] has a trailing slash
- issue #14875 Fix shp file import tests where failing when php dbase extension was enabled
- issue #14299 Fix JS error "PMA_makegrid is not defined" when clicking on a table from the "Insert" tab opened in a new tab
- issue #15351 Fixed 2FA setting removed each time the user edits another configuration setting
- issue [security] Fix SQL injection vulnerability on the user accounts page (PMASA-2020-1)
5.0.0 (2019-12-26)
- issue #13896 Drop support for PHP 5.5, PHP 5.6, PHP 7.0 and HHVM
- issue #14007 Enable columns names by default for CSV exports
- issue #13919 Remove font size feature
- issue #12373 Add Metro theme
- issue #14155 Add move columns preview SQL button
- issue #14296 Enable strict mode in PHP files
- issue #13627 Increase field width for editing varchar fields
- issue #12603 Show warning for users with the default values for controluser and controlpass
- issue #14589 Fix rendering of column comments in Safari, improve display in all browsers
- issue #14330 New features for csv import plugin
- issue #14417 Automatically add index while editing an existing row and setting auto increment
- issue #13057 Add export option to drop user security definers from views
- issue #14404 Drop view and or replace added to exporting view
- issue #14594 Database "Search" selects all tables by default
- issue #12158 Auto expand the single database
- issue #13067 Inconsistency with submit buttons
- issue #14683 Improper message in Show Hidden Navigation Tree Items
- issue #14695 Remove unlabeled default collation from the bottom of the database list; this information is available elsewhere
- issue #14677 Security confirm() before running UPDATE statement without WHERE condition
- issue #13023 Show errors at the bottom of the page and add copy query button for errors in processing sql queries
- issue #14633 Use Sass instead of PHP to compile CSS
- issue #14765 Add initial support for Bootstrap 4
- issue #14829 Change table column comment field from input to textarea
- issue #14725 Console: ctrl+l clear line and ctrl+u clear console
- issue #14837 Use charset 'windows-1252' when format is MS Excel
- issue #15030 Move 'More settings' link from 'Appearance settings' to 'General settings'
- issue #15029 Remove the redundant 'i' help/tool tip in page settings "Query History Length" area
- issue #13424 Importing CSV now uses file name as the table name instead of 'TABLE #'
- issue #14926 Add an Edit link for each view in tables list
- issue #14890 Display column details in navigation bar
- issue #14977 Add title for group in navigation bar
- issue #14927 Show InnoDB table overhead (free space)
- issue #15072 Add 'Close' button to the Monitor Instructions modal
- issue #15174 Improved filter method in server variables page
- issue #15266 Add an external dependency injection system
- issue #15350 Change MIME type references to Media (MIME) type
- issue Fixed url.php crashing because it's not loading the DatabaseInterface service
- issue #15540 Fixed uncaught TypeError: htmlspecialchars() in NavigationTree
- issue Fix twig deprecation notices for php 8.0
- issue #15435 Fix ReCAPTCHA couldn't find user-provided function: Functions.recaptchaCallback
- issue #15623 Fix width of picker modal and remove date picker for int fields
- issue #14732 Fixed can't rename primary key with auto increment
- issue #15677 Fix show process-list triggers a php exception
- issue #15697 Fix uncaught php error: "Call to a member function get() on null" in db_export.php when exporting a table from the list
4.9.7 (2020-10-15)
- issue #16397 Fix compatibility problems with older PHP versions (also issue #16399)
- issue #16396 Fix broken two-factor authentication
4.9.6 (2020-10-09)
- issue [security] Fix XSS vulnerability with the transformation feature (PMASA-2020-5)
- issue [security] Fix SQL injection vulnerability with search feature (PMASA-2020-6)
4.9.5 (2020-03-20)
- issue [security] Fix SQL injection with certain usernames (PMASA-2020-2)
- issue [security] Fix SQL injection in particular search situations (PMASA-2020-3)
- issue [security] Fix SQL injection and XSS flaw (PMASA-2020-4)
- issue Deprecate "options" for the external transformation; options must now be hard-coded along with the program name directly in the file.
4.9.4 (2020-01-07)
- issue #15724 Fix 2FA was disabled by a bug
- issue [security] Fix SQL injection vulnerability on the user accounts page (PMASA-2020-1)
4.9.3 (2019-12-26)
- issue #15570 Fix page contents go underneath of floating menubar in some cases
- issue #15591 Fix php notice 'Undefined index: foreign_keys_data' on relations view when the user has column access
- issue #15592 Fix php warning "error_reporting() has been disabled for security reasons"
- issue #15434 Fix middle click on table sort column name shows a blank page
- issue Fix php notice "Undefined index table_create_time" when setting displayed columns on results of a view
- issue #15571 Fix fatal error when trying to edit row with row checked and button under the table
- issue #15633 Fix designer set display field broken for php 5.x versions
- issue #15621 Support CloudFront-Forwarded-Proto header for Amazon CloudFront proxy
- issue Fix php 8.0 php notices - Undefined index on login page
- issue #15640 Fix php 7.4 error when trying to access array offset on value of type null on table browse
- issue #15641 Fix replication actions where broken (start slave, stop slave, reset, ...)
- issue #15608 Fix DisableIS is broken when with controluser configured (database list broken)
- issue #15614 Fix undefined offset on index page for MySQL 5.7.8 (server charset)
- issue #15692 Fix JavaScript error when user has not enough privilege to view query statistics.
- issue #14248 Fixed date selection in search menu missing higher Z-index value
- issue Fix Uncaught php TypeError on php 8.0 when adding a column to table create form
- issue #15682 Fix calendar not taking current time as default value
- issue #15636 Fix php error trying to access array offset on value o type null on replication GUI
- issue #15695 Fix input field for the time in datetime picker is disabled
4.9.2 (2019-11-21)
- issue #14184 Change the cookie name from phpMyAdmin to phpMyAdmin_https for HTTPS, fixes many "Failed to set session cookie" errors
- issue #15304 Fix ssl_use php error
- issue #14804 Fix undefined index: ssl_* variables
- issue #14245 Fix mysql 8.0.3 and above fails on advisor
- issue #15499 Fix unparenthesized php deprecation
- issue #15482 Fix URL encoding plus sign (+) in the table or DB name when configuring foreign keys
- issue #14898 Fixed bottom table in list in left panel blocked by horizontal scroll bar
- issue #15161 Fix text area overflows its parent element on "Query" page
- issue #15511 Fixed exporting users after a delete will delete all selected users on "Users" page
- issue #14598 Fixed checking referencial integrity on "Operations" page
- issue #14433 Fix "You do not have privileges to manipulate with the users!" on root superadmin
- issue #15391 Fix GIS polygon of a geometry field is not drawn on "GIS visualization"
- issue #15311 Fix adjust privileges on copy database fails with MariaDB
- issue #15477 Fix display referential integrity check for InnoDB
- issue #15236 Support phpunit 8 in our test suite to help packaging phpMyAdmin on Debian
- issue #15522 Fix missing image error fills logs, removed ic_b_info icon from icon list
- issue #15537 Fixed some issues with the sort by key selectors
- issue #15546 Fix operators precedence in DatabaseInterface class
- issue #14906 Test test suite on 32-bit systems
- issue Fix Long2IP transformation issue with PHP 7.1
- issue #14951 Fix moving columns with DEFAULT NULL doesn't work on MariaDB 10.2+
- issue #14951 Fix moving columns with INT AND DEFAULT CURRENT_TIMESTAMP doesn't work on MariaDB
- issue #12241 Fixed table alias is removed when exporting a query
- issue #15316 Fixed cross join clause is removed on export
- issue #14809 Fix error "is_uploaded_file() expects parameter 1 to be string" when inserting blobs from files
- issue #15127 Fix white square when refreshing designer or browsing other pages
- issue #13912 Detect when phpMyAdmin storage tables are not accessible, help users browse corrupt DBs
- issue #15465 Display profiling when query outputs no rows
- issue Fix setting and removing display field on Designer
- issue Added a warning when trying to set a display field on Designer and configuration storage is not setup
- issue #15327 Fix shift-click in Export misses a checkbox
- issue [security] Fix improperly sanitized data when showing the Git branch (thanks to Ali Hubail for this report)
- issue [security] Fix security weaknesses in Designer feature,including a flaw where an attacker could trigger an SQL injection attack (PMASA-2019-5)
4.9.1 (2019-09-20)
- issue #15313 Added support for Twig 2
- issue #15315 Fix cannot edit or export column with default CURRENT_TIMESTAMP in MySQL >= 8.0.13
- issue Fix a TypeError in Import class with PHP 8
- issue #14270 Fix Middle-click on foreign key link broken
- issue #14363 Fix broken relational links in tables
- issue #14987 Fix weird error for empty collation
- issue #15334 Fix export of GIS visualisation not working (PNG, PDF, SVG)
- issue #14918 Use hex for the phpMyAdmin session token
- issue Added GB18030 Chinese collations description
- issue Added Russian, Swedish, Slovak and Chinese UCA 9.0.0 collations description
- issue Added description for the _ks (kana-sensitive) collation suffix
- issue Added description for the _nopad (NO PAD) collation suffix
- issue #15404 Remove array/string curly braces access
- issue #15427 Fixed "FilterLanguages" option does not work (configuration)
- issue #15202 Fixed creating user with single quote in password results in no password user
- issue #14950 Fixed left database overview "add column" triggers error
- issue #15363 Fix remove unexpected quotes on text fields (structure and insert)
- issue Fix NULL wrongly checked on field change
- issue #15388 Fix allow to rollback an empty statement
- issue #14291 Fixed incorrect linkage from one table's value to another table
- issue #15446 Fix tables added from other databases are not collapsing in the designer section
- issue #14945 Fix designer page save fails if dB name contains period
- issue Display an error when trying to import in designer a table that's already imported
- issue Fix many bugs when adding new tables to designer
- issue Update CodeMirror to v5.48.4
- issue Update jQuery Migrate to v3.1.0
- issue Update jQuery Validation to v1.19.1
- issue Update jQuery to v3.4.1
- issue Update js-cookie to v2.2.1
- issue Remove fieldset closing tag when setting global privileges
- issue #15425 Fix backslash in column name resulting an error in editing
- issue #15380 Fix Status - Advisor error
- issue #15439 Fix designer page status not updated when added a new table from another database
- issue #15440 Fix page number is not being updated in the URL after saving a designer's page
- issue Fix reloading a designer's page
- issue Fix designer full screen mode button and text stuck when exiting full-screen mode
- issue Reduced possibility of causing heavy server traffic between the database and web servers
- issue Fix a situation where a server could be deleted while an administator is using the setup script
4.9.0.1 (2019-06-04)
- issue #14478 phpMyAdmin no longer streams the export data
- issue #14514 Tables with SYSTEM VERSIONING show up as views instead of tables
- issue #14515 Values cannot be edited in SYSTEM VERSIONING tables with INVISIBLE timestamps
- issue Fix header icon on server plugins page
- issue #14298 Fixed error 500 on MultiTableQuery page when a empty query is passed
- issue #14402 Fixed fatal javascript error while adding index to a new column
- issue #14896 Fixed issue with plus/minus icon when refreshing an expanded database
- issue #14922 Fixed json encode error in export
- issue #13975 Fixed missing query time in German (fix decimal number format issue)
- issue #14503 Fixed JavaScript events not activating on input (sql bookmark issue)
- issue #14898 Fixed Bottom table is blocked in database list (left panel)
- issue #14425 Fixed Null Checkbox automatically unmarked
- issue #14870 Display correct date and time in Zip files
- issue #14763 Fixed the loading symbol not appearing when refreshing the navigation
- issue #14607 Count rows only if needed
- issue #14832 Show Designer combo boxes when adding a constraint
- issue #14948 Fix change password is not showing password strength difference at the second attempt
- issue #14868 Fix edit view
- issue #14943 Fixed loading Forever when creating new view without filling any field
- issue #14843 Fix Bookmark::get() id matching SQL
- issue #14734 Fixed invalid default value for bit field
- issue #14311 Fixed undefined index in setup script
- issue #14991 Fixed TypeError in GIS editor
- issue Fixed GIS data editor for multi server setup
- issue #14312 Fixed type error in setup script when adding new server
- issue #14053 Fix missed padding on query results
- issue #14826 Fixed javascript error PMA_messages is not defined
- issue Show error message if config-set fails and not "loading..." forever
- issue #14359 Prevent multiple error modals, and error-report request spamming from script
- issue Fixed error reporting javascript errors on multi server setup
- issue Fixed wrong property name on TableStructureController
- issue #14811 Fix SHOW FULL TABLES FROM when a table is locked
- issue #14916 Fix bug when creating or editing views
- issue #14931 Fixed php error when using a query like SELECT 1 INTO @a; SELECT @a; in inline query edit
- issue #15074 Make the server logo visible on theme "original"
- issue #15077 Fixed incorrect page numbers
- issue #14205 Fixed "No tables found in database" when you delete all tables from last page
- issue #14957 Virtuality is not selected when editing generated column (added virtuality(stored) option for mariadb)
- issue #14853 Insert page should not allow entering things into virtual columns
- issue #15110 Fixed TypeError e.preventDefaulut is not a function
- issue #15115 Improved label in Settings export, clarifying that it's a JSON file
- issue #14816 Fixed [designer] Cannot read property 'style' of null
- issue Fixed [designer] Add new tables with database/table list modal
- issue Fixed query format on multi server setup
- issue Fixed remove partitioning on multi server setup
- issue Fixed normalization
- issue Fixed 'RESET SLAVE' button on replication slave
- issue Fixed sending a php error report on multi server setup
- issue Fixed downloading of monitor parameters for IE 11, Edge, Chrome and others
- issue #15141 Fixed php notice Undefined index: designer_settings
- issue #12729 Fixed sticky table header over dropdown menu
- issue #15140 Fixed edit link does not work on failed insert
- issue #14334 Fixed export table structure shows rows fields
- issue #15010 Fixed empty SQL preview modal on tbl_relation
- issue #14673 Fixed innodb & MySQL 8: DYNAMIC & COMPRESSED ROW_FORMAT missing
- issue Fixed empty success message when adding a new INDEX from left panel
- issue #15150 Fixed generate password hidden on second open of change password modal
- issue Fixed import XML data with leading zeros
- issue #15036 Fixed missing input fields checks for MaxSizeForInputField
- issue #15119 Fixed uninterpreted HTML on Settings->Export page
- issue #15159 Fixed missing query time and database in console
- issue #13713 Fixed column comments in the floating table header
- issue #15177 Fixed label alignment on login page
- issue #15210 Fixed a typo in the english name of the Albanian language
- issue Fixed issue when resetting charset in import.php
- issue #14460 Fixed forms where submitted multiple times on CTRL + ENTER
- issue #15038 Fixed console height was allowing a negative values
- issue #15219 Fixed 'No Password' option does not switch automatically to 'Use Text Field' in add user account
- issue Fixed importing the exported config on Server status monitor page
- issue #15228 Fixed php notice 'Undefined index: foreign_keys_data' on designer when the user has column access
- issue #12900 Fixed designer page saving gives error when configuration storage is not set up
- issue #15229 Fixed php notice, added support for 'DELETE HISTORY' table privilege (MariaDB >= 10.3.4)
- issue #14527 Fixed import settings function not working
- issue #14908 Fixed uninterpreted HTML on Settings->Import (missing data error descriptions)
- issue #14800 Fixed status->Processes doesn't show full query process list page
- issue #14833 Fixed sort by Time not working in process list page
- issue #14982 Fixed setting "null" keep an "enum" value
- issue #14401 Fixed insert rows keypress Enter behavior
- issue #15146 Fixed error reports can not be sent because they are too large
- issue #15205 Fixed useless backquotes on sql preview modal when deleting an index
- issue #13178 Fixed issues with uppercase table and database names (lower_case_table_names=1)
- issue #14383 Fixed warning when browsing certain tables (GIS data)
- issue #12865 Fixed MySQL 8.0.0 issues with GIS display
- issue #15059 Fixed "Server charset" in "Database server" tab showing wrong information
- issue #14614 Fixed mysql error "#2014 - Commands out of sync; you can't run this command now" on sql query
- issue #15238 Fixed phpMyAdmin 4.8.5 doesn't show privileges of procedures (raw html displayed instead)
- issue #13726 Fixed can not copy user on Percona Server 5.7
- issue #15239 Fixed javascript error while fetching latest version info and switching pages
- issue #14301 Fixed javascript error when editing a JSON data type column
- issue #15240 Fixed apply a Settings form with errors shows a JSON response after using return back
- issue #15043 Fixed multiple errors printing on Settings page
- issue #15037 Fixed unexpected behavior of reset button on Settings
- issue #15157 Fixed 'Settings' tab not marked as active when browsing 2FA settings
- issue #14934 Fixed all fields readonly on Edit/Insert screens
- issue #14588 Fixed export of geometry objects, GIS objects are now exported as hex
- issue #14412 Better handling of errors with Signon authentication type
- issue Added support for AUTO_INCREMENT when using ROCKSDB, on Operations page
- issue #15276 Fixed partitioning is missing in Structure page UI (MySQL 8.0)
- issue #14252 Fixed DisableIS and database tree list (new database missing when refreshing the list)
- issue #14621 Removed "Propose table structure" on MySQL 8.0
- issue Fixed editing of virtual columns on PerconaDB
- issue #13854 Fixed column options are ignored for GENERATED/VIRTUAL/STORED columns
- issue #15262 Fixed incorrect display of charset column (raw html)
- issue Added explicit parentheses in nested ternary operators
- issue #15287 Fix auto_increment field is too small
- issue #15283 Fix tries to change collation on views when changing collation on all tables/fields
- issue Fixed empty PMA_gotoWhitelist JavaScript array
- issue #15079 Fixed responsive behaviour of instruction dialog box
- issue #10846 Fixed javascript error when renaming a table
- issue Updated sql-parser to version 4.3.2
- issue [security] SQL injection in Designer (PMASA-2019-3)
- issue [security] CSRF attack on 'cookie' login form (PMASA-2019-4)
4.8.5 (2019-01-25)
- issue Developer debug data was saved to the PHP error log
- issue #14217 Fix issue when adding user on MySQL 8.0.11
- issue #13788 Exporting a view structure based on another view with a sub-query throws no database selected error
- issue #14635 Fix PHP error in GitRevision, error in processing request, error code 200
- issue #14787 Cannot execute stored procedure
- issue Add Burmese language
- issue #14794 Not responding to click, frozen interface, plugin Text_Plain_Sql error
- issue #14786 Table level Operations functions missing
- issue #14791 PHP warning, db_export.php#L91 urldecode()
- issue #14775 Export to SQL format not available for tables
- issue #14782 Error message shown instead of two-factor QR code when adding 2fa to a user
- issue [security] Arbitrary file read/delete relating to MySQL LOAD DATA LOCAL INFILE and an evil server instance (PMASA-2019-1)
- issue [security] SQL injection in Designer (PMASA-2019-2)
--- Older ChangeLogs can be found on our project website ---
https://www.phpmyadmin.net/old-stuff/ChangeLogs/
# vim: et ts=4 sw=4 sts=4
# vim: ft=changelog fenc=utf-8
# vim: fde=getline(v\:lnum-1)=~'^\\s*$'&&getline(v\:lnum)=~'\\S'?'>1'\:1&&v\:lnum>4&&getline(v\:lnum)!~'^#'
# vim: fdn=1 fdm=expr

View File

@ -1,52 +0,0 @@
phpMyAdmin - Readme
===================
Version 5.0.4
A web interface for MySQL and MariaDB.
https://www.phpmyadmin.net/
Summary
-------
phpMyAdmin is intended to handle the administration of MySQL over the web.
For a summary of features, list of requirements, and installation instructions,
please see the documentation in the ./doc/ folder or at https://docs.phpmyadmin.net/
Copyright
---------
Copyright © 1998 onwards -- the phpMyAdmin team
Certain libraries are copyrighted by their respective authors;
see the full copyright list for details.
For full copyright information, please see ./doc/copyright.rst
License
-------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2, as published by the
Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Licensing of current contributions
----------------------------------
Beginning on 2013-12-01, new contributions to this codebase are all licensed
under terms compatible with GPLv2-or-later. phpMyAdmin is currently
transitioning older code to GPLv2-or-later, but work is not yet complete.
Enjoy!
------
The phpMyAdmin team

View File

@ -1 +0,0 @@
Thu Oct 15 18:06:40 UTC 2020

View File

@ -1,74 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Generic AJAX endpoint for getting information about database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\AjaxController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
$_GET['ajax_request'] = 'true';
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
$response->setAjax(true);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var AjaxController $controller */
$controller = $containerBuilder->get(AjaxController::class);
if (empty($_POST['type'])) {
Core::fatalError(__('Bad type!'));
}
switch ($_POST['type']) {
case 'list-databases':
$response->addJSON($controller->databases());
break;
case 'list-tables':
Util::checkParameters(['db'], true);
$response->addJSON($controller->tables([
'db' => $_POST['db'],
]));
break;
case 'list-columns':
Util::checkParameters(['db', 'table'], true);
$response->addJSON($controller->columns([
'db' => $_POST['db'],
'table' => $_POST['table'],
]));
break;
case 'config-get':
Util::checkParameters(['key'], true);
$response->addJSON($controller->getConfig([
'key' => $_POST['key'],
]));
break;
case 'config-set':
Util::checkParameters(['key', 'value'], true);
$result = $controller->setConfig([
'key' => $_POST['key'],
'value' => $_POST['value'],
]);
if ($result !== true) {
$response->setRequestStatus(false);
$response->addJSON('message', $result);
}
break;
default:
Core::fatalError(__('Bad type!'));
}

View File

@ -1,62 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* display selection for relational field values
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\BrowseForeigners;
use PhpMyAdmin\Controllers\BrowseForeignersController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
Util::checkParameters(['db', 'table', 'field'], true);
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
/* Register BrowseForeignersController dependencies */
$containerBuilder->set(
'browse_foreigners',
new BrowseForeigners(
(int) $GLOBALS['cfg']['LimitChars'],
(int) $GLOBALS['cfg']['MaxRows'],
(int) $GLOBALS['cfg']['RepeatCells'],
(bool) $GLOBALS['cfg']['ShowAll'],
$GLOBALS['pmaThemeImage'],
$template
)
);
/** @var BrowseForeignersController $controller */
$controller = $containerBuilder->get(BrowseForeignersController::class);
$response->getFooter()->setMinimal();
$header = $response->getHeader();
$header->disableMenuAndConsole();
$header->setBodyId('body_browse_foreigners');
$response->addHTML($controller->index([
'db' => $_POST['db'] ?? null,
'table' => $_POST['table'] ?? null,
'field' => $_POST['field'] ?? null,
'fieldkey' => $_POST['fieldkey'] ?? null,
'data' => $_POST['data'] ?? null,
'foreign_showAll' => $_POST['foreign_showAll'] ?? null,
'foreign_filter' => $_POST['foreign_filter'] ?? null,
]));

View File

@ -1,112 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Simple script to set correct charset for changelog
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/**
* Gets core libraries and defines some variables
*/
require ROOT_PATH . 'libraries/common.inc.php';
/** @var Template $template */
$template = $containerBuilder->get('template');
$response = Response::getInstance();
$response->disable();
$response->getHeader()->sendHttpHeaders();
$filename = CHANGELOG_FILE;
/**
* Read changelog.
*/
// Check if the file is available, some distributions remove these.
if (@is_readable($filename)) {
// Test if the if is in a compressed format
if (substr($filename, -3) == '.gz') {
ob_start();
readgzfile($filename);
$changelog = ob_get_contents();
ob_end_clean();
} else {
$changelog = file_get_contents($filename);
}
} else {
printf(
__(
'The %s file is not available on this system, please visit ' .
'%s for more information.'
),
$filename,
'<a href="https://www.phpmyadmin.net/">phpmyadmin.net</a>'
);
exit;
}
/**
* Whole changelog in variable.
*/
$changelog = htmlspecialchars($changelog);
$github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
$faq_url = 'https://docs.phpmyadmin.net/en/latest/faq.html';
$replaces = [
'@(https?://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
=> '<a href="url.php?url=\\1">\\1</a>',
// mail address
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*@.*)&gt;/i'
=> '\\1 <a href="mailto:\\3">\\2</a>',
// FAQ entries
'/FAQ ([0-9]+)\.([0-9a-z]+)/i'
=> '<a href="url.php?url=' . $faq_url . '#faq\\1-\\2">FAQ \\1.\\2</a>',
// GitHub issues
'/issue\s*#?([0-9]{4,5}) /i'
=> '<a href="url.php?url=' . $github_url . 'issues/\\1">issue #\\1</a> ',
// CVE/CAN entries
'/((CAN|CVE)-[0-9]+-[0-9]+)/'
=> '<a href="url.php?url=https://cve.mitre.org/cgi-bin/cvename.cgi?name=\\1">\\1</a>',
// PMASAentries
'/(PMASA-[0-9]+-[0-9]+)/'
=> '<a href="url.php?url=https://www.phpmyadmin.net/security/\\1/">\\1</a>',
// Highlight releases (with links)
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.0 (\([0-9-]+\))/'
=> '<a id="\\1_\\2_\\3"></a>'
. '<a href="url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3">'
. '\\1.\\2.\\3.0 \\4</a>',
'/([0-9]+)\.([0-9]+)\.([0-9]+)\.([1-9][0-9]*) (\([0-9-]+\))/'
=> '<a id="\\1_\\2_\\3_\\4"></a>'
. '<a href="url.php?url=' . $github_url . 'commits/RELEASE_\\1_\\2_\\3_\\4">'
. '\\1.\\2.\\3.\\4 \\5</a>',
// Highlight releases (not linkable)
'/( ### )(.*)/'
=> '\\1<b>\\2</b>',
// Links target and rel
'/a href="/' => 'a target="_blank" rel="noopener noreferrer" href="',
];
header('Content-type: text/html; charset=utf-8');
echo $template->render('changelog', [
'changelog' => preg_replace(array_keys($replaces), $replaces, $changelog),
]);

View File

@ -1,47 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays status of phpMyAdmin configuration storage
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
// If request for creating the pmadb
if (isset($_POST['create_pmadb']) && $relation->createPmaDatabase()) {
$relation->fixPmaTables('phpmyadmin');
}
// If request for creating all PMA tables.
if (isset($_POST['fixall_pmadb'])) {
$relation->fixPmaTables($GLOBALS['db']);
}
$cfgRelation = $relation->getRelationsParam();
// If request for creating missing PMA tables.
if (isset($_POST['fix_pmadb'])) {
$relation->fixPmaTables($cfgRelation['db']);
}
$response->addHTML(
$relation->getRelationsParamDiagnostic($cfgRelation)
);

View File

@ -1,112 +0,0 @@
{
"name": "phpmyadmin/phpmyadmin",
"type": "project",
"description": "A web interface for MySQL and MariaDB",
"keywords": ["phpmyadmin","mysql","web"],
"homepage": "https://www.phpmyadmin.net/",
"support": {
"forum": "https://www.phpmyadmin.net/support/",
"issues": "https://github.com/phpmyadmin/phpmyadmin/issues",
"wiki": "https://wiki.phpmyadmin.net/",
"docs": "https://docs.phpmyadmin.net/",
"source": "https://github.com/phpmyadmin/phpmyadmin"
},
"license": "GPL-2.0-only",
"authors": [
{
"name": "The phpMyAdmin Team",
"email": "developers@phpmyadmin.net",
"homepage": "https://www.phpmyadmin.net/team/"
}
],
"non-feature-branches": ["RELEASE_.*"],
"autoload": {
"psr-4": {
"PhpMyAdmin\\": "libraries/classes"
}
},
"autoload-dev": {
"psr-4": {
"PhpMyAdmin\\Tests\\": "test/classes",
"PhpMyAdmin\\Tests\\Selenium\\": "test/selenium/"
}
},
"repositories": [
{
"type": "composer",
"url": "https://www.phpmyadmin.net"
}
],
"require": {
"php": "^7.1.3",
"ext-hash": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mysqli": "*",
"ext-pcre": "*",
"ext-xml": "*",
"google/recaptcha": "^1.1",
"phpmyadmin/motranslator": "^4.0",
"phpmyadmin/shapefile": "^2.0",
"phpmyadmin/sql-parser": "^5.0",
"phpmyadmin/twig-i18n-extension": "^2.0 || ^3.0",
"phpseclib/phpseclib": "^2.0",
"symfony/config": "^4.2.8",
"symfony/dependency-injection": "^4.2.8",
"symfony/expression-language": "^4.2",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3",
"symfony/yaml": "^4.2.8",
"twig/twig": "^2.9 || ^3",
"williamdes/mariadb-mysql-kbs": "^1.2"
},
"conflict": {
"phpseclib/phpseclib": "2.0.8",
"tecnickcom/tcpdf": "<6.2",
"pragmarx/google2fa": ">=6.1",
"pragmarx/google2fa-qrcode": "<1.0.1",
"samyoul/u2f-php-server": "<1.1"
},
"suggest": {
"ext-openssl": "Cookie encryption",
"ext-curl": "Updates checking",
"ext-opcache": "Better performance",
"ext-zlib": "For gz import and export",
"ext-bz2": "For bzip2 import and export",
"ext-zip": "For zip import and export",
"ext-gd2": "For image transformations",
"ext-mbstring": "For best performance",
"tecnickcom/tcpdf": "For PDF support",
"pragmarx/google2fa-qrcode": "For 2FA authentication",
"samyoul/u2f-php-server": "For FIDO U2F authentication"
},
"require-dev": {
"php-webdriver/webdriver": "^1.7.1",
"phpmyadmin/coding-standard": "^1.0",
"phpstan/phpstan": "^0.11.5",
"phpunit/phpunit": "^7.5 || ^8.0 || ^9.0",
"pragmarx/google2fa-qrcode": "^1.0.1",
"samyoul/u2f-php-server": "^1.1",
"squizlabs/php_codesniffer": "^3.0",
"tecnickcom/tcpdf": "^6.3"
},
"extra": {
"branch-alias": {
"dev-master": "5.0.x-dev"
}
},
"scripts": {
"phpcbf": "phpcbf",
"phpcs": "phpcs",
"phpstan": "phpstan analyse",
"phpunit": "phpunit",
"test": [
"@phpcs",
"@phpstan",
"@phpunit"
]
},
"config":{
"sort-packages": true
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,138 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Central Columns view/edit
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
use PhpMyAdmin\CentralColumns;
use PhpMyAdmin\Controllers\Database\CentralColumnsController;
use PhpMyAdmin\Core;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var CentralColumns $centralColumns */
$centralColumns = $containerBuilder->get('central_columns');
/** @var CentralColumnsController $controller */
$controller = $containerBuilder->get(CentralColumnsController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
if (isset($_POST['edit_save'])) {
echo $controller->editSave([
'col_name' => $_POST['col_name'] ?? null,
'orig_col_name' => $_POST['orig_col_name'] ?? null,
'col_default' => $_POST['col_default'] ?? null,
'col_default_sel' => $_POST['col_default_sel'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
'col_isNull' => $_POST['col_isNull'] ?? null,
'col_length' => $_POST['col_length'] ?? null,
'col_attribute' => $_POST['col_attribute'] ?? null,
'col_type' => $_POST['col_type'] ?? null,
'collation' => $_POST['collation'] ?? null,
]);
exit;
} elseif (isset($_POST['add_new_column'])) {
$tmp_msg = $controller->addNewColumn([
'col_name' => $_POST['col_name'] ?? null,
'col_default' => $_POST['col_default'] ?? null,
'col_default_sel' => $_POST['col_default_sel'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
'col_isNull' => $_POST['col_isNull'] ?? null,
'col_length' => $_POST['col_length'] ?? null,
'col_attribute' => $_POST['col_attribute'] ?? null,
'col_type' => $_POST['col_type'] ?? null,
'collation' => $_POST['collation'] ?? null,
]);
}
if (isset($_POST['populateColumns'])) {
$response->addHTML($controller->populateColumns([
'selectedTable' => $_POST['selectedTable'],
]));
exit;
}
if (isset($_POST['getColumnList'])) {
$response->addJSON('message', $controller->getColumnList([
'cur_table' => $_POST['cur_table'] ?? null,
]));
exit;
}
if (isset($_POST['add_column'])) {
$tmp_msg = $controller->addColumn([
'table-select' => $_POST['table-select'] ?? null,
'column-select' => $_POST['column-select'] ?? null,
]);
}
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('database/central_columns.js');
if (isset($_POST['edit_central_columns_page'])) {
$response->addHTML($controller->editPage([
'selected_fld' => $_POST['selected_fld'] ?? null,
'db' => $_POST['db'] ?? null,
]));
exit;
}
if (isset($_POST['multi_edit_central_column_save'])) {
$message = $controller->updateMultipleColumn([
'db' => $_POST['db'] ?? null,
'orig_col_name' => $_POST['orig_col_name'] ?? null,
'field_name' => $_POST['field_name'] ?? null,
'field_default_type' => $_POST['field_default_type'] ?? null,
'field_default_value' => $_POST['field_default_value'] ?? null,
'field_length' => $_POST['field_length'] ?? null,
'field_attribute' => $_POST['field_attribute'] ?? null,
'field_type' => $_POST['field_type'] ?? null,
'field_collation' => $_POST['field_collation'] ?? null,
'field_null' => $_POST['field_null'] ?? null,
'col_extra' => $_POST['col_extra'] ?? null,
]);
if (! is_bool($message)) {
$response->setRequestStatus(false);
$response->addJSON('message', $message);
}
}
if (isset($_POST['delete_save'])) {
$tmp_msg = $controller->deleteSave([
'db' => $_POST['db'] ?? null,
'col_name' => $_POST['col_name'] ?? null,
]);
}
$response->addHTML($controller->index([
'pos' => $_POST['pos'] ?? null,
'total_rows' => $_POST['total_rows'] ?? null,
]));
$pos = 0;
if (Core::isValid($_POST['pos'], 'integer')) {
$pos = (int) $_POST['pos'];
}
$num_cols = $centralColumns->getColumnsCount(
$db,
$pos,
(int) $GLOBALS['cfg']['MaxRows']
);
$message = Message::success(
sprintf(__('Showing rows %1$s - %2$s.'), $pos + 1, $pos + $num_cols)
);
if (isset($tmp_msg) && $tmp_msg !== true) {
$message = $tmp_msg;
}

View File

@ -1,31 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Renders data dictionary
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\DataDictionaryController;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
Util::checkParameters(['db']);
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DataDictionaryController $controller */
$controller = $containerBuilder->get(DataDictionaryController::class);
$header = $response->getHeader();
$header->enablePrintView();
$response->addHTML($controller->index());

View File

@ -1,236 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* phpMyAdmin designer general code
*
* @package PhpMyAdmin-Designer
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Designer;
use PhpMyAdmin\Database\Designer\Common;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Designer $databaseDesigner */
$databaseDesigner = $containerBuilder->get('designer');
/** @var Common $designerCommon */
$designerCommon = $containerBuilder->get('designer_common');
if (isset($_POST['dialog'])) {
if ($_POST['dialog'] == 'edit') {
$html = $databaseDesigner->getHtmlForEditOrDeletePages($_POST['db'], 'editPage');
} elseif ($_POST['dialog'] == 'delete') {
$html = $databaseDesigner->getHtmlForEditOrDeletePages($_POST['db'], 'deletePage');
} elseif ($_POST['dialog'] == 'save_as') {
$html = $databaseDesigner->getHtmlForPageSaveAs($_POST['db']);
} elseif ($_POST['dialog'] == 'export') {
$html = $databaseDesigner->getHtmlForSchemaExport(
$_POST['db'],
$_POST['selected_page']
);
} elseif ($_POST['dialog'] == 'add_table') {
// Pass the db and table to the getTablesInfo so we only have the table we asked for
$script_display_field = $designerCommon->getTablesInfo($_POST['db'], $_POST['table']);
$tab_column = $designerCommon->getColumnsInfo($script_display_field);
$tables_all_keys = $designerCommon->getAllKeys($script_display_field);
$tables_pk_or_unique_keys = $designerCommon->getPkOrUniqueKeys($script_display_field);
$html = $databaseDesigner->getDatabaseTables(
$_POST['db'],
$script_display_field,
[],
-1,
$tab_column,
$tables_all_keys,
$tables_pk_or_unique_keys
);
}
if (! empty($html)) {
$response->addHTML($html);
}
return;
}
if (isset($_POST['operation'])) {
if ($_POST['operation'] == 'deletePage') {
$success = $designerCommon->deletePage($_POST['selected_page']);
$response->setRequestStatus($success);
} elseif ($_POST['operation'] == 'savePage') {
if ($_POST['save_page'] == 'same') {
$page = $_POST['selected_page'];
} else { // new
if ($designerCommon->getPageExists($_POST['selected_value'])) {
$response->addJSON(
'message',
/* l10n: The user tries to save a page with an existing name in Designer */
__(
sprintf(
"There already exists a page named \"%s\" please rename it to something else.",
htmlspecialchars($_POST['selected_value'])
)
)
);
$response->setRequestStatus(false);
return;
} else {
$page = $designerCommon->createNewPage($_POST['selected_value'], $_POST['db']);
$response->addJSON('id', $page);
}
}
$success = $designerCommon->saveTablePositions($page);
$response->setRequestStatus($success);
} elseif ($_POST['operation'] == 'setDisplayField') {
[
$success,
$message,
] = $designerCommon->saveDisplayField(
$_POST['db'],
$_POST['table'],
$_POST['field']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'addNewRelation') {
list($success, $message) = $designerCommon->addNewRelation(
$_POST['db'],
$_POST['T1'],
$_POST['F1'],
$_POST['T2'],
$_POST['F2'],
$_POST['on_delete'],
$_POST['on_update'],
$_POST['DB1'],
$_POST['DB2']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'removeRelation') {
list($success, $message) = $designerCommon->removeRelation(
$_POST['T1'],
$_POST['F1'],
$_POST['T2'],
$_POST['F2']
);
$response->setRequestStatus($success);
$response->addJSON('message', $message);
} elseif ($_POST['operation'] == 'save_setting_value') {
$success = $designerCommon->saveSetting($_POST['index'], $_POST['value']);
$response->setRequestStatus($success);
}
return;
}
require ROOT_PATH . 'libraries/db_common.inc.php';
$script_display_field = $designerCommon->getTablesInfo();
$display_page = -1;
$selected_page = null;
if (isset($_GET['query'])) {
$display_page = $designerCommon->getDefaultPage($_GET['db']);
} elseif (! empty($_GET['page'])) {
$display_page = $_GET['page'];
} else {
$display_page = $designerCommon->getLoadingPage($_GET['db']);
}
if ($display_page != -1) {
$selected_page = $designerCommon->getPageName($display_page);
}
$tab_pos = $designerCommon->getTablePositions($display_page);
$fullTableNames = [];
foreach ($script_display_field as $designerTable) {
$fullTableNames[] = $designerTable->getDbTableString();
}
foreach ($tab_pos as $position) {
if (! in_array($position['dbName'] . '.' . $position['tableName'], $fullTableNames)) {
foreach ($designerCommon->getTablesInfo($position['dbName'], $position['tableName']) as $designerTable) {
$script_display_field[] = $designerTable;
}
}
}
$tab_column = $designerCommon->getColumnsInfo($script_display_field);
$script_tables = $designerCommon->getScriptTabs($script_display_field);
$tables_pk_or_unique_keys = $designerCommon->getPkOrUniqueKeys($script_display_field);
$tables_all_keys = $designerCommon->getAllKeys($script_display_field);
$classes_side_menu = $databaseDesigner->returnClassNamesFromMenuButtons();
$script_contr = $designerCommon->getScriptContr($script_display_field);
$params = ['lang' => $GLOBALS['lang']];
if (isset($_GET['db'])) {
$params['db'] = $_GET['db'];
}
$response = Response::getInstance();
$response->getFooter()->setMinimal();
$header = $response->getHeader();
$header->setBodyId('designer_body');
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.fullscreen.js');
$scripts->addFile('designer/database.js');
$scripts->addFile('designer/objects.js');
$scripts->addFile('designer/page.js');
$scripts->addFile('designer/history.js');
$scripts->addFile('designer/move.js');
$scripts->addFile('designer/init.js');
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = PhpMyAdmin\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
// Embed some data into HTML, later it will be read
// by designer/init.js and converted to JS variables.
$response->addHTML(
$databaseDesigner->getHtmlForMain(
$db,
$_GET['db'],
$script_display_field,
$script_tables,
$script_contr,
$script_display_field,
$display_page,
isset($_GET['query']),
$selected_page,
$classes_side_menu,
$tab_pos,
$tab_column,
$tables_all_keys,
$tables_pk_or_unique_keys
)
);
$response->addHTML('<div id="PMA_disable_floating_menubar"></div>');

View File

@ -1,80 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Events management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\EventsController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$_PMA_RTE = 'EVN';
/** @var EventsController $controller */
$controller = $containerBuilder->get(EventsController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index();

View File

@ -1,173 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* dumps a database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\Export as DisplayExport;
use PhpMyAdmin\Export;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $table, $url_query, $containerBuilder;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
PageSettings::showGroup('Export');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export.js');
/** @var Export $export */
$export = $containerBuilder->get('export');
// $sub_part is used in Util::getDbInfo() to see if we are coming from
// db_export.php, in which case we don't obey $cfg['MaxTableList']
$sub_part = '_export';
require_once ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_export.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
/**
* Displays the form
*/
$export_page_title = __('View dump (schema) of database');
// exit if no tables in db found
if ($num_tables < 1) {
$response->addHTML(
Message::error(__('No tables found in database.'))->getDisplay()
);
exit;
} // end if
$multi_values = '<div class="export_table_list_container">';
if (isset($_POST['structure_or_data_forced'])) {
$force_val = htmlspecialchars($_POST['structure_or_data_forced']);
} else {
$force_val = 0;
}
$multi_values .= '<input type="hidden" name="structure_or_data_forced" value="'
. $force_val . '">';
$multi_values .= '<table class="export_table_select">'
. '<thead><tr><th></th>'
. '<th>' . __('Tables') . '</th>'
. '<th class="export_structure">' . __('Structure') . '</th>'
. '<th class="export_data">' . __('Data') . '</th>'
. '</tr><tr>'
. '<td></td>'
. '<td class="export_table_name all">' . __('Select all') . '</td>'
. '<td class="export_structure all">'
. '<input type="checkbox" id="table_structure_all"></td>'
. '<td class="export_data all"><input type="checkbox" id="table_data_all">'
. '</td>'
. '</tr></thead>'
. '<tbody>';
$multi_values .= "\n";
// when called by libraries/mult_submits.inc.php
if (! empty($_POST['selected_tbl']) && empty($table_select)) {
$table_select = $_POST['selected_tbl'];
}
foreach ($tables as $each_table) {
if (isset($_POST['table_select']) && is_array($_POST['table_select'])) {
$is_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_select']
);
} elseif (isset($table_select)) {
$is_checked = $export->getCheckedClause(
$each_table['Name'],
$table_select
);
} else {
$is_checked = ' checked="checked"';
}
if (isset($_POST['table_structure']) && is_array($_POST['table_structure'])) {
$structure_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_structure']
);
} else {
$structure_checked = $is_checked;
}
if (isset($_POST['table_data']) && is_array($_POST['table_data'])) {
$data_checked = $export->getCheckedClause(
$each_table['Name'],
$_POST['table_data']
);
} else {
$data_checked = $is_checked;
}
$table_html = htmlspecialchars($each_table['Name']);
$multi_values .= '<tr class="marked">';
$multi_values .= '<td><input type="checkbox" name="table_select[]"'
. ' value="' . $table_html . '"' . $is_checked . ' class="checkall"></td>';
$multi_values .= '<td class="export_table_name">'
. str_replace(' ', '&nbsp;', $table_html) . '</td>';
$multi_values .= '<td class="export_structure">'
. '<input type="checkbox" name="table_structure[]"'
. ' value="' . $table_html . '"' . $structure_checked . '></td>';
$multi_values .= '<td class="export_data">'
. '<input type="checkbox" name="table_data[]"'
. ' value="' . $table_html . '"' . $data_checked . '></td>';
$multi_values .= '</tr>';
} // end for
$multi_values .= "\n";
$multi_values .= '</tbody></table></div>';
if (! isset($sql_query)) {
$sql_query = '';
}
if (! isset($num_tables)) {
$num_tables = 0;
}
if (! isset($unlim_num_rows)) {
$unlim_num_rows = 0;
}
if ($multi_values === null) {
$multi_values = '';
}
$response = Response::getInstance();
$displayExport = new DisplayExport();
$response->addHTML(
$displayExport->getDisplay(
'database',
$db,
$table,
$sql_query,
$num_tables,
$unlim_num_rows,
$multi_values
)
);

View File

@ -1,56 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database import page
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Config\PageSettings;
use PhpMyAdmin\Display\Import;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $table;
require_once ROOT_PATH . 'libraries/common.inc.php';
PageSettings::showGroup('Import');
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('import.js');
$import = new Import();
/**
* Gets tables information and displays top links
*/
require ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = PhpMyAdmin\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
$response = Response::getInstance();
$response->addHTML(
$import->get(
'database',
$db,
$table,
$max_upload_size
)
);

View File

@ -1,51 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Handles database multi-table querying
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\MultiTableQueryController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var MultiTableQueryController $controller */
$controller = $containerBuilder->get(MultiTableQueryController::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
if (isset($_POST['sql_query'])) {
$controller->displayResults([
'sql_query' => $_POST['sql_query'],
'db' => $_REQUEST['db'] ?? null,
]);
} elseif (isset($_GET['tables'])) {
$response->addJSON($controller->table([
'tables' => $_GET['tables'],
'db' => $_REQUEST['db'] ?? null,
]));
} else {
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.md5.js');
$scripts->addFile('database/multi_table_query.js');
$scripts->addFile('database/query_generator.js');
$response->addHTML($controller->index($template));
}

View File

@ -1,321 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* handles miscellaneous db operations:
* - move/rename
* - copy
* - changing collation
* - changing comment
* - adding tables
* - viewing PDF schemas
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\CheckUserPrivileges;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Display\CreateTable;
use PhpMyAdmin\Message;
use PhpMyAdmin\Operations;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\Export\ExportSql;
use PhpMyAdmin\Relation;
use PhpMyAdmin\RelationCleanup;
use PhpMyAdmin\Response;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $cfg, $db, $server, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$checkUserPrivileges = new CheckUserPrivileges($dbi);
$checkUserPrivileges->getPrivileges();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/operations.js');
$sql_query = '';
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
$operations = new Operations($dbi, $relation);
$relationCleanup = new RelationCleanup($dbi, $relation);
/**
* Rename/move or copy database
*/
if (strlen($db) > 0
&& (! empty($_POST['db_rename']) || ! empty($_POST['db_copy']))
) {
if (! empty($_POST['db_rename'])) {
$move = true;
} else {
$move = false;
}
if (! isset($_POST['newname']) || strlen($_POST['newname']) === 0) {
$message = Message::error(__('The database name is empty!'));
} else {
// lower_case_table_names=1 `DB` becomes `db`
if ($dbi->getLowerCaseNames() === '1') {
$_POST['newname'] = mb_strtolower(
$_POST['newname']
);
}
if ($_POST['newname'] === $_REQUEST['db']) {
$message = Message::error(
__('Cannot copy database to the same name. Change the name and try again.')
);
} else {
$_error = false;
if ($move || ! empty($_POST['create_database_before_copying'])) {
$operations->createDbBeforeCopy();
}
// here I don't use DELIMITER because it's not part of the
// language; I have to send each statement one by one
// to avoid selecting alternatively the current and new db
// we would need to modify the CREATE definitions to qualify
// the db name
$operations->runProcedureAndFunctionDefinitions($db);
// go back to current db, just in case
$dbi->selectDb($db);
$tables_full = $dbi->getTablesFull($db);
// remove all foreign key constraints, otherwise we can get errors
/** @var ExportSql $export_sql_plugin */
$export_sql_plugin = Plugins::getPlugin(
"export",
"sql",
'libraries/classes/Plugins/Export/',
[
'single_table' => isset($single_table),
'export_type' => 'database',
]
);
// create stand-in tables for views
$views = $operations->getViewsAndCreateSqlViewStandIn(
$tables_full,
$export_sql_plugin,
$db
);
// copy tables
$sqlConstratints = $operations->copyTables(
$tables_full,
$move,
$db
);
// handle the views
if (! $_error) {
$operations->handleTheViews($views, $move, $db);
}
unset($views);
// now that all tables exist, create all the accumulated constraints
if (! $_error && count($sqlConstratints) > 0) {
$operations->createAllAccumulatedConstraints($sqlConstratints);
}
unset($sqlConstratints);
if ($dbi->getVersion() >= 50100) {
// here DELIMITER is not used because it's not part of the
// language; each statement is sent one by one
$operations->runEventDefinitionsForDb($db);
}
// go back to current db, just in case
$dbi->selectDb($db);
// Duplicate the bookmarks for this db (done once for each db)
$operations->duplicateBookmarks($_error, $db);
if (! $_error && $move) {
if (isset($_POST['adjust_privileges'])
&& ! empty($_POST['adjust_privileges'])
) {
$operations->adjustPrivilegesMoveDb($db, $_POST['newname']);
}
/**
* cleanup pmadb stuff for this db
*/
$relationCleanup->database($db);
// if someday the RENAME DATABASE reappears, do not DROP
$local_query = 'DROP DATABASE '
. Util::backquote($db) . ';';
$sql_query .= "\n" . $local_query;
$dbi->query($local_query);
$message = Message::success(
__('Database %1$s has been renamed to %2$s.')
);
$message->addParam($db);
$message->addParam($_POST['newname']);
} elseif (! $_error) {
if (isset($_POST['adjust_privileges'])
&& ! empty($_POST['adjust_privileges'])
) {
$operations->adjustPrivilegesCopyDb($db, $_POST['newname']);
}
$message = Message::success(
__('Database %1$s has been copied to %2$s.')
);
$message->addParam($db);
$message->addParam($_POST['newname']);
} else {
$message = Message::error();
}
$reload = true;
/* Change database to be used */
if (! $_error && $move) {
$db = $_POST['newname'];
} elseif (! $_error) {
if (isset($_POST['switch_to_new'])
&& $_POST['switch_to_new'] == 'true'
) {
$_SESSION['pma_switch_to_new'] = true;
$db = $_POST['newname'];
} else {
$_SESSION['pma_switch_to_new'] = false;
}
}
}
}
/**
* Database has been successfully renamed/moved. If in an Ajax request,
* generate the output with {@link PhpMyAdmin\Response} and exit
*/
if ($response->isAjax()) {
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('newname', $_POST['newname']);
$response->addJSON(
'sql_query',
Util::getMessage(null, $sql_query)
);
$response->addJSON('db', $db);
exit;
}
}
/**
* Settings for relations stuff
*/
$cfgRelation = $relation->getRelationsParam();
/**
* Check if comments were updated
* (must be done before displaying the menu tabs)
*/
if (isset($_POST['comment'])) {
$relation->setDbComment($db, $_POST['comment']);
}
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_operations.php';
// Gets the database structure
$sub_part = '_structure';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
echo "\n";
if (isset($message)) {
echo Util::getMessage($message, $sql_query);
unset($message);
}
$db_collation = $dbi->getDbCollation($db);
$is_information_schema = $dbi->isSystemSchema($db);
if (! $is_information_schema) {
if ($cfgRelation['commwork']) {
/**
* database comment
*/
$response->addHTML($operations->getHtmlForDatabaseComment($db));
}
$response->addHTML('<div>');
$response->addHTML(CreateTable::getHtml($db));
$response->addHTML('</div>');
/**
* rename database
*/
if ($db != 'mysql') {
$response->addHTML($operations->getHtmlForRenameDatabase($db, $db_collation));
}
// Drop link if allowed
// Don't even try to drop information_schema.
// You won't be able to. Believe me. You won't.
// Don't allow to easily drop mysql database, RFE #1327514.
if (($dbi->isSuperuser() || $cfg['AllowUserDropDatabase'])
&& ! $db_is_system_schema
&& $db != 'mysql'
) {
$response->addHTML($operations->getHtmlForDropDatabaseLink($db));
}
/**
* Copy database
*/
$response->addHTML($operations->getHtmlForCopyDatabase($db, $db_collation));
/**
* Change database charset
*/
$response->addHTML($operations->getHtmlForChangeDatabaseCharset($db, $db_collation));
if (! $cfgRelation['allworks']
&& $cfg['PmaNoRelation_DisableWarning'] == false
) {
$message = Message::notice(
__(
'The phpMyAdmin configuration storage has been deactivated. ' .
'%sFind out why%s.'
)
);
$message->addParamHtml('<a href="./chk_rel.php" data-post="' . $url_query . '">');
$message->addParamHtml('</a>');
/* Show error if user has configured something, notice elsewhere */
if (! empty($cfg['Servers'][$server]['pmadb'])) {
$message->isError(true);
}
} // end if
} // end if (!$is_information_schema)

View File

@ -1,192 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* query by example the whole database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Qbe;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Message;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\SavedSearches;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Template;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $pmaThemeImage, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
/** @var Template $template */
$template = $containerBuilder->get('template');
// Gets the relation settings
$cfgRelation = $relation->getRelationsParam();
$savedSearchList = [];
$savedSearch = null;
$currentSearchId = null;
if ($cfgRelation['savedsearcheswork']) {
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/qbe.js');
//Get saved search list.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
if (! empty($_POST['searchId'])) {
$savedSearch->setId($_POST['searchId']);
}
//Action field is sent.
if (isset($_POST['action'])) {
$savedSearch->setSearchName($_POST['searchName']);
if ('create' === $_POST['action']) {
$saveResult = $savedSearch->setId(null)
->setCriterias($_POST)
->save();
} elseif ('update' === $_POST['action']) {
$saveResult = $savedSearch->setCriterias($_POST)
->save();
} elseif ('delete' === $_POST['action']) {
$deleteResult = $savedSearch->delete();
//After deletion, reset search.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
$_POST = [];
} elseif ('load' === $_POST['action']) {
if (empty($_POST['searchId'])) {
//when not loading a search, reset the object.
$savedSearch = new SavedSearches($GLOBALS, $relation);
$savedSearch->setUsername($GLOBALS['cfg']['Server']['user'])
->setDbname($db);
$_POST = [];
} else {
$loadResult = $savedSearch->load();
}
}
//Else, it's an "update query"
}
$savedSearchList = $savedSearch->getList();
$currentSearchId = $savedSearch->getId();
}
/**
* A query has been submitted -> (maybe) execute it
*/
$message_to_display = false;
if (isset($_POST['submit_sql']) && ! empty($sql_query)) {
if (0 !== stripos($sql_query, "SELECT")) {
$message_to_display = true;
} else {
$goto = 'db_sql.php';
$sql = new Sql();
$sql->executeQueryAndSendQueryResponse(
null, // analyzed_sql_results
false, // is_gotofile
$_POST['db'], // db
null, // table
false, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
}
$sub_part = '_qbe';
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_qbe.php';
$url_params['goto'] = 'db_qbe.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
if ($message_to_display) {
Message::error(
__('You have to choose at least one column to display!')
)
->display();
}
unset($message_to_display);
// create new qbe search instance
$db_qbe = new Qbe($relation, $template, $dbi, $db, $savedSearchList, $savedSearch);
$secondaryTabs = [
'multi' => [
'link' => 'db_multi_table_query.php',
'text' => __('Multi-table query'),
],
'qbe' => [
'link' => 'db_qbe.php',
'text' => __('Query by example'),
],
];
$response->addHTML(
$template->render('secondary_tabs', [
'url_params' => $url_params,
'sub_tabs' => $secondaryTabs,
])
);
$url = 'db_designer.php' . Url::getCommon(
array_merge(
$url_params,
['query' => 1]
)
);
$response->addHTML(
Message::notice(
sprintf(
__('Switch to %svisual builder%s'),
'<a href="' . $url . '">',
'</a>'
)
)
);
/**
* Displays the Query by example form
*/
$response->addHTML($db_qbe->getSelectionForm());

View File

@ -1,87 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Routines management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\CheckUserPrivileges;
use PhpMyAdmin\Controllers\Database\RoutinesController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
/** @var CheckUserPrivileges $checkUserPrivileges */
$checkUserPrivileges = $containerBuilder->get('check_user_privileges');
$checkUserPrivileges->getPrivileges();
$_PMA_RTE = 'RTN';
/** @var RoutinesController $controller */
$controller = $containerBuilder->get(RoutinesController::class);
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index([
'type' => $_REQUEST['type'] ?? null,
]);

View File

@ -1,85 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* searches the entire database
*
* @todo make use of UNION when searching multiple tables
* @todo display executed query, optional?
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Database\Search;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var Template $template */
$template = $containerBuilder->get('template');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('database/search.js');
$scripts->addFile('vendor/stickyfill.min.js');
$scripts->addFile('sql.js');
$scripts->addFile('makegrid.js');
require ROOT_PATH . 'libraries/db_common.inc.php';
// If config variable $GLOBALS['cfg']['UseDbSearch'] is on false : exit.
if (! $GLOBALS['cfg']['UseDbSearch']) {
Util::mysqlDie(
__('Access denied!'),
'',
false,
$err_url
);
} // end if
$url_query .= '&amp;goto=db_search.php';
$url_params['goto'] = 'db_search.php';
// Create a database search instance
$db_search = new Search($dbi, $db, $template);
// Display top links if we are not in an Ajax request
if (! $response->isAjax()) {
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
// Main search form has been submitted, get results
if (isset($_POST['submit_search'])) {
$response->addHTML($db_search->getSearchResults());
}
// If we are in an Ajax request, we need to exit after displaying all the HTML
if ($response->isAjax() && empty($_REQUEST['ajax_page_request'])) {
exit;
}
// Display the search form
$response->addHTML($db_search->getMainHtml());

View File

@ -1,49 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database SQL executor
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\SqlController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\SqlQueryForm;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $containerBuilder;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var SqlController $controller */
$controller = $containerBuilder->get(SqlController::class);
/** @var SqlQueryForm $sqlQueryForm */
$sqlQueryForm = $containerBuilder->get('sql_query_form');
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('makegrid.js');
$scripts->addFile('vendor/jquery/jquery.uitablefilter.js');
$scripts->addFile('vendor/stickyfill.min.js');
$scripts->addFile('sql.js');
$response->addHTML(
$controller->index(
[
'delimiter' => $_POST['delimiter'] ?? null,
],
$sqlQueryForm
)
);

View File

@ -1,41 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Table/Column autocomplete in SQL editors
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
if ($GLOBALS['cfg']['EnableAutocompleteForTablesAndColumns']) {
$db = isset($_POST['db']) ? $_POST['db'] : $GLOBALS['db'];
$sql_autocomplete = [];
if ($db) {
$tableNames = $dbi->getTables($db);
foreach ($tableNames as $tableName) {
$sql_autocomplete[$tableName] = $dbi->getColumns(
$db,
$tableName
);
}
}
} else {
$sql_autocomplete = true;
}
$response->addJSON("tables", json_encode($sql_autocomplete));

View File

@ -1,27 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Format SQL for SQL editors
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/**
* Loading common files. Used to check for authorization, localization and to
* load the parsing library.
*/
require_once ROOT_PATH . 'libraries/common.inc.php';
$query = ! empty($_POST['sql']) ? $_POST['sql'] : '';
$query = PhpMyAdmin\SqlParser\Utils\Formatter::format($query);
$response = Response::getInstance();
$response->addJSON("sql", $query);

View File

@ -1,62 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Database structure manipulation
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\StructureController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
require_once ROOT_PATH . 'libraries/db_common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var StructureController $controller */
$controller = $containerBuilder->get(StructureController::class);
if ($response->isAjax() && ! empty($_REQUEST['favorite_table'])) {
$json = $controller->addRemoveFavoriteTablesAction([
'favorite_table' => $_REQUEST['favorite_table'],
'favoriteTables' => $_REQUEST['favoriteTables'] ?? null,
'sync_favorite_tables' => $_REQUEST['sync_favorite_tables'] ?? null,
'add_favorite' => $_REQUEST['add_favorite'] ?? null,
'remove_favorite' => $_REQUEST['remove_favorite'] ?? null,
]);
if ($json !== null) {
$response->addJSON($json);
}
} elseif ($response->isAjax()
&& isset($_REQUEST['real_row_count'])
&& (bool) $_REQUEST['real_row_count'] === true
) {
$response->addJSON($controller->handleRealRowCountRequestAction([
'real_row_count_all' => $_REQUEST['real_row_count_all'] ?? null,
'table' => $_REQUEST['table'] ?? null,
]));
} else {
$response->getHeader()->getScripts()->addFiles([
'database/structure.js',
'table/change.js',
]);
$response->addHTML($controller->index([
'submit_mult' => $_POST['submit_mult'] ?? null,
'selected_tbl' => $_POST['selected_tbl'] ?? null,
'mult_btn' => $_POST['mult_btn'] ?? null,
'sort' => $_REQUEST['sort'] ?? null,
'sort_order' => $_REQUEST['sort_order'] ?? null,
]));
}

View File

@ -1,129 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Tracking configuration for database
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Display\CreateTable;
use PhpMyAdmin\Message;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\Tracker;
use PhpMyAdmin\Tracking;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $pmaThemeImage, $text_dir, $url_query;
require_once ROOT_PATH . 'libraries/common.inc.php';
//Get some js files needed for Ajax requests
$response = Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('vendor/jquery/jquery.tablesorter.js');
$scripts->addFile('database/tracking.js');
/** @var Tracking $tracking */
$tracking = $containerBuilder->get('tracking');
/**
* If we are not in an Ajax request, then do the common work and show the links etc.
*/
require ROOT_PATH . 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=tbl_tracking.php&amp;back=db_tracking.php';
$url_params['goto'] = 'tbl_tracking.php';
$url_params['back'] = 'db_tracking.php';
// Get the database structure
$sub_part = '_structure';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, $sub_part === null ? '' : $sub_part);
if (isset($_POST['delete_tracking']) && isset($_POST['table'])) {
Tracker::deleteTracking($db, $_POST['table']);
Message::success(
__('Tracking data deleted successfully.')
)->display();
} elseif (isset($_POST['submit_create_version'])) {
$tracking->createTrackingForMultipleTables($_POST['selected']);
Message::success(
sprintf(
__(
'Version %1$s was created for selected tables,'
. ' tracking is active for them.'
),
htmlspecialchars($_POST['version'])
)
)->display();
} elseif (isset($_POST['submit_mult'])) {
if (! empty($_POST['selected_tbl'])) {
if ($_POST['submit_mult'] == 'delete_tracking') {
foreach ($_POST['selected_tbl'] as $table) {
Tracker::deleteTracking($db, $table);
}
Message::success(
__('Tracking data deleted successfully.')
)->display();
} elseif ($_POST['submit_mult'] == 'track') {
echo $tracking->getHtmlForDataDefinitionAndManipulationStatements(
'db_tracking.php' . $url_query,
0,
$db,
$_POST['selected_tbl']
);
exit;
}
} else {
Message::notice(
__('No tables selected.')
)->display();
}
}
// Get tracked data about the database
$data = Tracker::getTrackedData($db, '', '1');
// No tables present and no log exist
if ($num_tables == 0 && count($data['ddlog']) === 0) {
echo '<p>' , __('No tables found in database.') , '</p>' , "\n";
if (empty($db_is_system_schema)) {
echo CreateTable::getHtml($db);
}
exit;
}
// ---------------------------------------------------------------------------
echo $tracking->getHtmlForDbTrackingTables(
$db,
$url_query,
$pmaThemeImage,
$text_dir
);
// If available print out database log
if (count($data['ddlog']) > 0) {
$log = '';
foreach ($data['ddlog'] as $entry) {
$log .= '# ' . $entry['date'] . ' ' . $entry['username'] . "\n"
. $entry['statement'] . "\n";
}
echo Util::getMessage(__('Database Log'), $log);
}

View File

@ -1,80 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Triggers management.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\Database\TriggersController;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$_PMA_RTE = 'TRI';
/** @var TriggersController $controller */
$controller = $containerBuilder->get(TriggersController::class);
/** @var string $db */
$db = $containerBuilder->getParameter('db');
/** @var string $table */
$table = $containerBuilder->getParameter('table');
if (! $response->isAjax()) {
/**
* Displays the header and tabs
*/
if (! empty($table) && in_array($table, $dbi->getTables($db))) {
include_once ROOT_PATH . 'libraries/tbl_common.inc.php';
} else {
$table = '';
include_once ROOT_PATH . 'libraries/db_common.inc.php';
list(
$tables,
$num_tables,
$total_num_tables,
$sub_part,
$is_show_stats,
$db_is_system_schema,
$tooltip_truename,
$tooltip_aliasname,
$pos
) = Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
}
} else {
/**
* Since we did not include some libraries, we need
* to manually select the required database and
* create the missing $url_query variable
*/
if (strlen($db) > 0) {
$dbi->selectDb($db);
if (! isset($url_query)) {
$url_query = Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
}
}
}
$controller->index();

View File

@ -1,422 +0,0 @@
.. _glossary:
Glossary
========
From Wikipedia, the free encyclopedia
.. glossary::
.htaccess
the default name of Apache's directory-level configuration file.
.. seealso:: <https://en.wikipedia.org/wiki/.htaccess>
ACL
Access Control List
Blowfish
a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.
.. seealso:: <https://en.wikipedia.org/wiki/Blowfish_(cipher)>
Browser
a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.
.. seealso:: <https://en.wikipedia.org/wiki/Web_browser>
bzip2
a free software/open-source data compression algorithm and program developed by Julian Seward.
.. seealso:: <https://en.wikipedia.org/wiki/Bzip2>
CGI
Common Gateway Interface is an important World Wide Web technology that
enables a client web browser to request data from a program executed on
the Web server.
.. seealso:: <https://en.wikipedia.org/wiki/Common_Gateway_Interface>
Changelog
a log or record of changes made to a project.
.. seealso:: <https://en.wikipedia.org/wiki/Changelog>
Client
a computer system that accesses a (remote) service on another computer by some kind of network.
.. seealso:: <https://en.wikipedia.org/wiki/Client_(computing)>
column
a set of data values of a particularly simple type, one for each row of the table.
.. seealso:: <https://en.wikipedia.org/wiki/Column_(database)>
Cookie
a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.
.. seealso:: <https://en.wikipedia.org/wiki/HTTP_cookie>
CSV
Comma-separated values
.. seealso:: <https://en.wikipedia.org/wiki/Comma-separated_values>
DB
look at :term:`database`
database
an organized collection of data.
.. seealso:: <https://en.wikipedia.org/wiki/Database>
Engine
look at :term:`Storage Engines`
extension
a PHP module that extends PHP with additional functionality.
.. seealso:: <https://en.wikipedia.org/wiki/Software_extension>
FAQ
Frequently Asked Questions is a list of commonly asked question and there
answers.
.. seealso:: <https://en.wikipedia.org/wiki/FAQ>
Field
one part of divided data/columns.
.. seealso:: <https://en.wikipedia.org/wiki/Field_(computer_science)>
foreign key
a column or group of columns in a database row that points to a key column
or group of columns forming a key of another database row in some
(usually different) table.
.. seealso:: <https://en.wikipedia.org/wiki/Foreign_key>
GD
Graphics Library by Thomas Boutell and others for dynamically manipulating images.
.. seealso:: <https://en.wikipedia.org/wiki/GD_Graphics_Library>
GD2
look at :term:`GD`
GZip
gzip is short for GNU zip, a GNU free software file compression program.
.. seealso:: <https://en.wikipedia.org/wiki/Gzip>
host
any machine connected to a computer network, a node that has a hostname.
.. seealso:: <https://en.wikipedia.org/wiki/Host>
hostname
the unique name by which a network-attached device is known on a network.
.. seealso:: <https://en.wikipedia.org/wiki/Hostname>
HTTP
HyperText Transfer Protocol is the primary method used to transfer or
convey information on the World Wide Web.
.. seealso:: <https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol>
https
a :term:`HTTP`-connection with additional security measures.
.. seealso:: <https://en.wikipedia.org/wiki/Https:_URI_scheme>
IEC
International Electrotechnical Commission
IIS
Internet Information Services is a set of Internet-based services for
servers using Microsoft Windows.
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Information_Services>
Index
a feature that allows quick access to the rows in a table.
.. seealso:: <https://en.wikipedia.org/wiki/Index_(database)>
IP
Internet Protocol is a data-oriented protocol used by source and
destination hosts for communicating data across a packet-switched
internetwork.
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Protocol>
IP Address
a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.
.. seealso:: <https://en.wikipedia.org/wiki/IP_Address>
IPv6
IPv6 (Internet Protocol version 6) is the latest revision of the
Internet Protocol (:term:`IP`), designed to deal with the
long-anticipated problem of its predecessor IPv4 running out of addresses.
.. seealso:: <https://en.wikipedia.org/wiki/IPv6>
ISAPI
Internet Server Application Programming Interface is the API of Internet Information Services (IIS).
.. seealso:: <https://en.wikipedia.org/wiki/ISAPI>
ISP
An Internet service provider is a business or organization that offers users
access to the Internet and related services.
.. seealso:: <https://en.wikipedia.org/wiki/ISP>
ISO
International Standards Organization
JPEG
a most commonly used standard method of lossy compression for photographic images.
.. seealso:: <https://en.wikipedia.org/wiki/JPEG>
JPG
look at :term:`JPEG`
Key
look at :term:`Index`
LATEX
a document preparation system for the TEX typesetting program.
.. seealso:: <https://en.wikipedia.org/wiki/LaTeX>
Mac
Apple Macintosh is a line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.
.. seealso:: <https://en.wikipedia.org/wiki/Mac>
Mac OS X
the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.
.. seealso:: <https://en.wikipedia.org/wiki/Mac_OS_X>
mbstring
The PHP `mbstring` functions provide support for languages represented by multi-byte character sets, most notably UTF-8.
If you have troubles installing this extension, please follow :ref:`faqmysql`, it provides useful hints.
.. seealso:: <https://www.php.net/manual/en/book.mbstring.php>
Media type
A media type (formerly known as MIME type) is a two-part identifier
for file formats and format contents transmitted on the Internet.
.. seealso:: <https://en.wikipedia.org/wiki/Media_type>
MIME
Multipurpose Internet Mail Extensions is
an Internet Standard for the format of e-mail.
.. seealso:: <https://en.wikipedia.org/wiki/MIME>
module
some sort of extension for the Apache Webserver.
.. seealso:: <https://en.wikipedia.org/wiki/Apache_HTTP_Server>
mod_proxy_fcgi
an Apache module implementing a Fast CGI interface; PHP can be run as a CGI module, FastCGI, or
directly as an Apache module.
MySQL
a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).
.. seealso:: <https://en.wikipedia.org/wiki/MySQL>
mysqli
the improved MySQL client PHP extension.
.. seealso:: <https://www.php.net/manual/en/book.mysqli.php>
mysql
the MySQL client PHP extension.
.. seealso:: <https://www.php.net/manual/en/book.mysql.php>
OpenDocument
an open standard for office documents.
.. seealso:: <https://en.wikipedia.org/wiki/OpenDocument>
OS X
look at :term:`Mac OS X`.
.. seealso:: <https://en.wikipedia.org/wiki/OS_X>
PDF
Portable Document Format is a file format developed by Adobe Systems for
representing two-dimensional documents in a device-independent and
resolution-independent format.
.. seealso:: <https://en.wikipedia.org/wiki/Portable_Document_Format>
PEAR
the PHP Extension and Application Repository.
.. seealso:: <https://pear.php.net/>
PCRE
Perl Compatible Regular Expressions is the perl-compatible regular
expression functions for PHP
.. seealso:: <https://www.php.net/pcre>
PHP
short for "PHP: Hypertext Preprocessor", is an open-source, reflective
programming language used mainly for developing server-side applications
and dynamic web content, and more recently, a broader range of software
applications.
.. seealso:: <https://en.wikipedia.org/wiki/PHP>
port
a connection through which data is sent and received.
.. seealso:: <https://en.wikipedia.org/wiki/Port_(computing)>
primary key
A primary key is an index over one or more fields in a table with
unique values for every single row in this table. Every table should have
a primary key for easier accessing/identifying data in this table. There
can only be one primary key per table and it is named always **PRIMARY**.
In fact, a primary key is just an :term:`unique key` with the name
**PRIMARY**. If no primary key is defined MySQL will use first *unique
key* as primary key if there is one.
You can create the primary key when creating the table (in phpMyAdmin
just check the primary key radio buttons for each field you wish to be
part of the primary key).
You can also add a primary key to an existing table with `ALTER` `TABLE`
or `CREATE` `INDEX` (in phpMyAdmin you can just click on 'add index' on
the table structure page below the listed fields).
RFC
Request for Comments (RFC) documents are a series of memoranda
encompassing new research, innovations, and methodologies applicable to
Internet technologies.
.. seealso:: <https://en.wikipedia.org/wiki/Request_for_Comments>
RFC 1952
GZIP file format specification version 4.3
.. seealso:: :rfc:`1952`
Row (record, tuple)
represents a single, implicitly structured data item in a table.
.. seealso:: <https://en.wikipedia.org/wiki/Row_(database)>
Server
a computer system that provides services to other computing systems over a network.
.. seealso:: <https://en.wikipedia.org/wiki/Server_(computing)>
Storage Engines
MySQL can use several different formats for storing data on disk, these
are called storage engines or table types. phpMyAdmin allows a user to
change their storage engine for a particular table through the operations
tab.
Common table types are InnoDB and MyISAM, though many others exist and
may be desirable in some situations.
.. seealso:: <https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html>
socket
a form of inter-process communication.
.. seealso:: <https://en.wikipedia.org/wiki/Unix_domain_socket>
SSL
Secure Sockets Layer is a cryptographic protocol which provides secure
communication on the Internet.
.. seealso:: <https://en.wikipedia.org/wiki/Secure_Sockets_Layer>
Stored procedure
a subroutine available to applications accessing a relational database system
.. seealso:: <https://en.wikipedia.org/wiki/Stored_procedure>
SQL
Structured Query Language
.. seealso:: <https://en.wikipedia.org/wiki/SQL>
table
a set of data elements (cells) that is organized, defined and stored as
horizontal rows and vertical columns where each item can be uniquely
identified by a label or key or by it's position in relation to other
items.
.. seealso:: <https://en.wikipedia.org/wiki/Table_(database)>
tar
a type of archive file format: the Tape ARchive format.
.. seealso:: <https://en.wikipedia.org/wiki/Tar_(file_format)>
TCP
Transmission Control Protocol is one of the core protocols of the
Internet protocol suite.
.. seealso:: <https://en.wikipedia.org/wiki/TCP>
TCPDF
PHP library to generate PDF files.
.. seealso:: <https://tcpdf.org/>
trigger
a procedural code that is automatically executed in response to certain events on a particular table or view in a database
.. seealso:: <https://en.wikipedia.org/wiki/Database_trigger>
unique key
A unique key is an index over one or more fields in a table which has a
unique value for each row. The first unique key will be treated as
:term:`primary key` if there is no *primary key* defined.
URL
Uniform Resource Locator is a sequence of characters, conforming to a
standardized format, that is used for referring to resources, such as
documents and images on the Internet, by their location.
.. seealso:: <https://en.wikipedia.org/wiki/URL>
Webserver
A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.
.. seealso:: <https://en.wikipedia.org/wiki/Webserver>
XML
Extensible Markup Language is a W3C-recommended general-purpose markup
language for creating special-purpose markup languages, capable of
describing many different kinds of data.
.. seealso:: <https://en.wikipedia.org/wiki/XML>
ZIP
a popular data compression and archival format.
.. seealso:: <https://en.wikipedia.org/wiki/ZIP_(file_format)>
Zlib
an open-source, cross-platform data compression library by Jean-loup Gailly and Mark Adler.
.. seealso:: <https://en.wikipedia.org/wiki/Zlib>

View File

@ -1,143 +0,0 @@
.. _transformations:
Transformations
===============
.. note::
You need to have configured the :ref:`linked-tables` for using transformations
feature.
.. _transformationsintro:
Introduction
++++++++++++
To enable transformations, you have to setup the ``column_info``
table and the proper directives. Please see the :ref:`config` on how to do so.
You can apply different transformations to the contents of each
column. The transformation will take the content of each column and
transform it with certain rules defined in the selected
transformation.
Say you have a column 'filename' which contains a filename. Normally
you would see in phpMyAdmin only this filename. Using transformations
you can transform that filename into a HTML link, so you can click
inside of the phpMyAdmin structure on the column's link and will see
the file displayed in a new browser window. Using transformation
options you can also specify strings to append/prepend to a string or
the format you want the output stored in.
For a general overview of all available transformations and their
options, you can consult your *<www.your-host.com>/<your-install-
dir>/transformation\_overview.php* installation.
For a tutorial on how to effectively use transformations, see our
`Link section <https://www.phpmyadmin.net/docs/>`_ on the
official phpMyAdmin homepage.
.. _transformationshowto:
Usage
+++++
Go to your *tbl\_structure.php* page (i.e. reached through clicking on
the 'Structure' link for a table). There click on "Change" (or change
icon) and there you will see three new fields at the end of the line.
They are called ':term:`Media type`', 'Browser transformation' and
'Transformation options'.
* The field ':term:`Media type`' is a drop-down field. Select the :term:`Media type` that
corresponds to the column's contents. Please note that transformations
are inactive as long as no :term:`Media type` is selected.
* The field 'Browser transformation' is a drop-down field. You can
choose from a hopefully growing amount of pre-defined transformations.
See below for information on how to build your own transformation.
There are global transformations and mimetype-bound transformations.
Global transformations can be used for any mimetype. They will take
the mimetype, if necessary, into regard. Mimetype-bound
transformations usually only operate on a certain mimetype. There are
transformations which operate on the main mimetype (like 'image'),
which will most likely take the subtype into regard, and those who
only operate on a specific subtype (like 'image/jpeg'). You can use
transformations on mimetypes for which the function was not defined
for. There is no security check for you selected the right
transformation, so take care of what the output will be like.
* The field 'Transformation options' is a free-type textfield. You have
to enter transform-function specific options here. Usually the
transforms can operate with default options, but it is generally a
good idea to look up the overview to see which options are necessary.
Much like the ENUM/SET-Fields, you have to split up several options
using the format 'a','b','c',...(NOTE THE MISSING BLANKS). This is
because internally the options will be parsed as an array, leaving the
first value the first element in the array, and so forth. If you want
to specify a MIME character set you can define it in the
transformation\_options. You have to put that outside of the pre-
defined options of the specific mime-transform, as the last value of
the set. Use the format "'; charset=XXX'". If you use a transform, for
which you can specify 2 options and you want to append a character
set, enter "'first parameter','second parameter','charset=us-ascii'".
You can, however use the defaults for the parameters: "'','','charset
=us-ascii'". The default options can be configured using
:config:option:`$cfg['DefaultTransformations']`
.. _transformationsfiles:
File structure
++++++++++++++
All specific transformations for mimetypes are defined through class
files in the directory 'libraries/classes/Plugins/Transformations/'. Each of
them extends a certain transformation abstract class declared in
libraries/classes/Plugins/Transformations/Abs.
They are stored in files to ease up customization and easy adding of
new transformations.
Because the user cannot enter own mimetypes, it is kept sure that
transformations always work. It makes no sense to apply a
transformation to a mimetype the transform-function doesn't know to
handle.
There is a file called ':file:`libraries/classes/Plugins/Transformations.php`' that provides some
basic functions which can be included by any other transform function.
The file name convention is ``[Mimetype]_[Subtype]_[Transformation
Name].php``, while the abstract class that it extends has the
name ``[Transformation Name]TransformationsPlugin``. All of the
methods that have to be implemented by a transformations plug-in are:
#. getMIMEType() and getMIMESubtype() in the main class;
#. getName(), getInfo() and applyTransformation() in the abstract class
it extends.
The getMIMEType(), getMIMESubtype() and getName() methods return the
name of the MIME type, MIME Subtype and transformation accordingly.
getInfo() returns the transformation's description and possible
options it may receive and applyTransformation() is the method that
does the actual work of the transformation plug-in.
Please see the :file:`libraries/classes/Plugins/Transformations/TEMPLATE` and
:file:`libraries/classes/Plugins/Transformations/TEMPLATE\_ABSTRACT` files for adding
your own transformation plug-in. You can also generate a new
transformation plug-in (with or without the abstract transformation
class), by using
:file:`scripts/transformations_generator_plugin.sh` or
:file:`scripts/transformations_generator_main_class.sh`.
The applyTransformation() method always gets passed three variables:
#. **$buffer** - Contains the text inside of the column. This is the
text, you want to transform.
#. **$options** - Contains any user-passed options to a transform
function as an array.
#. **$meta** - Contains an object with information about your column. The
data is drawn from the output of the `mysql\_fetch\_field()
<https://www.php.net/mysql_fetch_field>`_ function. This means, all
object properties described on the `manual page
<https://www.php.net/mysql_fetch_field>`_ are available in this
variable and can be used to transform a column accordingly to
unsigned/zerofill/not\_null/... properties. The $meta->mimetype
variable contains the original :term:`Media type` of the column (i.e.
'text/plain', 'image/jpeg' etc.)

View File

@ -1,32 +0,0 @@
Distributing and packaging phpMyAdmin
=====================================
This document is intended to give pieces of advice to people who want to
redistribute phpMyAdmin inside other software packages such as Linux
distribution or some all in one package including web server and MySQL
server.
Generally, you can customize some basic aspects (paths to some files and
behavior) in :file:`libraries/vendor_config.php`.
For example, if you want setup script to generate a config file in var, change
``SETUP_CONFIG_FILE`` to :file:`/var/lib/phpmyadmin/config.inc.php` and you
will also probably want to skip directory writable check, so set
``SETUP_DIR_WRITABLE`` to false.
External libraries
------------------
phpMyAdmin includes several external libraries, you might want to
replace them with system ones if they are available, but please note
that you should test whether the version you provide is compatible with the
one we ship.
Currently known list of external libraries:
js/vendor
jQuery js framework libraries and various js libraries.
vendor/
The download kit includes various Composer packages as
dependencies.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

View File

@ -1,10 +0,0 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '5.0.4',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false,
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

View File

@ -1,808 +0,0 @@
/*
* websupport.js
* ~~~~~~~~~~~~~
*
* sphinx.websupport utilities for all documentation.
*
* :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
(function($) {
$.fn.autogrow = function() {
return this.each(function() {
var textarea = this;
$.fn.autogrow.resize(textarea);
$(textarea)
.focus(function() {
textarea.interval = setInterval(function() {
$.fn.autogrow.resize(textarea);
}, 500);
})
.blur(function() {
clearInterval(textarea.interval);
});
});
};
$.fn.autogrow.resize = function(textarea) {
var lineHeight = parseInt($(textarea).css('line-height'), 10);
var lines = textarea.value.split('\n');
var columns = textarea.cols;
var lineCount = 0;
$.each(lines, function() {
lineCount += Math.ceil(this.length / columns) || 1;
});
var height = lineHeight * (lineCount + 1);
$(textarea).css('height', height);
};
})(jQuery);
(function($) {
var comp, by;
function init() {
initEvents();
initComparator();
}
function initEvents() {
$(document).on("click", 'a.comment-close', function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
});
$(document).on("click", 'a.vote', function(event) {
event.preventDefault();
handleVote($(this));
});
$(document).on("click", 'a.reply', function(event) {
event.preventDefault();
openReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.close-reply', function(event) {
event.preventDefault();
closeReply($(this).attr('id').substring(2));
});
$(document).on("click", 'a.sort-option', function(event) {
event.preventDefault();
handleReSort($(this));
});
$(document).on("click", 'a.show-proposal', function(event) {
event.preventDefault();
showProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-proposal', function(event) {
event.preventDefault();
hideProposal($(this).attr('id').substring(2));
});
$(document).on("click", 'a.show-propose-change', function(event) {
event.preventDefault();
showProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.hide-propose-change', function(event) {
event.preventDefault();
hideProposeChange($(this).attr('id').substring(2));
});
$(document).on("click", 'a.accept-comment', function(event) {
event.preventDefault();
acceptComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.delete-comment', function(event) {
event.preventDefault();
deleteComment($(this).attr('id').substring(2));
});
$(document).on("click", 'a.comment-markup', function(event) {
event.preventDefault();
toggleCommentMarkupBox($(this).attr('id').substring(2));
});
}
/**
* Set comp, which is a comparator function used for sorting and
* inserting comments into the list.
*/
function setComparator() {
// If the first three letters are "asc", sort in ascending order
// and remove the prefix.
if (by.substring(0,3) == 'asc') {
var i = by.substring(3);
comp = function(a, b) { return a[i] - b[i]; };
} else {
// Otherwise sort in descending order.
comp = function(a, b) { return b[by] - a[by]; };
}
// Reset link styles and format the selected sort option.
$('a.sel').attr('href', '#').removeClass('sel');
$('a.by' + by).removeAttr('href').addClass('sel');
}
/**
* Create a comp function. If the user has preferences stored in
* the sortBy cookie, use those, otherwise use the default.
*/
function initComparator() {
by = 'rating'; // Default to sort by rating.
// If the sortBy cookie is set, use that instead.
if (document.cookie.length > 0) {
var start = document.cookie.indexOf('sortBy=');
if (start != -1) {
start = start + 7;
var end = document.cookie.indexOf(";", start);
if (end == -1) {
end = document.cookie.length;
by = unescape(document.cookie.substring(start, end));
}
}
}
setComparator();
}
/**
* Show a comment div.
*/
function show(id) {
$('#ao' + id).hide();
$('#ah' + id).show();
var context = $.extend({id: id}, opts);
var popup = $(renderTemplate(popupTemplate, context)).hide();
popup.find('textarea[name="proposal"]').hide();
popup.find('a.by' + by).addClass('sel');
var form = popup.find('#cf' + id);
form.submit(function(event) {
event.preventDefault();
addComment(form);
});
$('#s' + id).after(popup);
popup.slideDown('fast', function() {
getComments(id);
});
}
/**
* Hide a comment div.
*/
function hide(id) {
$('#ah' + id).hide();
$('#ao' + id).show();
var div = $('#sc' + id);
div.slideUp('fast', function() {
div.remove();
});
}
/**
* Perform an ajax request to get comments for a node
* and insert the comments into the comments tree.
*/
function getComments(id) {
$.ajax({
type: 'GET',
url: opts.getCommentsURL,
data: {node: id},
success: function(data, textStatus, request) {
var ul = $('#cl' + id);
var speed = 100;
$('#cf' + id)
.find('textarea[name="proposal"]')
.data('source', data.source);
if (data.comments.length === 0) {
ul.html('<li>No comments yet.</li>');
ul.data('empty', true);
} else {
// If there are comments, sort them and put them in the list.
var comments = sortComments(data.comments);
speed = data.comments.length * 100;
appendComments(comments, ul);
ul.data('empty', false);
}
$('#cn' + id).slideUp(speed + 200);
ul.slideDown(speed);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem retrieving the comments.');
},
dataType: 'json'
});
}
/**
* Add a comment via ajax and insert the comment into the comment tree.
*/
function addComment(form) {
var node_id = form.find('input[name="node"]').val();
var parent_id = form.find('input[name="parent"]').val();
var text = form.find('textarea[name="comment"]').val();
var proposal = form.find('textarea[name="proposal"]').val();
if (text == '') {
showError('Please enter a comment.');
return;
}
// Disable the form that is being submitted.
form.find('textarea,input').attr('disabled', 'disabled');
// Send the comment to the server.
$.ajax({
type: "POST",
url: opts.addCommentURL,
dataType: 'json',
data: {
node: node_id,
parent: parent_id,
text: text,
proposal: proposal
},
success: function(data, textStatus, error) {
// Reset the form.
if (node_id) {
hideProposeChange(node_id);
}
form.find('textarea')
.val('')
.add(form.find('input'))
.removeAttr('disabled');
var ul = $('#cl' + (node_id || parent_id));
if (ul.data('empty')) {
$(ul).empty();
ul.data('empty', false);
}
insertComment(data.comment);
var ao = $('#ao' + node_id);
ao.find('img').attr({'src': opts.commentBrightImage});
if (node_id) {
// if this was a "root" comment, remove the commenting box
// (the user can get it back by reopening the comment popup)
$('#ca' + node_id).slideUp();
}
},
error: function(request, textStatus, error) {
form.find('textarea,input').removeAttr('disabled');
showError('Oops, there was a problem adding the comment.');
}
});
}
/**
* Recursively append comments to the main comment list and children
* lists, creating the comment tree.
*/
function appendComments(comments, ul) {
$.each(comments, function() {
var div = createCommentDiv(this);
ul.append($(document.createElement('li')).html(div));
appendComments(this.children, div.find('ul.comment-children'));
// To avoid stagnating data, don't store the comments children in data.
this.children = null;
div.data('comment', this);
});
}
/**
* After adding a new comment, it must be inserted in the correct
* location in the comment tree.
*/
function insertComment(comment) {
var div = createCommentDiv(comment);
// To avoid stagnating data, don't store the comments children in data.
comment.children = null;
div.data('comment', comment);
var ul = $('#cl' + (comment.node || comment.parent));
var siblings = getChildren(ul);
var li = $(document.createElement('li'));
li.hide();
// Determine where in the parents children list to insert this comment.
for(var i=0; i < siblings.length; i++) {
if (comp(comment, siblings[i]) <= 0) {
$('#cd' + siblings[i].id)
.parent()
.before(li.html(div));
li.slideDown('fast');
return;
}
}
// If we get here, this comment rates lower than all the others,
// or it is the only comment in the list.
ul.append(li.html(div));
li.slideDown('fast');
}
function acceptComment(id) {
$.ajax({
type: 'POST',
url: opts.acceptCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
$('#cm' + id).fadeOut('fast');
$('#cd' + id).removeClass('moderate');
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem accepting the comment.');
}
});
}
function deleteComment(id) {
$.ajax({
type: 'POST',
url: opts.deleteCommentURL,
data: {id: id},
success: function(data, textStatus, request) {
var div = $('#cd' + id);
if (data == 'delete') {
// Moderator mode: remove the comment and all children immediately
div.slideUp('fast', function() {
div.remove();
});
return;
}
// User mode: only mark the comment as deleted
div
.find('span.user-id:first')
.text('[deleted]').end()
.find('div.comment-text:first')
.text('[deleted]').end()
.find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
.remove();
var comment = div.data('comment');
comment.username = '[deleted]';
comment.text = '[deleted]';
div.data('comment', comment);
},
error: function(request, textStatus, error) {
showError('Oops, there was a problem deleting the comment.');
}
});
}
function showProposal(id) {
$('#sp' + id).hide();
$('#hp' + id).show();
$('#pr' + id).slideDown('fast');
}
function hideProposal(id) {
$('#hp' + id).hide();
$('#sp' + id).show();
$('#pr' + id).slideUp('fast');
}
function showProposeChange(id) {
$('#pc' + id).hide();
$('#hc' + id).show();
var textarea = $('#pt' + id);
textarea.val(textarea.data('source'));
$.fn.autogrow.resize(textarea[0]);
textarea.slideDown('fast');
}
function hideProposeChange(id) {
$('#hc' + id).hide();
$('#pc' + id).show();
var textarea = $('#pt' + id);
textarea.val('').removeAttr('disabled');
textarea.slideUp('fast');
}
function toggleCommentMarkupBox(id) {
$('#mb' + id).toggle();
}
/** Handle when the user clicks on a sort by link. */
function handleReSort(link) {
var classes = link.attr('class').split(/\s+/);
for (var i=0; i<classes.length; i++) {
if (classes[i] != 'sort-option') {
by = classes[i].substring(2);
}
}
setComparator();
// Save/update the sortBy cookie.
var expiration = new Date();
expiration.setDate(expiration.getDate() + 365);
document.cookie= 'sortBy=' + escape(by) +
';expires=' + expiration.toUTCString();
$('ul.comment-ul').each(function(index, ul) {
var comments = getChildren($(ul), true);
comments = sortComments(comments);
appendComments(comments, $(ul).empty());
});
}
/**
* Function to process a vote when a user clicks an arrow.
*/
function handleVote(link) {
if (!opts.voting) {
showError("You'll need to login to vote.");
return;
}
var id = link.attr('id');
if (!id) {
// Didn't click on one of the voting arrows.
return;
}
// If it is an unvote, the new vote value is 0,
// Otherwise it's 1 for an upvote, or -1 for a downvote.
var value = 0;
if (id.charAt(1) != 'u') {
value = id.charAt(0) == 'u' ? 1 : -1;
}
// The data to be sent to the server.
var d = {
comment_id: id.substring(2),
value: value
};
// Swap the vote and unvote links.
link.hide();
$('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
.show();
// The div the comment is displayed in.
var div = $('div#cd' + d.comment_id);
var data = div.data('comment');
// If this is not an unvote, and the other vote arrow has
// already been pressed, unpress it.
if ((d.value !== 0) && (data.vote === d.value * -1)) {
$('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
$('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
}
// Update the comments rating in the local data.
data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
data.vote = d.value;
div.data('comment', data);
// Change the rating text.
div.find('.rating:first')
.text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
// Send the vote information to the server.
$.ajax({
type: "POST",
url: opts.processVoteURL,
data: d,
error: function(request, textStatus, error) {
showError('Oops, there was a problem casting that vote.');
}
});
}
/**
* Open a reply form used to reply to an existing comment.
*/
function openReply(id) {
// Swap out the reply link for the hide link
$('#rl' + id).hide();
$('#cr' + id).show();
// Add the reply li to the children ul.
var div = $(renderTemplate(replyTemplate, {id: id})).hide();
$('#cl' + id)
.prepend(div)
// Setup the submit handler for the reply form.
.find('#rf' + id)
.submit(function(event) {
event.preventDefault();
addComment($('#rf' + id));
closeReply(id);
})
.find('input[type=button]')
.click(function() {
closeReply(id);
});
div.slideDown('fast', function() {
$('#rf' + id).find('textarea').focus();
});
}
/**
* Close the reply form opened with openReply.
*/
function closeReply(id) {
// Remove the reply div from the DOM.
$('#rd' + id).slideUp('fast', function() {
$(this).remove();
});
// Swap out the hide link for the reply link
$('#cr' + id).hide();
$('#rl' + id).show();
}
/**
* Recursively sort a tree of comments using the comp comparator.
*/
function sortComments(comments) {
comments.sort(comp);
$.each(comments, function() {
this.children = sortComments(this.children);
});
return comments;
}
/**
* Get the children comments from a ul. If recursive is true,
* recursively include childrens' children.
*/
function getChildren(ul, recursive) {
var children = [];
ul.children().children("[id^='cd']")
.each(function() {
var comment = $(this).data('comment');
if (recursive)
comment.children = getChildren($(this).find('#cl' + comment.id), true);
children.push(comment);
});
return children;
}
/** Create a div to display a comment in. */
function createCommentDiv(comment) {
if (!comment.displayed && !opts.moderator) {
return $('<div class="moderate">Thank you! Your comment will show up '
+ 'once it is has been approved by a moderator.</div>');
}
// Prettify the comment rating.
comment.pretty_rating = comment.rating + ' point' +
(comment.rating == 1 ? '' : 's');
// Make a class (for displaying not yet moderated comments differently)
comment.css_class = comment.displayed ? '' : ' moderate';
// Create a div for this comment.
var context = $.extend({}, opts, comment);
var div = $(renderTemplate(commentTemplate, context));
// If the user has voted on this comment, highlight the correct arrow.
if (comment.vote) {
var direction = (comment.vote == 1) ? 'u' : 'd';
div.find('#' + direction + 'v' + comment.id).hide();
div.find('#' + direction + 'u' + comment.id).show();
}
if (opts.moderator || comment.text != '[deleted]') {
div.find('a.reply').show();
if (comment.proposal_diff)
div.find('#sp' + comment.id).show();
if (opts.moderator && !comment.displayed)
div.find('#cm' + comment.id).show();
if (opts.moderator || (opts.username == comment.username))
div.find('#dc' + comment.id).show();
}
return div;
}
/**
* A simple template renderer. Placeholders such as <%id%> are replaced
* by context['id'] with items being escaped. Placeholders such as <#id#>
* are not escaped.
*/
function renderTemplate(template, context) {
var esc = $(document.createElement('div'));
function handle(ph, escape) {
var cur = context;
$.each(ph.split('.'), function() {
cur = cur[this];
});
return escape ? esc.text(cur || "").html() : cur;
}
return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
return handle(arguments[2], arguments[1] == '%' ? true : false);
});
}
/** Flash an error message briefly. */
function showError(message) {
$(document.createElement('div')).attr({'class': 'popup-error'})
.append($(document.createElement('div'))
.attr({'class': 'error-message'}).text(message))
.appendTo('body')
.fadeIn("slow")
.delay(2000)
.fadeOut("slow");
}
/** Add a link the user uses to open the comments popup. */
$.fn.comment = function() {
return this.each(function() {
var id = $(this).attr('id').substring(1);
var count = COMMENT_METADATA[id];
var title = count + ' comment' + (count == 1 ? '' : 's');
var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
var addcls = count == 0 ? ' nocomment' : '';
$(this)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-open' + addcls,
id: 'ao' + id
})
.append($(document.createElement('img')).attr({
src: image,
alt: 'comment',
title: title
}))
.click(function(event) {
event.preventDefault();
show($(this).attr('id').substring(2));
})
)
.append(
$(document.createElement('a')).attr({
href: '#',
'class': 'sphinx-comment-close hidden',
id: 'ah' + id
})
.append($(document.createElement('img')).attr({
src: opts.closeCommentImage,
alt: 'close',
title: 'close'
}))
.click(function(event) {
event.preventDefault();
hide($(this).attr('id').substring(2));
})
);
});
};
var opts = {
processVoteURL: '/_process_vote',
addCommentURL: '/_add_comment',
getCommentsURL: '/_get_comments',
acceptCommentURL: '/_accept_comment',
deleteCommentURL: '/_delete_comment',
commentImage: '/static/_static/comment.png',
closeCommentImage: '/static/_static/comment-close.png',
loadingImage: '/static/_static/ajax-loader.gif',
commentBrightImage: '/static/_static/comment-bright.png',
upArrow: '/static/_static/up.png',
downArrow: '/static/_static/down.png',
upArrowPressed: '/static/_static/up-pressed.png',
downArrowPressed: '/static/_static/down-pressed.png',
voting: false,
moderator: false
};
if (typeof COMMENT_OPTIONS != "undefined") {
opts = jQuery.extend(opts, COMMENT_OPTIONS);
}
var popupTemplate = '\
<div class="sphinx-comments" id="sc<%id%>">\
<p class="sort-options">\
Sort by:\
<a href="#" class="sort-option byrating">best rated</a>\
<a href="#" class="sort-option byascage">newest</a>\
<a href="#" class="sort-option byage">oldest</a>\
</p>\
<div class="comment-header">Comments</div>\
<div class="comment-loading" id="cn<%id%>">\
loading comments... <img src="<%loadingImage%>" alt="" /></div>\
<ul id="cl<%id%>" class="comment-ul"></ul>\
<div id="ca<%id%>">\
<p class="add-a-comment">Add a comment\
(<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
<div class="comment-markup-box" id="mb<%id%>">\
reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
<code>``code``</code>, \
code blocks: <code>::</code> and an indented block after blank line</div>\
<form method="post" id="cf<%id%>" class="comment-form" action="">\
<textarea name="comment" cols="80"></textarea>\
<p class="propose-button">\
<a href="#" id="pc<%id%>" class="show-propose-change">\
Propose a change &#9657;\
</a>\
<a href="#" id="hc<%id%>" class="hide-propose-change">\
Propose a change &#9663;\
</a>\
</p>\
<textarea name="proposal" id="pt<%id%>" cols="80"\
spellcheck="false"></textarea>\
<input type="submit" value="Add comment" />\
<input type="hidden" name="node" value="<%id%>" />\
<input type="hidden" name="parent" value="" />\
</form>\
</div>\
</div>';
var commentTemplate = '\
<div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
<div class="vote">\
<div class="arrow">\
<a href="#" id="uv<%id%>" class="vote" title="vote up">\
<img src="<%upArrow%>" />\
</a>\
<a href="#" id="uu<%id%>" class="un vote" title="vote up">\
<img src="<%upArrowPressed%>" />\
</a>\
</div>\
<div class="arrow">\
<a href="#" id="dv<%id%>" class="vote" title="vote down">\
<img src="<%downArrow%>" id="da<%id%>" />\
</a>\
<a href="#" id="du<%id%>" class="un vote" title="vote down">\
<img src="<%downArrowPressed%>" />\
</a>\
</div>\
</div>\
<div class="comment-content">\
<p class="tagline comment">\
<span class="user-id"><%username%></span>\
<span class="rating"><%pretty_rating%></span>\
<span class="delta"><%time.delta%></span>\
</p>\
<div class="comment-text comment"><#text#></div>\
<p class="comment-opts comment">\
<a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
<a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
<a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
<a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
<a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
<span id="cm<%id%>" class="moderation hidden">\
<a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
</span>\
</p>\
<pre class="proposal" id="pr<%id%>">\
<#proposal_diff#>\
</pre>\
<ul class="comment-children" id="cl<%id%>"></ul>\
</div>\
<div class="clearleft"></div>\
</div>\
</div>';
var replyTemplate = '\
<li>\
<div class="reply-div" id="rd<%id%>">\
<form id="rf<%id%>">\
<textarea name="comment" cols="80"></textarea>\
<input type="submit" value="Add reply" />\
<input type="button" value="Cancel" />\
<input type="hidden" name="parent" value="<%id%>" />\
<input type="hidden" name="node" value="" />\
</form>\
</div>\
</li>';
$(document).ready(function() {
init();
});
})(jQuery);
$(document).ready(function() {
// add comment anchors for all paragraphs that are commentable
$('.sphinx-has-comment').comment();
// highlight search words in search results
$("div.context").each(function() {
var params = $.getQueryParameters();
var terms = (params.q) ? params.q[0].split(/\s+/) : [];
var result = $(this);
$.each(terms, function() {
result.highlightText(this.toLowerCase(), 'highlighted');
});
});
// directly open comment window if requested
var anchor = document.location.hash;
if (anchor.substring(0, 9) == '#comment-') {
$('#ao' + anchor.substring(9)).click();
document.location.hash = '#s' + anchor.substring(9);
}
});

View File

@ -1,292 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Charts &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Import and export" href="import_export.html" />
<link rel="prev" title="Relations" href="relations.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="import_export.html" title="Import and export"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="relations.html" title="Relations"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="charts">
<span id="id1"></span><h1>Charts<a class="headerlink" href="#charts" title="Permalink to this headline"></a></h1>
<div class="versionadded">
<p><span class="versionmodified">New in version 3.4.0.</span></p>
</div>
<p>Since phpMyAdmin version 3.4.0, you can easily generate charts from a SQL query
by clicking the “Display chart” link in the “Query results operations” area.</p>
<img alt="_images/query_result_operations.png" src="_images/query_result_operations.png" />
<p>A window layer “Display chart” is shown in which you can customize the chart with the following options.</p>
<ul class="simple">
<li>Chart type: Allows you to choose the type of chart. Supported types are bar charts, column charts, line charts, spline charts, area charts, pie charts and timeline charts (only the chart types applicable for current series selection are offered).</li>
<li>X-axis: Allows to choose the field for the main axis.</li>
<li>Series: Allows to choose series for the chart. You can choose multiple series.</li>
<li>Title: Allows specifying a title for the chart which is displayed above the chart.</li>
<li>X-axis and Y-axis labels: Allows specifying labels for axes.</li>
<li>Start row and a number of rows: Allows generating charts only for a specified number of rows of the results set.</li>
</ul>
<img alt="_images/chart.png" src="_images/chart.png" />
<div class="section" id="chart-implementation">
<h2>Chart implementation<a class="headerlink" href="#chart-implementation" title="Permalink to this headline"></a></h2>
<p>Charts in phpMyAdmin are drawn using <a class="reference external" href="http://www.jqplot.com/">jqPlot</a> jQuery library.</p>
</div>
<div class="section" id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h2>
<div class="section" id="pie-chart">
<h3>Pie chart<a class="headerlink" href="#pie-chart" title="Permalink to this headline"></a></h3>
<p>Query results for a simple pie chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span> <span class="s1">&#39;Food&#39;</span> <span class="k">AS</span> <span class="s1">&#39;expense&#39;</span><span class="p">,</span>
<span class="mi">1250</span> <span class="k">AS</span> <span class="s1">&#39;amount&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Accommodation&#39;</span><span class="p">,</span> <span class="mi">500</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Travel&#39;</span><span class="p">,</span> <span class="mi">720</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;Misc&#39;</span><span class="p">,</span> <span class="mi">220</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="65%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">expense</th>
<th class="head">amount</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Food</td>
<td>1250</td>
</tr>
<tr class="row-odd"><td>Accommodation</td>
<td>500</td>
</tr>
<tr class="row-even"><td>Travel</td>
<td>720</td>
</tr>
<tr class="row-odd"><td>Misc</td>
<td>220</td>
</tr>
</tbody>
</table>
<p>Choosing expense as the X-axis and amount in series:</p>
<img alt="_images/pie_chart.png" src="_images/pie_chart.png" />
</div>
<div class="section" id="bar-and-column-chart">
<h3>Bar and column chart<a class="headerlink" href="#bar-and-column-chart" title="Permalink to this headline"></a></h3>
<p>Both bar charts and column chats support stacking. Upon selecting one of these types a checkbox is displayed to select stacking.</p>
<p>Query results for a simple bar or column chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span>
<span class="s1">&#39;ACADEMY DINOSAUR&#39;</span> <span class="k">AS</span> <span class="s1">&#39;title&#39;</span><span class="p">,</span>
<span class="mi">0</span><span class="p">.</span><span class="mi">99</span> <span class="k">AS</span> <span class="s1">&#39;rental_rate&#39;</span><span class="p">,</span>
<span class="mi">20</span><span class="p">.</span><span class="mi">99</span> <span class="k">AS</span> <span class="s1">&#39;replacement_cost&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;ACE GOLDFINGER&#39;</span><span class="p">,</span> <span class="mi">4</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">12</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;ADAPTATION HOLES&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">18</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;AFFAIR PREJUDICE&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">26</span><span class="p">.</span><span class="mi">99</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="s1">&#39;AFRICAN EGG&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">.</span><span class="mi">99</span><span class="p">,</span> <span class="mi">22</span><span class="p">.</span><span class="mi">99</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="35%" />
<col width="27%" />
<col width="37%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">title</th>
<th class="head">rental_rate</th>
<th class="head">replacement_cost</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>ACADEMY DINOSAUR</td>
<td>0.99</td>
<td>20.99</td>
</tr>
<tr class="row-odd"><td>ACE GOLDFINGER</td>
<td>4.99</td>
<td>12.99</td>
</tr>
<tr class="row-even"><td>ADAPTATION HOLES</td>
<td>2.99</td>
<td>18.99</td>
</tr>
<tr class="row-odd"><td>AFFAIR PREJUDICE</td>
<td>2.99</td>
<td>26.99</td>
</tr>
<tr class="row-even"><td>AFRICAN EGG</td>
<td>2.99</td>
<td>22.99</td>
</tr>
</tbody>
</table>
<p>Choosing title as the X-axis and rental_rate and replacement_cost as series:</p>
<img alt="_images/column_chart.png" src="_images/column_chart.png" />
</div>
<div class="section" id="scatter-chart">
<h3>Scatter chart<a class="headerlink" href="#scatter-chart" title="Permalink to this headline"></a></h3>
<p>Scatter charts are useful in identifying the movement of one or more variable(s) compared to another variable.</p>
<p>Using the same data set from bar and column charts section and choosing replacement_cost as the X-axis and rental_rate in series:</p>
<img alt="_images/scatter_chart.png" src="_images/scatter_chart.png" />
</div>
<div class="section" id="line-spline-and-timeline-charts">
<h3>Line, spline and timeline charts<a class="headerlink" href="#line-spline-and-timeline-charts" title="Permalink to this headline"></a></h3>
<p>These charts can be used to illustrate trends in underlying data. Spline charts draw smooth lines while timeline charts draw X-axis taking the distances between the dates/time into consideration.</p>
<p>Query results for a simple line, spline or timeline chart can be generated with:</p>
<div class="highlight-mysql notranslate"><div class="highlight"><pre><span></span><span class="k">SELECT</span>
<span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-08&#39;</span><span class="p">)</span> <span class="k">AS</span> <span class="s1">&#39;date&#39;</span><span class="p">,</span>
<span class="mi">2056</span> <span class="k">AS</span> <span class="s1">&#39;revenue&#39;</span><span class="p">,</span>
<span class="mi">1378</span> <span class="k">AS</span> <span class="s1">&#39;cost&#39;</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-09&#39;</span><span class="p">),</span> <span class="mi">1898</span><span class="p">,</span> <span class="mi">2301</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-15&#39;</span><span class="p">),</span> <span class="mi">1560</span><span class="p">,</span> <span class="mi">600</span> <span class="k">UNION</span>
<span class="k">SELECT</span> <span class="kt">DATE</span><span class="p">(</span><span class="s1">&#39;2006-01-17&#39;</span><span class="p">),</span> <span class="mi">3457</span><span class="p">,</span> <span class="mi">1565</span>
</pre></div>
</div>
<p>And the result of this query is:</p>
<table border="1" class="docutils">
<colgroup>
<col width="44%" />
<col width="33%" />
<col width="22%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">date</th>
<th class="head">revenue</th>
<th class="head">cost</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>2016-01-08</td>
<td>2056</td>
<td>1378</td>
</tr>
<tr class="row-odd"><td>2006-01-09</td>
<td>1898</td>
<td>2301</td>
</tr>
<tr class="row-even"><td>2006-01-15</td>
<td>1560</td>
<td>600</td>
</tr>
<tr class="row-odd"><td>2006-01-17</td>
<td>3457</td>
<td>1565</td>
</tr>
</tbody>
</table>
<img alt="_images/line_chart.png" src="_images/line_chart.png" />
<img alt="_images/spline_chart.png" src="_images/spline_chart.png" />
<img alt="_images/timeline_chart.png" src="_images/timeline_chart.png" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Charts</a><ul>
<li><a class="reference internal" href="#chart-implementation">Chart implementation</a></li>
<li><a class="reference internal" href="#examples">Examples</a><ul>
<li><a class="reference internal" href="#pie-chart">Pie chart</a></li>
<li><a class="reference internal" href="#bar-and-column-chart">Bar and column chart</a></li>
<li><a class="reference internal" href="#scatter-chart">Scatter chart</a></li>
<li><a class="reference internal" href="#line-spline-and-timeline-charts">Line, spline and timeline charts</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="relations.html"
title="previous chapter">Relations</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="import_export.html"
title="next chapter">Import and export</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/charts.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="import_export.html" title="Import and export"
>next</a> |</li>
<li class="right" >
<a href="relations.html" title="Relations"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,110 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Developers Information &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Security policy" href="security.html" />
<link rel="prev" title="FAQ - Frequently Asked Questions" href="faq.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="security.html" title="Security policy"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="developers-information">
<span id="developers"></span><h1>Developers Information<a class="headerlink" href="#developers-information" title="Permalink to this headline"></a></h1>
<p>phpMyAdmin is Open Source, so youre invited to contribute to it. Many
great features have been written by other people and you too can help
to make phpMyAdmin a useful tool.</p>
<p>You can check out all the possibilities to contribute in the
<a class="reference external" href="https://www.phpmyadmin.net/contribute/">contribute section on our website</a>.</p>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="faq.html"
title="previous chapter">FAQ - Frequently Asked Questions</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="security.html"
title="next chapter">Security policy</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/developers.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="security.html" title="Security policy"
>next</a> |</li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -1,628 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Glossary &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="prev" title="Credits" href="credits.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="credits.html" title="Credits"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="glossary">
<span id="id1"></span><h1>Glossary<a class="headerlink" href="#glossary" title="Permalink to this headline"></a></h1>
<p>From Wikipedia, the free encyclopedia</p>
<dl class="glossary docutils">
<dt id="term-htaccess">.htaccess</dt>
<dd><p class="first">the default name of Apaches directory-level configuration file.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/.htaccess">https://en.wikipedia.org/wiki/.htaccess</a>&gt;</p>
</div>
</dd>
<dt id="term-acl">ACL</dt>
<dd>Access Control List</dd>
<dt id="term-blowfish">Blowfish</dt>
<dd><p class="first">a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Blowfish_(cipher)">https://en.wikipedia.org/wiki/Blowfish_(cipher)</a>&gt;</p>
</div>
</dd>
<dt id="term-browser">Browser</dt>
<dd><p class="first">a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Web_browser">https://en.wikipedia.org/wiki/Web_browser</a>&gt;</p>
</div>
</dd>
<dt id="term-bzip2">bzip2</dt>
<dd><p class="first">a free software/open-source data compression algorithm and program developed by Julian Seward.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Bzip2">https://en.wikipedia.org/wiki/Bzip2</a>&gt;</p>
</div>
</dd>
<dt id="term-cgi">CGI</dt>
<dd><p class="first">Common Gateway Interface is an important World Wide Web technology that
enables a client web browser to request data from a program executed on
the Web server.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Common_Gateway_Interface">https://en.wikipedia.org/wiki/Common_Gateway_Interface</a>&gt;</p>
</div>
</dd>
<dt id="term-changelog">Changelog</dt>
<dd><p class="first">a log or record of changes made to a project.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Changelog">https://en.wikipedia.org/wiki/Changelog</a>&gt;</p>
</div>
</dd>
<dt id="term-client">Client</dt>
<dd><p class="first">a computer system that accesses a (remote) service on another computer by some kind of network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Client_(computing)">https://en.wikipedia.org/wiki/Client_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-column">column</dt>
<dd><p class="first">a set of data values of a particularly simple type, one for each row of the table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Column_(database)">https://en.wikipedia.org/wiki/Column_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-cookie">Cookie</dt>
<dd><p class="first">a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/HTTP_cookie">https://en.wikipedia.org/wiki/HTTP_cookie</a>&gt;</p>
</div>
</dd>
<dt id="term-csv">CSV</dt>
<dd><p class="first">Comma-separated values</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Comma-separated_values">https://en.wikipedia.org/wiki/Comma-separated_values</a>&gt;</p>
</div>
</dd>
<dt id="term-db">DB</dt>
<dd>look at <a class="reference internal" href="#term-database"><span class="xref std std-term">database</span></a></dd>
<dt id="term-database">database</dt>
<dd><p class="first">an organized collection of data.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Database">https://en.wikipedia.org/wiki/Database</a>&gt;</p>
</div>
</dd>
<dt id="term-engine">Engine</dt>
<dd>look at <a class="reference internal" href="#term-storage-engines"><span class="xref std std-term">Storage Engines</span></a></dd>
<dt id="term-extension">extension</dt>
<dd><p class="first">a PHP module that extends PHP with additional functionality.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Software_extension">https://en.wikipedia.org/wiki/Software_extension</a>&gt;</p>
</div>
</dd>
<dt id="term-faq">FAQ</dt>
<dd><p class="first">Frequently Asked Questions is a list of commonly asked question and there
answers.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/FAQ">https://en.wikipedia.org/wiki/FAQ</a>&gt;</p>
</div>
</dd>
<dt id="term-field">Field</dt>
<dd><p class="first">one part of divided data/columns.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Field_(computer_science)">https://en.wikipedia.org/wiki/Field_(computer_science)</a>&gt;</p>
</div>
</dd>
<dt id="term-foreign-key">foreign key</dt>
<dd><p class="first">a column or group of columns in a database row that points to a key column
or group of columns forming a key of another database row in some
(usually different) table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Foreign_key">https://en.wikipedia.org/wiki/Foreign_key</a>&gt;</p>
</div>
</dd>
<dt id="term-gd">GD</dt>
<dd><p class="first">Graphics Library by Thomas Boutell and others for dynamically manipulating images.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/GD_Graphics_Library">https://en.wikipedia.org/wiki/GD_Graphics_Library</a>&gt;</p>
</div>
</dd>
<dt id="term-gd2">GD2</dt>
<dd>look at <a class="reference internal" href="#term-gd"><span class="xref std std-term">GD</span></a></dd>
<dt id="term-gzip">GZip</dt>
<dd><p class="first">gzip is short for GNU zip, a GNU free software file compression program.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Gzip">https://en.wikipedia.org/wiki/Gzip</a>&gt;</p>
</div>
</dd>
<dt id="term-host">host</dt>
<dd><p class="first">any machine connected to a computer network, a node that has a hostname.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Host">https://en.wikipedia.org/wiki/Host</a>&gt;</p>
</div>
</dd>
<dt id="term-hostname">hostname</dt>
<dd><p class="first">the unique name by which a network-attached device is known on a network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Hostname">https://en.wikipedia.org/wiki/Hostname</a>&gt;</p>
</div>
</dd>
<dt id="term-http">HTTP</dt>
<dd><p class="first">HyperText Transfer Protocol is the primary method used to transfer or
convey information on the World Wide Web.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol">https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol</a>&gt;</p>
</div>
</dd>
<dt id="term-https">https</dt>
<dd><p class="first">a <a class="reference internal" href="#term-http"><span class="xref std std-term">HTTP</span></a>-connection with additional security measures.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Https:_URI_scheme">https://en.wikipedia.org/wiki/Https:_URI_scheme</a>&gt;</p>
</div>
</dd>
<dt id="term-iec">IEC</dt>
<dd>International Electrotechnical Commission</dd>
<dt id="term-iis">IIS</dt>
<dd><p class="first">Internet Information Services is a set of Internet-based services for
servers using Microsoft Windows.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Internet_Information_Services">https://en.wikipedia.org/wiki/Internet_Information_Services</a>&gt;</p>
</div>
</dd>
<dt id="term-index">Index</dt>
<dd><p class="first">a feature that allows quick access to the rows in a table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Index_(database)">https://en.wikipedia.org/wiki/Index_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-ip">IP</dt>
<dd><p class="first">Internet Protocol is a data-oriented protocol used by source and
destination hosts for communicating data across a packet-switched
internetwork.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Internet_Protocol">https://en.wikipedia.org/wiki/Internet_Protocol</a>&gt;</p>
</div>
</dd>
<dt id="term-ip-address">IP Address</dt>
<dd><p class="first">a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/IP_Address">https://en.wikipedia.org/wiki/IP_Address</a>&gt;</p>
</div>
</dd>
<dt id="term-ipv6">IPv6</dt>
<dd><p class="first">IPv6 (Internet Protocol version 6) is the latest revision of the
Internet Protocol (<a class="reference internal" href="#term-ip"><span class="xref std std-term">IP</span></a>), designed to deal with the
long-anticipated problem of its predecessor IPv4 running out of addresses.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/IPv6">https://en.wikipedia.org/wiki/IPv6</a>&gt;</p>
</div>
</dd>
<dt id="term-isapi">ISAPI</dt>
<dd><p class="first">Internet Server Application Programming Interface is the API of Internet Information Services (IIS).</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ISAPI">https://en.wikipedia.org/wiki/ISAPI</a>&gt;</p>
</div>
</dd>
<dt id="term-isp">ISP</dt>
<dd><p class="first">An Internet service provider is a business or organization that offers users
access to the Internet and related services.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ISP">https://en.wikipedia.org/wiki/ISP</a>&gt;</p>
</div>
</dd>
<dt id="term-iso">ISO</dt>
<dd>International Standards Organization</dd>
<dt id="term-jpeg">JPEG</dt>
<dd><p class="first">a most commonly used standard method of lossy compression for photographic images.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/JPEG">https://en.wikipedia.org/wiki/JPEG</a>&gt;</p>
</div>
</dd>
<dt id="term-jpg">JPG</dt>
<dd>look at <a class="reference internal" href="#term-jpeg"><span class="xref std std-term">JPEG</span></a></dd>
<dt id="term-key">Key</dt>
<dd>look at <a class="reference internal" href="#term-index"><span class="xref std std-term">Index</span></a></dd>
<dt id="term-latex">LATEX</dt>
<dd><p class="first">a document preparation system for the TEX typesetting program.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/LaTeX">https://en.wikipedia.org/wiki/LaTeX</a>&gt;</p>
</div>
</dd>
<dt id="term-mac">Mac</dt>
<dd><p class="first">Apple Macintosh is a line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Mac">https://en.wikipedia.org/wiki/Mac</a>&gt;</p>
</div>
</dd>
<dt id="term-mac-os-x">Mac OS X</dt>
<dd><p class="first">the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Mac_OS_X">https://en.wikipedia.org/wiki/Mac_OS_X</a>&gt;</p>
</div>
</dd>
<dt id="term-mbstring">mbstring</dt>
<dd><p class="first">The PHP <cite>mbstring</cite> functions provide support for languages represented by multi-byte character sets, most notably UTF-8.</p>
<p>If you have troubles installing this extension, please follow <a class="reference internal" href="faq.html#faqmysql"><span class="std std-ref">1.20 I receive an error about missing mysqli and mysql extensions.</span></a>, it provides useful hints.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mbstring.php">https://www.php.net/manual/en/book.mbstring.php</a>&gt;</p>
</div>
</dd>
<dt id="term-media-type">Media type</dt>
<dd><p class="first">A media type (formerly known as MIME type) is a two-part identifier
for file formats and format contents transmitted on the Internet.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Media_type">https://en.wikipedia.org/wiki/Media_type</a>&gt;</p>
</div>
</dd>
<dt id="term-mime">MIME</dt>
<dd><p class="first">Multipurpose Internet Mail Extensions is
an Internet Standard for the format of e-mail.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/MIME">https://en.wikipedia.org/wiki/MIME</a>&gt;</p>
</div>
</dd>
<dt id="term-module">module</dt>
<dd><p class="first">some sort of extension for the Apache Webserver.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Apache_HTTP_Server">https://en.wikipedia.org/wiki/Apache_HTTP_Server</a>&gt;</p>
</div>
</dd>
<dt id="term-mod-proxy-fcgi">mod_proxy_fcgi</dt>
<dd>an Apache module implementing a Fast CGI interface; PHP can be run as a CGI module, FastCGI, or
directly as an Apache module.</dd>
<dt id="term-mysql">MySQL</dt>
<dd><p class="first">a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/MySQL">https://en.wikipedia.org/wiki/MySQL</a>&gt;</p>
</div>
</dd>
<dt id="term-mysqli">mysqli</dt>
<dd><p class="first">the improved MySQL client PHP extension.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mysqli.php">https://www.php.net/manual/en/book.mysqli.php</a>&gt;</p>
</div>
</dd>
<dt id="term-47">mysql</dt>
<dd><p class="first">the MySQL client PHP extension.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/manual/en/book.mysql.php">https://www.php.net/manual/en/book.mysql.php</a>&gt;</p>
</div>
</dd>
<dt id="term-opendocument">OpenDocument</dt>
<dd><p class="first">an open standard for office documents.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/OpenDocument">https://en.wikipedia.org/wiki/OpenDocument</a>&gt;</p>
</div>
</dd>
<dt id="term-os-x">OS X</dt>
<dd><p class="first">look at <a class="reference internal" href="#term-mac-os-x"><span class="xref std std-term">Mac OS X</span></a>.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/OS_X">https://en.wikipedia.org/wiki/OS_X</a>&gt;</p>
</div>
</dd>
<dt id="term-pdf">PDF</dt>
<dd><p class="first">Portable Document Format is a file format developed by Adobe Systems for
representing two-dimensional documents in a device-independent and
resolution-independent format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Portable_Document_Format">https://en.wikipedia.org/wiki/Portable_Document_Format</a>&gt;</p>
</div>
</dd>
<dt id="term-pear">PEAR</dt>
<dd><p class="first">the PHP Extension and Application Repository.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://pear.php.net/">https://pear.php.net/</a>&gt;</p>
</div>
</dd>
<dt id="term-pcre">PCRE</dt>
<dd><p class="first">Perl Compatible Regular Expressions is the perl-compatible regular
expression functions for PHP</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://www.php.net/pcre">https://www.php.net/pcre</a>&gt;</p>
</div>
</dd>
<dt id="term-php">PHP</dt>
<dd><p class="first">short for “PHP: Hypertext Preprocessor”, is an open-source, reflective
programming language used mainly for developing server-side applications
and dynamic web content, and more recently, a broader range of software
applications.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/PHP">https://en.wikipedia.org/wiki/PHP</a>&gt;</p>
</div>
</dd>
<dt id="term-port">port</dt>
<dd><p class="first">a connection through which data is sent and received.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Port_(computing)">https://en.wikipedia.org/wiki/Port_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-primary-key">primary key</dt>
<dd><p class="first">A primary key is an index over one or more fields in a table with
unique values for every single row in this table. Every table should have
a primary key for easier accessing/identifying data in this table. There
can only be one primary key per table and it is named always <strong>PRIMARY</strong>.
In fact, a primary key is just an <a class="reference internal" href="#term-unique-key"><span class="xref std std-term">unique key</span></a> with the name
<strong>PRIMARY</strong>. If no primary key is defined MySQL will use first <em>unique
key</em> as primary key if there is one.</p>
<p>You can create the primary key when creating the table (in phpMyAdmin
just check the primary key radio buttons for each field you wish to be
part of the primary key).</p>
<p class="last">You can also add a primary key to an existing table with <cite>ALTER</cite> <cite>TABLE</cite>
or <cite>CREATE</cite> <cite>INDEX</cite> (in phpMyAdmin you can just click on add index on
the table structure page below the listed fields).</p>
</dd>
<dt id="term-rfc">RFC</dt>
<dd><p class="first">Request for Comments (RFC) documents are a series of memoranda
encompassing new research, innovations, and methodologies applicable to
Internet technologies.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Request_for_Comments">https://en.wikipedia.org/wiki/Request_for_Comments</a>&gt;</p>
</div>
</dd>
<dt id="term-rfc-1952">RFC 1952</dt>
<dd><p class="first">GZIP file format specification version 4.3</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><span class="target" id="index-0"></span><a class="rfc reference external" href="https://tools.ietf.org/html/rfc1952.html"><strong>RFC 1952</strong></a></p>
</div>
</dd>
<dt id="term-row-record-tuple">Row (record, tuple)</dt>
<dd><p class="first">represents a single, implicitly structured data item in a table.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Row_(database)">https://en.wikipedia.org/wiki/Row_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-server">Server</dt>
<dd><p class="first">a computer system that provides services to other computing systems over a network.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Server_(computing)">https://en.wikipedia.org/wiki/Server_(computing)</a>&gt;</p>
</div>
</dd>
<dt id="term-storage-engines">Storage Engines</dt>
<dd><p class="first">MySQL can use several different formats for storing data on disk, these
are called storage engines or table types. phpMyAdmin allows a user to
change their storage engine for a particular table through the operations
tab.</p>
<p>Common table types are InnoDB and MyISAM, though many others exist and
may be desirable in some situations.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html">https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html</a>&gt;</p>
</div>
</dd>
<dt id="term-socket">socket</dt>
<dd><p class="first">a form of inter-process communication.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Unix_domain_socket">https://en.wikipedia.org/wiki/Unix_domain_socket</a>&gt;</p>
</div>
</dd>
<dt id="term-ssl">SSL</dt>
<dd><p class="first">Secure Sockets Layer is a cryptographic protocol which provides secure
communication on the Internet.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Secure_Sockets_Layer">https://en.wikipedia.org/wiki/Secure_Sockets_Layer</a>&gt;</p>
</div>
</dd>
<dt id="term-stored-procedure">Stored procedure</dt>
<dd><p class="first">a subroutine available to applications accessing a relational database system</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Stored_procedure">https://en.wikipedia.org/wiki/Stored_procedure</a>&gt;</p>
</div>
</dd>
<dt id="term-sql">SQL</dt>
<dd><p class="first">Structured Query Language</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/SQL">https://en.wikipedia.org/wiki/SQL</a>&gt;</p>
</div>
</dd>
<dt id="term-table">table</dt>
<dd><p class="first">a set of data elements (cells) that is organized, defined and stored as
horizontal rows and vertical columns where each item can be uniquely
identified by a label or key or by its position in relation to other
items.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Table_(database)">https://en.wikipedia.org/wiki/Table_(database)</a>&gt;</p>
</div>
</dd>
<dt id="term-tar">tar</dt>
<dd><p class="first">a type of archive file format: the Tape ARchive format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Tar_(file_format)">https://en.wikipedia.org/wiki/Tar_(file_format)</a>&gt;</p>
</div>
</dd>
<dt id="term-tcp">TCP</dt>
<dd><p class="first">Transmission Control Protocol is one of the core protocols of the
Internet protocol suite.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/TCP">https://en.wikipedia.org/wiki/TCP</a>&gt;</p>
</div>
</dd>
<dt id="term-tcpdf">TCPDF</dt>
<dd><p class="first">PHP library to generate PDF files.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://tcpdf.org/">https://tcpdf.org/</a>&gt;</p>
</div>
</dd>
<dt id="term-trigger">trigger</dt>
<dd><p class="first">a procedural code that is automatically executed in response to certain events on a particular table or view in a database</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Database_trigger">https://en.wikipedia.org/wiki/Database_trigger</a>&gt;</p>
</div>
</dd>
<dt id="term-unique-key">unique key</dt>
<dd>A unique key is an index over one or more fields in a table which has a
unique value for each row. The first unique key will be treated as
<a class="reference internal" href="#term-primary-key"><span class="xref std std-term">primary key</span></a> if there is no <em>primary key</em> defined.</dd>
<dt id="term-url">URL</dt>
<dd><p class="first">Uniform Resource Locator is a sequence of characters, conforming to a
standardized format, that is used for referring to resources, such as
documents and images on the Internet, by their location.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/URL">https://en.wikipedia.org/wiki/URL</a>&gt;</p>
</div>
</dd>
<dt id="term-webserver">Webserver</dt>
<dd><p class="first">A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Webserver">https://en.wikipedia.org/wiki/Webserver</a>&gt;</p>
</div>
</dd>
<dt id="term-xml">XML</dt>
<dd><p class="first">Extensible Markup Language is a W3C-recommended general-purpose markup
language for creating special-purpose markup languages, capable of
describing many different kinds of data.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/XML">https://en.wikipedia.org/wiki/XML</a>&gt;</p>
</div>
</dd>
<dt id="term-zip">ZIP</dt>
<dd><p class="first">a popular data compression and archival format.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/ZIP_(file_format)">https://en.wikipedia.org/wiki/ZIP_(file_format)</a>&gt;</p>
</div>
</dd>
<dt id="term-zlib">Zlib</dt>
<dd><p class="first">an open-source, cross-platform data compression library by Jean-loup Gailly and Mark Adler.</p>
<div class="last admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last">&lt;<a class="reference external" href="https://en.wikipedia.org/wiki/Zlib">https://en.wikipedia.org/wiki/Zlib</a>&gt;</p>
</div>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>Previous topic</h4>
<p class="topless"><a href="credits.html"
title="previous chapter">Credits</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/glossary.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="credits.html" title="Credits"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,188 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Introduction &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Requirements" href="require.html" />
<link rel="prev" title="Welcome to phpMyAdmins documentation!" href="index.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="require.html" title="Requirements"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to phpMyAdmins documentation!"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="introduction">
<span id="intro"></span><h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h1>
<p>phpMyAdmin is a free software tool written in PHP that is intended to handle the
administration of a MySQL or MariaDB database server. You can use phpMyAdmin to
perform most administration tasks, including creating a database, running queries,
and adding user accounts.</p>
<div class="section" id="supported-features">
<h2>Supported features<a class="headerlink" href="#supported-features" title="Permalink to this headline"></a></h2>
<p>Currently phpMyAdmin can:</p>
<ul class="simple">
<li>create, browse, edit, and drop databases, tables, views, columns, and indexes</li>
<li>display multiple results sets through stored procedures or queries</li>
<li>create, copy, drop, rename and alter databases, tables, columns and
indexes</li>
<li>maintenance server, databases and tables, with proposals on server
configuration</li>
<li>execute, edit and bookmark any <a class="reference internal" href="glossary.html#term-sql"><span class="xref std std-term">SQL</span></a>-statement, even batch-queries</li>
<li>load text files into tables</li>
<li>create <a class="footnote-reference" href="#f1" id="id1">[1]</a> and read dumps of tables</li>
<li>export <a class="footnote-reference" href="#f1" id="id2">[1]</a> data to various formats: <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a>, <a class="reference internal" href="glossary.html#term-xml"><span class="xref std std-term">XML</span></a>, <a class="reference internal" href="glossary.html#term-pdf"><span class="xref std std-term">PDF</span></a>,
<a class="reference internal" href="glossary.html#term-iso"><span class="xref std std-term">ISO</span></a>/<a class="reference internal" href="glossary.html#term-iec"><span class="xref std std-term">IEC</span></a> 26300 - <a class="reference internal" href="glossary.html#term-opendocument"><span class="xref std std-term">OpenDocument</span></a> Text and Spreadsheet, Microsoft
Word 2000, and LATEX formats</li>
<li>import data and <a class="reference internal" href="glossary.html#term-47"><span class="xref std std-term">MySQL</span></a> structures from <a class="reference internal" href="glossary.html#term-opendocument"><span class="xref std std-term">OpenDocument</span></a> spreadsheets, as
well as <a class="reference internal" href="glossary.html#term-xml"><span class="xref std std-term">XML</span></a>, <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a>, and <a class="reference internal" href="glossary.html#term-sql"><span class="xref std std-term">SQL</span></a> files</li>
<li>administer multiple servers</li>
<li>add, edit, and remove MySQL user accounts and privileges</li>
<li>check referential integrity in MyISAM tables</li>
<li>using Query-by-example (QBE), create complex queries automatically
connecting required tables</li>
<li>create <a class="reference internal" href="glossary.html#term-pdf"><span class="xref std std-term">PDF</span></a> graphics of your
database layout</li>
<li>search globally in a database or a subset of it</li>
<li>transform stored data into any format using a set of predefined
functions, like displaying BLOB-data as image or download-link</li>
<li>track changes on databases, tables and views</li>
<li>support InnoDB tables and foreign keys</li>
<li>support mysqli, the improved MySQL extension see <a class="reference internal" href="faq.html#faq1-17"><span class="std std-ref">1.17 Which Database versions does phpMyAdmin support?</span></a></li>
<li>create, edit, call, export and drop stored procedures and functions</li>
<li>create, edit, export and drop events and triggers</li>
<li>communicate in <a class="reference external" href="https://www.phpmyadmin.net/translations/">80 different languages</a></li>
</ul>
</div>
<div class="section" id="shortcut-keys">
<h2>Shortcut keys<a class="headerlink" href="#shortcut-keys" title="Permalink to this headline"></a></h2>
<p>Currently phpMyAdmin supports following shortcuts:</p>
<ul class="simple">
<li>k - Toggle console</li>
<li>h - Go to home page</li>
<li>s - Open settings</li>
<li>d + s - Go to database structure (Provided you are in database related page)</li>
<li>d + f - Search database (Provided you are in database related page)</li>
<li>t + s - Go to table structure (Provided you are in table related page)</li>
<li>t + f - Search table (Provided you are in table related page)</li>
<li>backspace - Takes you to older page.</li>
</ul>
</div>
<div class="section" id="a-word-about-users">
<h2>A word about users<a class="headerlink" href="#a-word-about-users" title="Permalink to this headline"></a></h2>
<p>Many people have difficulty understanding the concept of user
management with regards to phpMyAdmin. When a user logs in to
phpMyAdmin, that username and password are passed directly to MySQL.
phpMyAdmin does no account management on its own (other than allowing
one to manipulate the MySQL user account information); all users must
be valid MySQL users.</p>
<p class="rubric">Footnotes</p>
<table class="docutils footnote" frame="void" id="f1" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id2">2</a>)</em> phpMyAdmin can compress (<a class="reference internal" href="glossary.html#term-zip"><span class="xref std std-term">ZIP</span></a>, <a class="reference internal" href="glossary.html#term-gzip"><span class="xref std std-term">GZip</span></a> or <a class="reference internal" href="glossary.html#term-rfc-1952"><span class="xref std std-term">RFC 1952</span></a>
formats) dumps and <a class="reference internal" href="glossary.html#term-csv"><span class="xref std std-term">CSV</span></a> exports if you use PHP with
<a class="reference internal" href="glossary.html#term-zlib"><span class="xref std std-term">Zlib</span></a> support (<code class="docutils literal notranslate"><span class="pre">--with-zlib</span></code>).
Proper support may also need changes in <code class="file docutils literal notranslate"><span class="pre">php.ini</span></code>.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Introduction</a><ul>
<li><a class="reference internal" href="#supported-features">Supported features</a></li>
<li><a class="reference internal" href="#shortcut-keys">Shortcut keys</a></li>
<li><a class="reference internal" href="#a-word-about-users">A word about users</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Welcome to phpMyAdmins documentation!</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="require.html"
title="next chapter">Requirements</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/intro.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="require.html" title="Requirements"
>next</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to phpMyAdmins documentation!"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,150 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Other sources of information &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="FAQ - Frequently Asked Questions" href="faq.html" />
<link rel="prev" title="Custom Themes" href="themes.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="themes.html" title="Custom Themes"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="other-sources-of-information">
<h1>Other sources of information<a class="headerlink" href="#other-sources-of-information" title="Permalink to this headline"></a></h1>
<div class="section" id="printed-book">
<h2>Printed Book<a class="headerlink" href="#printed-book" title="Permalink to this headline"></a></h2>
<p>The definitive guide to using phpMyAdmin is the book Mastering phpMyAdmin for
Effective MySQL Management by Marc Delisle. You can get information on that
book and other officially endorsed <a class="reference external" href="https://www.phpmyadmin.net/docs/">books at the phpMyAdmin site</a>.</p>
</div>
<div class="section" id="tutorials">
<h2>Tutorials<a class="headerlink" href="#tutorials" title="Permalink to this headline"></a></h2>
<p>Third party tutorials and articles which you might find interesting:</p>
<div class="section" id="cesky-czech">
<h3>Česky (Czech)<a class="headerlink" href="#cesky-czech" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://cihar.com/publications/linuxsoft/">Seriál o phpMyAdminovi</a></li>
</ul>
</div>
<div class="section" id="english">
<h3>English<a class="headerlink" href="#english" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://garv.in/tops/texte/mimetutorial">Having fun with phpMyAdmins MIME-transformations &amp; PDF-features</a></li>
<li><a class="reference external" href="http://www.php-editors.com/articles/sql_phpmyadmin.php">Learning SQL Using phpMyAdmin (old tutorial)</a></li>
</ul>
</div>
<div class="section" id="russian">
<h3>Русский (Russian)<a class="headerlink" href="#russian" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><a class="reference external" href="https://php-myadmin.ru/">Russian server about phpMyAdmin</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Other sources of information</a><ul>
<li><a class="reference internal" href="#printed-book">Printed Book</a></li>
<li><a class="reference internal" href="#tutorials">Tutorials</a><ul>
<li><a class="reference internal" href="#cesky-czech">Česky (Czech)</a></li>
<li><a class="reference internal" href="#english">English</a></li>
<li><a class="reference internal" href="#russian">Русский (Russian)</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="themes.html"
title="previous chapter">Custom Themes</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="faq.html"
title="next chapter">FAQ - Frequently Asked Questions</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/other.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="faq.html" title="FAQ - Frequently Asked Questions"
>next</a> |</li>
<li class="right" >
<a href="themes.html" title="Custom Themes"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,165 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Requirements &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Installation" href="setup.html" />
<link rel="prev" title="Introduction" href="intro.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="setup.html" title="Installation"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="requirements">
<span id="require"></span><h1>Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h1>
<div class="section" id="web-server">
<h2>Web server<a class="headerlink" href="#web-server" title="Permalink to this headline"></a></h2>
<p>Since phpMyAdmins interface is based entirely in your browser, youll need a
web server (such as Apache, nginx, <a class="reference internal" href="glossary.html#term-iis"><span class="xref std std-term">IIS</span></a>) to install phpMyAdmins files into.</p>
</div>
<div class="section" id="php">
<h2>PHP<a class="headerlink" href="#php" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>You need PHP 7.1.3 or newer, with <code class="docutils literal notranslate"><span class="pre">session</span></code> support, the Standard PHP Library
(SPL) extension, hash, ctype, and JSON support.</li>
<li>The <code class="docutils literal notranslate"><span class="pre">mbstring</span></code> extension (see <a class="reference internal" href="glossary.html#term-mbstring"><span class="xref std std-term">mbstring</span></a>) is strongly recommended
for performance reasons.</li>
<li>To support uploading of ZIP files, you need the PHP <code class="docutils literal notranslate"><span class="pre">zip</span></code> extension.</li>
<li>You need GD2 support in PHP to display inline thumbnails of JPEGs
(“image/jpeg: inline”) with their original aspect ratio.</li>
<li>When using the cookie authentication (the default), the <a class="reference external" href="https://www.php.net/openssl">openssl</a> extension is strongly suggested.</li>
<li>To support upload progress bars, see <a class="reference internal" href="faq.html#faq2-9"><span class="std std-ref">2.9 Seeing an upload progress bar</span></a>.</li>
<li>To support XML and Open Document Spreadsheet importing, you need the
<a class="reference external" href="https://www.php.net/libxml">libxml</a> extension.</li>
<li>To support reCAPTCHA on the login page, you need the
<a class="reference external" href="https://www.php.net/openssl">openssl</a> extension.</li>
<li>To support displaying phpMyAdmins latest version, you need to enable
<code class="docutils literal notranslate"><span class="pre">allow_url_open</span></code> in your <code class="file docutils literal notranslate"><span class="pre">php.ini</span></code> or to have the
<a class="reference external" href="https://www.php.net/curl">curl</a> extension.</li>
</ul>
<div class="admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="faq.html#faq1-31"><span class="std std-ref">1.31 Which PHP versions does phpMyAdmin support?</span></a>, <a class="reference internal" href="setup.html#authentication-modes"><span class="std std-ref">Using authentication modes</span></a></p>
</div>
</div>
<div class="section" id="database">
<h2>Database<a class="headerlink" href="#database" title="Permalink to this headline"></a></h2>
<p>phpMyAdmin supports MySQL-compatible databases.</p>
<ul class="simple">
<li>MySQL 5.5 or newer</li>
<li>MariaDB 5.5 or newer</li>
</ul>
<div class="admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="faq.html#faq1-17"><span class="std std-ref">1.17 Which Database versions does phpMyAdmin support?</span></a></p>
</div>
</div>
<div class="section" id="web-browser">
<h2>Web browser<a class="headerlink" href="#web-browser" title="Permalink to this headline"></a></h2>
<p>To access phpMyAdmin you need a web browser with cookies and JavaScript
enabled.</p>
<p>You need a browser which is supported by jQuery 2.0, see
&lt;<a class="reference external" href="https://jquery.com/browser-support/">https://jquery.com/browser-support/</a>&gt;.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Requirements</a><ul>
<li><a class="reference internal" href="#web-server">Web server</a></li>
<li><a class="reference internal" href="#php">PHP</a></li>
<li><a class="reference internal" href="#database">Database</a></li>
<li><a class="reference internal" href="#web-browser">Web browser</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="intro.html"
title="previous chapter">Introduction</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="setup.html"
title="next chapter">Installation</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/require.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="setup.html" title="Installation"
>next</a> |</li>
<li class="right" >
<a href="intro.html" title="Introduction"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,94 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,237 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Transformations &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Bookmarks" href="bookmarks.html" />
<link rel="prev" title="Two-factor authentication" href="two_factor.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="bookmarks.html" title="Bookmarks"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="two_factor.html" title="Two-factor authentication"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="transformations">
<span id="id1"></span><h1>Transformations<a class="headerlink" href="#transformations" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You need to have configured the <a class="reference internal" href="setup.html#linked-tables"><span class="std std-ref">phpMyAdmin configuration storage</span></a> for using transformations
feature.</p>
</div>
<div class="section" id="introduction">
<span id="transformationsintro"></span><h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p>To enable transformations, you have to setup the <code class="docutils literal notranslate"><span class="pre">column_info</span></code>
table and the proper directives. Please see the <a class="reference internal" href="config.html#config"><span class="std std-ref">Configuration</span></a> on how to do so.</p>
<p>You can apply different transformations to the contents of each
column. The transformation will take the content of each column and
transform it with certain rules defined in the selected
transformation.</p>
<p>Say you have a column filename which contains a filename. Normally
you would see in phpMyAdmin only this filename. Using transformations
you can transform that filename into a HTML link, so you can click
inside of the phpMyAdmin structure on the columns link and will see
the file displayed in a new browser window. Using transformation
options you can also specify strings to append/prepend to a string or
the format you want the output stored in.</p>
<p>For a general overview of all available transformations and their
options, you can consult your <em>&lt;www.your-host.com&gt;/&lt;your-install-
dir&gt;/transformation_overview.php</em> installation.</p>
<p>For a tutorial on how to effectively use transformations, see our
<a class="reference external" href="https://www.phpmyadmin.net/docs/">Link section</a> on the
official phpMyAdmin homepage.</p>
</div>
<div class="section" id="usage">
<span id="transformationshowto"></span><h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline"></a></h2>
<p>Go to your <em>tbl_structure.php</em> page (i.e. reached through clicking on
the Structure link for a table). There click on “Change” (or change
icon) and there you will see three new fields at the end of the line.
They are called <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a>, Browser transformation and
Transformation options.</p>
<ul class="simple">
<li>The field <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> is a drop-down field. Select the <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> that
corresponds to the columns contents. Please note that transformations
are inactive as long as no <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> is selected.</li>
<li>The field Browser transformation is a drop-down field. You can
choose from a hopefully growing amount of pre-defined transformations.
See below for information on how to build your own transformation.
There are global transformations and mimetype-bound transformations.
Global transformations can be used for any mimetype. They will take
the mimetype, if necessary, into regard. Mimetype-bound
transformations usually only operate on a certain mimetype. There are
transformations which operate on the main mimetype (like image),
which will most likely take the subtype into regard, and those who
only operate on a specific subtype (like image/jpeg). You can use
transformations on mimetypes for which the function was not defined
for. There is no security check for you selected the right
transformation, so take care of what the output will be like.</li>
<li>The field Transformation options is a free-type textfield. You have
to enter transform-function specific options here. Usually the
transforms can operate with default options, but it is generally a
good idea to look up the overview to see which options are necessary.
Much like the ENUM/SET-Fields, you have to split up several options
using the format a,b,c,…(NOTE THE MISSING BLANKS). This is
because internally the options will be parsed as an array, leaving the
first value the first element in the array, and so forth. If you want
to specify a MIME character set you can define it in the
transformation_options. You have to put that outside of the pre-
defined options of the specific mime-transform, as the last value of
the set. Use the format “’; charset=XXX”. If you use a transform, for
which you can specify 2 options and you want to append a character
set, enter “first parameter,second parameter,charset=us-ascii”.
You can, however use the defaults for the parameters: “’‘,,charset
=us-ascii”. The default options can be configured using
<span class="target" id="index-0"></span><a class="reference internal" href="config.html#cfg_DefaultTransformations"><code class="xref config config-option docutils literal notranslate"><span class="pre">$cfg['DefaultTransformations']</span></code></a></li>
</ul>
</div>
<div class="section" id="file-structure">
<span id="transformationsfiles"></span><h2>File structure<a class="headerlink" href="#file-structure" title="Permalink to this headline"></a></h2>
<p>All specific transformations for mimetypes are defined through class
files in the directory libraries/classes/Plugins/Transformations/. Each of
them extends a certain transformation abstract class declared in
libraries/classes/Plugins/Transformations/Abs.</p>
<p>They are stored in files to ease up customization and easy adding of
new transformations.</p>
<p>Because the user cannot enter own mimetypes, it is kept sure that
transformations always work. It makes no sense to apply a
transformation to a mimetype the transform-function doesnt know to
handle.</p>
<p>There is a file called <code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations.php</span></code> that provides some
basic functions which can be included by any other transform function.</p>
<p>The file name convention is <code class="docutils literal notranslate"><span class="pre">[Mimetype]_[Subtype]_[Transformation</span>
<span class="pre">Name].php</span></code>, while the abstract class that it extends has the
name <code class="docutils literal notranslate"><span class="pre">[Transformation</span> <span class="pre">Name]TransformationsPlugin</span></code>. All of the
methods that have to be implemented by a transformations plug-in are:</p>
<ol class="arabic simple">
<li>getMIMEType() and getMIMESubtype() in the main class;</li>
<li>getName(), getInfo() and applyTransformation() in the abstract class
it extends.</li>
</ol>
<p>The getMIMEType(), getMIMESubtype() and getName() methods return the
name of the MIME type, MIME Subtype and transformation accordingly.
getInfo() returns the transformations description and possible
options it may receive and applyTransformation() is the method that
does the actual work of the transformation plug-in.</p>
<p>Please see the <code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations/TEMPLATE</span></code> and
<code class="file docutils literal notranslate"><span class="pre">libraries/classes/Plugins/Transformations/TEMPLATE_ABSTRACT</span></code> files for adding
your own transformation plug-in. You can also generate a new
transformation plug-in (with or without the abstract transformation
class), by using
<code class="file docutils literal notranslate"><span class="pre">scripts/transformations_generator_plugin.sh</span></code> or
<code class="file docutils literal notranslate"><span class="pre">scripts/transformations_generator_main_class.sh</span></code>.</p>
<p>The applyTransformation() method always gets passed three variables:</p>
<ol class="arabic simple">
<li><strong>$buffer</strong> - Contains the text inside of the column. This is the
text, you want to transform.</li>
<li><strong>$options</strong> - Contains any user-passed options to a transform
function as an array.</li>
<li><strong>$meta</strong> - Contains an object with information about your column. The
data is drawn from the output of the <a class="reference external" href="https://www.php.net/mysql_fetch_field">mysql_fetch_field()</a> function. This means, all
object properties described on the <a class="reference external" href="https://www.php.net/mysql_fetch_field">manual page</a> are available in this
variable and can be used to transform a column accordingly to
unsigned/zerofill/not_null/… properties. The $meta-&gt;mimetype
variable contains the original <a class="reference internal" href="glossary.html#term-media-type"><span class="xref std std-term">Media type</span></a> of the column (i.e.
text/plain, image/jpeg etc.)</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Transformations</a><ul>
<li><a class="reference internal" href="#introduction">Introduction</a></li>
<li><a class="reference internal" href="#usage">Usage</a></li>
<li><a class="reference internal" href="#file-structure">File structure</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="two_factor.html"
title="previous chapter">Two-factor authentication</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="bookmarks.html"
title="next chapter">Bookmarks</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/transformations.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="bookmarks.html" title="Bookmarks"
>next</a> |</li>
<li class="right" >
<a href="two_factor.html" title="Two-factor authentication"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,172 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Two-factor authentication &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Transformations" href="transformations.html" />
<link rel="prev" title="Configuring phpMyAdmin" href="settings.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="transformations.html" title="Transformations"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="settings.html" title="Configuring phpMyAdmin"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" accesskey="U">User Guide</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="two-factor-authentication">
<span id="fa"></span><h1>Two-factor authentication<a class="headerlink" href="#two-factor-authentication" title="Permalink to this headline"></a></h1>
<div class="versionadded">
<p><span class="versionmodified">New in version 4.8.0.</span></p>
</div>
<p>Since phpMyAdmin 4.8.0 you can configure two-factor authentication to be
used when logging in. To use this, you first need to configure the
<a class="reference internal" href="setup.html#linked-tables"><span class="std std-ref">phpMyAdmin configuration storage</span></a>. Once this is done, every user can opt-in for the second
authentication factor in the <span class="guilabel">Settings</span>.</p>
<p>When running phpMyAdmin from the Git source repository, the dependencies must be installed
manually; the typical way of doing so is with the command:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>composer require pragmarx/google2fa-qrcode
</pre></div>
</div>
<p>Or when using a hardware security key with FIDO U2F:</p>
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span>composer require samyoul/u2f-php-server
</pre></div>
</div>
<div class="section" id="authentication-application-2fa">
<h2>Authentication Application (2FA)<a class="headerlink" href="#authentication-application-2fa" title="Permalink to this headline"></a></h2>
<p>Using an application for authentication is a quite common approach based on HOTP and
<a class="reference external" href="https://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm">TOTP</a>.
It is based on transmitting a private key from phpMyAdmin to the authentication
application and the application is then able to generate one time codes based
on this key. The easiest way to enter the key in to the application from phpMyAdmin is
through scanning a QR code.</p>
<p>There are dozens of applications available for mobile phones to implement these
standards, the most widely used include:</p>
<ul class="simple">
<li><a class="reference external" href="https://freeotp.github.io/">FreeOTP for iOS, Android and Pebble</a></li>
<li><a class="reference external" href="https://authy.com/">Authy for iOS, Android, Chrome, OS X</a></li>
<li><a class="reference external" href="https://apps.apple.com/us/app/google-authenticator/id388497605">Google Authenticator for iOS</a></li>
<li><a class="reference external" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator for Android</a></li>
<li><a class="reference external" href="https://lastpass.com/auth/">LastPass Authenticator for iOS, Android, OS X, Windows</a></li>
</ul>
</div>
<div class="section" id="hardware-security-key-fido-u2f">
<h2>Hardware Security Key (FIDO U2F)<a class="headerlink" href="#hardware-security-key-fido-u2f" title="Permalink to this headline"></a></h2>
<p>Using hardware tokens is considered to be more secure than a software based
solution. phpMyAdmin supports <a class="reference external" href="https://en.wikipedia.org/wiki/Universal_2nd_Factor">FIDO U2F</a>
tokens.</p>
<p>There are several manufacturers of these tokens, for example:</p>
<ul class="simple">
<li><a class="reference external" href="https://www.yubico.com/fido-u2f/">youbico FIDO U2F Security Key</a></li>
<li><a class="reference external" href="https://www.hypersecu.com/hyperfido">HyperFIDO</a></li>
<li><a class="reference external" href="https://trezor.io/?offer_id=12&amp;aff_id=1592&amp;source=phpmyadmin">Trezor Hardware Wallet</a> can act as an <a class="reference external" href="https://wiki.trezor.io/User_manual:Two-factor_Authentication_with_U2F">U2F token</a></li>
<li><a class="reference external" href="https://www.dongleauth.info/dongles/">List of Two Factor Auth (2FA) Dongles</a></li>
</ul>
</div>
<div class="section" id="simple-two-factor-authentication">
<span id="simple2fa"></span><h2>Simple two-factor authentication<a class="headerlink" href="#simple-two-factor-authentication" title="Permalink to this headline"></a></h2>
<p>This authentication is included for testing and demonstration purposes only as
it really does not provide two-factor authentication, it just asks the user to confirm login by
clicking on the button.</p>
<p>It should not be used in the production and is disabled unless
<span class="target" id="index-0"></span><a class="reference internal" href="config.html#cfg_DBG_simple2fa"><code class="xref config config-option docutils literal notranslate"><span class="pre">$cfg['DBG']['simple2fa']</span></code></a> is set.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Two-factor authentication</a><ul>
<li><a class="reference internal" href="#authentication-application-2fa">Authentication Application (2FA)</a></li>
<li><a class="reference internal" href="#hardware-security-key-fido-u2f">Hardware Security Key (FIDO U2F)</a></li>
<li><a class="reference internal" href="#simple-two-factor-authentication">Simple two-factor authentication</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="settings.html"
title="previous chapter">Configuring phpMyAdmin</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="transformations.html"
title="next chapter">Transformations</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/two_factor.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="transformations.html" title="Transformations"
>next</a> |</li>
<li class="right" >
<a href="settings.html" title="Configuring phpMyAdmin"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="user.html" >User Guide</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,138 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Distributing and packaging phpMyAdmin &#8212; phpMyAdmin 5.0.4 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="copyright" title="Copyright" href="copyright.html" />
<link rel="next" title="Copyright" href="copyright.html" />
<link rel="prev" title="Security policy" href="security.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="copyright.html" title="Copyright"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="security.html" title="Security policy"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="distributing-and-packaging-phpmyadmin">
<h1>Distributing and packaging phpMyAdmin<a class="headerlink" href="#distributing-and-packaging-phpmyadmin" title="Permalink to this headline"></a></h1>
<p>This document is intended to give pieces of advice to people who want to
redistribute phpMyAdmin inside other software packages such as Linux
distribution or some all in one package including web server and MySQL
server.</p>
<p>Generally, you can customize some basic aspects (paths to some files and
behavior) in <code class="file docutils literal notranslate"><span class="pre">libraries/vendor_config.php</span></code>.</p>
<p>For example, if you want setup script to generate a config file in var, change
<code class="docutils literal notranslate"><span class="pre">SETUP_CONFIG_FILE</span></code> to <code class="file docutils literal notranslate"><span class="pre">/var/lib/phpmyadmin/config.inc.php</span></code> and you
will also probably want to skip directory writable check, so set
<code class="docutils literal notranslate"><span class="pre">SETUP_DIR_WRITABLE</span></code> to false.</p>
<div class="section" id="external-libraries">
<h2>External libraries<a class="headerlink" href="#external-libraries" title="Permalink to this headline"></a></h2>
<p>phpMyAdmin includes several external libraries, you might want to
replace them with system ones if they are available, but please note
that you should test whether the version you provide is compatible with the
one we ship.</p>
<p>Currently known list of external libraries:</p>
<dl class="docutils">
<dt>js/vendor</dt>
<dd>jQuery js framework libraries and various js libraries.</dd>
<dt>vendor/</dt>
<dd>The download kit includes various Composer packages as
dependencies.</dd>
</dl>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Distributing and packaging phpMyAdmin</a><ul>
<li><a class="reference internal" href="#external-libraries">External libraries</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="security.html"
title="previous chapter">Security policy</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="copyright.html"
title="next chapter">Copyright</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/vendors.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="copyright.html" title="Copyright"
>next</a> |</li>
<li class="right" >
<a href="security.html" title="Security policy"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">phpMyAdmin 5.0.4 documentation</a> &#187;</li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; <a href="copyright.html">Copyright</a> 2012 - 2020, The phpMyAdmin devel team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
</div>
</body>
</html>

View File

@ -1,140 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Handle error report submission
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\ErrorReport;
use PhpMyAdmin\Message;
use PhpMyAdmin\Response;
use PhpMyAdmin\UserPreferences;
use PhpMyAdmin\Utils\HttpRequest;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
if (! isset($_POST['exception_type'])
|| ! in_array($_POST['exception_type'], ['js', 'php'])
) {
die('Oops, something went wrong!!');
}
$response = Response::getInstance();
/** @var ErrorReport $errorReport */
$errorReport = $containerBuilder->get('error_report');
if (isset($_POST['send_error_report'])
&& ($_POST['send_error_report'] == true
|| $_POST['send_error_report'] == '1')
) {
if ($_POST['exception_type'] == 'php') {
/**
* Prevent infinite error submission.
* Happens in case error submissions fails.
* If reporting is done in some time interval,
* just clear them & clear json data too.
*/
if (isset($_SESSION['prev_error_subm_time'])
&& isset($_SESSION['error_subm_count'])
&& $_SESSION['error_subm_count'] >= 3
&& ($_SESSION['prev_error_subm_time'] - time()) <= 3000
) {
$_SESSION['error_subm_count'] = 0;
$_SESSION['prev_errors'] = '';
$response->addJSON('stopErrorReportLoop', '1');
} else {
$_SESSION['prev_error_subm_time'] = time();
$_SESSION['error_subm_count'] = (
isset($_SESSION['error_subm_count'])
? ($_SESSION['error_subm_count'] + 1)
: 0
);
}
}
$reportData = $errorReport->getData($_POST['exception_type']);
// report if and only if there were 'actual' errors.
if (count($reportData) > 0) {
$server_response = $errorReport->send($reportData);
if (! is_string($server_response)) {
$success = false;
} else {
$decoded_response = json_decode($server_response, true);
$success = ! empty($decoded_response) ?
$decoded_response["success"] : false;
}
/* Message to show to the user */
if ($success) {
if ((isset($_POST['automatic'])
&& $_POST['automatic'] === "true")
|| $GLOBALS['cfg']['SendErrorReports'] == 'always'
) {
$msg = __(
'An error has been detected and an error report has been '
. 'automatically submitted based on your settings.'
);
} else {
$msg = __('Thank you for submitting this report.');
}
} else {
$msg = __(
'An error has been detected and an error report has been '
. 'generated but failed to be sent.'
)
. ' '
. __(
'If you experience any '
. 'problems please submit a bug report manually.'
);
}
$msg .= ' ' . __('You may want to refresh the page.');
/* Create message object */
if ($success) {
$msg = Message::notice($msg);
} else {
$msg = Message::error($msg);
}
/* Add message to response */
if ($response->isAjax()) {
if ($_POST['exception_type'] == 'js') {
$response->addJSON('message', $msg);
} else {
$response->addJSON('errSubmitMsg', $msg);
}
} elseif ($_POST['exception_type'] == 'php') {
$jsCode = 'Functions.ajaxShowMessage("<div class=\"error\">'
. $msg
. '</div>", false);';
$response->getFooter()->getScripts()->addCode($jsCode);
}
if ($_POST['exception_type'] == 'php') {
// clear previous errors & save new ones.
$GLOBALS['error_handler']->savePreviousErrors();
}
/* Persist always send settings */
if (isset($_POST['always_send'])
&& $_POST['always_send'] === "true"
) {
$userPreferences = new UserPreferences();
$userPreferences->persistOption("SendErrorReports", "always", "ask");
}
}
} elseif (! empty($_POST['get_settings'])) {
$response->addJSON('report_setting', $GLOBALS['cfg']['SendErrorReports']);
} elseif ($_POST['exception_type'] == 'js') {
$response->addHTML($errorReport->getForm());
} else {
// clear previous errors & save new ones.
$GLOBALS['error_handler']->savePreviousErrors();
}

View File

@ -1,178 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Single signon for phpMyAdmin using OpenID
*
* This is just example how to use single signon with phpMyAdmin, it is
* not intended to be perfect code and look, only shows how you can
* integrate this functionality in your application.
*
* It uses OpenID pear package, see https://pear.php.net/package/OpenID
*
* User first authenticates using OpenID and based on content of $AUTH_MAP
* the login information is passed to phpMyAdmin in session data.
*
* @package PhpMyAdmin
* @subpackage Example
*/
declare(strict_types=1);
if (false === @include_once 'OpenID/RelyingParty.php') {
exit;
}
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/**
* Map of authenticated users to MySQL user/password pairs.
*/
$AUTH_MAP = [
'https://launchpad.net/~username' => [
'user' => 'root',
'password' => '',
],
];
/**
* Simple function to show HTML page with given content.
*
* @param string $contents Content to include in page
*
* @return void
*/
function Show_page($contents)
{
header('Content-Type: text/html; charset=utf-8');
echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";
?>
<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin OpenID signon example</title>
</head>
<body>
<?php
if (isset($_SESSION) && isset($_SESSION['PMA_single_signon_error_message'])) {
echo '<p class="error">' , $_SESSION['PMA_single_signon_message'] , '</p>';
unset($_SESSION['PMA_single_signon_message']);
}
echo $contents;
?>
</body>
</html>
<?php
}
/**
* Display error and exit
*
* @param Exception $e Exception object
*
* @return void
*/
function Die_error($e)
{
$contents = "<div class='relyingparty_results'>\n";
$contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
$contents .= "</div class='relyingparty_results'>";
Show_page($contents);
exit;
}
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
@session_start();
// Determine realm and return_to
$base = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$base .= 's';
}
$base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];
$realm = $base . '/';
$returnTo = $base . dirname($_SERVER['PHP_SELF']);
if ($returnTo[strlen($returnTo) - 1] != '/') {
$returnTo .= '/';
}
$returnTo .= 'openid.php';
/* Display form */
if (! count($_GET) && ! count($_POST) || isset($_GET['phpMyAdmin'])) {
/* Show simple form */
$content = '<form action="openid.php" method="post">
OpenID: <input type="text" name="identifier"><br>
<input type="submit" name="start">
</form>
</body>
</html>';
Show_page($content);
exit;
}
/* Grab identifier */
if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {
$identifier = $_POST['identifier'];
} elseif (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {
$identifier = $_SESSION['identifier'];
} else {
$identifier = null;
}
/* Create OpenID object */
try {
$o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
} catch (Exception $e) {
Die_error($e);
}
/* Redirect to OpenID provider */
if (isset($_POST['start'])) {
try {
$authRequest = $o->prepare();
} catch (Exception $e) {
Die_error($e);
}
$url = $authRequest->getAuthorizeURL();
header("Location: $url");
exit;
} else {
/* Grab query string */
if (! count($_POST)) {
list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);
} else {
// I hate php sometimes
$queryString = file_get_contents('php://input');
}
/* Check reply */
try {
$message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
} catch (Exception $e) {
Die_error($e);
}
$id = $message->get('openid.claimed_id');
if (! empty($id) && isset($AUTH_MAP[$id])) {
$_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user'];
$_SESSION['PMA_single_signon_password'] = $AUTH_MAP[$id]['password'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {
Show_page('<p>User not allowed!</p>');
exit;
}
}

View File

@ -1,77 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Single signon for phpMyAdmin
*
* This is just example how to use session based single signon with
* phpMyAdmin, it is not intended to be perfect code and look, only
* shows how you can integrate this functionality in your application.
*
* @package PhpMyAdmin
* @subpackage Example
*/
declare(strict_types=1);
/* Use cookies for session */
ini_set('session.use_cookies', 'true');
/* Change this to true if using phpMyAdmin over https */
$secure_cookie = false;
/* Need to have cookie visible from parent directory */
session_set_cookie_params(0, '/', '', $secure_cookie, true);
/* Create signon session */
$session_name = 'SignonSession';
session_name($session_name);
// Uncomment and change the following line to match your $cfg['SessionSavePath']
//session_save_path('/foobar');
@session_start();
/* Was data posted? */
if (isset($_POST['user'])) {
/* Store there credentials */
$_SESSION['PMA_single_signon_user'] = $_POST['user'];
$_SESSION['PMA_single_signon_password'] = $_POST['password'];
$_SESSION['PMA_single_signon_host'] = $_POST['host'];
$_SESSION['PMA_single_signon_port'] = $_POST['port'];
/* Update another field of server configuration */
$_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];
$_SESSION['PMA_single_signon_HMAC_secret'] = hash('sha1', uniqid(strval(rand()), true));
$id = session_id();
/* Close that session */
@session_write_close();
/* Redirect to phpMyAdmin (should use absolute URL here!) */
header('Location: ../index.php');
} else {
/* Show simple form */
header('Content-Type: text/html; charset=utf-8');
echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";
?>
<!DOCTYPE HTML>
<html lang="en" dir="ltr">
<head>
<link rel="icon" href="../favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
<meta charset="utf-8">
<title>phpMyAdmin single signon example</title>
</head>
<body>
<?php
if (isset($_SESSION['PMA_single_signon_error_message'])) {
echo '<p class="error">';
echo $_SESSION['PMA_single_signon_error_message'];
echo '</p>';
}
?>
<form action="signon.php" method="post">
Username: <input type="text" name="user"><br>
Password: <input type="password" name="password"><br>
Host: (will use the one from config.inc.php by default)
<input type="text" name="host"><br>
Port: (will use the one from config.inc.php by default)
<input type="text" name="port"><br>
<input type="submit">
</form>
</body>
</html>
<?php
}
?>

View File

@ -1,650 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Main export handling code
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\Export;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ExportPlugin;
use PhpMyAdmin\Relation;
use PhpMyAdmin\Response;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\SelectStatement;
use PhpMyAdmin\SqlParser\Utils\Misc;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $db, $sql_query;
include_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export_output.js');
/** @var Export $export */
$export = $containerBuilder->get('export');
//check if it's the GET request to check export time out
if (isset($_GET['check_time_out'])) {
if (isset($_SESSION['pma_export_error'])) {
$err = $_SESSION['pma_export_error'];
unset($_SESSION['pma_export_error']);
echo "timeout";
} else {
echo "success";
}
exit;
}
/**
* Sets globals from $_POST
*
* - Please keep the parameters in order of their appearance in the form
* - Some of these parameters are not used, as the code below directly
* verifies from the superglobal $_POST or $_REQUEST
* TODO: this should be removed to avoid passing user input to GLOBALS
* without checking
*/
$post_params = [
'db',
'table',
'what',
'single_table',
'export_type',
'export_method',
'quick_or_custom',
'db_select',
'table_select',
'table_structure',
'table_data',
'limit_to',
'limit_from',
'allrows',
'lock_tables',
'output_format',
'filename_template',
'maxsize',
'remember_template',
'charset',
'compression',
'as_separate_files',
'knjenc',
'xkana',
'htmlword_structure_or_data',
'htmlword_null',
'htmlword_columns',
'mediawiki_headers',
'mediawiki_structure_or_data',
'mediawiki_caption',
'pdf_structure_or_data',
'odt_structure_or_data',
'odt_relation',
'odt_comments',
'odt_mime',
'odt_columns',
'odt_null',
'codegen_structure_or_data',
'codegen_format',
'excel_null',
'excel_removeCRLF',
'excel_columns',
'excel_edition',
'excel_structure_or_data',
'yaml_structure_or_data',
'ods_null',
'ods_structure_or_data',
'ods_columns',
'json_structure_or_data',
'json_pretty_print',
'json_unicode',
'xml_structure_or_data',
'xml_export_events',
'xml_export_functions',
'xml_export_procedures',
'xml_export_tables',
'xml_export_triggers',
'xml_export_views',
'xml_export_contents',
'texytext_structure_or_data',
'texytext_columns',
'texytext_null',
'phparray_structure_or_data',
'sql_include_comments',
'sql_header_comment',
'sql_dates',
'sql_relation',
'sql_mime',
'sql_use_transaction',
'sql_disable_fk',
'sql_compatibility',
'sql_structure_or_data',
'sql_create_database',
'sql_drop_table',
'sql_procedure_function',
'sql_create_table',
'sql_create_view',
'sql_create_trigger',
'sql_view_current_user',
'sql_if_not_exists',
'sql_or_replace_view',
'sql_auto_increment',
'sql_backquotes',
'sql_truncate',
'sql_delayed',
'sql_ignore',
'sql_type',
'sql_insert_syntax',
'sql_max_query_size',
'sql_hex_for_binary',
'sql_utc_time',
'sql_drop_database',
'sql_views_as_tables',
'sql_metadata',
'csv_separator',
'csv_enclosed',
'csv_escaped',
'csv_terminated',
'csv_null',
'csv_removeCRLF',
'csv_columns',
'csv_structure_or_data',
// csv_replace should have been here but we use it directly from $_POST
'latex_caption',
'latex_structure_or_data',
'latex_structure_caption',
'latex_structure_continued_caption',
'latex_structure_label',
'latex_relation',
'latex_comments',
'latex_mime',
'latex_columns',
'latex_data_caption',
'latex_data_continued_caption',
'latex_data_label',
'latex_null',
'aliases',
];
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
$table = $GLOBALS['table'];
PhpMyAdmin\Util::checkParameters(['what', 'export_type']);
// sanitize this parameter which will be used below in a file inclusion
$what = Core::securePath($_POST['what']);
// export class instance, not array of properties, as before
/** @var ExportPlugin $export_plugin */
$export_plugin = Plugins::getPlugin(
"export",
$what,
'libraries/classes/Plugins/Export/',
[
'export_type' => $export_type,
'single_table' => isset($single_table),
]
);
// Check export type
if (empty($export_plugin)) {
Core::fatalError(__('Bad type!'));
}
/**
* valid compression methods
*/
$compression_methods = [];
if ($GLOBALS['cfg']['ZipDump'] && function_exists('gzcompress')) {
$compression_methods[] = 'zip';
}
if ($GLOBALS['cfg']['GZipDump'] && function_exists('gzencode')) {
$compression_methods[] = 'gzip';
}
/**
* init and variable checking
*/
$compression = '';
$onserver = false;
$save_on_server = false;
$buffer_needed = false;
$back_button = '';
$refreshButton = '';
$save_filename = '';
$file_handle = '';
$err_url = '';
$filename = '';
$separate_files = '';
// Is it a quick or custom export?
if (isset($_POST['quick_or_custom'])
&& $_POST['quick_or_custom'] == 'quick'
) {
$quick_export = true;
} else {
$quick_export = false;
}
if ($_POST['output_format'] == 'astext') {
$asfile = false;
} else {
$asfile = true;
if (isset($_POST['as_separate_files'])
&& ! empty($_POST['as_separate_files'])
) {
if (isset($_POST['compression'])
&& ! empty($_POST['compression'])
&& $_POST['compression'] == 'zip'
) {
$separate_files = $_POST['as_separate_files'];
}
}
if (in_array($_POST['compression'], $compression_methods)) {
$compression = $_POST['compression'];
$buffer_needed = true;
}
if (($quick_export && ! empty($_POST['quick_export_onserver']))
|| (! $quick_export && ! empty($_POST['onserver']))
) {
if ($quick_export) {
$onserver = $_POST['quick_export_onserver'];
} else {
$onserver = $_POST['onserver'];
}
// Will we save dump on server?
$save_on_server = ! empty($cfg['SaveDir']) && $onserver;
}
}
/**
* If we are sending the export file (as opposed to just displaying it
* as text), we have to bypass the usual PhpMyAdmin\Response mechanism
*/
if (isset($_POST['output_format']) && $_POST['output_format'] == 'sendit' && ! $save_on_server) {
$response->disable();
//Disable all active buffers (see: ob_get_status(true) at this point)
do {
if (ob_get_length() > 0 || ob_get_level() > 0) {
$hasBuffer = ob_end_clean();
} else {
$hasBuffer = false;
}
} while ($hasBuffer);
}
$tables = [];
// Generate error url and check for needed variables
if ($export_type == 'server') {
$err_url = 'server_export.php' . Url::getCommon();
} elseif ($export_type == 'database' && strlen($db) > 0) {
$err_url = 'db_export.php' . Url::getCommon(['db' => $db]);
// Check if we have something to export
if (isset($table_select)) {
$tables = $table_select;
} else {
$tables = [];
}
} elseif ($export_type == 'table' && strlen($db) > 0 && strlen($table) > 0) {
$err_url = 'tbl_export.php' . Url::getCommon(
[
'db' => $db,
'table' => $table,
]
);
} else {
Core::fatalError(__('Bad parameters!'));
}
// Merge SQL Query aliases with Export aliases from
// export page, Export page aliases are given more
// preference over SQL Query aliases.
$parser = new Parser($sql_query);
$aliases = [];
if (! empty($parser->statements[0])
&& ($parser->statements[0] instanceof SelectStatement)
) {
$aliases = Misc::getAliases($parser->statements[0], $db);
}
if (! empty($_POST['aliases'])) {
$aliases = $export->mergeAliases($aliases, $_POST['aliases']);
$_SESSION['tmpval']['aliases'] = $_POST['aliases'];
}
/**
* Increase time limit for script execution and initializes some variables
*/
Util::setTimeLimit();
if (! empty($cfg['MemoryLimit'])) {
ini_set('memory_limit', $cfg['MemoryLimit']);
}
register_shutdown_function([$export, 'shutdown']);
// Start with empty buffer
$dump_buffer = '';
$dump_buffer_len = 0;
// Array of dump_buffers - used in separate file exports
$dump_buffer_objects = [];
// We send fake headers to avoid browser timeout when buffering
$time_start = time();
// Defines the default <CR><LF> format.
// For SQL always use \n as MySQL wants this on all platforms.
if ($what == 'sql') {
$crlf = "\n";
} else {
$crlf = PHP_EOL;
}
$output_kanji_conversion = Encoding::canConvertKanji();
// Do we need to convert charset?
$output_charset_conversion = $asfile
&& Encoding::isSupported()
&& isset($charset) && $charset != 'utf-8';
// Use on the fly compression?
$GLOBALS['onfly_compression'] = $GLOBALS['cfg']['CompressOnFly']
&& $compression == 'gzip';
if ($GLOBALS['onfly_compression']) {
$GLOBALS['memory_limit'] = $export->getMemoryLimit();
}
// Generate filename and mime type if needed
if ($asfile) {
if (empty($remember_template)) {
$remember_template = '';
}
list($filename, $mime_type) = $export->getFilenameAndMimetype(
$export_type,
$remember_template,
$export_plugin,
$compression,
$filename_template
);
} else {
$mime_type = '';
}
// Open file on server if needed
if ($save_on_server) {
list($save_filename, $message, $file_handle) = $export->openFile(
$filename,
$quick_export
);
// problem opening export file on server?
if (! empty($message)) {
$export->showPage($db, $table, $export_type);
}
} else {
/**
* Send headers depending on whether the user chose to download a dump file
* or not
*/
if ($asfile) {
// Download
// (avoid rewriting data containing HTML with anchors and forms;
// this was reported to happen under Plesk)
ini_set('url_rewriter.tags', '');
$filename = Sanitize::sanitizeFilename($filename);
Core::downloadHeader($filename, $mime_type);
} else {
// HTML
if ($export_type == 'database') {
$num_tables = count($tables);
if ($num_tables === 0) {
$message = PhpMyAdmin\Message::error(
__('No tables found in database.')
);
$active_page = 'db_export.php';
include ROOT_PATH . 'db_export.php';
exit;
}
}
list($html, $back_button, $refreshButton) = $export->getHtmlForDisplayedExportHeader(
$export_type,
$db,
$table
);
echo $html;
unset($html);
} // end download
}
/** @var Relation $relation */
$relation = $containerBuilder->get('relation');
// Fake loop just to allow skip of remain of this code by break, I'd really
// need exceptions here :-)
do {
// Re - initialize
$dump_buffer = '';
$dump_buffer_len = 0;
// Add possibly some comments to export
if (! $export_plugin->exportHeader()) {
break;
}
// Will we need relation & co. setup?
$do_relation = isset($GLOBALS[$what . '_relation']);
$do_comments = isset($GLOBALS[$what . '_include_comments'])
|| isset($GLOBALS[$what . '_comments']);
$do_mime = isset($GLOBALS[$what . '_mime']);
if ($do_relation || $do_comments || $do_mime) {
$cfgRelation = $relation->getRelationsParam();
}
// Include dates in export?
$do_dates = isset($GLOBALS[$what . '_dates']);
$whatStrucOrData = $GLOBALS[$what . '_structure_or_data'];
/**
* Builds the dump
*/
if ($export_type == 'server') {
if (! isset($db_select)) {
$db_select = '';
}
$export->exportServer(
$db_select,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
} elseif ($export_type == 'database') {
if (! isset($table_structure) || ! is_array($table_structure)) {
$table_structure = [];
}
if (! isset($table_data) || ! is_array($table_data)) {
$table_data = [];
}
if (! empty($_POST['structure_or_data_forced'])) {
$table_structure = $tables;
$table_data = $tables;
}
if (isset($lock_tables)) {
$export->lockTables($db, $tables, "READ");
try {
$export->exportDatabase(
$db,
$tables,
$whatStrucOrData,
$table_structure,
$table_data,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
} finally {
$export->unlockTables();
}
} else {
$export->exportDatabase(
$db,
$tables,
$whatStrucOrData,
$table_structure,
$table_data,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$aliases,
$separate_files
);
}
} else {
// We export just one table
// $allrows comes from the form when "Dump all rows" has been selected
if (! isset($allrows)) {
$allrows = '';
}
if (! isset($limit_to)) {
$limit_to = '0';
}
if (! isset($limit_from)) {
$limit_from = '0';
}
if (isset($lock_tables)) {
try {
$export->lockTables($db, [$table], "READ");
$export->exportTable(
$db,
$table,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$allrows,
$limit_to,
$limit_from,
$sql_query,
$aliases
);
} finally {
$export->unlockTables();
}
} else {
$export->exportTable(
$db,
$table,
$whatStrucOrData,
$export_plugin,
$crlf,
$err_url,
$export_type,
$do_relation,
$do_comments,
$do_mime,
$do_dates,
$allrows,
$limit_to,
$limit_from,
$sql_query,
$aliases
);
}
}
if (! $export_plugin->exportFooter()) {
break;
}
} while (false);
// End of fake loop
if ($save_on_server && ! empty($message)) {
$export->showPage($db, $table, $export_type);
}
/**
* Send the dump as a file...
*/
if (empty($asfile)) {
echo $export->getHtmlForDisplayedExportFooter($back_button, $refreshButton);
return;
} // end if
// Convert the charset if required.
if ($output_charset_conversion) {
$dump_buffer = Encoding::convertString(
'utf-8',
$GLOBALS['charset'],
$dump_buffer
);
}
// Compression needed?
if ($compression) {
if (! empty($separate_files)) {
$dump_buffer = $export->compress(
$dump_buffer_objects,
$compression,
$filename
);
} else {
$dump_buffer = $export->compress($dump_buffer, $compression, $filename);
}
}
/* If we saved on server, we have to close file now */
if ($save_on_server) {
$message = $export->closeFile(
$file_handle,
$dump_buffer,
$save_filename
);
$export->showPage($db, $table, $export_type);
} else {
echo $dump_buffer;
}

View File

@ -1,139 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Editor for Geometry data types.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\Gis\GisFactory;
use PhpMyAdmin\Gis\GisVisualization;
use PhpMyAdmin\Response;
use PhpMyAdmin\Template;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Template $template */
$template = $containerBuilder->get('template');
if (! isset($_POST['field'])) {
Util::checkParameters(['field']);
}
// Get data if any posted
$gis_data = [];
if (Core::isValid($_POST['gis_data'], 'array')) {
$gis_data = $_POST['gis_data'];
}
$gis_types = [
'POINT',
'MULTIPOINT',
'LINESTRING',
'MULTILINESTRING',
'POLYGON',
'MULTIPOLYGON',
'GEOMETRYCOLLECTION',
];
// Extract type from the initial call and make sure that it's a valid one.
// Extract from field's values if available, if not use the column type passed.
if (! isset($gis_data['gis_type'])) {
if (isset($_POST['type']) && $_POST['type'] != '') {
$gis_data['gis_type'] = mb_strtoupper($_POST['type']);
}
if (isset($_POST['value']) && trim($_POST['value']) != '') {
$start = (substr($_POST['value'], 0, 1) == "'") ? 1 : 0;
$gis_data['gis_type'] = mb_substr(
$_POST['value'],
$start,
mb_strpos($_POST['value'], "(") - $start
);
}
if (! isset($gis_data['gis_type'])
|| (! in_array($gis_data['gis_type'], $gis_types))
) {
$gis_data['gis_type'] = $gis_types[0];
}
}
$geom_type = $gis_data['gis_type'];
// Generate parameters from value passed.
$gis_obj = GisFactory::factory($geom_type);
if (isset($_POST['value'])) {
$gis_data = array_merge(
$gis_data,
$gis_obj->generateParams($_POST['value'])
);
}
// Generate Well Known Text
$srid = (isset($gis_data['srid']) && $gis_data['srid'] != '') ? $gis_data['srid'] : 0;
$wkt = $gis_obj->generateWkt($gis_data, 0);
$wkt_with_zero = $gis_obj->generateWkt($gis_data, 0, '0');
$result = "'" . $wkt . "'," . $srid;
// Generate SVG based visualization
$visualizationSettings = [
'width' => 450,
'height' => 300,
'spatialColumn' => 'wkt',
'mysqlVersion' => $GLOBALS['dbi']->getVersion(),
'isMariaDB' => $GLOBALS['dbi']->isMariaDB(),
];
$data = [
[
'wkt' => $wkt_with_zero,
'srid' => $srid,
],
];
$visualization = GisVisualization::getByData($data, $visualizationSettings)
->toImage('svg');
$open_layers = GisVisualization::getByData($data, $visualizationSettings)
->asOl();
// If the call is to update the WKT and visualization make an AJAX response
if (isset($_POST['generate']) && $_POST['generate'] == true) {
$extra_data = [
'result' => $result,
'visualization' => $visualization,
'openLayers' => $open_layers,
];
$response = Response::getInstance();
$response->addJSON($extra_data);
exit;
}
$geom_count = 1;
if ($geom_type == 'GEOMETRYCOLLECTION') {
$geom_count = isset($gis_data[$geom_type]['geom_count'])
? intval($gis_data[$geom_type]['geom_count']) : 1;
if (isset($gis_data[$geom_type]['add_geom'])) {
$geom_count++;
}
}
$templateOutput = $template->render('gis_data_editor_form', [
'width' => $visualizationSettings['width'],
'height' => $visualizationSettings['height'],
'pma_theme_image' => $GLOBALS['pmaThemeImage'],
'field' => $_POST['field'],
'input_name' => $_POST['input_name'],
'srid' => $srid,
'visualization' => $visualization,
'open_layers' => $open_layers,
'gis_types' => $gis_types,
'geom_type' => $geom_type,
'geom_count' => $geom_count,
'gis_data' => $gis_data,
'result' => $result,
]);
Response::getInstance()->addJSON('gis_editor', $templateOutput);

View File

@ -1,809 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Core script for import, this is just the glue around all other stuff
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Bookmark;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Encoding;
use PhpMyAdmin\File;
use PhpMyAdmin\Import;
use PhpMyAdmin\ParseAnalyze;
use PhpMyAdmin\Plugins;
use PhpMyAdmin\Plugins\ImportPlugin;
use PhpMyAdmin\Response;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
define('PMA_ENABLE_LDI', 1);
}
global $db, $pmaThemeImage, $table;
require_once ROOT_PATH . 'libraries/common.inc.php';
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var import $import */
$import = $containerBuilder->get('import');
if (isset($_POST['show_as_php'])) {
$GLOBALS['show_as_php'] = $_POST['show_as_php'];
}
// If there is a request to 'Simulate DML'.
if (isset($_POST['simulate_dml'])) {
$import->handleSimulateDmlRequest();
exit;
}
$sql = new Sql();
// If it's a refresh console bookmarks request
if (isset($_GET['console_bookmark_refresh'])) {
$response->addJSON(
'console_message_bookmark',
PhpMyAdmin\Console::getBookmarkContent()
);
exit;
}
// If it's a console bookmark add request
if (isset($_POST['console_bookmark_add'])) {
if (isset($_POST['label']) && isset($_POST['db'])
&& isset($_POST['bookmark_query']) && isset($_POST['shared'])
) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$bookmarkFields = [
'bkm_database' => $_POST['db'],
'bkm_user' => $cfgBookmark['user'],
'bkm_sql_query' => $_POST['bookmark_query'],
'bkm_label' => $_POST['label'],
];
$isShared = ($_POST['shared'] == 'true' ? true : false);
$bookmark = Bookmark::createBookmark(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$bookmarkFields,
$isShared
);
if ($bookmark !== false && $bookmark->save()) {
$response->addJSON('message', __('Succeeded'));
$response->addJSON('data', $bookmarkFields);
$response->addJSON('isShared', $isShared);
} else {
$response->addJSON('message', __('Failed'));
}
die();
} else {
$response->addJSON('message', __('Incomplete params'));
die();
}
}
$format = '';
/**
* Sets globals from $_POST
*/
$post_params = [
'charset_of_file',
'format',
'import_type',
'is_js_confirmed',
'MAX_FILE_SIZE',
'message_to_show',
'noplugin',
'skip_queries',
'local_import_file',
];
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
// reset import messages for ajax request
$_SESSION['Import_message']['message'] = null;
$_SESSION['Import_message']['go_back_url'] = null;
// default values
$GLOBALS['reload'] = false;
// Use to identify current cycle is executing
// a multiquery statement or stored routine
if (! isset($_SESSION['is_multi_query'])) {
$_SESSION['is_multi_query'] = false;
}
$ajax_reload = [];
$import_text = '';
// Are we just executing plain query or sql file?
// (eg. non import, but query box/window run)
if (! empty($sql_query)) {
// apply values for parameters
if (! empty($_POST['parameterized'])
&& ! empty($_POST['parameters'])
&& is_array($_POST['parameters'])
) {
$parameters = $_POST['parameters'];
foreach ($parameters as $parameter => $replacement) {
$quoted = preg_quote($parameter, '/');
// making sure that :param does not apply values to :param1
$sql_query = preg_replace(
'/' . $quoted . '([^a-zA-Z0-9_])/',
$dbi->escapeString($replacement) . '${1}',
$sql_query
);
// for parameters the appear at the end of the string
$sql_query = preg_replace(
'/' . $quoted . '$/',
$dbi->escapeString($replacement),
$sql_query
);
}
}
// run SQL query
$import_text = $sql_query;
$import_type = 'query';
$format = 'sql';
$_SESSION['sql_from_query_box'] = true;
// If there is a request to ROLLBACK when finished.
if (isset($_POST['rollback_query'])) {
$import->handleRollbackRequest($import_text);
}
// refresh navigation and main panels
if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) {
$GLOBALS['reload'] = true;
$ajax_reload['reload'] = true;
}
// refresh navigation panel only
if (preg_match(
'/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$sql_query
)) {
$ajax_reload['reload'] = true;
}
// do a dynamic reload if table is RENAMED
// (by sending the instruction to the AJAX response handler)
if (preg_match(
'/^RENAME\s+TABLE\s+(.*?)\s+TO\s+(.*?)($|;|\s)/i',
$sql_query,
$rename_table_names
)) {
$ajax_reload['reload'] = true;
$ajax_reload['table_name'] = PhpMyAdmin\Util::unQuote(
$rename_table_names[2]
);
}
$sql_query = '';
} elseif (! empty($sql_file)) {
// run uploaded SQL file
$import_file = $sql_file;
$import_type = 'queryfile';
$format = 'sql';
unset($sql_file);
} elseif (! empty($_POST['id_bookmark'])) {
// run bookmark
$import_type = 'query';
$format = 'sql';
}
// If we didn't get any parameters, either user called this directly, or
// upload limit has been reached, let's assume the second possibility.
if ($_POST == [] && $_GET == []) {
$message = PhpMyAdmin\Message::error(
__(
'You probably tried to upload a file that is too large. Please refer ' .
'to %sdocumentation%s for a workaround for this limit.'
)
);
$message->addParam('[doc@faq1-16]');
$message->addParam('[/doc]');
// so we can obtain the message
$_SESSION['Import_message']['message'] = $message->getDisplay();
$_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto'];
$response->setRequestStatus(false);
$response->addJSON('message', $message);
exit; // the footer is displayed automatically
}
// Add console message id to response output
if (isset($_POST['console_message_id'])) {
$response->addJSON('console_message_id', $_POST['console_message_id']);
}
/**
* Sets globals from $_POST patterns, for import plugins
* We only need to load the selected plugin
*/
if (! in_array(
$format,
[
'csv',
'ldi',
'mediawiki',
'ods',
'shp',
'sql',
'xml',
]
)
) {
// this should not happen for a normal user
// but only during an attack
Core::fatalError('Incorrect format parameter');
}
$post_patterns = [
'/^force_file_/',
'/^' . $format . '_/',
];
Core::setPostAsGlobal($post_patterns);
// Check needed parameters
PhpMyAdmin\Util::checkParameters(['import_type', 'format']);
// We don't want anything special in format
$format = Core::securePath($format);
if (strlen($table) > 0 && strlen($db) > 0) {
$urlparams = [
'db' => $db,
'table' => $table,
];
} elseif (strlen($db) > 0) {
$urlparams = ['db' => $db];
} else {
$urlparams = [];
}
// Create error and goto url
if ($import_type == 'table') {
$goto = 'tbl_import.php';
} elseif ($import_type == 'database') {
$goto = 'db_import.php';
} elseif ($import_type == 'server') {
$goto = 'server_import.php';
} elseif (empty($goto) || ! preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) {
if (strlen($table) > 0 && strlen($db) > 0) {
$goto = 'tbl_structure.php';
} elseif (strlen($db) > 0) {
$goto = 'db_structure.php';
} else {
$goto = 'server_sql.php';
}
}
$err_url = $goto . Url::getCommon($urlparams);
$_SESSION['Import_message']['go_back_url'] = $err_url;
// Avoid setting selflink to 'import.php'
// problem similar to bug 4276
if (basename($_SERVER['SCRIPT_NAME']) === 'import.php') {
$_SERVER['SCRIPT_NAME'] = $goto;
}
if (strlen($db) > 0) {
$dbi->selectDb($db);
}
Util::setTimeLimit();
if (! empty($cfg['MemoryLimit'])) {
ini_set('memory_limit', $cfg['MemoryLimit']);
}
$timestamp = time();
if (isset($_POST['allow_interrupt'])) {
$maximum_time = ini_get('max_execution_time');
} else {
$maximum_time = 0;
}
// set default values
$timeout_passed = false;
$error = false;
$read_multiply = 1;
$finished = false;
$offset = 0;
$max_sql_len = 0;
$file_to_unlink = '';
$sql_query = '';
$sql_query_disabled = false;
$go_sql = false;
$executed_queries = 0;
$run_query = true;
$charset_conversion = false;
$reset_charset = false;
$bookmark_created = false;
$result = false;
$msg = 'Sorry an unexpected error happened!';
// Bookmark Support: get a query back from bookmark if required
if (! empty($_POST['id_bookmark'])) {
$id_bookmark = (int) $_POST['id_bookmark'];
switch ($_POST['action_bookmark']) {
case 0: // bookmarked query that have to be run
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark,
'id',
isset($_POST['action_bookmark_all'])
);
if (! empty($_POST['bookmark_variable'])) {
$import_text = $bookmark->applyVariables(
$_POST['bookmark_variable']
);
} else {
$import_text = $bookmark->getQuery();
}
// refresh navigation and main panels
if (preg_match(
'/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$import_text
)) {
$GLOBALS['reload'] = true;
$ajax_reload['reload'] = true;
}
// refresh navigation panel only
if (preg_match(
'/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i',
$import_text
)
) {
$ajax_reload['reload'] = true;
}
break;
case 1: // bookmarked query that have to be displayed
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark
);
$import_text = $bookmark->getQuery();
if ($response->isAjax()) {
$message = PhpMyAdmin\Message::success(__('Showing bookmark'));
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('sql_query', $import_text);
$response->addJSON('action_bookmark', $_POST['action_bookmark']);
exit;
} else {
$run_query = false;
}
break;
case 2: // bookmarked query that have to be deleted
$bookmark = Bookmark::get(
$dbi,
$GLOBALS['cfg']['Server']['user'],
$db,
$id_bookmark
);
if (! empty($bookmark)) {
$bookmark->delete();
if ($response->isAjax()) {
$message = PhpMyAdmin\Message::success(
__('The bookmark has been deleted.')
);
$response->setRequestStatus($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('action_bookmark', $_POST['action_bookmark']);
$response->addJSON('id_bookmark', $id_bookmark);
exit;
} else {
$run_query = false;
$error = true; // this is kind of hack to skip processing the query
}
}
break;
}
} // end bookmarks reading
// Do no run query if we show PHP code
if (isset($GLOBALS['show_as_php'])) {
$run_query = false;
$go_sql = true;
}
// We can not read all at once, otherwise we can run out of memory
$memory_limit = trim(ini_get('memory_limit'));
// 2 MB as default
if (empty($memory_limit)) {
$memory_limit = 2 * 1024 * 1024;
}
// In case no memory limit we work on 10MB chunks
if ($memory_limit == -1) {
$memory_limit = 10 * 1024 * 1024;
}
// Calculate value of the limit
$memoryUnit = mb_strtolower(substr((string) $memory_limit, -1));
if ('m' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024;
} elseif ('k' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024;
} elseif ('g' == $memoryUnit) {
$memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024 * 1024;
} else {
$memory_limit = (int) $memory_limit;
}
// Just to be sure, there might be lot of memory needed for uncompression
$read_limit = $memory_limit / 8;
// handle filenames
if (isset($_FILES['import_file'])) {
$import_file = $_FILES['import_file']['tmp_name'];
$import_file_name = $_FILES['import_file']['name'];
}
if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
// sanitize $local_import_file as it comes from a POST
$local_import_file = Core::securePath($local_import_file);
$import_file = PhpMyAdmin\Util::userDir($cfg['UploadDir'])
. $local_import_file;
/*
* Do not allow symlinks to avoid security issues
* (user can create symlink to file he can not access,
* but phpMyAdmin can).
*/
if (@is_link($import_file)) {
$import_file = 'none';
}
} elseif (empty($import_file) || ! is_uploaded_file($import_file)) {
$import_file = 'none';
}
// Do we have file to import?
if ($import_file != 'none' && ! $error) {
/**
* Handle file compression
*/
$import_handle = new File($import_file);
$import_handle->checkUploadedFile();
if ($import_handle->isError()) {
$import->stop($import_handle->getError());
}
$import_handle->setDecompressContent(true);
$import_handle->open();
if ($import_handle->isError()) {
$import->stop($import_handle->getError());
}
} elseif (! $error) {
if (! isset($import_text) || empty($import_text)) {
$message = PhpMyAdmin\Message::error(
__(
'No data was received to import. Either no file name was ' .
'submitted, or the file size exceeded the maximum size permitted ' .
'by your PHP configuration. See [doc@faq1-16]FAQ 1.16[/doc].'
)
);
$import->stop($message);
}
}
// so we can obtain the message
//$_SESSION['Import_message'] = $message->getDisplay();
// Convert the file's charset if necessary
if (Encoding::isSupported() && isset($charset_of_file)) {
if ($charset_of_file != 'utf-8') {
$charset_conversion = true;
}
} elseif (isset($charset_of_file) && $charset_of_file != 'utf-8') {
$dbi->query('SET NAMES \'' . $charset_of_file . '\'');
// We can not show query in this case, it is in different charset
$sql_query_disabled = true;
$reset_charset = true;
}
// Something to skip? (because timeout has passed)
if (! $error && isset($_POST['skip'])) {
$original_skip = $skip = intval($_POST['skip']);
while ($skip > 0 && ! $finished) {
$import->getNextChunk($skip < $read_limit ? $skip : $read_limit);
// Disable read progressivity, otherwise we eat all memory!
$read_multiply = 1;
$skip -= $read_limit;
}
unset($skip);
}
// This array contain the data like numberof valid sql queries in the statement
// and complete valid sql statement (which affected for rows)
$sql_data = [
'valid_sql' => [],
'valid_queries' => 0,
];
if (! $error) {
/**
* @var ImportPlugin $import_plugin
*/
$import_plugin = Plugins::getPlugin(
"import",
$format,
'libraries/classes/Plugins/Import/',
$import_type
);
if ($import_plugin == null) {
$message = PhpMyAdmin\Message::error(
__('Could not load import plugins, please check your installation!')
);
$import->stop($message);
} else {
// Do the real import
$default_fk_check = PhpMyAdmin\Util::handleDisableFKCheckInit();
try {
$import_plugin->doImport($sql_data);
PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check);
} catch (Exception $e) {
PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check);
throw $e;
}
}
}
if (isset($import_handle)) {
$import_handle->close();
}
// Cleanup temporary file
if ($file_to_unlink != '') {
unlink($file_to_unlink);
}
// Reset charset back, if we did some changes
if ($reset_charset) {
$dbi->query('SET CHARACTER SET ' . $GLOBALS['charset_connection']);
$dbi->setCollation($collation_connection);
}
// Show correct message
if (! empty($id_bookmark) && $_POST['action_bookmark'] == 2) {
$message = PhpMyAdmin\Message::success(__('The bookmark has been deleted.'));
$display_query = $import_text;
$error = false; // unset error marker, it was used just to skip processing
} elseif (! empty($id_bookmark) && $_POST['action_bookmark'] == 1) {
$message = PhpMyAdmin\Message::notice(__('Showing bookmark'));
} elseif ($bookmark_created) {
$special_message = '[br]' . sprintf(
__('Bookmark %s has been created.'),
htmlspecialchars($_POST['bkm_label'])
);
} elseif ($finished && ! $error) {
// Do not display the query with message, we do it separately
$display_query = ';';
if ($import_type != 'query') {
$message = PhpMyAdmin\Message::success(
'<em>'
. _ngettext(
'Import has been successfully finished, %d query executed.',
'Import has been successfully finished, %d queries executed.',
$executed_queries
)
. '</em>'
);
$message->addParam($executed_queries);
if (! empty($import_notice)) {
$message->addHtml($import_notice);
}
if (! empty($local_import_file)) {
$message->addText('(' . $local_import_file . ')');
} else {
$message->addText('(' . $_FILES['import_file']['name'] . ')');
}
}
}
// Did we hit timeout? Tell it user.
if ($timeout_passed) {
$urlparams['timeout_passed'] = '1';
$urlparams['offset'] = $GLOBALS['offset'];
if (isset($local_import_file)) {
$urlparams['local_import_file'] = $local_import_file;
}
$importUrl = $err_url = $goto . Url::getCommon($urlparams);
$message = PhpMyAdmin\Message::error(
__(
'Script timeout passed, if you want to finish import,'
. ' please %sresubmit the same file%s and import will resume.'
)
);
$message->addParamHtml('<a href="' . $importUrl . '">');
$message->addParamHtml('</a>');
if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) {
$message->addText(
__(
'However on last run no data has been parsed,'
. ' this usually means phpMyAdmin won\'t be able to'
. ' finish this import unless you increase php time limits.'
)
);
}
}
// if there is any message, copy it into $_SESSION as well,
// so we can obtain it by AJAX call
if (isset($message)) {
$_SESSION['Import_message']['message'] = $message->getDisplay();
}
// Parse and analyze the query, for correct db and table name
// in case of a query typed in the query window
// (but if the query is too large, in case of an imported file, the parser
// can choke on it so avoid parsing)
$sqlLength = mb_strlen($sql_query);
if ($sqlLength <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
list(
$analyzed_sql_results,
$db,
$table_from_sql
) = ParseAnalyze::sqlQuery($sql_query, $db);
// @todo: possibly refactor
extract($analyzed_sql_results);
if ($table != $table_from_sql && ! empty($table_from_sql)) {
$table = $table_from_sql;
}
}
// There was an error?
if (isset($my_die)) {
foreach ($my_die as $key => $die) {
PhpMyAdmin\Util::mysqlDie(
$die['error'],
$die['sql'],
false,
$err_url,
$error
);
}
}
if ($go_sql) {
if (! empty($sql_data) && ($sql_data['valid_queries'] > 1)) {
$_SESSION['is_multi_query'] = true;
$sql_queries = $sql_data['valid_sql'];
} else {
$sql_queries = [$sql_query];
}
$html_output = '';
foreach ($sql_queries as $sql_query) {
// parse sql query
list(
$analyzed_sql_results,
$db,
$table_from_sql
) = ParseAnalyze::sqlQuery($sql_query, $db);
// @todo: possibly refactor
extract($analyzed_sql_results);
// Check if User is allowed to issue a 'DROP DATABASE' Statement
if ($sql->hasNoRightsToDropDatabase(
$analyzed_sql_results,
$cfg['AllowUserDropDatabase'],
$dbi->isSuperuser()
)) {
PhpMyAdmin\Util::mysqlDie(
__('"DROP DATABASE" statements are disabled.'),
'',
false,
$_SESSION['Import_message']['go_back_url']
);
return;
} // end if
if ($table != $table_from_sql && ! empty($table_from_sql)) {
$table = $table_from_sql;
}
$html_output .= $sql->executeQueryAndGetQueryResponse(
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark - see below
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
// sql_query_for_bookmark is not included in Sql::executeQueryAndGetQueryResponse
// since only one bookmark has to be added for all the queries submitted through
// the SQL tab
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$sql->storeTheQueryAsBookmark(
$db,
$cfgBookmark['user'],
$_POST['sql_query'],
$_POST['bkm_label'],
isset($_POST['bkm_replace'])
);
}
$response->addJSON('ajax_reload', $ajax_reload);
$response->addHTML($html_output);
exit;
} elseif ($result) {
// Save a Bookmark with more than one queries (if Bookmark label given).
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
$cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']);
$sql->storeTheQueryAsBookmark(
$db,
$cfgBookmark['user'],
$_POST['sql_query'],
$_POST['bkm_label'],
isset($_POST['bkm_replace'])
);
}
$response->setRequestStatus(true);
$response->addJSON('message', PhpMyAdmin\Message::success($msg));
$response->addJSON(
'sql_query',
PhpMyAdmin\Util::getMessage($msg, $sql_query, 'success')
);
} elseif ($result === false) {
$response->setRequestStatus(false);
$response->addJSON('message', PhpMyAdmin\Message::error($msg));
} else {
$active_page = $goto;
include ROOT_PATH . $goto;
}
// If there is request for ROLLBACK in the end.
if (isset($_POST['rollback_query'])) {
$dbi->query('ROLLBACK');
}

View File

@ -1,129 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Import progress bar backend
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Core;
use PhpMyAdmin\Display\ImportAjax;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
/* PHP 5.4 stores upload progress data only in the default session.
* After calling session_name(), we won't find the progress data anymore.
*
* https://bugs.php.net/bug.php?id=64075
*
* The bug should be somewhere in
* https://github.com/php/php-src/blob/master/ext/session/session.c#L2342
*
* Until this is fixed, we need to load the default session to load the data,
* export the upload progress information from there,
* and re-import after switching to our session.
*
* However, since https://github.com/phpmyadmin/phpmyadmin/commit/063a2d99
* we have deactivated this feature, so the corresponding code is now
* commented out.
*/
/*
if (ini_get('session.upload_progress.enabled')) {
$sessionupload = array();
define('UPLOAD_PREFIX', ini_get('session.upload_progress.prefix'));
session_start();
foreach ($_SESSION as $key => $value) {
// only copy session-prefixed data
if (substr($key, 0, strlen(UPLOAD_PREFIX))
== UPLOAD_PREFIX) {
$sessionupload[$key] = $value;
}
}
// PMA will kill all variables, so let's use a constant
define('SESSIONUPLOAD', serialize($sessionupload));
session_write_close();
// The cookie name is not good anymore since PR #15273
session_name('phpMyAdmin');
session_id($_COOKIE['phpMyAdmin']);
}
*/
define('PMA_MINIMUM_COMMON', 1);
require_once ROOT_PATH . 'libraries/common.inc.php';
list(
$SESSION_KEY,
$upload_id,
$plugins
) = ImportAjax::uploadProgressSetup();
/*
if (defined('SESSIONUPLOAD')) {
// write sessionupload back into the loaded PMA session
$sessionupload = unserialize(SESSIONUPLOAD);
foreach ($sessionupload as $key => $value) {
$_SESSION[$key] = $value;
}
// remove session upload data that are not set anymore
foreach ($_SESSION as $key => $value) {
if (substr($key, 0, strlen(UPLOAD_PREFIX))
== UPLOAD_PREFIX
&& ! isset($sessionupload[$key])
) {
unset($_SESSION[$key]);
}
}
}
*/
// $_GET["message"] is used for asking for an import message
if (isset($_GET["message"]) && $_GET["message"]) {
// AJAX requests can't be cached!
Core::noCacheHeader();
header('Content-type: text/html');
// wait 0.3 sec before we check for $_SESSION variable,
// which is set inside import.php
usleep(300000);
$maximumTime = ini_get('max_execution_time');
$timestamp = time();
// wait until message is available
while ($_SESSION['Import_message']['message'] == null) {
// close session before sleeping
session_write_close();
// sleep
usleep(250000); // 0.25 sec
// reopen session
session_start();
if ((time() - $timestamp) > $maximumTime) {
$_SESSION['Import_message']['message'] = PhpMyAdmin\Message::error(
__('Could not load the progress of the import.')
)->getDisplay();
break;
}
}
if (isset($_SESSION['Import_message']['message'])) {
echo $_SESSION['Import_message']['message'];
}
if (isset($_SESSION['Import_message']['go_back_url'])) {
echo '<fieldset class="tblFooters">' , "\n";
echo ' [ <a href="' , $_SESSION['Import_message']['go_back_url']
. '">' , __('Back') , '</a> ]' , "\n";
echo '</fieldset>' , "\n";
}
} else {
ImportAjax::status($_GET["id"]);
}

View File

@ -1,120 +0,0 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Main loader script
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
use PhpMyAdmin\Controllers\HomeController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Response;
use PhpMyAdmin\Url;
use PhpMyAdmin\Util;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR);
}
global $server;
require_once ROOT_PATH . 'libraries/common.inc.php';
/**
* pass variables to child pages
*/
$drops = [
'lang',
'server',
'collation_connection',
'db',
'table',
];
foreach ($drops as $each_drop) {
if (array_key_exists($each_drop, $_GET)) {
unset($_GET[$each_drop]);
}
}
unset($drops, $each_drop);
/**
* Black list of all scripts to which front-end must submit data.
* Such scripts must not be loaded on home page.
*/
$target_blacklist = [
'import.php',
'export.php',
];
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& 0 !== strpos($_REQUEST['target'], "index")
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'], [], true)
) {
include ROOT_PATH . $_REQUEST['target'];
exit;
}
/** @var Response $response */
$response = $containerBuilder->get(Response::class);
/** @var DatabaseInterface $dbi */
$dbi = $containerBuilder->get(DatabaseInterface::class);
/** @var HomeController $controller */
$controller = $containerBuilder->get(HomeController::class);
if (isset($_REQUEST['ajax_request']) && ! empty($_REQUEST['access_time'])) {
exit;
}
if (isset($_POST['set_theme'])) {
$controller->setTheme([
'set_theme' => $_POST['set_theme'],
]);
header('Location: index.php' . Url::getCommonRaw());
} elseif (isset($_POST['collation_connection'])) {
$controller->setCollationConnection([
'collation_connection' => $_POST['collation_connection'],
]);
header('Location: index.php' . Url::getCommonRaw());
} elseif (! empty($_REQUEST['db'])) {
// See FAQ 1.34
$page = null;
if (! empty($_REQUEST['table'])) {
$page = Util::getScriptNameForOption(
$GLOBALS['cfg']['DefaultTabTable'],
'table'
);
} else {
$page = Util::getScriptNameForOption(
$GLOBALS['cfg']['DefaultTabDatabase'],
'database'
);
}
include ROOT_PATH . $page;
} elseif ($response->isAjax() && ! empty($_REQUEST['recent_table'])) {
$response->addJSON($controller->reloadRecentTablesList());
} elseif ($GLOBALS['PMA_Config']->isGitRevision()
&& isset($_REQUEST['git_revision'])
&& $response->isAjax()
) {
$response->addHTML($controller->gitRevision());
} else {
// Handles some variables that may have been sent by the calling script
$GLOBALS['db'] = '';
$GLOBALS['table'] = '';
$show_query = '1';
if ($server > 0) {
include ROOT_PATH . 'libraries/server_common.inc.php';
}
$response->addHTML($controller->index());
}

View File

@ -1,973 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* global isStorageSupported */ // js/config.js
/* global ErrorReport */ // js/error_report.js
/* global MicroHistory */ // js/microhistory.js
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
*/
var AJAX = {
/**
* @var bool active Whether we are busy
*/
active: false,
/**
* @var object source The object whose event initialized the request
*/
source: null,
/**
* @var object xhr A reference to the ajax request that is currently running
*/
xhr: null,
/**
* @var object lockedTargets, list of locked targets
*/
lockedTargets: {},
/**
* @var function Callback to execute after a successful request
* Used by PMA_commonFunctions from common.js
*/
callback: function () {},
/**
* @var bool debug Makes noise in your Firebug console
*/
debug: false,
/**
* @var object $msgbox A reference to a jQuery object that links to a message
* box that is generated by Functions.ajaxShowMessage()
*/
$msgbox: null,
/**
* Given the filename of a script, returns a hash to be
* used to refer to all the events registered for the file
*
* @param key string key The filename for which to get the event name
*
* @return int
*/
hash: function (key) {
var newKey = key;
/* http://burtleburtle.net/bob/hash/doobs.html#one */
newKey += '';
var len = newKey.length;
var hash = 0;
var i = 0;
for (; i < len; ++i) {
hash += newKey.charCodeAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return Math.abs(hash);
},
/**
* Registers an onload event for a file
*
* @param file string file The filename for which to register the event
* @param func function func The function to execute when the page is ready
*
* @return self For chaining
*/
registerOnload: function (file, func) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Registers a teardown event for a file. This is useful to execute functions
* that unbind events for page elements that are about to be removed.
*
* @param string file The filename for which to register the event
* @param function func The function to execute when
* the page is about to be torn down
*
* @return self For chaining
*/
registerTeardown: function (file, func) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Called when a page has finished loading, once for every
* file that registered to the onload event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireOnload: function (file) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).trigger(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* Called just before a page is torn down, once for every
* file that registered to the teardown event of that file.
*
* @param string file The filename for which to fire the event
*
* @return void
*/
fireTeardown: function (file) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).triggerHandler(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* function to handle lock page mechanism
*
* @param event the event object
*
* @return void
*/
lockPageHandler: function (event) {
// don't consider checkbox event
if (typeof event.target !== 'undefined') {
if (event.target.type === 'checkbox') {
return;
}
}
var newHash = null;
var oldHash = null;
var lockId;
// CodeMirror lock
if (event.data.value === 3) {
newHash = event.data.content;
oldHash = true;
lockId = 'cm';
} else {
// Don't lock on enter.
if (0 === event.charCode) {
return;
}
lockId = $(this).data('lock-id');
if (typeof lockId === 'undefined') {
return;
}
/*
* @todo Fix Code mirror does not give correct full value (query)
* in textarea, it returns only the change in content.
*/
if (event.data.value === 1) {
newHash = AJAX.hash($(this).val());
} else {
newHash = AJAX.hash($(this).is(':checked'));
}
oldHash = $(this).data('val-hash');
}
// Set lock if old value !== new value
// otherwise release lock
if (oldHash !== newHash) {
AJAX.lockedTargets[lockId] = true;
} else {
delete AJAX.lockedTargets[lockId];
}
// Show lock icon if locked targets is not empty.
// otherwise remove lock icon
if (!jQuery.isEmptyObject(AJAX.lockedTargets)) {
$('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString());
} else {
$('#lock_page_icon').html('');
}
},
/**
* resets the lock
*
* @return void
*/
resetLock: function () {
AJAX.lockedTargets = {};
$('#lock_page_icon').html('');
},
handleMenu: {
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(Functions.mainMenuResizerCallback);
}
},
/**
* Event handler for clicks on links and form submissions
*
* @param object e Event data
*
* @return void
*/
requestHandler: function (event) {
// In some cases we don't want to handle the request here and either
// leave the browser deal with it natively (e.g: file download)
// or leave an existing ajax event handler present elsewhere deal with it
var href = $(this).attr('href');
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey)) {
return true;
} else if ($(this).attr('target')) {
return true;
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
// reset the lockedTargets object, as specified AJAX operation has finished
AJAX.resetLock();
return true;
} else if (href && href.match(/^#/)) {
return true;
} else if (href && href.match(/^mailto/)) {
return true;
} else if ($(this).hasClass('ui-datepicker-next') ||
$(this).hasClass('ui-datepicker-prev')
) {
return true;
}
if (typeof event !== 'undefined') {
event.preventDefault();
event.stopImmediatePropagation();
}
// triggers a confirm dialog if:
// the user has performed some operations on loaded page
// the user clicks on some link, (won't trigger for buttons)
// the click event is not triggered by script
if (typeof event !== 'undefined' && event.type === 'click' &&
event.isTrigger !== true &&
!jQuery.isEmptyObject(AJAX.lockedTargets)
) {
if (confirm(Messages.strConfirmNavigation) === false) {
return false;
} else {
if (isStorageSupported('localStorage')) {
window.localStorage.removeItem('autoSavedSql');
} else {
Cookies.set('autoSavedSql', '');
}
}
}
AJAX.resetLock();
var isLink = !! href || false;
var previousLinkAborted = false;
if (AJAX.active === true) {
// Cancel the old request if abortable, when the user requests
// something else. Otherwise silently bail out, as there is already
// a request well in progress.
if (AJAX.xhr) {
// In case of a link request, attempt aborting
AJAX.xhr.abort();
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
// If aborted
AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest);
AJAX.active = false;
AJAX.xhr = null;
previousLinkAborted = true;
} else {
// If can't abort
return false;
}
} else {
// In case submitting a form, don't attempt aborting
return false;
}
}
AJAX.source = $(this);
$('html, body').animate({ scrollTop: 0 }, 'fast');
var url = isLink ? href : $(this).attr('action');
var argsep = CommonParams.get('arg_separator');
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
var dataPost = AJAX.source.getPostData();
if (! isLink) {
params += argsep + $(this).serialize();
} else if (dataPost) {
params += argsep + dataPost;
isLink = false;
}
if (! (history && history.pushState)) {
// Add a list of menu hashes that we have in the cache to the request
params += MicroHistory.menus.getRequestParam();
}
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('Loading: ' + url); // no need to translate
}
if (isLink) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
// Save reference for the new link request
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
if (history && history.pushState) {
var state = {
url : href
};
if (previousLinkAborted) {
// hack: there is already an aborted entry on stack
// so just modify the aborted one
history.replaceState(state, null, href);
} else {
history.pushState(state, null, href);
}
}
} else {
/**
* Manually fire the onsubmit event for the form, if any.
* The event was saved in the jQuery data object by an onload
* handler defined below. Workaround for bug #3583316
*/
var onsubmit = $(this).data('onsubmit');
// Submit the request if there is no onsubmit handler
// or if it returns a value that evaluates to true
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
if ($(this).attr('id') === 'login_form') {
$.post(url, params, AJAX.loginResponseHandler);
} else {
$.post(url, params, AJAX.responseHandler);
}
}
}
},
/**
* Response handler to handle login request from login modal after session expiration
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param object data Event data
*
* @return void
*/
loginResponseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
Functions.ajaxRemoveMessage(AJAX.$msgbox);
CommonParams.set('token', data.new_token);
AJAX.scriptHandler.load([]);
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof data.success !== 'undefined' && data.success) {
// reload page if user trying to login has changed
if (CommonParams.get('user') !== data.params.user) {
window.location = 'index.php';
Functions.ajaxShowMessage(Messages.strLoading, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
// remove the login modal if the login is successful otherwise show error.
if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) {
if ($('#modalOverlay').length) {
$('#modalOverlay').remove();
}
$('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration');
AJAX.fireTeardown('functions.js');
AJAX.fireOnload('functions.js');
}
if (typeof data.new_token !== 'undefined') {
$('input[name=token]').val(data.new_token);
}
} else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) {
$('#modalOverlay').replaceWith(data.error);
} else {
Functions.ajaxShowMessage(data.error, false);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* Called after the request that was initiated by this.requestHandler()
* has completed successfully or with a caught error. For completely
* failed requests or requests with uncaught errors, see the .ajaxError
* handler at the bottom of this file.
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param object e Event data
*
* @return void
*/
responseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
if (typeof data.success !== 'undefined' && data.success) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
Functions.ajaxRemoveMessage(AJAX.$msgbox);
if (data.redirect) {
Functions.ajaxShowMessage(data.redirect, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
AJAX.scriptHandler.reset(function () {
if (data.reloadNavigation) {
Navigation.reload();
}
if (data.title) {
$('title').replaceWith(data.title);
}
if (data.menu) {
if (history && history.pushState) {
var state = {
url : data.selflink,
menu : data.menu
};
history.replaceState(state, null);
AJAX.handleMenu.replace(data.menu);
} else {
MicroHistory.menus.replace(data.menu);
MicroHistory.menus.add(data.menuHash, data.menu);
}
} else if (data.menuHash) {
if (! (history && history.pushState)) {
MicroHistory.menus.replace(MicroHistory.menus.get(data.menuHash));
}
}
if (data.disableNaviSettings) {
Navigation.disableSettings();
} else {
Navigation.ensureSettings(data.selflink);
}
// Remove all containers that may have
// been added outside of #page_content
$('body').children()
.not('#pma_navigation')
.not('#floating_menubar')
.not('#page_nav_icons')
.not('#page_content')
.not('#selflink')
.not('#pma_header')
.not('#pma_footer')
.not('#pma_demo')
.not('#pma_console_container')
.not('#prefs_autoload')
.remove();
// Replace #page_content with new content
if (data.message && data.message.length > 0) {
$('#page_content').replaceWith(
'<div id=\'page_content\'>' + data.message + '</div>'
);
Functions.highlightSql($('#page_content'));
Functions.checkNumberOfFields();
}
if (data.selflink) {
var source = data.selflink.split('?')[0];
// Check for faulty links
var $selflinkReplace = {
'import.php': 'tbl_sql.php',
'tbl_chart.php': 'sql.php',
'tbl_gis_visualization.php': 'sql.php'
};
if ($selflinkReplace[source]) {
var replacement = $selflinkReplace[source];
data.selflink = data.selflink.replace(source, replacement);
}
$('#selflink').find('> a').attr('href', data.selflink);
}
if (data.params) {
CommonParams.setAll(data.params);
}
if (data.scripts) {
AJAX.scriptHandler.load(data.scripts);
}
if (data.selflink && data.scripts && data.menuHash && data.params) {
if (! (history && history.pushState)) {
MicroHistory.add(
data.selflink,
data.scripts,
data.menuHash,
data.params,
AJAX.source.attr('rel')
);
}
}
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof AJAX.callback === 'function') {
AJAX.callback.call();
}
AJAX.callback = function () {};
});
} else {
Functions.ajaxShowMessage(data.error, false);
Functions.ajaxRemoveMessage(AJAX.$msgbox);
var $ajaxError = $('<div></div>');
$ajaxError.attr({ 'id': 'ajaxError' });
$('#page_content').append($ajaxError);
$ajaxError.html(data.error);
$('html, body').animate({ scrollTop: $(document).height() }, 200);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* This object is in charge of downloading scripts,
* keeping track of what's downloaded and firing
* the onload event for them when the page is ready.
*/
scriptHandler: {
/**
* @var array scripts The list of files already downloaded
*/
scripts: [],
/**
* @var string scriptsVersion version of phpMyAdmin from which the
* scripts have been loaded
*/
scriptsVersion: null,
/**
* @var array scriptsToBeLoaded The list of files that
* need to be downloaded
*/
scriptsToBeLoaded: [],
/**
* @var array scriptsToBeFired The list of files for which
* to fire the onload and unload events
*/
scriptsToBeFired: [],
scriptsCompleted: false,
/**
* Records that a file has been downloaded
*
* @param string file The filename
* @param string fire Whether this file will be registering
* onload/teardown events
*
* @return self For chaining
*/
add: function (file, fire) {
this.scripts.push(file);
if (fire) {
// Record whether to fire any events for the file
// This is necessary to correctly tear down the initial page
this.scriptsToBeFired.push(file);
}
return this;
},
/**
* Download a list of js files in one request
*
* @param array files An array of filenames and flags
*
* @return void
*/
load: function (files, callback) {
var self = this;
var i;
// Clear loaded scripts if they are from another version of phpMyAdmin.
// Depends on common params being set before loading scripts in responseHandler
if (self.scriptsVersion === null) {
self.scriptsVersion = CommonParams.get('PMA_VERSION');
} else if (self.scriptsVersion !== CommonParams.get('PMA_VERSION')) {
self.scripts = [];
self.scriptsVersion = CommonParams.get('PMA_VERSION');
}
self.scriptsCompleted = false;
self.scriptsToBeFired = [];
// We need to first complete list of files to load
// as next loop will directly fire requests to load them
// and that triggers removal of them from
// self.scriptsToBeLoaded
for (i in files) {
self.scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
self.scriptsToBeFired.push(files[i].name);
}
}
for (i in files) {
var script = files[i].name;
// Only for scripts that we don't already have
if ($.inArray(script, self.scripts) === -1) {
this.add(script);
this.appendScript(script, callback);
} else {
self.done(script, callback);
}
}
// Trigger callback if there is nothing else to load
self.done(null, callback);
},
/**
* Called whenever all files are loaded
*
* @return void
*/
done: function (script, callback) {
if (typeof ErrorReport !== 'undefined') {
ErrorReport.wrapGlobalFunctions();
}
if ($.inArray(script, this.scriptsToBeFired)) {
AJAX.fireOnload(script);
}
if ($.inArray(script, this.scriptsToBeLoaded)) {
this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1);
}
if (script === null) {
this.scriptsCompleted = true;
}
/* We need to wait for last signal (with null) or last script load */
AJAX.active = (this.scriptsToBeLoaded.length > 0) || ! this.scriptsCompleted;
/* Run callback on last script */
if (! AJAX.active && typeof callback === 'function') {
callback();
}
},
/**
* Appends a script element to the head to load the scripts
*
* @return void
*/
appendScript: function (name, callback) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var self = this;
script.type = 'text/javascript';
script.src = 'js/' + name + '?' + 'v=' + encodeURIComponent(CommonParams.get('PMA_VERSION'));
script.async = false;
script.onload = function () {
self.done(name, callback);
};
head.appendChild(script);
},
/**
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param function callback The callback to call after resetting
*
* @return void
*/
reset: function (callback) {
for (var i in this.scriptsToBeFired) {
AJAX.fireTeardown(this.scriptsToBeFired[i]);
}
this.scriptsToBeFired = [];
/**
* Re-attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
if (! (history && history.pushState)) {
MicroHistory.update();
}
callback();
}
}
};
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
AJAX.registerOnload('functions.js', function () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $pageContent = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$pageContent.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input>', {
'type' : 'hidden',
'name' : buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$pageContent.on(
'keyup change',
'form.lock-page textarea, ' +
'form.lock-page input[type="text"], ' +
'form.lock-page input[type="number"], ' +
'form.lock-page select',
{ value:1 },
AJAX.lockPageHandler
);
$pageContent.on(
'change',
'form.lock-page input[type="checkbox"], ' +
'form.lock-page input[type="radio"]',
{ value:2 },
AJAX.lockPageHandler
);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function () {
AJAX.resetLock();
});
});
/**
* Page load event handler
*/
$(function () {
var menuContent = $('<div></div>')
.append($('#serverinfo').clone())
.append($('#topmenucontainer').clone())
.html();
if (history && history.pushState) {
// set initial state reload
var initState = ('state' in window.history && window.history.state !== null);
var initURL = $('#selflink').find('> a').attr('href') || location.href;
var state = {
url : initURL,
menu : menuContent
};
history.replaceState(state, null);
$(window).on('popstate', function (event) {
var initPop = (! initState && location.href === initURL);
initState = true;
// check if popstate fired on first page itself
if (initPop) {
return;
}
var state = event.originalEvent.state;
if (state && state.menu) {
AJAX.$msgbox = Functions.ajaxShowMessage();
var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true';
var url = state.url || location.href;
$.get(url, params, AJAX.responseHandler);
// TODO: Check if sometimes menu is not retrieved from server,
// Not sure but it seems menu was missing only for printview which
// been removed lately, so if it's right some dead menu checks/fallbacks
// may need to be removed from this file and Header.php
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
}
});
} else {
// Fallback to microhistory mechanism
AJAX.scriptHandler
.load([{ 'name' : 'microhistory.js', 'fire' : 1 }], function () {
// The cache primer is set by the footer class
if (MicroHistory.primer.url) {
MicroHistory.menus.add(
MicroHistory.primer.menuHash,
menuContent
);
}
$(function () {
// Queue up this event twice to make sure that we get a copy
// of the page after all other onload events have been fired
if (MicroHistory.primer.url) {
MicroHistory.add(
MicroHistory.primer.url,
MicroHistory.primer.scripts,
MicroHistory.primer.menuHash
);
}
});
});
}
});
/**
* Attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).on('click', 'a', AJAX.requestHandler);
$(document).on('submit', 'form', AJAX.requestHandler);
/**
* Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).ajaxError(function (event, request) {
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + Functions.escapeHtml(Messages.strErrorConnection) + '</div>';
}
Functions.ajaxShowMessage(
'<div class="error">' +
Messages.strErrorProcessingRequest +
details +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
}
});

View File

@ -1,677 +0,0 @@
/**
* Chart type enumerations
*/
var ChartType = {
LINE : 'line',
SPLINE : 'spline',
AREA : 'area',
BAR : 'bar',
COLUMN : 'column',
PIE : 'pie',
TIMELINE: 'timeline',
SCATTER: 'scatter'
};
/**
* Column type enumeration
*/
var ColumnType = {
STRING : 'string',
NUMBER : 'number',
BOOLEAN : 'boolean',
DATE : 'date'
};
/**
* Abstract chart factory which defines the contract for chart factories
*/
var ChartFactory = function () {
};
ChartFactory.prototype = {
createChart : function () {
throw new Error('createChart must be implemented by a subclass');
}
};
/**
* Abstract chart which defines the contract for charts
*
* @param elementId
* id of the div element the chart is drawn in
*/
var Chart = function (elementId) {
this.elementId = elementId;
};
Chart.prototype = {
draw : function () {
throw new Error('draw must be implemented by a subclass');
},
redraw : function () {
throw new Error('redraw must be implemented by a subclass');
},
destroy : function () {
throw new Error('destroy must be implemented by a subclass');
},
toImageString : function () {
throw new Error('toImageString must be implemented by a subclass');
}
};
/**
* Abstract representation of charts that operates on DataTable where,<br>
* <ul>
* <li>First column provides index to the data.</li>
* <li>Each subsequent columns are of type
* <code>ColumnType.NUMBER<code> and represents a data series.</li>
* </ul>
* Line chart, area chart, bar chart, column chart are typical examples.
*
* @param elementId
* id of the div element the chart is drawn in
*/
var BaseChart = function (elementId) {
Chart.call(this, elementId);
};
BaseChart.prototype = new Chart();
BaseChart.prototype.constructor = BaseChart;
BaseChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length < 2) {
throw new Error('Minimum of two columns are required for this chart');
}
for (var i = 1; i < columns.length; i++) {
if (columns[i].type !== ColumnType.NUMBER) {
throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
}
}
return true;
};
/**
* Abstract pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var PieChart = function (elementId) {
BaseChart.call(this, elementId);
};
PieChart.prototype = new BaseChart();
PieChart.prototype.constructor = PieChart;
PieChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length > 2) {
throw new Error('Pie charts can draw only one series');
}
return BaseChart.prototype.validateColumns.call(this, dataTable);
};
/**
* Abstract timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var TimelineChart = function (elementId) {
BaseChart.call(this, elementId);
};
TimelineChart.prototype = new BaseChart();
TimelineChart.prototype.constructor = TimelineChart;
TimelineChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.DATE) {
throw new Error('First column of timeline chart need to be a date column');
}
}
return result;
};
/**
* Abstract scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var ScatterChart = function (elementId) {
BaseChart.call(this, elementId);
};
ScatterChart.prototype = new BaseChart();
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.NUMBER) {
throw new Error('First column of scatter chart need to be a numeric column');
}
}
return result;
};
/**
* The data table contains column information and data for the chart.
*/
// eslint-disable-next-line no-unused-vars
var DataTable = function () {
var columns = [];
var data = null;
this.addColumn = function (type, name) {
columns.push({
'type' : type,
'name' : name
});
};
this.getColumns = function () {
return columns;
};
this.setData = function (rows) {
data = rows;
fillMissingValues();
};
this.getData = function () {
return data;
};
var fillMissingValues = function () {
if (columns.length === 0) {
throw new Error('Set columns first');
}
var row;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row.length > columns.length) {
row.splice(columns.length - 1, row.length - columns.length);
} else if (row.length < columns.length) {
for (var j = row.length; j < columns.length; j++) {
row.push(null);
}
}
}
};
};
/** *****************************************************************************
* JQPlot specific code
******************************************************************************/
/**
* Abstract JQplot chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotChart = function (elementId) {
Chart.call(this, elementId);
this.plot = null;
this.validator = null;
};
JQPlotChart.prototype = new Chart();
JQPlotChart.prototype.constructor = JQPlotChart;
JQPlotChart.prototype.draw = function (data, options) {
if (this.validator.validateColumns(data)) {
this.plot = $.jqplot(this.elementId, this.prepareData(data), this
.populateOptions(data, options));
}
};
JQPlotChart.prototype.destroy = function () {
if (this.plot !== null) {
this.plot.destroy();
}
};
JQPlotChart.prototype.redraw = function (options) {
if (this.plot !== null) {
this.plot.replot(options);
}
};
JQPlotChart.prototype.toImageString = function () {
if (this.plot !== null) {
return $('#' + this.elementId).jqplotToImageStr({});
}
};
JQPlotChart.prototype.populateOptions = function () {
throw new Error('populateOptions must be implemented by a subclass');
};
JQPlotChart.prototype.prepareData = function () {
throw new Error('prepareData must be implemented by a subclass');
};
/**
* JQPlot line chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotLineChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = BaseChart.prototype;
};
JQPlotLineChart.prototype = new JQPlotChart();
JQPlotLineChart.prototype.constructor = JQPlotLineChart;
JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
formatString:'%d'
},
series : []
};
$.extend(true, optional, options);
if (optional.series.length === 0) {
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
}
if (optional.axes.xaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var j = 0; j < data.length; j++) {
optional.axes.xaxis.ticks.push(data[j][0].toString());
}
}
return optional;
};
JQPlotLineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push(row[j]);
}
}
return retData;
};
/**
* JQPlot spline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotSplineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotSplineChart.prototype = new JQPlotLineChart();
JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
rendererOptions : {
smooth : true
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotScatterChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = ScatterChart.prototype;
};
JQPlotScatterChart.prototype = new JQPlotChart();
JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%d, %d'
},
series : []
};
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
var compulsory = {
seriesDefaults : {
showLine: false,
markerOptions: {
size: 7,
style: 'x'
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotScatterChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row[0]) {
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push([row[0], row[j]]);
}
}
}
return retData;
};
/**
* JQPlot timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotTimelineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
this.validator = TimelineChart.prototype;
};
JQPlotTimelineChart.prototype = new JQPlotLineChart();
JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
axes : {
xaxis : {
tickOptions : {
formatString: '%b %#d, %y'
}
}
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var d;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
d = row[0];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
if (d !== null) {
retRow.push([d.getTime(), row[j]]);
}
}
}
return retData;
};
/**
* JQPlot area chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotAreaChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotAreaChart.prototype = new JQPlotLineChart();
JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
fill : true
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot column chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotColumnChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotColumnChart.prototype = new JQPlotLineChart();
JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot bar chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotBarChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotBarChart.prototype = new JQPlotLineChart();
JQPlotBarChart.prototype.constructor = JQPlotBarChart;
JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
yaxis : {
label : columns[0].name,
labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
xaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'x',
formatString:'%d'
},
series : [],
seriesDefaults : {
fillToZero : true
}
};
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
rendererOptions : {
barDirection : 'horizontal'
}
}
};
$.extend(true, optional, options, compulsory);
if (optional.axes.yaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var i = 0; i < data.length; i++) {
optional.axes.yaxis.ticks.push(data[i][0].toString());
}
}
if (optional.series.length === 0) {
for (var j = 1; j < columns.length; j++) {
optional.series.push({
label : columns[j].name.toString()
});
}
}
return optional;
};
/**
* JQPlot pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotPieChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = PieChart.prototype;
};
JQPlotPieChart.prototype = new JQPlotChart();
JQPlotPieChart.prototype.constructor = JQPlotPieChart;
JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%s, %d',
useAxesFormatters: false
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer,
},
};
var compulsory = {
seriesDefaults : {
shadow: false,
renderer : $.jqplot.PieRenderer,
rendererOptions: { sliceMargin: 1, showDataLabels: true }
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotPieChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
for (var i = 0; i < data.length; i++) {
row = data[i];
retData.push([row[0], row[1]]);
}
return [retData];
};
/**
* Chart factory that returns JQPlotCharts
*/
var JQPlotChartFactory = function () {
};
JQPlotChartFactory.prototype = new ChartFactory();
JQPlotChartFactory.prototype.createChart = function (type, elementId) {
var chart = null;
switch (type) {
case ChartType.LINE:
chart = new JQPlotLineChart(elementId);
break;
case ChartType.SPLINE:
chart = new JQPlotSplineChart(elementId);
break;
case ChartType.TIMELINE:
chart = new JQPlotTimelineChart(elementId);
break;
case ChartType.AREA:
chart = new JQPlotAreaChart(elementId);
break;
case ChartType.BAR:
chart = new JQPlotBarChart(elementId);
break;
case ChartType.COLUMN:
chart = new JQPlotColumnChart(elementId);
break;
case ChartType.PIE:
chart = new JQPlotPieChart(elementId);
break;
case ChartType.SCATTER:
chart = new JQPlotScatterChart(elementId);
break;
}
return chart;
};

View File

@ -1,40 +0,0 @@
CodeMirror.sqlLint = function (text, updateLinting, options, cm) {
// Skipping check if text box is empty.
if (text.trim() === '') {
updateLinting(cm, []);
return;
}
function handleResponse (response) {
var found = [];
for (var idx in response) {
found.push({
// eslint-disable-next-line new-cap
from: CodeMirror.Pos(
response[idx].fromLine, response[idx].fromColumn
),
// eslint-disable-next-line new-cap
to: CodeMirror.Pos(
response[idx].toLine, response[idx].toColumn
),
messageHTML: response[idx].message,
severity : response[idx].severity
});
}
updateLinting(cm, found);
}
$.ajax({
method: 'POST',
url: 'lint.php',
dataType: 'json',
data: {
'sql_query': text,
'server': CommonParams.get('server'),
'options': options.lintOptions,
'no_history': true,
},
success: handleResponse
});
};

View File

@ -1,160 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
$(function () {
Functions.checkNumberOfFields();
});
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
var CommonParams = (function () {
/**
* @var hash params An associative array of key value pairs
* @access private
*/
var params = {};
// The returned object is the public part of the module
return {
/**
* Saves all the key value pair that
* are provided in the input array
*
* @param obj hash The input array
*
* @return void
*/
setAll: function (obj) {
var updateNavigation = false;
for (var i in obj) {
if (params[i] !== undefined && params[i] !== obj[i]) {
if (i === 'db' || i === 'table') {
updateNavigation = true;
}
}
params[i] = obj[i];
}
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
},
/**
* Retrieves a value given its key
* Returns empty string for undefined values
*
* @param name string The key
*
* @return string
*/
get: function (name) {
return params[name];
},
/**
* Saves a single key value pair
*
* @param name string The key
* @param value string The value
*
* @return self For chainability
*/
set: function (name, value) {
var updateNavigation = false;
if (name === 'db' || name === 'table' &&
params[name] !== value
) {
updateNavigation = true;
}
params[name] = value;
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
return this;
},
/**
* Returns the url query string using the saved parameters
*
* @return string
*/
getUrlQuery: function () {
var common = this.get('common_query');
var separator = '?';
var argsep = CommonParams.get('arg_separator');
if (common.length > 0) {
separator = argsep;
}
return Functions.sprintf(
'%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s',
this.get('common_query'),
separator,
encodeURIComponent(this.get('server')),
encodeURIComponent(this.get('db')),
encodeURIComponent(this.get('table'))
);
}
};
}());
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
// eslint-disable-next-line no-unused-vars
var CommonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param newDb string new_db The name of the new database
*
* @return void
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({ 'db': newDb, 'table': '' });
}
},
/**
* Opens a database in the main part of the page
*
* @param newDb string The name of the new database
*
* @return void
*/
openDb: function (newDb) {
CommonParams
.set('db', newDb)
.set('table', '');
this.refreshMain(
CommonParams.get('opendb_url')
);
},
/**
* Refreshes the main frame
*
* @param mixed url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
*
* @return void
*/
refreshMain: function (url, callback) {
var newUrl = url;
if (! newUrl) {
newUrl = $('#selflink').find('a').attr('href') || window.location.pathname;
newUrl = newUrl.substring(0, newUrl.indexOf('?'));
}
newUrl += CommonParams.getUrlQuery();
$('<a></a>', { href: newUrl })
.appendTo('body')
.trigger('click')
.remove();
AJAX.callback = callback;
}
};

View File

@ -1,885 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Functions used in configuration forms and on user preferences pages
*/
var configInlineParams;
var configScriptLoaded;
/**
* checks whether browser supports web storage
*
* @param type the type of storage i.e. localStorage or sessionStorage
*
* @returns bool
*/
function isStorageSupported (type, warn) {
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
Functions.ajaxShowMessage(Messages.strNoLocalStorage, false);
}
}
return false;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('config.js', function () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tabs_contents').off();
$('#import_local_storage, #export_local_storage').off('click');
$('form.prefs-form').off('change').off('submit');
$(document).off('click', 'div.click-hide-message');
$('#prefs_autoload').find('a').off('click');
});
AJAX.registerOnload('config.js', function () {
var $topmenuUpt = $('#topmenu2.user_prefs_tabs');
$topmenuUpt.find('li.active a').attr('rel', 'samepage');
$topmenuUpt.find('li:not(.active) a').attr('rel', 'newpage');
});
// default values for fields
var defaultValues = {};
/**
* Returns field type
*
* @param {Element} field
*/
function getFieldType (field) {
var $field = $(field);
var tagName = $field.prop('tagName');
if (tagName === 'INPUT') {
return $field.attr('type');
} else if (tagName === 'SELECT') {
return 'select';
} else if (tagName === 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* Enables or disables the "restore default value" button
*
* @param {Element} field
* @param {boolean} display
*/
function setRestoreDefaultBtn (field, display) {
var $el = $(field).closest('td').find('.restore-default img');
$el[display ? 'show' : 'hide']();
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element} field
*/
function markField (field) {
var $field = $(field);
var type = getFieldType($field);
var isDefault = checkFieldDefault($field, type);
// checkboxes uses parent <span> for marking
var $fieldMarker = (type === 'checkbox') ? $field.parent() : $field;
setRestoreDefaultBtn($field, !isDefault);
$fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
}
/**
* Sets field value
*
* value must be of type:
* o undefined (omitted) - restore default value (form default, not PMA default)
* o String - if field_type is 'text'
* o boolean - if field_type is 'checkbox'
* o Array of values - if field_type is 'select'
*
* @param {Element} field
* @param {String} fieldType see {@link #getFieldType}
* @param {String|Boolean} value
*/
function setFieldValue (field, fieldType, value) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
$field.val(value);
break;
case 'checkbox':
$field.prop('checked', value);
break;
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
for (i = 0; i < imax; i++) {
options[i].selected = (value.indexOf(options[i].value) !== -1);
}
break;
}
markField($field);
}
/**
* Gets field value
*
* Will return one of:
* o String - if type is 'text'
* o boolean - if type is 'checkbox'
* o Array of values - if type is 'select'
*
* @param {Element} field
* @param {String} fieldType returned by {@link #getFieldType}
* @type Boolean|String|String[]
*/
function getFieldValue (field, fieldType) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
return $field.prop('value');
case 'checkbox':
return $field.prop('checked');
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
var items = [];
for (i = 0; i < imax; i++) {
if (options[i].selected) {
items.push(options[i].value);
}
}
return items;
}
return null;
}
/**
* Returns values for all fields in fieldsets
*/
// eslint-disable-next-line no-unused-vars
function getAllValues () {
var $elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type;
var value;
for (var i = 0; i < $elements.length; i++) {
type = getFieldType($elements[i]);
value = getFieldValue($elements[i], type);
if (typeof value !== 'undefined') {
// we only have single selects, fatten array
if (type === 'select') {
value = value[0];
}
values[$elements[i].name] = value;
}
}
return values;
}
/**
* Checks whether field has its default value
*
* @param {Element} field
* @param {String} type
* @return boolean
*/
function checkFieldDefault (field, type) {
var $field = $(field);
var fieldId = $field.attr('id');
if (typeof defaultValues[fieldId] === 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue($field, type);
if (type !== 'select') {
isDefault = currentValue === defaultValues[fieldId];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length !== defaultValues[fieldId].length) {
isDefault = false;
} else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] !== defaultValues[fieldId][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Returns element's id prefix
* @param {Element} element
*/
// eslint-disable-next-line no-unused-vars
function getIdPrefix (element) {
return $(element).attr('id').replace(/[^-]+$/, '');
}
// ------------------------------------------------------------------
// Form validation and field operations
//
// form validator assignments
var validate = {};
// form validator list
var validators = {
// regexp: numeric value
regExpNumeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
regExpPcreExtract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*/
validatePositiveNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = this.value !== '0' && validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_p;
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*/
validateNonNegativeNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_nneg;
},
/**
* Validates port number
*/
validatePortNumber: function () {
if (this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value) && this.value !== '0';
return result && this.value <= 65535 ? true : Messages.error_incorrect_port;
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*/
validateByRegex: function (isKeyUp, regexp) {
if (isKeyUp && this.value === '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators.regExpPcreExtract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null;
return valid ? true : Messages.error_invalid_value;
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {int} maxValue
*/
validateUpperBound: function (isKeyUp, maxValue) {
var val = parseInt(this.value, 10);
if (isNaN(val)) {
return true;
}
return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue);
},
// field validators
field: {
},
// fieldset validators
fieldset: {
}
};
/**
* Registers validator for given field
*
* @param {String} id field id
* @param {String} type validator (key in validators object)
* @param {boolean} onKeyUp whether fire on key up
* @param {Array} params validation function parameters
*/
// eslint-disable-next-line no-unused-vars
function registerFieldValidator (id, type, onKeyUp, params) {
if (typeof validators[type] === 'undefined') {
return;
}
if (typeof validate[id] === 'undefined') {
validate[id] = [];
}
if (validate[id].length === 0) {
validate[id].push([type, params, onKeyUp]);
}
}
/**
* Returns validation functions associated with form field
*
* @param {String} fieldId form field id
* @param {boolean} onKeyUpOnly see registerFieldValidator
* @type Array
* @return array of [function, parameters to be passed to function]
*/
function getFieldValidators (fieldId, onKeyUpOnly) {
// look for field bound validator
var name = fieldId && fieldId.match(/[^-]+$/)[0];
if (typeof validators.field[name] !== 'undefined') {
return [[validators.field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[fieldId] !== 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[fieldId].length; i < imax; i++) {
if (onKeyUpOnly && !validate[fieldId][i][2]) {
continue;
}
functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* PhpMyAdmin\Config\FormDisplayTemplate::displayInput()!
*
* @param {Object} errorList list of errors in the form {field id: error array}
*/
function displayErrors (errorList) {
var tempIsEmpty = function (item) {
return item !== '';
};
for (var fieldId in errorList) {
var errors = errorList[fieldId];
var $field = $('#' + fieldId);
var isFieldset = $field.attr('tagName') === 'FIELDSET';
var $errorCnt;
if (isFieldset) {
$errorCnt = $field.find('dl.errors');
} else {
$errorCnt = $field.siblings('.inline_errors');
}
// remove empty errors (used to clear error list)
errors = $.grep(errors, tempIsEmpty);
// CSS error class
if (!isFieldset) {
// checkboxes uses parent <span> for marking
var $fieldMarker = ($field.attr('type') === 'checkbox') ? $field.parent() : $field;
$fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error');
}
if (errors.length) {
// if error container doesn't exist, create it
if ($errorCnt.length === 0) {
if (isFieldset) {
$errorCnt = $('<dl class="errors"></dl>');
$field.find('table').before($errorCnt);
} else {
$errorCnt = $('<dl class="inline_errors"></dl>');
$field.closest('td').append($errorCnt);
}
}
var html = '';
for (var i = 0, imax = errors.length; i < imax; i++) {
html += '<dd>' + errors[i] + '</dd>';
}
$errorCnt.html(html);
} else if ($errorCnt !== null) {
// remove useless error container
$errorCnt.remove();
}
}
}
/**
* Validates fields and fieldsets and call displayError function as required
*/
function setDisplayError () {
var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
// run all field validators
var errors = {};
for (var i = 0; i < elements.length; i++) {
validateField(elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
}
/**
* Validates fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validateFieldset (fieldset, isKeyUp, errors) {
var $fieldset = $(fieldset);
if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') {
var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]);
for (var fieldId in fieldsetErrors) {
if (typeof errors[fieldId] === 'undefined') {
errors[fieldId] = [];
}
if (typeof fieldsetErrors[fieldId] === 'string') {
fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]];
}
$.merge(errors[fieldId], fieldsetErrors[fieldId]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {Object} errors
*/
function validateField (field, isKeyUp, errors) {
var args;
var result;
var $field = $(field);
var fieldId = $field.attr('id');
errors[fieldId] = [];
var functions = getFieldValidators(fieldId, isKeyUp);
for (var i = 0; i < functions.length; i++) {
if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) {
args = functions[i][1].slice(0);
} else {
args = [];
}
args.unshift(isKeyUp);
result = functions[i][0].apply($field[0], args);
if (result !== true) {
if (typeof result === 'string') {
result = [result];
}
$.merge(errors[fieldId], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validateFieldAndFieldset (field, isKeyUp) {
var $field = $(field);
var errors = {};
validateField($field, isKeyUp, errors);
validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors);
displayErrors(errors);
}
function loadInlineConfig () {
if (!Array.isArray(configInlineParams)) {
return;
}
for (var i = 0; i < configInlineParams.length; ++i) {
if (typeof configInlineParams[i] === 'function') {
configInlineParams[i]();
}
}
}
function setupValidation () {
validate = {};
configScriptLoaded = true;
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
loadInlineConfig();
}
// register validators and mark custom values
var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
$elements.each(function () {
markField(this);
var $el = $(this);
$el.on('change', function () {
validateFieldAndFieldset(this, false);
markField(this);
});
var tagName = $el.attr('tagName');
// text fields can be validated after each change
if (tagName === 'INPUT' && $el.attr('type') === 'text') {
$el.on('keyup', function () {
validateFieldAndFieldset($el, true);
markField($el);
});
}
// disable textarea spellcheck
if (tagName === 'TEXTAREA') {
$el.attr('spellcheck', false);
}
});
// check whether we've refreshed a page and browser remembered modified
// form values
var $checkPageRefresh = $('#check_page_refresh');
if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') {
// run all field validators
var errors = {};
for (var i = 0; i < $elements.length; i++) {
validateField($elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
} else if ($checkPageRefresh) {
$checkPageRefresh.val('1');
}
}
AJAX.registerOnload('config.js', function () {
setupValidation();
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Tabbed forms
//
/**
* Sets active tab
*
* @param {String} tabId
*/
function setTab (tabId) {
$('ul.tabs').each(function () {
var $this = $(this);
if (!$this.find('li a[href="#' + tabId + '"]').length) {
return;
}
$this.find('li').removeClass('active').find('a[href="#' + tabId + '"]').parent().addClass('active');
$this.parent().find('div.tabs_contents fieldset').hide().filter('#' + tabId).show();
var hashValue = 'tab_' + tabId;
location.hash = hashValue;
$this.parent().find('input[name=tab_hash]').val(hashValue);
});
}
function setupConfigTabs () {
var forms = $('form.config-form');
forms.each(function () {
var $this = $(this);
var $tabs = $this.find('ul.tabs');
if (!$tabs.length) {
return;
}
// add tabs events and activate one tab (the first one or indicated by location hash)
$tabs.find('li').removeClass('active');
$tabs.find('a')
.on('click', function (e) {
e.preventDefault();
setTab($(this).attr('href').substr(1));
})
.filter(':first')
.parent()
.addClass('active');
$this.find('div.tabs_contents fieldset').hide().filter(':first').show();
});
}
function adjustPrefsNotification () {
var $prefsAutoLoad = $('#prefs_autoload');
var $tableNameControl = $('#table_name_col_no');
var $prefsAutoShowing = ($prefsAutoLoad.css('display') !== 'none');
if ($prefsAutoShowing && $tableNameControl.length) {
$tableNameControl.css('top', '55px');
}
}
AJAX.registerOnload('config.js', function () {
setupConfigTabs();
adjustPrefsNotification();
// tab links handling, check each 200ms
// (works with history in FF, further browser support here would be an overkill)
var prevHash;
var tabCheckFnc = function () {
if (location.hash !== prevHash) {
prevHash = location.hash;
if (prevHash.match(/^#tab_[a-zA-Z0-9_]+$/)) {
// session ID is sometimes appended here
var hash = prevHash.substr(5).split('&')[0];
if ($('#' + hash).length) {
setTab(hash);
}
}
}
};
tabCheckFnc();
setInterval(tabCheckFnc, 200);
});
//
// END: Tabbed forms
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Form reset buttons
//
AJAX.registerOnload('config.js', function () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
}
setDisplayError();
});
});
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
/**
* Restores field's default value
*
* @param {String} fieldId
*/
function restoreField (fieldId) {
var $field = $('#' + fieldId);
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
return;
}
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
}
function setupRestoreField () {
$('div.tabs_contents')
.on('mouseenter', '.restore-default, .set-value', function () {
$(this).css('opacity', 1);
})
.on('mouseleave', '.restore-default, .set-value', function () {
$(this).css('opacity', 0.25);
})
.on('click', '.restore-default, .set-value', function (e) {
e.preventDefault();
var href = $(this).attr('href');
var fieldSel;
if ($(this).hasClass('restore-default')) {
fieldSel = href;
restoreField(fieldSel.substr(1));
} else {
fieldSel = href.match(/^[^=]+/)[0];
var value = href.match(/=(.+)$/)[1];
setFieldValue($(fieldSel), 'text', value);
}
$(fieldSel).trigger('change');
})
.find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({ display: 'inline-block', opacity: 0.25 });
}
AJAX.registerOnload('config.js', function () {
setupRestoreField();
});
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
AJAX.registerOnload('config.js', function () {
offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
return;
}
// enable JavaScript dependent fields
$radios
.prop('disabled', false)
.add('#export_text_file, #import_text_file')
.on('click', function () {
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
var lsSupported = isStorageSupported('localStorage', true);
var lsExists = lsSupported ? (window.localStorage.config || false) : false;
$('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide();
$('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide();
if (lsExists) {
updatePrefsDate();
}
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!lsExists && $form.attr('name') === 'prefs_import' &&
$('#import_local_storage')[0].checked
) {
disabled = true;
}
$form.find('input[type=submit]').prop('disabled', disabled);
}).submit(function (e) {
var $form = $(this);
if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) {
e.preventDefault();
// use AJAX to read JSON settings and save them
savePrefsToLocalStorage($form);
} else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
// set 'json' input and submit form
$form.find('input[name=json]').val(window.localStorage.config);
}
});
$(document).on('click', 'div.click-hide-message', function () {
$(this)
.hide()
.parent('.group')
.css('height', '')
.next('form')
.show();
});
});
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
function savePrefsToLocalStorage (form) {
var $form = $(form);
var submit = $form.find('input[type=submit]');
submit.prop('disabled', true);
$.ajax({
url: 'prefs_manage.php',
cache: false,
type: 'POST',
data: {
'ajax_request': true,
'server': CommonParams.get('server'),
'submit_get_json': true
},
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
window.localStorage.config = data.prefs;
window.localStorage.configMtime = data.mtime;
window.localStorage.configMtimeLocal = (new Date()).toUTCString();
updatePrefsDate();
$('div.localStorage-empty').hide();
$('div.localStorage-exists').show();
var group = $form.parent('.group');
group.css('height', group.height() + 'px');
$form.hide('fast');
$form.prev('.click-hide-message').show('fast');
} else {
Functions.ajaxShowMessage(data.error);
}
},
complete: function () {
submit.prop('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
function updatePrefsDate () {
var d = new Date(window.localStorage.configMtimeLocal);
var msg = Messages.strSavedOn.replace(
'@DATE@',
Functions.formatDateTime(d)
);
$('#opts_import_local_storage').find('div.localStorage-exists').html(msg);
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
*/
function offerPrefsAutoimport () {
var hasConfig = (isStorageSupported('localStorage')) && (window.localStorage.config || false);
var $cnt = $('#prefs_autoload');
if (!$cnt.length || !hasConfig) {
return;
}
$cnt.find('a').on('click', function (e) {
e.preventDefault();
var $a = $(this);
if ($a.attr('href') === '#no') {
$cnt.remove();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
} else if ($a.attr('href') === '#delete') {
$cnt.remove();
localStorage.clear();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
}
$cnt.find('input[name=json]').val(window.localStorage.config);
$cnt.find('form').trigger('submit');
});
$cnt.show();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var styleElement = document.getElementById('cfs-style');
// check if styleElement has already been removed
// to avoid frequently reported js error
if (typeof(styleElement) !== 'undefined' && styleElement !== null) {
styleElement.parentNode.removeChild(styleElement);
}
} else {
top.location = self.location;
}

View File

@ -1,241 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview events handling from central columns page
* @name Central columns
*
* @requires jQuery
*/
/**
* AJAX scripts for db_central_columns.php
*
* Actions ajaxified here:
* Inline Edit and save of a result row
* Delete a row
* Multiple edit and delete option
*
*/
AJAX.registerTeardown('database/central_columns.js', function () {
$('.edit').off('click');
$('.edit_save_form').off('click');
$('.edit_cancel_form').off('click');
$('.del_row').off('click');
$(document).off('keyup', '.filter_rows');
$('.edit_cancel_form').off('click');
$('#table-select').off('change');
$('#column-select').off('change');
$('#add_col_div').find('>a').off('click');
$('#add_new').off('submit');
$('#multi_edit_central_columns').off('submit');
$('select.default_type').off('change');
$('button[name=\'delete_central_columns\']').off('click');
$('button[name=\'edit_central_columns\']').off('click');
});
AJAX.registerOnload('database/central_columns.js', function () {
$('#tableslistcontainer input,#tableslistcontainer select,#tableslistcontainer .default_value,#tableslistcontainer .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
$('#tableslistcontainer').find('.checkall_box').show();
if ($('#table_columns').find('tbody tr').length > 0) {
$('#table_columns').tablesorter({
headers: {
0: { sorter: false },
1: { sorter: false }, // hidden column
4: { sorter: 'integer' }
}
});
}
$('#tableslistcontainer').find('button[name="delete_central_columns"]').on('click', function (event) {
event.preventDefault();
var multiDeleteColumns = $('.checkall:checkbox:checked').serialize();
if (multiDeleteColumns === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
Functions.ajaxShowMessage();
$('#del_col_name').val(multiDeleteColumns);
$('#del_form').trigger('submit');
});
$('#tableslistcontainer').find('button[name="edit_central_columns"]').on('click', function (event) {
event.preventDefault();
var editColumnList = $('.checkall:checkbox:checked').serialize();
if (editColumnList === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
var argsep = CommonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db'));
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('db_central_columns.php', editColumnData, AJAX.responseHandler);
});
$('#multi_edit_central_columns').submit(function (event) {
event.preventDefault();
event.stopPropagation();
var argsep = CommonParams.get('arg_separator');
var multiColumnEditData = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db'));
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('db_central_columns.php', multiColumnEditData, AJAX.responseHandler);
});
$('#add_new').find('td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find('input,select:first').attr('name', $(this).attr('name'));
}
});
$('#field_0_0').attr('required','required');
$('#add_new input[type="text"], #add_new input[type="number"], #add_new select')
.css({
'width' : '10em',
'-moz-box-sizing' : 'border-box'
});
window.scrollTo(0, 0);
$(document).on('keyup', '.filter_rows', function () {
// get the column names
var cols = $('th.column_heading').map(function () {
return $.trim($(this).text());
}).get();
$.uiTableFilter($('#table_columns'), $(this).val(), cols, null, 'td span');
});
$('.edit').on('click', function () {
var rownum = $(this).parent().data('rownum');
$('#save_' + rownum).show();
$(this).hide();
$('#f_' + rownum + ' td span').hide();
$('#f_' + rownum + ' input, #f_' + rownum + ' select, #f_' + rownum + ' .open_enum_editor').show();
var attributeVal = $('#f_' + rownum + ' td[name=col_attribute] span').html();
$('#f_' + rownum + ' select[name=field_attribute\\[' + rownum + '\\] ] option[value="' + attributeVal + '"]').attr('selected','selected');
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').siblings('.default_value').show();
} else {
$('#f_' + rownum + ' .default_type').siblings('.default_value').hide();
}
});
$('.del_row').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var $td = $(this);
var question = Messages.strDeleteCentralColumnWarning;
$td.confirm(question, null, function () {
var rownum = $td.data('rownum');
$('#del_col_name').val('selected_fld%5B%5D=' + $('#checkbox_row_' + rownum).val());
$('#del_form').trigger('submit');
});
});
$('.edit_cancel_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
});
$('.edit_save_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#f_' + rownum + ' td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find(':input[type!="hidden"],select:first')
.attr('name', $(this).attr('name'));
}
});
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').attr('name','col_default_sel');
} else {
$('#f_' + rownum + ' .default_value').attr('name','col_default_val');
}
var datastring = $('#f_' + rownum + ' :input').serialize();
$.ajax({
type: 'POST',
url: 'db_central_columns.php',
data: datastring + CommonParams.get('arg_separator') + 'ajax_request=true',
dataType: 'json',
success: function (data) {
if (data.message !== '1') {
Functions.ajaxShowMessage(
'<div class="error">' +
data.message +
'</div>',
false
);
} else {
$('#f_' + rownum + ' td input[id=checkbox_row_' + rownum + ']').val($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_name] span').text($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_type] span').text($('#f_' + rownum + ' select[name=col_type]').val()).html();
$('#f_' + rownum + ' td[name=col_length] span').text($('#f_' + rownum + ' input[name=col_length]').val()).html();
$('#f_' + rownum + ' td[name=collation] span').text($('#f_' + rownum + ' select[name=collation]').val()).html();
$('#f_' + rownum + ' td[name=col_attribute] span').text($('#f_' + rownum + ' select[name=col_attribute]').val()).html();
$('#f_' + rownum + ' td[name=col_isNull] span').text($('#f_' + rownum + ' input[name=col_isNull]').is(':checked') ? 'Yes' : 'No').html();
$('#f_' + rownum + ' td[name=col_extra] span').text($('#f_' + rownum + ' input[name=col_extra]').is(':checked') ? 'auto_increment' : '').html();
$('#f_' + rownum + ' td[name=col_default] span').text($('#f_' + rownum + ' :input[name=col_default]').val()).html();
}
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
},
error: function () {
Functions.ajaxShowMessage(
'<div class="error">' +
Messages.strErrorProcessingRequest +
'</div>',
false
);
}
});
});
$('#table-select').on('change', function () {
var selectValue = $(this).val();
var defaultColumnSelect = $('#column-select').find('option:first');
var href = 'db_central_columns.php';
var params = {
'ajax_request' : true,
'server' : CommonParams.get('server'),
'db' : CommonParams.get('db'),
'selectedTable' : selectValue,
'populateColumns' : true
};
$('#column-select').html('<option value="">' + Messages.strLoading + '</option>');
if (selectValue !== '') {
$.post(href, params, function (data) {
$('#column-select').empty().append(defaultColumnSelect);
$('#column-select').append(data.message);
});
}
});
$('#add_column').submit(function (e) {
var selectvalue = $('#column-select').val();
if (selectvalue === '') {
e.preventDefault();
e.stopPropagation();
}
});
$('#add_col_div').find('>a').on('click', function () {
$('#add_new').slideToggle('slow');
var $addColDivLinkSpan = $('#add_col_div').find('>a span');
if ($addColDivLinkSpan.html() === '+') {
$addColDivLinkSpan.html('-');
} else {
$addColDivLinkSpan.html('+');
}
});
$('#add_new').submit(function () {
$('#add_new').toggle();
});
$('#tableslistcontainer').find('select.default_type').on('change', function () {
if ($(this).val() === 'USER_DEFINED') {
$(this).siblings('.default_value').attr('name','col_default');
$(this).attr('name','col_default_sel');
} else {
$(this).attr('name','col_default');
$(this).siblings('.default_value').attr('name','col_default_val');
}
});
});

View File

@ -1,222 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
* @requires js/database/query_generator.js
*
*/
/* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js
/**
* js file for handling AJAX and other events in db_multi_table_query.php
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/multi_table_query.js', function () {
$('.tableNameSelect').each(function () {
$(this).off('change');
});
$('#update_query_button').off('click');
$('#add_column_button').off('click');
});
AJAX.registerOnload('database/multi_table_query.js', function () {
var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both');
$('.CodeMirror-line').css('text-align', 'left');
editor.setSize(-1, 50);
var columnCount = 3;
Functions.initSlider();
addNewColumnCallbacks();
$('#update_query_button').on('click', function () {
var columns = [];
var tableAliases = {};
$('.tableNameSelect').each(function () {
var $show = $(this).siblings('.show_col').first();
if ($(this).val() !== '' && $show.prop('checked')) {
var tableAlias = $(this).siblings('.table_alias').first().val();
var columnAlias = $(this).siblings('.col_alias').first().val();
if (tableAlias !== '') {
columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]);
} else {
columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]);
}
columns[columns.length - 1].push(columnAlias);
if ($(this).val() in tableAliases) {
if (!(tableAliases[$(this).val()].includes(tableAlias))) {
tableAliases[$(this).val()].push(tableAlias);
}
} else {
tableAliases[$(this).val()] = [tableAlias];
}
}
});
if (Object.keys(tableAliases).length === 0) {
Functions.ajaxShowMessage('Nothing selected', false, 'error');
return;
}
var foreignKeys;
$.ajax({
type: 'GET',
async: false,
url: 'db_multi_table_query.php',
data: {
'server': sessionStorage.server,
'db': $('#db_name').val(),
'tables': Object.keys(tableAliases),
'ajax_request': '1',
'token': CommonParams.get('token')
},
success: function (response) {
foreignKeys = response.foreignKeyConstrains;
}
});
var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.';
if (columns[0][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[0][1]) + '`';
}
if (columns[0][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`';
}
for (var i = 1; i < columns.length; i++) {
query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.';
if (columns[i][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[i][1]) + '`';
}
if (columns[i][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`';
}
}
query += '\nFROM ';
query += generateFromBlock(tableAliases, foreignKeys);
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 0) {
query += '\nWHERE ';
query += generateWhereBlock();
}
query += ';';
editor.getDoc().setValue(query);
});
$('#submit_query').on('click', function () {
var query = editor.getDoc().getValue();
// Verifying that the query is not empty
if (query === '') {
Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error');
return;
}
var data = {
'db': $('#db_name').val(),
'sql_query': query,
'ajax_request': '1',
'token': CommonParams.get('token')
};
$.ajax({
type: 'POST',
url: 'db_multi_table_query.php',
data: data,
success: function (data) {
var $resultsDom = $(data.message);
$resultsDom.find('.ajax:not(.pageselector)').each(function () {
$(this).on('click', function (event) {
event.preventDefault();
});
});
$resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () {
$(this).on('change click select focus', function (event) {
event.preventDefault();
});
});
$('#sql_results').html($resultsDom);
$('#page_content').find('a').first().trigger('click');
}
});
});
$('#add_column_button').on('click', function () {
columnCount++;
var $newColumnDom = $($('#new_column_layout').html()).clone();
$newColumnDom.find('div').first().find('div').first().attr('id', columnCount.toString());
$newColumnDom.find('a').first().remove();
$newColumnDom.find('.pma_auto_slider').first().unwrap();
$newColumnDom.find('.pma_auto_slider').first().attr('title', 'criteria');
$('#add_column_button').parent().before($newColumnDom);
Functions.initSlider();
addNewColumnCallbacks();
});
function addNewColumnCallbacks () {
$('.tableNameSelect').each(function () {
$(this).on('change', function () {
var $sibs = $(this).siblings('.columnNameSelect');
if ($sibs.length === 0) {
$sibs = $(this).parent().parent().find('.columnNameSelect');
}
$sibs.first().html($('#' + $.md5($(this).val())).html());
});
});
$('.removeColumn').each(function () {
$(this).on('click', function () {
$(this).parent().remove();
});
});
$('a.ajax').each(function () {
$(this).on('click', function (event, from) {
if (from === null) {
var $checkbox = $(this).siblings('.criteria_col').first();
$checkbox.prop('checked', !$checkbox.prop('checked'));
}
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 1) {
$(this).siblings('.slide-wrapper').first().find('.logical_operator').first().css('display','table-row');
}
});
});
$('.criteria_col').each(function () {
$(this).on('change', function () {
var $anchor = $(this).siblings('a.ajax').first();
$anchor.trigger('click', ['Trigger']);
});
});
$('.criteria_rhs').each(function () {
$(this).on('change', function () {
var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first();
var $rhsText = $(this).parent().parent().siblings('.rhs_text').first();
if ($(this).val() === 'text') {
$rhsCol.css('display', 'none');
$rhsText.css('display', 'table-row');
} else if ($(this).val() === 'anotherColumn') {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'table-row');
} else {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'none');
}
});
});
}
});

View File

@ -1,167 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in server privilege pages
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for db_operations.php
*
* Actions Ajaxified here:
* Rename Database
* Copy Database
* Change Charset
* Drop Database
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/operations.js', function () {
$(document).off('submit', '#rename_db_form.ajax');
$(document).off('submit', '#copy_db_form.ajax');
$(document).off('submit', '#change_db_charset_form.ajax');
$(document).off('click', '#drop_db_anchor.ajax');
});
AJAX.registerOnload('database/operations.js', function () {
/**
* Ajax event handlers for 'Rename Database'
*/
$(document).on('submit', '#rename_db_form.ajax', function (event) {
event.preventDefault();
var oldDbName = CommonParams.get('db');
var newDbName = $('#new_db_name').val();
if (newDbName === oldDbName) {
Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error');
return false;
}
var $form = $(this);
var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName);
Functions.prepareForAjaxRequest($form);
$form.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strRenamingDatabases, false);
$.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
CommonParams.set('db', data.newname);
Navigation.reload(function () {
$('#pma_navigation_tree')
.find('a:not(\'.expander\')')
.each(function () {
var $thisAnchor = $(this);
if ($thisAnchor.text() === data.newname) {
// simulate a click on the new db name
// in navigation
$thisAnchor.trigger('click');
}
});
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
}); // end Rename Database
/**
* Ajax Event Handler for 'Copy Database'
*/
$(document).on('submit', '#copy_db_form.ajax', function (event) {
event.preventDefault();
Functions.ajaxShowMessage(Messages.strCopyingDatabase, false);
var $form = $(this);
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
// use messages that stay on screen
$('div.success, div.error').fadeOut();
if (typeof data !== 'undefined' && data.success === true) {
if ($('#checkbox_switch').is(':checked')) {
CommonParams.set('db', data.newname);
CommonActions.refreshMain(false, function () {
Functions.ajaxShowMessage(data.message);
});
} else {
CommonParams.set('db', data.db);
Functions.ajaxShowMessage(data.message);
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end copy database
/**
* Change tables columns visible only if change tables is checked
*/
$('#span_change_all_tables_columns_collations').hide();
$('#checkbox_change_all_tables_collations').on('click', function () {
$('#span_change_all_tables_columns_collations').toggle();
});
/**
* Ajax Event handler for 'Change Charset' of the database
*/
$(document).on('submit', '#change_db_charset_form.ajax', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
Functions.ajaxShowMessage(Messages.strChangingCharset);
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'submitcollation=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end change charset
/**
* Ajax event handlers for Drop Database
*/
$(document).on('click', '#drop_db_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strDropDatabaseStrongWarning + ' ';
question += Functions.sprintf(
Messages.strDoYouReally,
'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`')
);
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$(this).confirm(question, $(this).attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
// Database deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('db', '');
CommonActions.refreshMain(
'server_databases.php',
function () {
Functions.ajaxShowMessage(data.message);
}
);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
});
});

View File

@ -1,87 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for db_qbe.php
*
* Actions Ajaxified here:
* Select saved search
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/qbe.js', function () {
$(document).off('change', 'select[name^=criteriaColumn]');
$(document).off('change', '#searchId');
$(document).off('click', '#saveSearch');
$(document).off('click', '#updateSearch');
$(document).off('click', '#deleteSearch');
});
AJAX.registerOnload('database/qbe.js', function () {
Functions.getSqlEditor($('#textSqlquery'), {}, 'none');
$('#tblQbe').width($('#tblQbe').parent().width());
$('#tblQbeFooters').width($('#tblQbeFooters').parent().width());
$('#tblQbe').resize(function () {
var newWidthTblQbe = $('#textSqlquery').next().width();
$('#tblQbe').width(newWidthTblQbe);
$('#tblQbeFooters').width(newWidthTblQbe);
});
/**
* Ajax handler to check the corresponding 'show' checkbox when column is selected
*/
$(document).on('change', 'select[name^=criteriaColumn]', function () {
if ($(this).val()) {
var index = (/\d+/).exec($(this).attr('name'));
$('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true);
}
});
/**
* Ajax event handlers for 'Select saved search'
*/
$(document).on('change', '#searchId', function () {
$('#action').val('load');
$('#formQBE').trigger('submit');
});
/**
* Ajax event handlers for 'Create bookmark'
*/
$(document).on('click', '#saveSearch', function () {
$('#action').val('create');
});
/**
* Ajax event handlers for 'Update bookmark'
*/
$(document).on('click', '#updateSearch', function () {
$('#action').val('update');
});
/**
* Ajax event handlers for 'Delete bookmark'
*/
$(document).on('click', '#deleteSearch', function () {
var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text());
if (!confirm(question)) {
return false;
}
$('#action').val('delete');
});
var windowwidth = $(window).width();
$('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
});

View File

@ -1,131 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/* global sprintf */ // js/vendor/sprintf.js
function getFormatsText () {
return {
'=': ' = \'%s\'',
'>': ' > \'%s\'',
'>=': ' >= \'%s\'',
'<': ' < \'%s\'',
'<=': ' <= \'%s\'',
'!=': ' != \'%s\'',
'LIKE': ' LIKE \'%s\'',
'LIKE %...%': ' LIKE \'%%%s%%\'',
'NOT LIKE': ' NOT LIKE \'%s\'',
'BETWEEN': ' BETWEEN \'%s\'',
'NOT BETWEEN': ' NOT BETWEEN \'%s\'',
'IS NULL': ' \'%s\' IS NULL',
'IS NOT NULL': ' \'%s\' IS NOT NULL',
'REGEXP': ' REGEXP \'%s\'',
'REGEXP ^...$': ' REGEXP \'^%s$\'',
'NOT REGEXP': ' NOT REGEXP \'%s\''
};
}
function generateCondition (criteriaDiv, table) {
var query = '`' + Functions.escapeBacktick(table.val()) + '`.';
query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`';
if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') {
var formatsText = getFormatsText();
query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val()));
} else {
query += ' ' + criteriaDiv.find('.criteria_op').first().val();
query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.';
query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`';
}
return query;
}
// eslint-disable-next-line no-unused-vars
function generateWhereBlock () {
var count = 0;
var query = '';
$('.tableNameSelect').each(function () {
var criteriaDiv = $(this).siblings('.slide-wrapper').first();
var useCriteria = $(this).siblings('.criteria_col').first();
if ($(this).val() !== '' && useCriteria.prop('checked')) {
if (count > 0) {
criteriaDiv.find('input.logical_op').each(function () {
if ($(this).prop('checked')) {
query += ' ' + $(this).val() + ' ';
}
});
}
query += generateCondition(criteriaDiv, $(this));
count++;
}
});
return query;
}
function generateJoin (newTable, tableAliases, fk) {
var query = '';
query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`';
if (tableAliases[fk.TABLE_NAME][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`';
query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`';
} else {
query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`';
}
query += '.`' + fk.COLUMN_NAME + '`';
if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') {
query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`';
} else {
query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`';
}
query += '.`' + fk.REFERENCED_COLUMN_NAME + '`';
return query;
}
function existReference (table, fk, usedTables) {
var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME);
var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME);
return isReferredBy || isReferencedBy;
}
function tryJoinTable (table, tableAliases, usedTables, foreignKeys) {
for (var i = 0; i < foreignKeys.length; i++) {
var fk = foreignKeys[i];
if (existReference(table, fk, usedTables)) {
return generateJoin(table, tableAliases, fk);
}
}
return '';
}
function appendTable (table, tableAliases, usedTables, foreignKeys) {
var query = tryJoinTable (table, tableAliases, usedTables, foreignKeys);
if (query === '') {
if (usedTables.length > 0) {
query += '\n\t, ';
}
query += '`' + Functions.escapeBacktick(table) + '`';
if (tableAliases[table][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`';
}
}
usedTables.push(table);
return query;
}
// eslint-disable-next-line no-unused-vars
function generateFromBlock (tableAliases, foreignKeys) {
var usedTables = [];
var query = '';
for (var table in tableAliases) {
if (tableAliases.hasOwnProperty(table)) {
query += appendTable(table, tableAliases, usedTables, foreignKeys);
}
}
return query;
}

View File

@ -1,248 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* JavaScript functions used on Database Search page
*
* @requires jQuery
* @requires js/functions.js
*
* @package PhpMyAdmin
*/
/* global makeGrid */ // js/makegrid.js
/**
* AJAX script for the Database Search page.
*
* Actions ajaxified here:
* Retrieve result of SQL query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/search.js', function () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
$('#togglesearchresultlink').off('click');
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$(document).off('submit', '#db_search_form.ajax');
});
AJAX.registerOnload('database/search.js', function () {
/** Hide the table link in the initial search result */
var icon = Functions.getImage('s_tbl', '', { 'id': 'table-image' }).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').on('click', function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
});
/**
* Prepare a div containing a link for toggle the search results
*/
$('#togglesearchresultsdiv')
/** don't show it until we have results on-screen */
.hide();
/**
* Changing the displayed text according to
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink')
.html(Messages.strHideSearchResults)
.on('click', function () {
var $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === Messages.strHideSearchResults) {
$link.text(Messages.strShowSearchResults);
} else {
$link.text(Messages.strHideSearchResults);
}
/** avoid default click action */
return false;
});
/**
* Prepare a div containing a link for toggle the search form,
* otherwise it's incorrectly displayed after a couple of clicks
*/
$('#togglesearchformdiv')
.hide(); // don't show it until we have results on-screen
/**
* Changing the displayed text according to
* the hide/show criteria in search form
*/
$('#togglequerybox')
.hide()
.on('click', function () {
var $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === Messages.strHideQueryBox) {
$link.text(Messages.strShowQueryBox);
} else {
$link.text(Messages.strHideQueryBox);
}
/** avoid default click action */
return false;
});
/** don't show it until we have results on-screen */
/**
* Changing the displayed text according to
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink')
.html(Messages.strShowSearchCriteria)
.on('click', function () {
var $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
var tableName = $(this).data('table-name');
$('#table-link').attr({ 'href' : $(this).attr('href') }).text(tableName);
var url = $(this).attr('href') + '#searchresults';
var browseSql = $(this).data('browse-sql');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browseSql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
Functions.ajaxRemoveMessage($msg);
$('.table_results').each(function () {
makeGrid(this, true, true, true, true);
});
$('#browse-results').show();
Functions.highlightSql($('#browse-results'));
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function (e) {
e.preventDefault();
/** Hides the results shown by the browse criteria */
$('#table-info').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = Functions.sprintf(
Messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
Functions.ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
document.getElementById('buttonGo').trigger('click');
$('#togglequerybox').html(Messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
Functions.ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val();
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
$('#searchresults').html(data.message);
$('#togglesearchresultlink')
// always start with the Show message
.text(Messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
$('#searchresults').show();
$('#db_search_form')
// workaround for Chrome problem (bug #3168569)
.slideToggle()
.hide();
$('#togglesearchformlink')
// always start with the Show message
.text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
} else {
// error message (zero rows)
$('#searchresults').html(data.error).show();
}
Functions.ajaxRemoveMessage($msgbox);
});
});
}); // end $()

View File

@ -1,429 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview functions used on the database structure page
* @name Database Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
var DatabaseStructure = {};
/**
* AJAX scripts for db_structure.php
*
* Actions ajaxified here:
* Drop Database
* Truncate Table
* Drop Table
*
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/structure.js', function () {
$(document).off('click', 'a.truncate_table_anchor.ajax');
$(document).off('click', 'a.drop_table_anchor.ajax');
$(document).off('click', '#real_end_input');
$(document).off('click', 'a.favorite_table_anchor.ajax');
$(document).off('click', '#printView');
$('a.real_row_count').off('click');
$('a.row_count_sum').off('click');
$('select[name=submit_mult]').off('change');
});
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
DatabaseStructure.adjustTotals = function () {
var byteUnits = [
Messages.strB,
Messages.strKiB,
Messages.strMiB,
Messages.strGiB,
Messages.strTiB,
Messages.strPiB,
Messages.strEiB
];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody:first tr');
// New summary values for the table
var tableSum = $allTr.length;
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.]/g, '');
var intRow = parseInt(strRows, 10);
if (! isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $.trim($this.find('.tbl_size span:not(.unit)').text());
var strSizeUnit = $.trim($this.find('.tbl_size span.unit').text());
var strOverhead = $.trim($this.find('.tbl_overhead span:not(.unit)').text());
var strOverheadUnit = $.trim($this.find('.tbl_overhead span.unit').text());
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var sizeMagnitude = 0;
var overheadMagnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
sizeMagnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overheadMagnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]);
};
/**
* Gets the real row count for a table or DB.
* @param object $target Target for appending the real count value.
*/
DatabaseStructure.fetchRealRowCount = function ($target) {
var $throbber = $('#pma_navigation').find('.throbber')
.first()
.clone()
.css({ visibility: 'visible', display: 'inline-block' })
.on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all),
function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]')
.text(table.row_count);
}
);
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
},
error: function () {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
});
};
AJAX.registerOnload('database/structure.js', function () {
/**
* function to open the confirmation dialog for making table consistent with central list
*
* @param string msg message text to be displayed to user
* @param function success function to be called on success
*
*/
var jqConfirm = function (msg, success) {
var dialogObj = $('<div class=\'hide\'>' + msg + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[Messages.strContinue] = function () {
success();
$(this).dialog('close');
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
$(dialogObj).dialog({
resizable: false,
modal: true,
title: Messages.confirmTitle,
buttons: buttonOptions
});
};
/**
* Event handler on select of "Make consistent with central list"
*/
$('select[name=submit_mult]').on('change', function (event) {
if ($(this).val() === 'make_consistent_with_central_list') {
event.preventDefault();
event.stopPropagation();
jqConfirm(
Messages.makeConsistentMessage, function () {
$('#tablesForm').trigger('submit');
}
);
return false;
} else if ($(this).val() === 'copy_tbl' || $(this).val() === 'add_prefix_tbl' || $(this).val() === 'replace_prefix_tbl' || $(this).val() === 'copy_tbl_change_prefix') {
event.preventDefault();
event.stopPropagation();
if ($('input[name="selected_tbl[]"]:checked').length === 0) {
return false;
}
var formData = $('#tablesForm').serialize();
var modalTitle = '';
if ($(this).val() === 'copy_tbl') {
modalTitle = Messages.strCopyTablesTo;
} else if ($(this).val() === 'add_prefix_tbl') {
modalTitle = Messages.strAddPrefix;
} else if ($(this).val() === 'replace_prefix_tbl') {
modalTitle = Messages.strReplacePrefix;
} else if ($(this).val() === 'copy_tbl_change_prefix') {
modalTitle = Messages.strCopyPrefix;
}
$.ajax({
type: 'POST',
url: 'db_structure.php',
dataType: 'html',
data: formData
}).done(function (data) {
var dialogObj = $('<div class=\'hide\'>' + data + '</div>');
$('body').append(dialogObj);
var buttonOptions = {};
buttonOptions[Messages.strContinue] = function () {
$('#ajax_form').trigger('submit');
$(this).dialog('close');
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
$('#tablesForm')[0].reset();
};
$(dialogObj).dialog({
minWidth: 500,
resizable: false,
modal: true,
title: modalTitle,
buttons: buttonOptions
});
});
} else {
$('#tablesForm').trigger('submit');
}
});
/**
* Ajax Event handler for 'Truncate Table'
*/
$(document).on('click', 'a.truncate_table_anchor.ajax', function (event) {
event.preventDefault();
/**
* @var $this_anchor Object referring to the anchor clicked
*/
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $thisAnchor.parents('tr').children('th').children('a').text();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strTruncateTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') +
Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
// Adjust table statistics
var $tr = $thisAnchor.closest('tr');
$tr.find('.tbl_rows').text('0');
$tr.find('.tbl_size, .tbl_overhead').text('-');
// Fetch inner span of this anchor
// and replace the icon with its disabled version
var span = $thisAnchor.html().replace(/b_empty/, 'bd_empty');
// To disable further attempts to truncate the table,
// replace the a element with its inner span (modified)
$thisAnchor
.replaceWith(span)
.removeClass('truncate_table_anchor');
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Truncate Table Ajax action
/**
* Ajax Event handler for 'Drop Table' or 'Drop View'
*/
$(document).on('click', 'a.drop_table_anchor.ajax', function (event) {
event.preventDefault();
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $thisAnchor.parents('tr');
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $currRow.children('th').children('a').text();
/**
* @var is_view Boolean telling if we have a view
*/
var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view');
/**
* @var question String containing the question to be asked for confirmation
*/
var question;
if (! isView) {
question = Messages.strDropTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`');
} else {
question =
Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`');
}
question += Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
$currRow.hide('medium').remove();
DatabaseStructure.adjustTotals();
Navigation.reload();
Functions.ajaxRemoveMessage($msg);
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Drop Table Ajax action
/**
* Attach Event Handler for 'Print' link
*/
$(document).on('click', '#printView', function (event) {
event.preventDefault();
// Take to preview mode
Functions.printPreview();
}); // end of Print View action
// Calculate Real End for InnoDB
/**
* Ajax Event handler for calculating the real end for a InnoDB table
*
*/
$(document).on('click', '#real_end_input', function (event) {
event.preventDefault();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strOperationTakesLongTime;
$(this).confirm(question, '', function () {
return true;
});
return false;
}); // end Calculate Real End for InnoDB
// Add tooltip to favorite icons.
$('.favorite_table_anchor').each(function () {
Functions.tooltip(
$(this),
'a',
$(this).attr('title')
);
});
// Get real row count via Ajax.
$('a.real_row_count').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
// Get all real row count.
$('a.row_count_sum').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
});

View File

@ -1,93 +0,0 @@
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('database/tracking.js', function () {
$('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]');
$('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_tracking_anchor.ajax');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('database/tracking.js', function () {
var $versions = $('#versions');
$versions.find('tr:first th').append($('<div class="sorticon"></div>'));
$versions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: 'integer' },
5: { sorter: false },
6: { sorter: false },
7: { sorter: false }
}
});
var $noVersions = $('#noversions');
$noVersions.find('tr:first th').append($('<div class="sorticon"></div>'));
$noVersions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: false }
}
});
var $body = $('body');
/**
* Handles multi submit for tracked tables
*/
$body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_tracking') {
var question = Messages.strDeleteTrackingDataMultiple;
$button.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $form;
$.post(url, submitData, AJAX.responseHandler);
});
} else {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
/**
* Handles multi submit for untracked tables
*/
$body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Delete tracking'
*/
$body.on('click', 'a.delete_tracking_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeleteTrackingData;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
});

View File

@ -1,859 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @fileoverview function used in this file builds history tab and generates query.
*
* @requires jQuery
* @requires move.js
* @version $Id$
*/
/* global contr */ // js/designer/init.js
/* global fromArray:writable */ // js/designer/move.js
/* global pmaThemeImage */ // js/messages.php
var DesignerHistory = {};
var historyArray = []; // Global array to store history objects
var selectField = []; // Global array to store information for columns which are used in select clause
var gIndex;
var vqbEditor = null;
/**
* To display details of objects(where,rename,Having,aggregate,groupby,orderby,having)
*
* @param index index of historyArray where change is to be made
*
**/
DesignerHistory.detail = function (index) {
var type = historyArray[index].getType();
var str;
if (type === 'Where') {
str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
if (type === 'Rename') {
str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo();
}
if (type === 'Aggregate') {
str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
}
if (type === 'GroupBy') {
str = 'GroupBy ' + historyArray[index].getColumnName();
}
if (type === 'OrderBy') {
str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder();
}
if (type === 'Having') {
str = 'Having ';
if (historyArray[index].getObj().getOperator() !== 'None') {
str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else {
str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
}
return str;
};
/**
* Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab,
* clubbing all objects of same tables together
* This function is called whenever changes are made in historyArray[]
*
*
* @param {int} init starting index of unsorted array
* @param {int} finit last index of unsorted array
*
**/
DesignerHistory.display = function (init, finit) {
var str;
var i;
var j;
var k;
var sto;
var temp;
// this part sorts the history array based on table name,this is needed for clubbing all object of same name together.
for (i = init; i < finit; i++) {
sto = historyArray[i];
temp = historyArray[i].getTab();// + '.' + historyArray[i].getObjNo(); for Self JOINS
for (j = 0; j < i; j++) {
if (temp > (historyArray[j].getTab())) {// + '.' + historyArray[j].getObjNo())) { //for Self JOINS
for (k = i; k > j; k--) {
historyArray[k] = historyArray[k - 1];
}
historyArray[j] = sto;
break;
}
}
}
// this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects.
str = ''; // string to store Html code for history tab
for (i = 0; i < historyArray.length; i++) {
temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
str += '<div class="toggle_container">\n';
while ((historyArray[i].getTab()) === temp) { // + '.' + historyArray[i].getObjNo()) === temp) {
str += '<div class="block"> <table width ="250">';
str += '<thead><tr><td>';
if (historyArray[i].getAndOr()) {
str += '<img src="' + pmaThemeImage + 'designer/or_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="OR"></td>';
} else {
str += '<img src="' + pmaThemeImage + 'designer/and_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="AND"></td>';
}
str += '<td style="padding-left: 5px;" class="right">' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '</td>' +
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') {
var detailDescGroupBy = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDescGroupBy + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
} else {
var detailDesc = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDesc + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyEdit(' + i + ')>' + Functions.getImage('b_edit', Messages.strEdit) + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
}
str += '</tr></thead>';
i++;
if (i >= historyArray.length) {
break;
}
str += '</table></div>';
}
i--;
str += '</div>';
}
return str;
};
/**
* To change And/Or relation in history tab
*
*
* @param {int} index of historyArray where change is to be made
*
**/
DesignerHistory.andOr = function (index) {
if (historyArray[index].getAndOr()) {
historyArray[index].setAndOr(0);
} else {
historyArray[index].setAndOr(1);
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* Deletes entry in historyArray
*
* @param index index of historyArray[] which is to be deleted
*
**/
DesignerHistory.historyDelete = function (index) {
for (var k = 0; k < fromArray.length; k++) {
if (fromArray[k] === historyArray[index].getTab()) {
fromArray.splice(k, 1);
break;
}
}
historyArray.splice(index, 1);
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* To show where,rename,aggregate,having forms to edit a object
*
* @param{int} index index of historyArray where change is to be made
*
**/
DesignerHistory.historyEdit = function (index) {
gIndex = index;
var type = historyArray[index].getType();
if (type === 'Where') {
document.getElementById('eQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('query_where').style.left = '530px';
document.getElementById('query_where').style.top = '130px';
document.getElementById('query_where').style.position = 'absolute';
document.getElementById('query_where').style.zIndex = '103';
document.getElementById('query_where').style.visibility = 'visible';
document.getElementById('query_where').style.display = 'block';
}
if (type === 'Having') {
document.getElementById('hQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('hoperator').value = historyArray[index].getObj().getOperator();
document.getElementById('query_having').style.left = '530px';
document.getElementById('query_having').style.top = '130px';
document.getElementById('query_having').style.position = 'absolute';
document.getElementById('query_having').style.zIndex = '103';
document.getElementById('query_having').style.visibility = 'visible';
document.getElementById('query_having').style.display = 'block';
}
if (type === 'Rename') {
document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo();
document.getElementById('query_rename_to').style.left = '530px';
document.getElementById('query_rename_to').style.top = '130px';
document.getElementById('query_rename_to').style.position = 'absolute';
document.getElementById('query_rename_to').style.zIndex = '103';
document.getElementById('query_rename_to').style.visibility = 'visible';
document.getElementById('query_rename_to').style.display = 'block';
}
if (type === 'Aggregate') {
document.getElementById('e_operator').value = historyArray[index].getObj().getOperator();
document.getElementById('query_Aggregate').style.left = '530px';
document.getElementById('query_Aggregate').style.top = '130px';
document.getElementById('query_Aggregate').style.position = 'absolute';
document.getElementById('query_Aggregate').style.zIndex = '103';
document.getElementById('query_Aggregate').style.visibility = 'visible';
document.getElementById('query_Aggregate').style.display = 'block';
}
};
/**
* Make changes in historyArray when Edit button is clicked
* checks for the type of object and then sets the new value
*
* @param index index of historyArray where change is to be made
**/
DesignerHistory.edit = function (type) {
if (type === 'Rename') {
if (document.getElementById('e_rename').value !== '') {
historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value);
document.getElementById('e_rename').value = '';
}
document.getElementById('query_rename_to').style.visibility = 'hidden';
}
if (type === 'Aggregate') {
if (document.getElementById('e_operator').value !== '---') {
historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value);
document.getElementById('e_operator').value = '---';
}
document.getElementById('query_Aggregate').style.visibility = 'hidden';
}
if (type === 'Where') {
if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value);
}
document.getElementById('query_where').style.visibility = 'hidden';
}
if (type === 'Having') {
if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value);
historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value);
}
document.getElementById('query_having').style.visibility = 'hidden';
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* history object closure
*
* @param nColumnName name of the column on which conditions are put
* @param nObj object details(where,rename,orderby,groupby,aggregate)
* @param nTab table name of the column on which conditions are applied
* @param nObjNo object no used for inner join
* @param nType type of object
*
**/
DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) {
var andOr;
var obj;
var tab;
var columnName;
var objNo;
var type;
this.setColumnName = function (nColumnName) {
columnName = nColumnName;
};
this.getColumnName = function () {
return columnName;
};
this.setAndOr = function (nAndOr) {
andOr = nAndOr;
};
this.getAndOr = function () {
return andOr;
};
this.getRelation = function () {
return andOr;
};
this.setObj = function (nObj) {
obj = nObj;
};
this.getObj = function () {
return obj;
};
this.setTab = function (nTab) {
tab = nTab;
};
this.getTab = function () {
return tab;
};
this.setObjNo = function (nObjNo) {
objNo = nObjNo;
};
this.getObjNo = function () {
return objNo;
};
this.setType = function (nType) {
type = nType;
};
this.getType = function () {
return type;
};
this.setObjNo(nObjNo);
this.setTab(nTab);
this.setAndOr(0);
this.setObj(nObj);
this.setColumnName(nColumnName);
this.setType(nType);
};
/**
* where object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
*
**/
DesignerHistory.Where = function (nRelationOperator, nQuery) {
var relationOperator;
var query;
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
};
/**
* Orderby object closure
*
* @param nOrder order, ASC or DESC
*/
DesignerHistory.OrderBy = function (nOrder) {
var order;
this.setOrder = function (nOrder) {
order = nOrder;
};
this.getOrder = function () {
return order;
};
this.setOrder(nOrder);
};
/**
* Having object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
* @param nOperator operator
**/
DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) {
var relationOperator;
var query;
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.getOperator = function () {
return operator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
this.setOperator(nOperator);
};
/**
* rename object closure,makes an object with all information of rename
*
* @param nRenameTo new name information
*
**/
DesignerHistory.Rename = function (nRenameTo) {
var renameTo;
this.setRenameTo = function (nRenameTo) {
renameTo = nRenameTo;
};
this.getRenameTo = function () {
return renameTo;
};
this.setRenameTo(nRenameTo);
};
/**
* aggregate object closure
*
* @param nOperator aggregte operator
*
**/
DesignerHistory.Aggregate = function (nOperator) {
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.getOperator = function () {
return operator;
};
this.setOperator(nOperator);
};
/**
* This function returns unique element from an array
*
* @param arrayName array from which duplicate elem are to be removed.
* @return unique array
*/
DesignerHistory.unique = function (arrayName) {
var newArray = [];
uniquetop:
for (var i = 0; i < arrayName.length; i++) {
for (var j = 0; j < newArray.length; j++) {
if (newArray[j] === arrayName[i]) {
continue uniquetop;
}
}
newArray[newArray.length] = arrayName[i];
}
return newArray;
};
/**
* This function takes in array and a value as input and returns 1 if values is present in array
* else returns -1
*
* @param arrayName array
* @param value value which is to be searched in the array
*/
DesignerHistory.found = function (arrayName, value) {
for (var i = 0; i < arrayName.length; i++) {
if (arrayName[i] === value) {
return 1;
}
}
return -1;
};
/**
* This function concatenates two array
*
* @params add array elements of which are pushed in
* @params arr array in which elements are added
*/
DesignerHistory.addArray = function (add, arr) {
for (var i = 0; i < add.length; i++) {
arr.push(add[i]);
}
return arr;
};
/**
* This function removes all elements present in one array from the other.
*
* @params rem array from which each element is removed from other array.
* @params arr array from which elements are removed.
*
*/
DesignerHistory.removeArray = function (rem, arr) {
for (var i = 0; i < rem.length; i++) {
for (var j = 0; j < arr.length; j++) {
if (rem[i] === arr[j]) {
arr.splice(j, 1);
}
}
}
return arr;
};
/**
* This function builds the groupby clause from history object
*
*/
DesignerHistory.queryGroupBy = function () {
var i;
var str = '';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'GroupBy') {
str += '`' + historyArray[i].getColumnName() + '`, ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Having clause from the history object.
*
*/
DesignerHistory.queryHaving = function () {
var i;
var and = '(';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'Having') {
if (historyArray[i].getObj().getOperator() !== 'None') {
and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator();
and += ' ' + historyArray[i].getObj().getQuery() + ', ';
} else {
and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', ';
}
}
}
if (and === '(') {
and = '';
} else {
and = and.substr(0, and.length - 2) + ')';
}
return and;
};
/**
* This function builds the orderby clause from the history object.
*
*/
DesignerHistory.queryOrderBy = function () {
var i;
var str = '';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'OrderBy') {
str += '`' + historyArray[i].getColumnName() + '` ' +
historyArray[i].getObj().getOrder() + ', ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Where clause from the history object.
*
*/
DesignerHistory.queryWhere = function () {
var i;
var and = '(';
var or = '(';
for (i = 0; i < historyArray.length; i++) {
if (historyArray[i].getType() === 'Where') {
if (historyArray[i].getAndOr() === 0) {
and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
and += ' AND ';
} else {
or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
or += ' OR ';
}
}
}
if (or !== '(') {
or = or.substring(0, (or.length - 4)) + ')';
} else {
or = '';
}
if (and !== '(') {
and = and.substring(0, (and.length - 5)) + ')';
} else {
and = '';
}
if (or !== '') {
and = and + ' OR ' + or + ' )';
}
return and;
};
DesignerHistory.checkAggregate = function (idThis) {
var i;
for (i = 0; i < historyArray.length; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Aggregate') {
return historyArray[i].getObj().getOperator() + '(' + idThis + ')';
}
}
return '';
};
DesignerHistory.checkRename = function (idThis) {
var i;
for (i = 0; i < historyArray.length; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Rename') {
return ' AS `' + historyArray[i].getObj().getRenameTo() + '`';
}
}
return '';
};
/**
* This function builds from clause of query
* makes automatic joins.
*
*
*/
DesignerHistory.queryFrom = function () {
var i;
var tabLeft = [];
var tabUsed = [];
var tTabLeft = [];
var temp;
var query = '';
var quer = '';
var parts = [];
var tArray = [];
tArray = fromArray;
var K = 0;
var k;
var key;
var key2;
var key3;
var parts1;
// the constraints that have been used in the LEFT JOIN
var constraintsAdded = [];
for (i = 0; i < historyArray.length; i++) {
fromArray.push(historyArray[i].getTab());
}
fromArray = DesignerHistory.unique(fromArray);
tabLeft = fromArray;
temp = tabLeft.shift();
quer = '`' + temp + '`';
tabUsed.push(temp);
// if master table (key2) matches with tab used get all keys and check if tab_left matches
// after this check if master table (key2) matches with tab left then check if any foreign matches with master .
for (i = 0; i < 2; i++) {
for (K in contr) {
for (key in contr[K]) {// contr name
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabUsed, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabLeft, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
K = 0;
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
for (K in contr) {
for (key in contr[K]) {
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabLeft, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabUsed, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
}
for (k in tabLeft) {
quer += ' , `' + tabLeft[k] + '`';
}
query = quer + query;
fromArray = tArray;
return query;
};
/**
* This function is the main function for query building.
* uses history object details for this.
*
* @uses DesignerHistory.queryWhere()
* @uses DesignerHistory.queryGroupBy()
* @uses DesignerHistory.queryHaving()
* @uses DesignerHistory.queryOrderBy()
*/
DesignerHistory.buildQuery = function () {
var qSelect = 'SELECT ';
var temp;
if (selectField.length > 0) {
for (var i = 0; i < selectField.length; i++) {
temp = DesignerHistory.checkAggregate(selectField[i]);
if (temp !== '') {
qSelect += temp;
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += temp + ', ';
} else {
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += selectField[i] + temp + ', ';
}
}
qSelect = qSelect.substring(0, qSelect.length - 2);
} else {
qSelect += '* ';
}
qSelect += '\nFROM ' + DesignerHistory.queryFrom();
var qWhere = DesignerHistory.queryWhere();
if (qWhere !== '') {
qSelect += '\nWHERE ' + qWhere;
}
var qGroupBy = DesignerHistory.queryGroupBy();
if (qGroupBy !== '') {
qSelect += '\nGROUP BY ' + qGroupBy;
}
var qHaving = DesignerHistory.queryHaving();
if (qHaving !== '') {
qSelect += '\nHAVING ' + qHaving;
}
var qOrderBy = DesignerHistory.queryOrderBy();
if (qOrderBy !== '') {
qSelect += '\nORDER BY ' + qOrderBy;
}
/**
* @var button_options Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {};
buttonOptions[Messages.strClose] = function () {
$(this).dialog('close');
};
buttonOptions[Messages.strSubmit] = function () {
if (vqbEditor) {
var $elm = $ajaxDialog.find('textarea');
vqbEditor.save();
$elm.val(vqbEditor.getValue());
}
$('#vqb_form').trigger('submit');
};
var $ajaxDialog = $('#box').dialog({
appendTo: '#page_content',
width: 500,
buttons: buttonOptions,
modal: true,
title: 'SELECT'
});
// Attach syntax highlighted editor to query dialog
/**
* @var $elm jQuery object containing the reference
* to the query textarea.
*/
var $elm = $ajaxDialog.find('textarea');
if (! vqbEditor) {
vqbEditor = Functions.getSqlEditor($elm);
}
if (vqbEditor) {
vqbEditor.setValue(qSelect);
vqbEditor.focus();
} else {
$elm.val(qSelect);
$elm.trigger('focus');
}
};
AJAX.registerTeardown('designer/history.js', function () {
vqbEditor = null;
historyArray = [];
selectField = [];
$('#ok_edit_rename').off('click');
$('#ok_edit_having').off('click');
$('#ok_edit_Aggr').off('click');
$('#ok_edit_where').off('click');
});
AJAX.registerOnload('designer/history.js', function () {
$('#ok_edit_rename').on('click', function () {
DesignerHistory.edit('Rename');
});
$('#ok_edit_having').on('click', function () {
DesignerHistory.edit('Having');
});
$('#ok_edit_Aggr').on('click', function () {
DesignerHistory.edit('Aggregate');
});
$('#ok_edit_where').on('click', function () {
DesignerHistory.edit('Where');
});
$('#ab').accordion({ collapsible : true, active : 'none' });
});

View File

@ -1,75 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Initialises the data required to run Designer, then fires it up.
*/
/* global DesignerOfflineDB */ // js/designer/database.js
/* global DesignerHistory */ // js/designer/history.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerPage */ // js/designer/page.js
/* global designerConfig */ // templates/database/designer/main.twig
/* eslint-disable no-unused-vars */
var jTabs;
var hTabs;
var contr;
var displayField;
var server;
var selectedPage;
/* eslint-enable no-unused-vars */
var db;
var designerTablesEnabled;
AJAX.registerTeardown('designer/init.js', function () {
$('.trigger').off('click');
});
AJAX.registerOnload('designer/init.js', function () {
$('.trigger').on('click', function () {
$('.panel').toggle('fast');
$(this).toggleClass('active');
$('#ab').accordion('refresh');
return false;
});
jTabs = designerConfig.scriptTables.j_tabs;
hTabs = designerConfig.scriptTables.h_tabs;
contr = designerConfig.scriptContr;
displayField = designerConfig.scriptDisplayField;
server = designerConfig.server;
db = designerConfig.db;
selectedPage = designerConfig.displayPage;
designerTablesEnabled = designerConfig.tablesEnabled;
DesignerMove.main();
if (! designerTablesEnabled) {
DesignerOfflineDB.open(function (success) {
if (success) {
DesignerPage.showTablesInLandingPage(db);
}
});
}
$('#query_Aggregate_Button').on('click', function () {
document.getElementById('query_Aggregate').style.display = 'none';
});
$('#query_having_button').on('click', function () {
document.getElementById('query_having').style.display = 'none';
});
$('#query_rename_to_button').on('click', function () {
document.getElementById('query_rename_to').style.display = 'none';
});
$('#build_query_button').on('click', function () {
DesignerHistory.buildQuery('SQL Query on Database', 0);
});
$('#query_where_button').on('click', function () {
document.getElementById('query_where').style.display = 'none';
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,169 +0,0 @@
/* global DesignerOfflineDB */ // js/designer/database.js
// eslint-disable-next-line no-unused-vars
/* global db, selectedPage:writable */ // js/designer/init.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerObjects */ // js/designer/objects.js
var DesignerPage = {};
DesignerPage.showTablesInLandingPage = function (db) {
DesignerPage.loadFirstPage(db, function (page) {
if (page) {
DesignerPage.loadHtmlForPage(page.pgNr);
selectedPage = page.pgNr;
} else {
DesignerPage.showNewPageTables(true);
}
});
};
DesignerPage.saveToNewPage = function (db, pageName, tablePositions, callback) {
DesignerPage.createNewPage(db, pageName, function (page) {
if (page) {
var tblCords = [];
var saveCallback = function (id) {
tblCords.push(id);
if (tablePositions.length === tblCords.length) {
page.tblCords = tblCords;
DesignerOfflineDB.addObject('pdf_pages', page);
}
};
for (var pos = 0; pos < tablePositions.length; pos++) {
tablePositions[pos].pdfPgNr = page.pgNr;
DesignerPage.saveTablePositions(tablePositions[pos], saveCallback);
}
if (typeof callback !== 'undefined') {
callback(page);
}
}
});
};
DesignerPage.saveToSelectedPage = function (db, pageId, pageName, tablePositions, callback) {
DesignerPage.deletePage(pageId);
DesignerPage.saveToNewPage(db, pageName, tablePositions, function (page) {
if (typeof callback !== 'undefined') {
callback(page);
}
selectedPage = page.pgNr;
});
};
DesignerPage.createNewPage = function (db, pageName, callback) {
var newPage = new DesignerObjects.PdfPage(db, pageName);
DesignerOfflineDB.addObject('pdf_pages', newPage, function (pgNr) {
newPage.pgNr = pgNr;
if (typeof callback !== 'undefined') {
callback(newPage);
}
});
};
DesignerPage.saveTablePositions = function (positions, callback) {
DesignerOfflineDB.addObject('table_coords', positions, callback);
};
DesignerPage.createPageList = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var html = '';
for (var p = 0; p < pages.length; p++) {
var page = pages[p];
if (page.dbName === db) {
html += '<option value="' + page.pgNr + '">';
html += Functions.escapeHtml(page.pageDescr) + '</option>';
}
}
if (typeof callback !== 'undefined') {
callback(html);
}
});
};
DesignerPage.deletePage = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
if (page) {
for (var i = 0; i < page.tblCords.length; i++) {
DesignerOfflineDB.deleteObject('table_coords', page.tblCords[i]);
}
DesignerOfflineDB.deleteObject('pdf_pages', pageId, callback);
}
});
};
DesignerPage.loadFirstPage = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var firstPage = null;
for (var i = 0; i < pages.length; i++) {
var page = pages[i];
if (page.dbName === db) {
// give preference to a page having same name as the db
if (page.pageDescr === db) {
callback(page);
return;
}
if (firstPage === null) {
firstPage = page;
}
}
}
callback(firstPage);
});
};
DesignerPage.showNewPageTables = function (check) {
var allTables = $('#id_scroll_tab').find('td input:checkbox');
allTables.prop('checked', check);
for (var tab = 0; tab < allTables.length; tab++) {
var input = allTables[tab];
if (input.value) {
var element = document.getElementById(input.value);
element.style.top = DesignerPage.getRandom(550, 20) + 'px';
element.style.left = DesignerPage.getRandom(700, 20) + 'px';
DesignerMove.visibleTab(input, input.value);
}
}
selectedPage = -1;
$('#page_name').text(Messages.strUntitled);
DesignerMove.markUnsaved();
};
DesignerPage.loadHtmlForPage = function (pageId) {
DesignerPage.showNewPageTables(false);
DesignerPage.loadPageObjects(pageId, function (page, tblCords) {
$('#name-panel').find('#page_name').text(page.pageDescr);
DesignerMove.markSaved();
for (var t = 0; t < tblCords.length; t++) {
var tbId = db + '.' + tblCords[t].tableName;
var table = document.getElementById(tbId);
table.style.top = tblCords[t].y + 'px';
table.style.left = tblCords[t].x + 'px';
var checkbox = document.getElementById('check_vis_' + tbId);
checkbox.checked = true;
DesignerMove.visibleTab(checkbox, checkbox.value);
}
selectedPage = page.pgNr;
});
};
DesignerPage.loadPageObjects = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
var tblCords = [];
var count = page.tblCords.length;
for (var i = 0; i < count; i++) {
DesignerOfflineDB.loadObject('table_coords', page.tblCords[i], function (tblCord) {
tblCords.push(tblCord);
if (tblCords.length === count) {
if (typeof callback !== 'undefined') {
callback(page, tblCords);
}
}
});
}
});
};
DesignerPage.getRandom = function (max, min) {
var val = Math.random() * (max - min) + min;
return Math.floor(val);
};

View File

@ -1,367 +0,0 @@
/**
* Definition of links to MySQL documentation.
*/
// eslint-disable-next-line no-unused-vars
var mysqlDocKeyword = {
/* Multi word */
'CHARACTER SET': ['charset'],
'SHOW AUTHORS': ['show-authors'],
'SHOW BINARY LOGS': ['show-binary-logs'],
'SHOW BINLOG EVENTS': ['show-binlog-events'],
'SHOW CHARACTER SET': ['show-character-set'],
'SHOW COLLATION': ['show-collation'],
'SHOW COLUMNS': ['show-columns'],
'SHOW CONTRIBUTORS': ['show-contributors'],
'SHOW CREATE DATABASE': ['show-create-database'],
'SHOW CREATE EVENT': ['show-create-event'],
'SHOW CREATE FUNCTION': ['show-create-function'],
'SHOW CREATE PROCEDURE': ['show-create-procedure'],
'SHOW CREATE TABLE': ['show-create-table'],
'SHOW CREATE TRIGGER': ['show-create-trigger'],
'SHOW CREATE VIEW': ['show-create-view'],
'SHOW DATABASES': ['show-databases'],
'SHOW ENGINE': ['show-engine'],
'SHOW ENGINES': ['show-engines'],
'SHOW ERRORS': ['show-errors'],
'SHOW EVENTS': ['show-events'],
'SHOW FUNCTION CODE': ['show-function-code'],
'SHOW FUNCTION STATUS': ['show-function-status'],
'SHOW GRANTS': ['show-grants'],
'SHOW INDEX': ['show-index'],
'SHOW MASTER STATUS': ['show-master-status'],
'SHOW OPEN TABLES': ['show-open-tables'],
'SHOW PLUGINS': ['show-plugins'],
'SHOW PRIVILEGES': ['show-privileges'],
'SHOW PROCEDURE CODE': ['show-procedure-code'],
'SHOW PROCEDURE STATUS': ['show-procedure-status'],
'SHOW PROCESSLIST': ['show-processlist'],
'SHOW PROFILE': ['show-profile'],
'SHOW PROFILES': ['show-profiles'],
'SHOW RELAYLOG EVENTS': ['show-relaylog-events'],
'SHOW SLAVE HOSTS': ['show-slave-hosts'],
'SHOW SLAVE STATUS': ['show-slave-status'],
'SHOW STATUS': ['show-status'],
'SHOW TABLE STATUS': ['show-table-status'],
'SHOW TABLES': ['show-tables'],
'SHOW TRIGGERS': ['show-triggers'],
'SHOW VARIABLES': ['show-variables'],
'SHOW WARNINGS': ['show-warnings'],
'LOAD DATA INFILE': ['load-data'],
'LOAD XML': ['load-xml'],
'LOCK TABLES': ['lock-tables'],
'UNLOCK TABLES': ['lock-tables'],
'ALTER DATABASE': ['alter-database'],
'ALTER EVENT': ['alter-event'],
'ALTER LOGFILE GROUP': ['alter-logfile-group'],
'ALTER FUNCTION': ['alter-function'],
'ALTER PROCEDURE': ['alter-procedure'],
'ALTER SERVER': ['alter-server'],
'ALTER TABLE': ['alter-table'],
'ALTER TABLESPACE': ['alter-tablespace'],
'ALTER VIEW': ['alter-view'],
'CREATE DATABASE': ['create-database'],
'CREATE EVENT': ['create-event'],
'CREATE FUNCTION': ['create-function'],
'CREATE INDEX': ['create-index'],
'CREATE LOGFILE GROUP': ['create-logfile-group'],
'CREATE PROCEDURE': ['create-procedure'],
'CREATE SERVER': ['create-server'],
'CREATE TABLE': ['create-table'],
'CREATE TABLESPACE': ['create-tablespace'],
'CREATE TRIGGER': ['create-trigger'],
'CREATE VIEW': ['create-view'],
'DROP DATABASE': ['drop-database'],
'DROP EVENT': ['drop-event'],
'DROP FUNCTION': ['drop-function'],
'DROP INDEX': ['drop-index'],
'DROP LOGFILE GROUP': ['drop-logfile-group'],
'DROP PROCEDURE': ['drop-procedure'],
'DROP SERVER': ['drop-server'],
'DROP TABLE': ['drop-table'],
'DROP TABLESPACE': ['drop-tablespace'],
'DROP TRIGGER': ['drop-trigger'],
'DROP VIEW': ['drop-view'],
'RENAME TABLE': ['rename-table'],
'TRUNCATE TABLE': ['truncate-table'],
/* Statements */
'SELECT': ['select'],
'SET': ['set'],
'EXPLAIN': ['explain'],
'DESCRIBE': ['describe'],
'DELETE': ['delete'],
'SHOW': ['show'],
'UPDATE': ['update'],
'INSERT': ['insert'],
'REPLACE': ['replace'],
'CALL': ['call'],
'DO': ['do'],
'HANDLER': ['handler'],
'COLLATE': ['charset-collations'],
/* Functions */
'ABS': ['mathematical-functions', 'function_abs'],
'ACOS': ['mathematical-functions', 'function_acos'],
'ADDDATE': ['date-and-time-functions', 'function_adddate'],
'ADDTIME': ['date-and-time-functions', 'function_addtime'],
'AES_DECRYPT': ['encryption-functions', 'function_aes_decrypt'],
'AES_ENCRYPT': ['encryption-functions', 'function_aes_encrypt'],
'AND': ['logical-operators', 'operator_and'],
'ASCII': ['string-functions', 'function_ascii'],
'ASIN': ['mathematical-functions', 'function_asin'],
'ATAN2': ['mathematical-functions', 'function_atan2'],
'ATAN': ['mathematical-functions', 'function_atan'],
'AVG': ['group-by-functions', 'function_avg'],
'BENCHMARK': ['information-functions', 'function_benchmark'],
'BIN': ['string-functions', 'function_bin'],
'BINARY': ['cast-functions', 'operator_binary'],
'BIT_AND': ['group-by-functions', 'function_bit_and'],
'BIT_COUNT': ['bit-functions', 'function_bit_count'],
'BIT_LENGTH': ['string-functions', 'function_bit_length'],
'BIT_OR': ['group-by-functions', 'function_bit_or'],
'BIT_XOR': ['group-by-functions', 'function_bit_xor'],
'CASE': ['control-flow-functions', 'operator_case'],
'CAST': ['cast-functions', 'function_cast'],
'CEIL': ['mathematical-functions', 'function_ceil'],
'CEILING': ['mathematical-functions', 'function_ceiling'],
'CHAR_LENGTH': ['string-functions', 'function_char_length'],
'CHAR': ['string-functions', 'function_char'],
'CHARACTER_LENGTH': ['string-functions', 'function_character_length'],
'CHARSET': ['information-functions', 'function_charset'],
'COALESCE': ['comparison-operators', 'function_coalesce'],
'COERCIBILITY': ['information-functions', 'function_coercibility'],
'COLLATION': ['information-functions', 'function_collation'],
'COMPRESS': ['encryption-functions', 'function_compress'],
'CONCAT_WS': ['string-functions', 'function_concat_ws'],
'CONCAT': ['string-functions', 'function_concat'],
'CONNECTION_ID': ['information-functions', 'function_connection_id'],
'CONV': ['mathematical-functions', 'function_conv'],
'CONVERT_TZ': ['date-and-time-functions', 'function_convert_tz'],
'Convert': ['cast-functions', 'function_convert'],
'COS': ['mathematical-functions', 'function_cos'],
'COT': ['mathematical-functions', 'function_cot'],
'COUNT': ['group-by-functions', 'function_count'],
'CRC32': ['mathematical-functions', 'function_crc32'],
'CURDATE': ['date-and-time-functions', 'function_curdate'],
'CURRENT_DATE': ['date-and-time-functions', 'function_current_date'],
'CURRENT_TIME': ['date-and-time-functions', 'function_current_time'],
'CURRENT_TIMESTAMP': ['date-and-time-functions', 'function_current_timestamp'],
'CURRENT_USER': ['information-functions', 'function_current_user'],
'CURTIME': ['date-and-time-functions', 'function_curtime'],
'DATABASE': ['information-functions', 'function_database'],
'DATE_ADD': ['date-and-time-functions', 'function_date_add'],
'DATE_FORMAT': ['date-and-time-functions', 'function_date_format'],
'DATE_SUB': ['date-and-time-functions', 'function_date_sub'],
'DATE': ['date-and-time-functions', 'function_date'],
'DATEDIFF': ['date-and-time-functions', 'function_datediff'],
'DAY': ['date-and-time-functions', 'function_day'],
'DAYNAME': ['date-and-time-functions', 'function_dayname'],
'DAYOFMONTH': ['date-and-time-functions', 'function_dayofmonth'],
'DAYOFWEEK': ['date-and-time-functions', 'function_dayofweek'],
'DAYOFYEAR': ['date-and-time-functions', 'function_dayofyear'],
'DECLARE': ['declare', 'declare'],
'DECODE': ['encryption-functions', 'function_decode'],
'DEFAULT': ['miscellaneous-functions', 'function_default'],
'DEGREES': ['mathematical-functions', 'function_degrees'],
'DES_DECRYPT': ['encryption-functions', 'function_des_decrypt'],
'DES_ENCRYPT': ['encryption-functions', 'function_des_encrypt'],
'DIV': ['arithmetic-functions', 'operator_div'],
'ELT': ['string-functions', 'function_elt'],
'ENCODE': ['encryption-functions', 'function_encode'],
'ENCRYPT': ['encryption-functions', 'function_encrypt'],
'EXP': ['mathematical-functions', 'function_exp'],
'EXPORT_SET': ['string-functions', 'function_export_set'],
'EXTRACT': ['date-and-time-functions', 'function_extract'],
'ExtractValue': ['xml-functions', 'function_extractvalue'],
'FIELD': ['string-functions', 'function_field'],
'FIND_IN_SET': ['string-functions', 'function_find_in_set'],
'FLOOR': ['mathematical-functions', 'function_floor'],
'FORMAT': ['string-functions', 'function_format'],
'FOUND_ROWS': ['information-functions', 'function_found_rows'],
'FROM_DAYS': ['date-and-time-functions', 'function_from_days'],
'FROM_UNIXTIME': ['date-and-time-functions', 'function_from_unixtime'],
'GET_FORMAT': ['date-and-time-functions', 'function_get_format'],
'GET_LOCK': ['miscellaneous-functions', 'function_get_lock'],
'GREATEST': ['comparison-operators', 'function_greatest'],
'GROUP_CONCAT': ['group-by-functions', 'function_group_concat'],
'HEX': ['string-functions', 'function_hex'],
'HOUR': ['date-and-time-functions', 'function_hour'],
'IF': ['control-flow-functions', 'function_if'],
'IFNULL': ['control-flow-functions', 'function_ifnull'],
'IN': ['comparison-operators', 'function_in'],
'INET_ATON': ['miscellaneous-functions', 'function_inet_aton'],
'INET_NTOA': ['miscellaneous-functions', 'function_inet_ntoa'],
'INSTR': ['string-functions', 'function_instr'],
'INTERVAL': ['comparison-operators', 'function_interval'],
'IS_FREE_LOCK': ['miscellaneous-functions', 'function_is_free_lock'],
'IS_USED_LOCK': ['miscellaneous-functions', 'function_is_used_lock'],
'IS': ['comparison-operators', 'operator_is'],
'ISNULL': ['comparison-operators', 'function_isnull'],
'LAST_DAY': ['date-and-time-functions', 'function_last_day'],
'LAST_INSERT_ID': ['information-functions', 'function_last_insert_id'],
'LCASE': ['string-functions', 'function_lcase'],
'LEAST': ['comparison-operators', 'function_least'],
'LEFT': ['string-functions', 'function_left'],
'LENGTH': ['string-functions', 'function_length'],
'LIKE': ['string-comparison-functions', 'operator_like'],
'LN': ['mathematical-functions', 'function_ln'],
'LOAD_FILE': ['string-functions', 'function_load_file'],
'LOCALTIME': ['date-and-time-functions', 'function_localtime'],
'LOCALTIMESTAMP': ['date-and-time-functions', 'function_localtimestamp'],
'LOCATE': ['string-functions', 'function_locate'],
'LOG10': ['mathematical-functions', 'function_log10'],
'LOG2': ['mathematical-functions', 'function_log2'],
'LOG': ['mathematical-functions', 'function_log'],
'LOWER': ['string-functions', 'function_lower'],
'LPAD': ['string-functions', 'function_lpad'],
'LTRIM': ['string-functions', 'function_ltrim'],
'MAKE_SET': ['string-functions', 'function_make_set'],
'MAKEDATE': ['date-and-time-functions', 'function_makedate'],
'MAKETIME': ['date-and-time-functions', 'function_maketime'],
'MASTER_POS_WAIT': ['miscellaneous-functions', 'function_master_pos_wait'],
'MATCH': ['fulltext-search', 'function_match'],
'MAX': ['group-by-functions', 'function_max'],
'MD5': ['encryption-functions', 'function_md5'],
'MICROSECOND': ['date-and-time-functions', 'function_microsecond'],
'MID': ['string-functions', 'function_mid'],
'MIN': ['group-by-functions', 'function_min'],
'MINUTE': ['date-and-time-functions', 'function_minute'],
'MOD': ['mathematical-functions', 'function_mod'],
'MONTH': ['date-and-time-functions', 'function_month'],
'MONTHNAME': ['date-and-time-functions', 'function_monthname'],
'NAME_CONST': ['miscellaneous-functions', 'function_name_const'],
'NOT': ['logical-operators', 'operator_not'],
'NOW': ['date-and-time-functions', 'function_now'],
'NULLIF': ['control-flow-functions', 'function_nullif'],
'OCT': ['mathematical-functions', 'function_oct'],
'OCTET_LENGTH': ['string-functions', 'function_octet_length'],
'OLD_PASSWORD': ['encryption-functions', 'function_old_password'],
'OR': ['logical-operators', 'operator_or'],
'ORD': ['string-functions', 'function_ord'],
'PASSWORD': ['encryption-functions', 'function_password'],
'PERIOD_ADD': ['date-and-time-functions', 'function_period_add'],
'PERIOD_DIFF': ['date-and-time-functions', 'function_period_diff'],
'PI': ['mathematical-functions', 'function_pi'],
'POSITION': ['string-functions', 'function_position'],
'POW': ['mathematical-functions', 'function_pow'],
'POWER': ['mathematical-functions', 'function_power'],
'QUARTER': ['date-and-time-functions', 'function_quarter'],
'QUOTE': ['string-functions', 'function_quote'],
'RADIANS': ['mathematical-functions', 'function_radians'],
'RAND': ['mathematical-functions', 'function_rand'],
'REGEXP': ['regexp', 'operator_regexp'],
'RELEASE_LOCK': ['miscellaneous-functions', 'function_release_lock'],
'REPEAT': ['string-functions', 'function_repeat'],
'REVERSE': ['string-functions', 'function_reverse'],
'RIGHT': ['string-functions', 'function_right'],
'RLIKE': ['regexp', 'operator_rlike'],
'ROUND': ['mathematical-functions', 'function_round'],
'ROW_COUNT': ['information-functions', 'function_row_count'],
'RPAD': ['string-functions', 'function_rpad'],
'RTRIM': ['string-functions', 'function_rtrim'],
'SCHEMA': ['information-functions', 'function_schema'],
'SEC_TO_TIME': ['date-and-time-functions', 'function_sec_to_time'],
'SECOND': ['date-and-time-functions', 'function_second'],
'SESSION_USER': ['information-functions', 'function_session_user'],
'SHA': ['encryption-functions', 'function_sha1'],
'SHA1': ['encryption-functions', 'function_sha1'],
'SIGN': ['mathematical-functions', 'function_sign'],
'SIN': ['mathematical-functions', 'function_sin'],
'SLEEP': ['miscellaneous-functions', 'function_sleep'],
'SOUNDEX': ['string-functions', 'function_soundex'],
'SPACE': ['string-functions', 'function_space'],
'SQRT': ['mathematical-functions', 'function_sqrt'],
'STD': ['group-by-functions', 'function_std'],
'STDDEV_POP': ['group-by-functions', 'function_stddev_pop'],
'STDDEV_SAMP': ['group-by-functions', 'function_stddev_samp'],
'STDDEV': ['group-by-functions', 'function_stddev'],
'STR_TO_DATE': ['date-and-time-functions', 'function_str_to_date'],
'STRCMP': ['string-comparison-functions', 'function_strcmp'],
'SUBDATE': ['date-and-time-functions', 'function_subdate'],
'SUBSTR': ['string-functions', 'function_substr'],
'SUBSTRING_INDEX': ['string-functions', 'function_substring_index'],
'SUBSTRING': ['string-functions', 'function_substring'],
'SUBTIME': ['date-and-time-functions', 'function_subtime'],
'SUM': ['group-by-functions', 'function_sum'],
'SYSDATE': ['date-and-time-functions', 'function_sysdate'],
'SYSTEM_USER': ['information-functions', 'function_system_user'],
'TAN': ['mathematical-functions', 'function_tan'],
'TIME_FORMAT': ['date-and-time-functions', 'function_time_format'],
'TIME_TO_SEC': ['date-and-time-functions', 'function_time_to_sec'],
'TIME': ['date-and-time-functions', 'function_time'],
'TIMEDIFF': ['date-and-time-functions', 'function_timediff'],
'TIMESTAMP': ['date-and-time-functions', 'function_timestamp'],
'TIMESTAMPADD': ['date-and-time-functions', 'function_timestampadd'],
'TIMESTAMPDIFF': ['date-and-time-functions', 'function_timestampdiff'],
'TO_DAYS': ['date-and-time-functions', 'function_to_days'],
'TRIM': ['string-functions', 'function_trim'],
'TRUNCATE': ['mathematical-functions', 'function_truncate'],
'UCASE': ['string-functions', 'function_ucase'],
'UNCOMPRESS': ['encryption-functions', 'function_uncompress'],
'UNCOMPRESSED_LENGTH': ['encryption-functions', 'function_uncompressed_length'],
'UNHEX': ['string-functions', 'function_unhex'],
'UNIX_TIMESTAMP': ['date-and-time-functions', 'function_unix_timestamp'],
'UpdateXML': ['xml-functions', 'function_updatexml'],
'UPPER': ['string-functions', 'function_upper'],
'USER': ['information-functions', 'function_user'],
'UTC_DATE': ['date-and-time-functions', 'function_utc_date'],
'UTC_TIME': ['date-and-time-functions', 'function_utc_time'],
'UTC_TIMESTAMP': ['date-and-time-functions', 'function_utc_timestamp'],
'UUID_SHORT': ['miscellaneous-functions', 'function_uuid_short'],
'UUID': ['miscellaneous-functions', 'function_uuid'],
'VALUES': ['miscellaneous-functions', 'function_values'],
'VAR_POP': ['group-by-functions', 'function_var_pop'],
'VAR_SAMP': ['group-by-functions', 'function_var_samp'],
'VARIANCE': ['group-by-functions', 'function_variance'],
'VERSION': ['information-functions', 'function_version'],
'WEEK': ['date-and-time-functions', 'function_week'],
'WEEKDAY': ['date-and-time-functions', 'function_weekday'],
'WEEKOFYEAR': ['date-and-time-functions', 'function_weekofyear'],
'XOR': ['logical-operators', 'operator_xor'],
'YEAR': ['date-and-time-functions', 'function_year'],
'YEARWEEK': ['date-and-time-functions', 'function_yearweek'],
'SOUNDS_LIKE': ['string-functions', 'operator_sounds-like'],
'IS_NOT_NULL': ['comparison-operators', 'operator_is-not-null'],
'IS_NOT': ['comparison-operators', 'operator_is-not'],
'IS_NULL': ['comparison-operators', 'operator_is-null'],
'NOT_LIKE': ['string-comparison-functions', 'operator_not-like'],
'NOT_REGEXP': ['regexp', 'operator_not-regexp'],
'COUNT_DISTINCT': ['group-by-functions', 'function_count-distinct'],
'NOT_IN': ['comparison-operators', 'function_not-in']
};
// eslint-disable-next-line no-unused-vars
var mysqlDocBuiltin = {
'TINYINT': ['numeric-types'],
'SMALLINT': ['numeric-types'],
'MEDIUMINT': ['numeric-types'],
'INT': ['numeric-types'],
'BIGINT': ['numeric-types'],
'DECIMAL': ['numeric-types'],
'FLOAT': ['numeric-types'],
'DOUBLE': ['numeric-types'],
'REAL': ['numeric-types'],
'BIT': ['numeric-types'],
'BOOLEAN': ['numeric-types'],
'SERIAL': ['numeric-types'],
'DATE': ['date-and-time-types'],
'DATETIME': ['date-and-time-types'],
'TIMESTAMP': ['date-and-time-types'],
'TIME': ['date-and-time-types'],
'YEAR': ['date-and-time-types'],
'CHAR': ['string-types'],
'VARCHAR': ['string-types'],
'TINYTEXT': ['string-types'],
'TEXT': ['string-types'],
'MEDIUMTEXT': ['string-types'],
'LONGTEXT': ['string-types'],
'BINARY': ['string-types'],
'VARBINARY': ['string-types'],
'TINYBLOB': ['string-types'],
'MEDIUMBLOB': ['string-types'],
'BLOB': ['string-types'],
'LONGBLOB': ['string-types'],
'ENUM': ['string-types'],
'SET': ['string-types']
};

View File

@ -1,392 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
/**
* Class to handle PMA Drag and Drop Import
* feature
*/
var DragDropImport = {
/**
* @var int, count of total uploads in this view
*/
uploadCount: 0,
/**
* @var int, count of live uploads
*/
liveUploadCount: 0,
/**
* @var string array, allowed extensions
*/
allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
/**
* @var string array, allowed extensions for compressed files
*/
allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
/**
* @var obj array to store message returned by import_status.php
*/
importStatus: [],
/**
* Checks if any dropped file has valid extension or not
*
* @param file filename
*
* @return string, extension for valid extension, '' otherwise
*/
getExtension: function (file) {
var arr = file.split('.');
var ext = arr[arr.length - 1];
// check if compressed
if (jQuery.inArray(ext.toLowerCase(),
DragDropImport.allowedCompressedExtensions) !== -1) {
ext = arr[arr.length - 2];
}
// Now check for extension
if (jQuery.inArray(ext.toLowerCase(),
DragDropImport.allowedExtensions) !== -1) {
return ext;
}
return '';
},
/**
* Shows upload progress for different sql uploads
*
* @param: hash (string), hash for specific file upload
* @param: percent (float), file upload percentage
*
* @return void
*/
setProgress: function (hash, percent) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.children('progress').val(percent);
},
/**
* Function to upload the file asynchronously
*
* @param formData FormData object for a specific file
* @param hash hash of the current file upload
*
* @return void
*/
sendFileToServer: function (formData, hash) {
var uploadURL = './import.php'; // Upload URL
var jqXHR = $.ajax({
xhr: function () {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// Set progress
DragDropImport.setProgress(hash, percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: 'POST',
contentType:false,
processData: false,
cache: false,
data: formData,
success: function (data) {
DragDropImport.importFinished(hash, false, data.success);
if (!data.success) {
DragDropImport.importStatus[DragDropImport.importStatus.length] = {
hash: hash,
message: data.error
};
}
}
});
// -- provide link to cancel the upload
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize').html('<span hash="' +
hash + '" class="pma_drop_file_status" task="cancel">' +
Messages.dropImportMessageCancel + '</span>');
// -- add event listener to this link to abort upload operation
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.on('click', function () {
if ($(this).attr('task') === 'cancel') {
jqXHR.abort();
$(this).html('<span>' + Messages.dropImportMessageAborted + '</span>');
DragDropImport.importFinished(hash, true, false);
} else if ($(this).children('span').html() ===
Messages.dropImportMessageFailed) {
// -- view information
var $this = $(this);
$.each(DragDropImport.importStatus,
function (key, value) {
if (value.hash === hash) {
$('.pma_drop_result:visible').remove();
var filename = $this.parent('span').attr('data-filename');
$('body').append('<div class="pma_drop_result"><h2>' +
Messages.dropImportImportResultHeader + ' - ' +
filename + '<span class="close">x</span></h2>' + value.message + '</div>');
$('.pma_drop_result').draggable(); // to make this dialog draggable
}
});
}
});
},
/**
* Triggered when an object is dragged into the PMA UI
*
* @param event obj
*
* @return void
*/
dragEnter : function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
if (CommonParams.get('db') === '') {
$('.pma_drop_handler').html(Messages.dropImportSelectDB);
} else {
$('.pma_drop_handler').html(Messages.dropImportDropFiles);
}
$('.pma_drop_handler').fadeIn();
},
/**
* Check if dragged element contains Files
*
* @param event the event object
*
* @return bool
*/
hasFiles: function (event) {
return !(typeof event.originalEvent.dataTransfer.types === 'undefined' ||
$.inArray('Files', event.originalEvent.dataTransfer.types) < 0 ||
$.inArray(
'application/x-moz-nativeimage',
event.originalEvent.dataTransfer.types
) >= 0);
},
/**
* Triggered when dragged file is being dragged over PMA UI
*
* @param event obj
*
* @return void
*/
dragOver: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
$('.pma_drop_handler').fadeIn();
},
/**
* Triggered when dragged objects are left
*
* @param event obj
*
* @return void
*/
dragLeave: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
var $dropHandler = $('.pma_drop_handler');
$dropHandler.clearQueue().stop();
$dropHandler.fadeOut();
$dropHandler.html(Messages.dropImportDropFiles);
},
/**
* Called when upload has finished
*
* @param string, unique hash for a certain upload
* @param bool, true if upload was aborted
* @param bool, status of sql upload, as sent by server
*
* @return void
*/
importFinished: function (hash, aborted, status) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.children('progress').hide();
var icon = 'icon ic_s_success';
// -- provide link to view upload status
if (!aborted) {
if (status) {
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.html('<span>' + Messages.dropImportMessageSuccess + '</a>');
} else {
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.html('<span class="underline">' + Messages.dropImportMessageFailed +
'</a>');
icon = 'icon ic_s_error';
}
} else {
icon = 'icon ic_s_notice';
}
$('.pma_sql_import_status div li[data-hash="' + hash +
'"] span.filesize span.pma_drop_file_status')
.attr('task', 'info');
// Set icon
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.prepend('<img src="./themes/dot.gif" title="finished" class="' +
icon + '"> ');
// Decrease liveUploadCount by one
$('.pma_import_count').html(--DragDropImport.liveUploadCount);
if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
},
/**
* Triggered when dragged objects are dropped to UI
* From this function, the AJAX Upload operation is initiated
*
* @param event object
*
* @return void
*/
drop: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
var dbname = CommonParams.get('db');
var server = CommonParams.get('server');
// if no database is selected -- no
if (dbname !== '') {
var files = event.originalEvent.dataTransfer.files;
if (!files || files.length === 0) {
// No files actually transferred
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
return;
}
$('.pma_sql_import_status').slideDown();
for (var i = 0; i < files.length; i++) {
var ext = (DragDropImport.getExtension(files[i].name));
var hash = AJAX.hash(++DragDropImport.uploadCount);
var $sqlImportStatusDiv = $('.pma_sql_import_status div');
$sqlImportStatusDiv.append('<li data-hash="' + hash + '">' +
((ext !== '') ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') +
Functions.escapeHtml(files[i].name) + '<span class="filesize" data-filename="' +
Functions.escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) +
' kb</span></li>');
// scroll the UI to bottom
$sqlImportStatusDiv.scrollTop(
$sqlImportStatusDiv.scrollTop() + 50
); // 50 hardcoded for now
if (ext !== '') {
// Increment liveUploadCount by one
$('.pma_import_count').html(++DragDropImport.liveUploadCount);
$('.pma_sql_import_status h2 .close').fadeOut();
$('.pma_sql_import_status div li[data-hash="' + hash + '"]')
.append('<br><progress max="100" value="2"></progress>');
// uploading
var fd = new FormData();
fd.append('import_file', files[i]);
fd.append('noplugin', Math.random().toString(36).substring(2, 12));
fd.append('db', dbname);
fd.append('server', server);
fd.append('token', CommonParams.get('token'));
fd.append('import_type', 'database');
// todo: method to find the value below
fd.append('MAX_FILE_SIZE', '4194304');
// todo: method to find the value below
fd.append('charset_of_file','utf-8');
// todo: method to find the value below
fd.append('allow_interrupt', 'yes');
fd.append('skip_queries', '0');
fd.append('format',ext);
fd.append('sql_compatibility','NONE');
fd.append('sql_no_auto_value_on_zero','something');
fd.append('ajax_request','true');
fd.append('hash', hash);
// init uploading
DragDropImport.sendFileToServer(fd, hash);
} else if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
}
}
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
}
};
/**
* Called when some user drags, dragover, leave
* a file to the PMA UI
* @param object Event data
* @return void
*/
$(document).on('dragenter', DragDropImport.dragEnter);
$(document).on('dragover', DragDropImport.dragOver);
$(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave);
// when file is dropped to PMA UI
$(document).on('drop', 'body', DragDropImport.drop);
// minimizing-maximising the sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
if ($(this).attr('toggle') === 'off') {
$('.pma_sql_import_status div').css('height','270px');
$(this).attr('toggle','on');
$(this).html('-'); // to minimize
} else {
$('.pma_sql_import_status div').css('height','0px');
$(this).attr('toggle','off');
$(this).html('+'); // to maximise
}
});
// closing sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .close', function () {
$('.pma_sql_import_status').fadeOut(function () {
$('.pma_sql_import_status div').html('');
DragDropImport.importStatus = []; // clear the message array
});
});
// Closing the import result box
$(document).on('click', '.pma_drop_result h2 .close', function () {
$(this).parent('h2').parent('div').remove();
});

View File

@ -1,327 +0,0 @@
/* vim: set expandtab sw=4 ts=4 sts=4: */
/* global TraceKit */ // js/vendor/tracekit.js
/**
* general function, usually for data manipulation pages
*
*/
var ErrorReport = {
/**
* @var object stores the last exception info
*/
lastException: null,
/**
* handles thrown error exceptions based on user preferences
*
* @return void
*/
errorHandler: function (exception) {
// issue: 14359
if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) {
return;
}
if (exception.name === null || typeof(exception.name) === 'undefined') {
exception.name = ErrorReport.extractExceptionName(exception);
}
ErrorReport.lastException = exception;
$.post('error_report.php', {
'ajax_request': true,
'server': CommonParams.get('server'),
'get_settings': true,
'exception_type': 'js'
}, function (data) {
if (data.success !== true) {
Functions.ajaxShowMessage(data.error, false);
return;
}
if (data.report_setting === 'ask') {
ErrorReport.showErrorNotification();
} else if (data.report_setting === 'always') {
var reportData = ErrorReport.getReportData(exception);
var postData = $.extend(reportData, {
'send_error_report': true,
'automatic': true
});
$.post('error_report.php', postData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, false);
}
});
}
});
},
/**
* Shows the modal dialog previewing the report
*
* @param exception object error report info
*
* @return void
*/
showReportDialog: function (exception) {
var reportData = ErrorReport.getReportData(exception);
/* Remove the hidden dialogs if there are*/
if ($('#error_report_dialog').length !== 0) {
$('#error_report_dialog').remove();
}
var $div = $('<div id="error_report_dialog"></div>');
$div.css('z-index', '1000');
var buttonOptions = {};
buttonOptions[Messages.strSendErrorReport] = function () {
var $dialog = $(this);
var postData = $.extend(reportData, {
'send_error_report': true,
'description': $('#report_description').val(),
'always_send': $('#always_send_checkbox')[0].checked
});
$.post('error_report.php', postData, function (data) {
$dialog.dialog('close');
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, 3000);
}
});
};
buttonOptions[Messages.strCancel] = function () {
$(this).dialog('close');
};
$.post('error_report.php', reportData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
// Show dialog if the request was successful
$div
.append(data.message)
.dialog({
title: Messages.strSubmitErrorReport,
width: 650,
modal: true,
buttons: buttonOptions,
close: function () {
$(this).remove();
}
});
}
});
},
/**
* Shows the small notification that asks for user permission
*
* @return void
*/
showErrorNotification: function () {
ErrorReport.removeErrorNotification();
var $div = $(
'<div style="position:fixed;bottom:0;left:0;right:0;margin:0;' +
'z-index:1000" class="error" id="error_notification"></div>'
).append(
Functions.getImage('s_error') + Messages.strErrorOccurred
);
var $buttons = $('<div class="floatright"></div>');
var buttonHtml = '<button class="btn btn-primary" id="show_error_report">';
buttonHtml += Messages.strShowReportDetails;
buttonHtml += '</button>';
buttonHtml += '<a id="change_error_settings">';
buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings);
buttonHtml += '</a>';
buttonHtml += '<a href="#" id="ignore_error">';
buttonHtml += Functions.getImage('b_close', Messages.strIgnore);
buttonHtml += '</a>';
$buttons.html(buttonHtml);
$div.append($buttons);
$div.appendTo(document.body);
$(document).on('click', '#change_error_settings', ErrorReport.redirectToSettings);
$(document).on('click', '#show_error_report', ErrorReport.createReportDialog);
$(document).on('click', '#ignore_error', ErrorReport.removeErrorNotification);
},
/**
* Removes the notification if it was displayed before
*
* @return void
*/
removeErrorNotification: function (e) {
if (e) {
// don't remove the hash fragment by navigating to #
e.preventDefault();
}
$('#error_notification').fadeOut(function () {
$(this).remove();
});
},
/**
* Extracts Exception name from message if it exists
*
* @return String
*/
extractExceptionName: function (exception) {
if (exception.message === null || typeof(exception.message) === 'undefined') {
return '';
}
var reg = /([a-zA-Z]+):/;
var regexResult = reg.exec(exception.message);
if (regexResult && regexResult.length === 2) {
return regexResult[1];
}
return '';
},
/**
* Shows the modal dialog previewing the report
*
* @return void
*/
createReportDialog: function () {
ErrorReport.removeErrorNotification();
ErrorReport.showReportDialog(ErrorReport.lastException);
},
/**
* Redirects to the settings page containing error report
* preferences
*
* @return void
*/
redirectToSettings: function () {
window.location.href = 'prefs_forms.php';
},
/**
* Returns the report data to send to the server
*
* @param exception object exception info
*
* @return object
*/
getReportData: function (exception) {
if (exception && exception.stack && exception.stack.length) {
for (var i = 0; i < exception.stack.length; i++) {
var stack = exception.stack[i];
if (stack.context && stack.context.length) {
for (var j = 0; j < stack.context.length; j++) {
if (stack.context[j].length > 80) {
stack.context[j] = stack.context[j].substring(-1, 75) + '//...';
}
}
}
}
}
var reportData = {
'server': CommonParams.get('server'),
'ajax_request': true,
'exception': exception,
'url': window.location.href,
'exception_type': 'js'
};
if (AJAX.scriptHandler.scripts.length > 0) {
reportData.scripts = AJAX.scriptHandler.scripts.map(
function (script) {
return script;
}
);
}
return reportData;
},
/**
* Wraps all global functions that start with PMA_
*
* @return void
*/
wrapGlobalFunctions: function () {
for (var key in window) {
if (key.indexOf('PMA_') === 0) {
var global = window[key];
if (typeof(global) === 'function') {
window[key] = ErrorReport.wrapFunction(global);
}
}
}
},
/**
* Wraps given function in error reporting code and returns wrapped function
*
* @param func function to be wrapped
*
* @return function
*/
wrapFunction: function (func) {
if (!func.wrapped) {
var newFunc = function () {
try {
return func.apply(this, arguments);
} catch (x) {
TraceKit.report(x);
}
};
newFunc.wrapped = true;
// Set guid of wrapped function same as original function, so it can be removed
// See bug#4146 (problem with jquery draggable and sortable)
newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++;
return newFunc;
} else {
return func;
}
},
/**
* Automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
wrapAjaxOnloadCallback: function () {
var oldOnload = AJAX.registerOnload;
AJAX.registerOnload = function (file, func) {
var wrappedFunction = ErrorReport.wrapFunction(func);
oldOnload.call(this, file, wrappedFunction);
};
},
/**
* Automatically wraps the callback in $.fn.on
*
* @return void
*/
wrapJqueryOnCallback: function () {
var oldOn = $.fn.on;
$.fn.on = function () {
for (var i = 1; i <= 3; i++) {
if (typeof(arguments[i]) === 'function') {
arguments[i] = ErrorReport.wrapFunction(arguments[i]);
break;
}
}
return oldOn.apply(this, arguments);
};
},
/**
* Wraps all global functions that start with PMA_
* also automatically wraps the callback in AJAX.registerOnload
*
* @return void
*/
setUpErrorReporting: function () {
ErrorReport.wrapGlobalFunctions();
ErrorReport.wrapAjaxOnloadCallback();
ErrorReport.wrapJqueryOnCallback();
}
};
AJAX.registerOnload('error_report.js', function () {
TraceKit.report.subscribe(ErrorReport.errorHandler);
ErrorReport.setUpErrorReporting();
ErrorReport.wrapGlobalFunctions();
});

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More