Compare commits

..

220 Commits

Author SHA1 Message Date
Michal Čihař
e5f1555e1b Merge tag 'RELEASE_4_0_10_14' into MAINT_4_0_10
Released 4.0.10.14
2017-12-16 13:06:41 +01:00
Tejisav Singh Brar
79f0afbd33 Fixed tracking report: cannot delete a statement (#13567)
Signed-off-by: Tejisav Singh Brar <tejisav@gmail.com>
2017-08-06 07:42:13 -04:00
Isaac Bennetch
9a9a6ab709 Prepare for 4.0.10.20
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-03-28 20:54:38 -04:00
Isaac Bennetch
83ea1f5e4f Add ChangeLog entries
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-03-28 20:53:12 -04:00
Michal Čihař
b6ca92cc75 Truncate only long passwords
This avoids problems with certain PHP versions returning false when
first parameter to substr is ''.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-03-27 16:23:01 +02:00
Michal Čihař
1f859b1b15 Merge pull request #13098 from schoonc/fix-search-new-php-gettext
Fix database search with newer php-gettext
2017-03-20 16:38:13 +01:00
Michal Čihař
ebb97a3960 Remove no longer working test
We no longer directly process value from cookie here, so the test can no
longer work.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-03-20 16:37:04 +01:00
Сорокин Александр
f9a74deeb6 Fix database search with newer php-gettext
Backport from 4.6.6 (see #12881)

Signed-off-by: Сорокин Александр <ale10059@yandex.ru>
2017-03-18 14:21:36 +03:00
Isaac Bennetch
3d8b97b255 ChangeLog for 4.0.10.19
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2017-01-23 12:59:50 -05:00
Michal Čihař
567b27487e Prepare changelog for 4.0.10.19
Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-21 16:42:07 +01:00
Michal Čihař
4b5f3f9a12 Merge changes from php-gettext 1.0.12
This ensures that parameter to select_string is numeric, avoiding code
injection through it.

Our code is not vulnerable as we do not pass user supplied values to
this function, this fix is included only to be closer to upstream.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-17 13:34:53 +01:00
Michal Čihař
88cc11ab13 Disable setup if configuration already exists
The setup allows to figure out quite a lot about system and network, so
it's safer to block access to it once phpMyAdmin has been configured.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-07 11:00:16 +01:00
Michal Čihař
801485a7f4 Remove setup download/load/delete features
This removes risk of third party manipulating with the configuration as
there was race condition between editing and using the file.

Downloading the file should not be big hassle and this really makes the
whole setup a bit simpler.

Signed-off-by: Michal Čihař <michal@cihar.com>
2017-01-07 10:59:39 +01:00
Michal Čihař
f8ad5bd759 Do not allow arbitrary connection in replication setup without AllowArbitraryServer
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-21 11:07:00 +01:00
Michal Čihař
8a0816266c Do not provide fallback to cookie for font size
* This should be already handled by Config class
* Injecting cookie value to CSS could be security risk

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:26:51 +01:00
Michal Čihař
00607e6041 Whitespace cleanup
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:19:12 +01:00
Michal Čihař
3d230b6ab7 Avoid infinite recursion on goto
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 11:18:51 +01:00
Michal Čihař
7fe97a1f3c Avoid using REQUEST_URI in form action
It's really not necessary here and might cause redirection issues.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 10:51:48 +01:00
Michal Čihař
afe84645f2 Quote table name for use in regexp
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-08 10:30:17 +01:00
Michal Čihař
69b4b5c7f5 Remove wrong changelog entry
This was not yet fixed.

Issue #12481

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-12-01 10:54:31 +01:00
Isaac Bennetch
8783113cec 4.0.10.18 release and ChangeLog
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-11-24 10:54:44 -05:00
Deven Bansod
6703597772 Handle multiple :p while sanitizing MySQL hosts
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-11-08 10:14:23 +05:30
Deven Bansod
337b38044d Manage new-lines and extra whitespaces properly
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-11 10:43:22 +05:30
Deven Bansod
54875fffc1 Manage new-lines and extra whitespaces properly
Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-11 10:35:47 +05:30
Michal Čihař
be5196ba44 Merge branch 'MAINT_4_0_10-security' of github.com:phpmyadmin/phpmyadmin-security into MAINT_4_0_10-security 2016-10-04 13:18:42 +02:00
Michal Čihař
5e108a340f Correctly parse string length when checking serialized data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-10-04 13:17:07 +02:00
Deven Bansod
773f126c89 Don't assume the default arg_separator in URL
Respect the value for arg_separator.input too.

Signed-off-by: Deven Bansod <devenbansod.bits@gmail.com>
2016-10-02 10:43:40 +05:30
Michal Čihař
63b7f6c0a9 Use hash_equals when comparing IPv6 allow rules
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 15:09:29 +02:00
Michal Čihař
af7c589391 Stricter URL validation
- do not use empty() as empty('0') is true
- do not lowercase the strings, use them as they are
- lowercase all domains in our codebase
- do not allow to specify port

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 15:02:44 +02:00
Michal Čihař
0c3dfd186c Fix possible DOS on too big skip value
- loop only as long as long we have data to skip
- convert skip parameter to integer

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-09-02 13:42:15 +02:00
Michal Čihař
d37abc38da Do not show warning about short blowfish_secret if none is set
With empty blowfish_secret user would always get both warnings...

Fixes #12485

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-24 12:04:45 +02:00
Michal Čihař
67700620db Limit maximal number of rows in QBE
User would be lost in them anyway by that count and it prevents DOS.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 16:55:48 +02:00
Michal Čihař
b2605ebba6 Fix hash validation
- use copy of hash to avoid race condition
- stricter regex to match whole string

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:25:21 +02:00
Michal Čihař
096856c70c Stricter validation of NavigationLogoLink
It now has to be URL including scheme. Otherwise it's not really
possible to validate it for being just http/https.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:18:21 +02:00
Michal Čihař
c2f7a898dd Store copy of hash instead of working on live object
This avoids possible race conditions when doing the checks.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 11:05:56 +02:00
Michal Čihař
f2add98bd9 Strip path even if openbasedir restrictions apply
This really should not be the case here as what we get here is code
executed by PHP, so it should have already passed openbasedir
restrictions.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 10:14:01 +02:00
Michal Čihař
6117ad5cef Use hash_equals for checking username
This makes the comparison happen in constant time and makes it
impossible to use it to guess stored usernames.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:39:22 +02:00
Michal Čihař
58245cb1cc Use hash_equals for comparing username in allow/deny rules
The comparison should happen in constant time to avoid possible leak of
usernames in rules.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:15:34 +02:00
Michal Čihař
285e5623b6 Strip null bytes from MySQL username
In old PHP versions this could lead to allow/deny rules bypass.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-08-18 09:10:55 +02:00
Isaac Bennetch
5ba96c8804 Release 4.0.10.17
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-08-16 16:33:47 -04:00
Michal Čihař
12db0baeae Move hostname sanitization to correct place
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-29 14:10:07 +02:00
Michal Čihař
2922cb7c70 Do not try to wrap output in case response handling is disabled
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:53:37 +02:00
Michal Čihař
533ffa4942 Add login and token validation to version_check
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:53:31 +02:00
Michal Čihař
126321da37 Escape string when showing confirmation message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-28 10:31:30 +02:00
Michal Čihař
b0e66715ba Do not allow to set too long password
We do not accept password longer than 256 chars, so do not accept it on
password change as well.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 17:03:00 +02:00
Michal Čihař
262aa8ec73 Fix password change with cookie auth
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 17:02:13 +02:00
Michal Čihař
47d00af08a Move generator scripts out of the code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 16:38:30 +02:00
Michal Čihař
eec14404a7 Remove option to show phpinfo() ($cfg['ShowPhpInfo'])
This is really more a PHP debugging feature than anything related to
phpMyAdmin. If user wants to debug, it's as simple a creating file with
one line of php code.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-26 11:03:53 +02:00
Michal Čihař
ac703223e9 Ensure GIS point coordinates are numeric
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 10:24:35 +02:00
Michal Čihař
4d15f6b131 Fix random invocation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 09:05:12 +02:00
Michal Čihař
d03954bf9c Enable LOAD DATA LOCAL INFILE only when needed
There is no need to have this feature allowed for normal SQL queries, it
can lead to leaking sensitive files from the web server. It's enough to
enable it only in LDI import plugin, where we control what queries are
executed.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-23 08:59:02 +02:00
Michal Čihař
f261abbdf9 Remove no longer used code
It was used by old charts code to download charts.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 16:46:32 +02:00
Michal Čihař
5a28b63f9c Limit maximal numver of fields to 4096
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 16:00:23 +02:00
Michal Čihař
ae8693db68 Backport cookie encryption from 4.6 branch
- Use hash_hmac for MAC rather than plain SHA1
- Use different secret for MAC than encryption
- Merge pmaServer and pmaPass cookies
- Document 32 chars length for blowfish_secret

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 14:40:02 +02:00
Michal Čihař
85e1d6ec80 Send standard set of HTTP headers on redirect
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 12:22:53 +02:00
Michal Čihař
378c3820bf Sanitize filename on SHP import
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 11:49:35 +02:00
Michal Čihař
6f8eb0993d Delete temporary file before reporting error
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-22 11:31:09 +02:00
Michal Čihař
e8c5cab3c1 Improve URL filtering in url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-18 16:41:04 +02:00
Michal Čihař
714818f3ad Use https to access phpmyadmin.net
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-18 16:20:34 +02:00
Michal Čihař
ab26a8fe97 Fix exporting multiline comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 12:13:28 +02:00
Michal Čihař
0f87b73ae2 HML encode embedded JSON data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 11:31:55 +02:00
Michal Čihař
04156efeb0 Ensure widht and height are integers
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:53:51 +02:00
Michal Čihař
31546255f3 Ensure widht and height are integers
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:51:53 +02:00
Michal Čihař
09a427b288 Escape HTML markup in transformation wrapper
...in case content type is html.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:34:19 +02:00
Michal Čihař
8f3ee9f9db Do not use empty MIME type
This will turn on content sniffing in browser leading to unwanted
results.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 10:27:43 +02:00
Michal Čihař
56e1350118 Properly handle newlines in SQL comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:58:14 +02:00
Michal Čihař
7f7a8ac467 Do not try to create non existing classes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:48:21 +02:00
Michal Čihař
ff88cdbed2 Validate image scaling dimensions
Ensure we pass only integers and they are not too big.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-13 09:39:30 +02:00
Michal Čihař
8ac57b1281 Correctly escape MySQL username in queries
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 17:35:56 +02:00
Michal Čihař
fec9b98a22 Ensure page number is integer
Even if somebody decides to change configuration storage structure.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:49:15 +02:00
Michal Čihař
a3953f88ef Escape suggested database name
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:40:36 +02:00
Michal Čihař
80c93025a7 Validate serialized data before unserializing
We need only strings, integers or arrays, so there is no need to
unserialize strings containing any complex types.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 16:25:20 +02:00
Michal Čihař
8e0918cc41 Sanitize MySQL host name before connecting
It can contain p: prefix which we don't want to honor.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 15:10:59 +02:00
Michal Čihař
bdc7436c77 Prefer curl over file_get_contents
Curl is better in SSL certificate verification.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:32:32 +02:00
Michal Čihař
14fd275811 Use iframe sandbox for rendering HTML in transformation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:13:14 +02:00
Michal Čihař
c8297b4718 Use phpseclib's Crypt module to generate encryption keys
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 14:02:26 +02:00
Michal Čihař
ab05803a42 Do not allow symlinks in UploadDir
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:47:35 +02:00
Michal Čihař
41684ff1a1 Hide session error messages to avoid FPD
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:37:19 +02:00
Michal Čihař
e9a4de70a7 Escape HTML in Mediawiki comments
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 12:29:35 +02:00
Michal Čihař
0a4cdc25f1 Use _blank target instead of invalid _new
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 11:20:16 +02:00
Michal Čihař
63a5fdaa21 Add rel="noopener noreferrer" to all target="_blank" links
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 10:59:38 +02:00
Michal Čihař
a416cbe6c7 Use whitelist rather than blacklist for URL filtering
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-12 10:36:33 +02:00
Madhura Jayaratne
6cbbcdb719 Fix XSS in server_replication.php
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-07-12 12:05:07 +10:00
Michal Čihař
dc25189741 Fix syntax error in older PHP versions
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 09:36:56 +02:00
Michal Čihař
ee6557a689 Remove debugging code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 09:31:55 +02:00
Michal Čihař
ec2bd5d84c Remove Swekey support
It is buggy and their servers are no longer working.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 08:57:21 +02:00
Michal Čihař
4440790902 Make proxy IP parsing aware of multiple proxies
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-11 08:22:32 +02:00
Isaac Bennetch
eb2c702ab2 Add Secure and HttpOnly flags for session cookie setup in examples
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-07-10 22:30:49 -04:00
Michal Čihař
a9005b20bc Properly escape MySQL status variables
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-10 18:06:25 +02:00
Michal Čihař
cf2e0afdb7 Use https for wiki links
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-09 09:10:57 +02:00
Michal Čihař
95b7b7d6dd Improve cookie encryption
- use MAC to validate content before decryption
- create unique IV for every cookie

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-07-08 17:54:25 +02:00
Michal Čihař
59e0f3dee4 Properly escape generated XML export
Many fields could contain XML markup, so we need to ensure the generated
XML is valid.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:59:44 +02:00
Michal Čihař
34a1cebf76 Generate valid PHP code even when table/database name contains PHP markup
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:26:29 +02:00
Michal Čihař
c6cfb58834 Avoid possible path traversal using MySQL username
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 10:04:46 +02:00
Michal Čihař
e46fdb8e5e Sent CSP headers for phpinfo
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-30 09:51:38 +02:00
Michal Čihař
01673e94dd Fix type conversion for numeric values
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-24 12:53:39 +02:00
Isaac Bennetch
83416df64f Release 4.0.10.16
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-06-23 00:01:11 -04:00
Isaac Bennetch
c3d22bee08 Changelog entries for security release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-06-22 13:29:21 -04:00
Michal Čihař
b04150e30e Do not allow javascript: links in transformation
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 13:26:03 +02:00
Michal Čihař
b974b56781 Fixed rendering of chart of columns with HTML inside
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 13:10:37 +02:00
Michal Čihař
9b6f64b8b9 Properly escape zoom search column type
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-22 11:11:47 +02:00
Michal Čihař
351019c074 Quote delimiter before using preg_replace
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 12:13:24 +02:00
Michal Čihař
8c336ba285 Update referrer <meta> to match current standards
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:46:51 +02:00
Michal Čihař
02971f754f Escape HTML when rendering AJAX error
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:06:42 +02:00
Michal Čihař
abfd97983a Escape attributes when showing images in javascript
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 10:03:40 +02:00
Michal Čihař
e13f9862ef Backport Content-Security-Policy from latest release
This way it will work well on current browsers.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 09:44:52 +02:00
Michal Čihař
32875196f9 Add referrer CSP and <meta> tag
This avoids leaking Referer header in modern browsers.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-20 09:38:52 +02:00
Michal Čihař
288efea5b4 Simplify and cleanup transformation plugins
Remove PMA_transformation_global_html_replace which makes the code only
more confusing.

Also add escaping to browse transformations.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 16:19:31 +02:00
Michal Čihař
f662d591c5 Escape binary log name
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:53:31 +02:00
Michal Čihař
975089b8c3 Properly escape translated string
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:48:05 +02:00
Michal Čihař
78f6c54f1b Add error handling to constructing openid message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:33:33 +02:00
Michal Čihař
5fefa51139 Escape error messages from OpenID
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:29:57 +02:00
Michal Čihař
c795a395ba Improve error handling in OpenID example
- properly check parameter types
- catch all exceptions (eg. network error)

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 14:26:05 +02:00
Michal Čihař
c93c82ee9c Fix typo in validator
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:59:03 +02:00
Michal Čihař
fa7a9b787b Improve error handling in setup in case config dir is not present
We do not show these options in UI, but the scripts should handle it
gracefully.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:58:53 +02:00
Michal Čihař
96c6a7c0a2 Validate input of validator
We can not trust the input here, so we can expect anything and deal with
missing parameters or invalid values.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 10:13:12 +02:00
Michal Čihař
e1eb5e8e89 Fix error reporting on invalid request data
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:52:12 +02:00
Michal Čihař
8451a7a5d2 Move request conversion to generic code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:35:02 +02:00
Michal Čihař
c9faf855a0 Properly convert POST parameters
We can get array instead of single parameter, so handle this gracefully.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-17 09:10:30 +02:00
Michal Čihař
6b52ae4d19 Adjust test expectations to match new code
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-16 08:55:39 +02:00
Michal Čihař
805225a28c Limit number of included scripts in get_scripts.js.php
This avoids potential DOS, the limit is same as we use for generating
the URLs.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 18:04:43 +02:00
Madhura Jayaratne
75724a361b Fix #11457 414 Request-URI Too Large
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 18:04:16 +02:00
Michal Čihař
bf7379771f Use javascript for redirection to https
The current approach is broken since whitelisting is active in url.php
and also allows potential bbcode injection.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-06-15 17:48:43 +02:00
Michal Čihař
ee10ed1306 Document changes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:37:33 +02:00
Michal Čihař
d26422eae5 Pass links from changelog through url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:31:27 +02:00
Michal Čihař
b2054a1834 Allow url.php to be used without valid token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:28:35 +02:00
Michal Čihař
82fc97b15e Pass external links from setup via url.php
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:23:36 +02:00
Michal Čihař
b19c426726 Extend url whitelist to match master
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:22:25 +02:00
Michal Čihař
27505e1c2d Use url.php even in the setup script
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-30 09:19:59 +02:00
Michal Čihař
6f413680b1 Backport URL redirection from later releases
- fixes token leak for browsers which do not change referer on
  Location header
- adds whitelist to avoid redirection to any domain

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-05-23 09:48:53 +02:00
Isaac Bennetch
b1cc43ee7f 4.0.10.15 release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-02-29 08:13:06 -05:00
Madhura Jayaratne
fe3be9f4b9 Fix XSS in zoom search
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-02-29 12:33:47 +11:00
Madhura Jayaratne
7ddce5e39a Fix XSS in User accounts page
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-02-29 11:24:04 +11:00
Michal Čihař
e795141fba Add changes for security issues
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 13:35:26 +01:00
Michal Čihař
25a632a9f4 Merge pull request #22 from phpmyadmin/json-response
Use correct headers for json data
2016-02-25 12:32:45 +01:00
Michal Čihař
155876b48f Merge pull request #20 from phpmyadmin/xss-host
Urlencode hostname
2016-02-25 11:57:24 +01:00
Michal Čihař
45ecc10d18 Avoid skipping the SSL certificate check in TCPDF
This code is never used in phpMyAdmin, but we fix it just to avoid
potential security reports.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 10:29:26 +01:00
Michal Čihař
0667ea8ac7 Use correct headers for json data
It was previously not marked as such what could potentially lead to
browsers doing some autodetection.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 10:23:23 +01:00
Michal Čihař
73c8245a3d Urlencode hostname
This can come from the HTTP header, so we need to be sure to sanitize
it.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 09:57:29 +01:00
Michal Čihař
b8f1e0f325 Escape SQL query for inline editing
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-02-25 09:13:09 +01:00
Isaac Bennetch
945c58b9d2 Release 4.0.10.14
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-29 09:49:22 -05:00
Isaac Bennetch
f166893777 Release 4.0.10.14
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-28 23:34:57 -05:00
Isaac Bennetch
8b3ac5f5e3 Correct release date
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-28 23:31:39 -05:00
Michal Čihař
04a20d5435 Fix syntax error in disabled test
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 15:10:10 +01:00
Michal Čihař
bf2fde282e Merge pull request #11893 from madhuracj/bug11891
Fix #11891 Error with PMA 4.0.10.13 with PHP 5.2
2016-01-28 15:04:19 +01:00
Michal Čihař
3f9c1680c0 Skip PDO test on PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 15:03:11 +01:00
Michal Čihař
f9b36a377a Use syntax compatible with older PHP versions
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:59:46 +01:00
Michal Čihař
d4447a53fa Include more verbose error message
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:57:27 +01:00
Michal Čihař
7ca28f105b Skip not supported test on PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:50:34 +01:00
Michal Čihař
1e5d12abcd Revert "Make test check compatible with PHP 5.2"
This reverts commit 6babab9874.
2016-01-28 14:46:34 +01:00
Michal Čihař
6babab9874 Make test check compatible with PHP 5.2
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:43:19 +01:00
Michal Čihař
9b5c64e14d Correctly place expected result
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:40:58 +01:00
Michal Čihař
ed9e2b474d Remove non working break
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:38:25 +01:00
Michal Čihař
c1377f30a2 Define missing queries in the dummy driver
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:33:37 +01:00
Michal Čihař
e167f5ade9 Make the test skip without pdo_mysql
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:30:05 +01:00
Michal Čihař
2cc9f56559 Remove mistakenly pasted filename
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:19:58 +01:00
Michal Čihař
00c64c6dde Skip tests if ReflectionClass::setAccessible is not available
This is the case on PHP 5.2.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:17:37 +01:00
Michal Čihař
16e2f464ff Try to run Travis own phpunit
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:12:37 +01:00
Michal Čihař
f1ceadaa46 Run php lint on all files
Also avoid trying to use composer on PHP 5.2, it simply doesn't work
there.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:11:40 +01:00
Michal Čihař
10dd46fca4 Use PHP 5.4 for running composer
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:04:28 +01:00
Michal Čihař
632380d3d9 Test with PHP 5.2 to ensure we don't again release something broken
Issue #11891

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 14:00:27 +01:00
Madhura Jayaratne
555e73f177 Fix #11891 Error with PMA 4.0.10.13 with PHP 5.2
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-28 22:08:02 +11:00
Michal Čihař
980ccb6ffb Use changelog from release notes
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 10:09:27 +01:00
Michal Čihař
28b5882b96 Document last release
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-28 09:30:00 +01:00
Isaac Bennetch
16136ea0ef Increment version for 4.0.10.13 release
Signed-off-by: Isaac Bennetch <bennetch@gmail.com>
2016-01-27 21:30:00 -05:00
Michal Čihař
5b79467245 Enable localization before redirect
This is needed in case of IIS which needs full HTML response.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-27 08:55:07 +01:00
Michal Čihař
25738352df Fallback to default collation connection
If user supplied wrong string we should gracefully fallback.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 15:05:42 +01:00
Michal Čihař
7056ca9458 Do not process subforms with PMA_MINIMUM_COMMON
In such case needed infrastructure is not loaded, so related code won't
work anyway.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:34:01 +01:00
Michal Čihař
215f4a8ebe Can not use PMA_fatalError when including fails
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:30:08 +01:00
Michal Čihař
8023340a25 Include common libraries in setup
We use PMA_fatalError which in turn needs Response and related objects.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 14:25:57 +01:00
Michal Čihař
fe62b69a5b Use hash_equals for comparing token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 13:00:50 +01:00
Madhura Jayaratne
27eb98faed Escape javascript variable content
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-26 22:21:24 +11:00
Michal Čihař
6fe54dfa00 Use phpseclib's Crypt::Random to generate CSRF token
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:51:12 +01:00
Michal Čihař
2369daa7f5 Use full alphabet to generate random passwords
Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:39:19 +01:00
Michal Čihař
6a96e67487 Use secure RNG if available
Recent browsers come with better RNG, so let's use it for generating
password instead of Math.random if available.

Signed-off-by: Michal Čihař <michal@cihar.com>
2016-01-26 09:39:09 +01:00
Madhura Jayaratne
0ce4fd2750 Fix XSS in DB_search.php
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-19 21:01:32 +11:00
Madhura Jayaratne
9f3488fc3a Fix XSS in zoom search
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-19 20:59:37 +11:00
Madhura Jayaratne
ac81596bfc [Security] Fix path disclosure, items 1.4.x, 1.5 and 1.6
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2016-01-15 08:12:48 +11:00
Marc Delisle
66149607b1 4.0.10.12 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-12-25 15:25:34 -05:00
Marc Delisle
f79d30dd98 [Security] Path disclosure, see PMASA-2015-6
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-12-25 15:24:18 -05:00
Marc Delisle
2694c36ef6 4.0.10.11 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-09-23 07:00:32 -04:00
Madhura Jayaratne
9730b16dd0 issue #11464 phpMyAdmin suggests upgrading to newer version not usable on that system
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-09-22 23:59:20 +10:00
Marc Delisle
d81165f345 4.0.10.10 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-05-13 11:06:36 -04:00
Madhura Jayaratne
e97e7fb0ea bug #4900 [security] Vulnerability allowing Man-in-the-middle attack
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-05-13 07:32:02 +05:30
Madhura Jayaratne
fea1d39fef bug #4899 [security] CSRF vulnerability in setup
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2015-05-12 19:56:53 +05:30
Marc Delisle
a395665715 4.0.10.9 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-03-04 10:34:18 -05:00
Marc Delisle
e1a68ad02c bug [security] Risk of BREACH attack
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-03-04 10:32:07 -05:00
Marc Delisle
5004dc4098 4.0.10.8 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-01-07 08:10:02 -05:00
Marc Delisle
1da7417fc2 ChangeLog entries
Signed-off-by: Marc Delisle <marc@infomarc.info>
2015-01-07 08:06:31 -05:00
Ian P. Christian
394bf9183c Support early versions of PHP5.2 (register_shutdown_function)
Signed-off-by: Ian P. Christian <ichristian@users.sf.net>
2015-01-07 08:03:09 -05:00
Ian P. Christian
9b7fbe29ce Recursive function too deep
Signed-off-by: Ian P. Christian <ichristian@users.sf.net>
2015-01-07 07:52:29 -05:00
Michal Čihař
26ce63dbde Cache composer cache
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:14:56 +01:00
Michal Čihař
853f7255c5 Create database for test
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:12:21 +01:00
Michal Čihař
9daeaff5f0 Use composer to install correct phpunit version
Signed-off-by: Michal Čihař <michal@cihar.com>
2014-12-04 13:09:26 +01:00
Marc Delisle
00828f9ccb 4.0.10.7 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-12-03 07:55:56 -05:00
Madhura Jayaratne
095729d812 bug #4611 [security] DOS attack with long passwords
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-12-01 20:49:45 +05:30
Marc Delisle
13a288d0da 4.0.10.6 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-11-20 10:09:42 -05:00
Madhura Jayaratne
c7685e5acd bug #4597 [security] XSS through pma_fontsize cookie
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-18 10:15:34 +05:30
Madhura Jayaratne
c5783321cd bug #4598 [security] XSS in multi submit
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-17 12:13:09 +05:30
Madhura Jayaratne
2e3f0b9457 bug #4594 [security] Path traversal in file inclusion of GIS factory
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-17 11:03:55 +05:30
Madhura Jayaratne
58cdd91fc8 bug #4579 [security] XSS vulnerability in zoom search page
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-04 16:20:15 +05:30
Madhura Jayaratne
42b64e12b5 bug #4578 XSS vulnerability in table print view
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-11-04 16:05:06 +05:30
Marc Delisle
d0f7dc7990 4.0.10.5 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-10-21 10:07:51 -04:00
Madhura Jayaratne
a150ea1df4 bug #4563 [security] XSS in monitor query analyzer
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-10-18 06:52:40 +05:30
Madhura Jayaratne
57594febab bug #4562 [security] XSS in debug SQL output
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-10-17 18:07:08 +05:30
Marc Delisle
5118938f10 4.0.10.4 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-10-01 07:20:09 -04:00
Marc Delisle
c6c77589a5 [security] XSS with malicious ENUM values
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-28 09:48:13 -04:00
Marc Delisle
ceb7d7e1b2 4.0.10.3 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-13 11:12:44 -04:00
Marc Delisle
ab0dba4533 bug #4530 [security] DOM based XSS that results to a CSRF that creates a ROOT account in certain conditions
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-09-12 08:22:14 -04:00
Marc Delisle
5e52612841 4.0.10.2 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-08-17 06:59:44 -04:00
Madhura Jayaratne
098caf93b6 bug #4517 [security] XSS in relation view
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-16 22:00:13 +05:30
Madhura Jayaratne
5cd9839467 Fix typo
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 20:00:45 +05:30
Madhura Jayaratne
03b92aa6e9 bug #4504 [security] Self-XSS in query charts
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 19:58:02 +05:30
Madhura Jayaratne
3668255202 bug #4503 [security] Self-XSSes in monitor
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 07:28:14 +05:30
Madhura Jayaratne
0433d463b6 bug #4502 [security] Self-XSS in enum value editor
Signed-off-by: Madhura Jayaratne <madhura.cj@gmail.com>
2014-08-06 07:20:52 +05:30
Madhura Jayaratne
285ed5b8d3 bug #4501 [security] XSS in table browse page 2014-08-06 07:16:17 +05:30
Marc Delisle
f86761326c 4.0.10.1 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 17:35:22 -04:00
Marc Delisle
a92753bd65 bug #4492 [security] XSS in AJAX confirmation messages
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 17:06:00 -04:00
Madhura Jayaratne
1b55924356 bug #4488 [security] XSS injection due to unescaped table name (triggers)
Signed-off-by: Marc Delisle <marc@infomarc.info>
2014-07-17 16:29:40 -04:00
Marc Delisle
82161a6c30 4.0.10 release
Signed-off-by: Marc Delisle <marc@infomarc.info>
2013-12-04 12:36:40 -05:00
4281 changed files with 1307329 additions and 2355705 deletions

View File

@ -1,11 +0,0 @@
# https://github.com/browserslist/browserslist#readme
>= 0.5%
last 2 major versions
not dead
Chrome >= 60
Firefox >= 60
Firefox ESR
iOS >= 12
Safari >= 12
not Explorer <= 11

View File

@ -1,24 +0,0 @@
# EditorConfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
indent_style = space
indent_size = 4
[{*.{sql,scss,css,twig,yml},package.json}]
indent_size = 2
[*.svg]
insert_final_newline = false
[tests/test_data/*]
insert_final_newline = false
[tests/unit/**/Fixtures/*.html]
insert_final_newline = false
trim_trailing_whitespace = false

View File

@ -1,4 +0,0 @@
public/js/
tmp/
vendor/
webpack.config.cjs

View File

@ -1,74 +0,0 @@
{
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:no-jquery/deprecated",
"plugin:compat/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [ "@typescript-eslint", "no-jquery" ],
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"env": {
"browser": true,
"es6": true
},
"rules": {
"array-bracket-spacing": "error",
"array-bracket-newline": ["error", { "multiline": true }],
"array-element-newline": ["error", "consistent"],
"brace-style": "error",
"camelcase": "error",
"comma-dangle": ["error", "only-multiline"],
"comma-style": ["error", "last"],
"curly": "error",
"dot-notation": "error",
"eol-last": "error",
"eqeqeq": "error",
"indent": ["error", 4],
"keyword-spacing": "error",
"lines-between-class-members": "error",
"new-cap": "error",
"no-array-constructor": "error",
"no-eval": "error",
"no-loop-func": "error",
"no-multiple-empty-lines": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-param-reassign": "error",
"no-prototype-builtins": "off",
"no-redeclare": ["error", { "builtinGlobals": false }],
"no-trailing-spaces": "error",
"no-underscore-dangle": "error",
"no-unneeded-ternary": "error",
"no-var": "off",
"object-curly-spacing": ["error", "always"],
"one-var": ["error", "never"],
"padded-blocks": ["error", "never"],
"padding-line-between-statements": [
"error",
{ "blankLine": "always", "prev": "block-like", "next": "*" },
{ "blankLine": "always", "prev": "multiline-expression", "next": "*" },
{ "blankLine": "always", "prev": "*", "next": "return" }
],
"prefer-const": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
"quotes": ["error", "single"],
"semi": "error",
"space-before-blocks": "error",
"space-before-function-paren": "error",
"space-in-parens": "error",
"space-infix-ops": "error",
"spaced-comment": ["error", "always"],
"wrap-iife": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-this-alias": "off"
}
}

34
.gitattributes vendored
View File

@ -1,34 +0,0 @@
*.php text diff=php
.gitattributes export-ignore
.gitignore export-ignore
.github export-ignore
.phpstorm.meta.php export-ignore
.scrutinizer.yml export-ignore
.jshintrc export-ignore
.stylelintrc.json export-ignore
.eslintrc.json export-ignore
.eslintignore export-ignore
.weblate export-ignore
codecov.yml export-ignore
infection.json5.dist export-ignore
phpcs.xml.dist export-ignore
phpstan.neon.dist export-ignore
phpstan-baseline.neon export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore
DCO export-ignore
.editorconfig export-ignore
# Exclude only the following files and not all files in tests/
# This is because some packaging teams need our test files but not the CI related files
tests/doctum-config.php export-ignore
tests/bootstrap-static.php export-ignore
tests/config.e2e.inc.php export-ignore
tests/phpstan-constants.php export-ignore
tests/*-local-server export-ignore
tests/*.conf export-ignore
tests/*.ini export-ignore
tests/ci-phplint export-ignore
.browserslistrc export-ignore
CODE_OF_CONDUCT.md export-ignore
CONTRIBUTING.md export-ignore

View File

@ -1,25 +0,0 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
build:
os: ubuntu-24.04
tools:
python: "3.12"
jobs:
post_create_environment:
- python -m pip install sphinx-rtd-theme
# Build documentation in the "doc/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# Fail on all warnings to avoid broken references
# fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
formats:
- pdf
- epub
- htmlzip

1
.github/FUNDING.yml vendored
View File

@ -1 +0,0 @@
custom: https://www.phpmyadmin.net/donate/

View File

@ -1,89 +0,0 @@
name: Bug report
description: Create a report to help us improve phpMyAdmin
title: "[Bug]: "
labels: ["Bug"]
body:
- type: textarea
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
placeholder: When ...
validations:
required: true
- type: textarea
id: how-to-reproduce
attributes:
label: How to Reproduce
description: Give us the steps to reproduce the bug on our side.
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
- type: textarea
id: expected
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
placeholder: I expected ...
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain the bug.
- type: dropdown
id: operating-systems
attributes:
label: Operating System
description: In which operating system this bug appears?
multiple: true
options:
- Linux
- macOS
- Windows
- type: input
id: web-server
attributes:
label: Web Server
placeholder: Apache/2.4.63
- type: dropdown
id: database-server
attributes:
label: Database Server
description: In which database server this bug appears?
multiple: true
options:
- MySQL
- MariaDB
- PerconaDB
- AuroraDB (by AWS)
- Other
- type: input
id: database-version
attributes:
label: Database version
placeholder: SELECT @@version;
- type: input
id: php-version
attributes:
label: PHP version
placeholder: 8.3.1
- type: input
id: phpmyadmin-version
attributes:
label: phpMyAdmin version
placeholder: 5.2.1
validations:
required: true
- type: input
id: browser
attributes:
label: browser
placeholder: Firefox v136.0.2
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add any other context about the bug here.

View File

@ -1,45 +0,0 @@
name: Feature request
description: Suggest an idea for phpMyAdmin
title: "[Feat]: "
labels: ["Enhancement"]
body:
- type: input
id: phpmyadmin-version
attributes:
label: phpMyAdmin version
placeholder: 5.2.1
validations:
required: true
- type: textarea
id: feat-description
attributes:
label: Describe the feature
description: Is your feature request related to a problem? Please describe.
placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
validations:
required: true
- type: textarea
id: solution-description
attributes:
label: Describe the solution
description: Describe the solution you'd like
placeholder: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives-description
attributes:
label: Describe the alternatives
description: Describe alternatives you've considered
placeholder: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add additional context here
placeholder: Add any other context or screenshots about the feature request here.
validations:
required: false

View File

@ -1,18 +0,0 @@
name: Security report
description: Disclose a security vulnerability responsibly by first reporting it to us privately
title: "[Security]: "
labels: ["Bug"]
body:
- type: textarea
id: description
attributes:
label: DON'T REPORT IN HERE
placeholder: |
Security problems should not be reported here.
See our security page: https://www.phpmyadmin.net/security/
Thanks for your help!
validations:
required: true

View File

@ -1,14 +0,0 @@
### Description
Please describe your pull request.
Fixes #
Before submitting pull request, please review the following checklist:
- [ ] Make sure you have read our [CONTRIBUTING.md](https://github.com/phpmyadmin/phpmyadmin/blob/master/CONTRIBUTING.md) document.
- [ ] Make sure you are making a pull request against the correct branch. For example, for bug fixes in a released version use the corresponding QA branch and for new features use the _master_ branch. If you have a doubt, you can ask as a comment in the bug report or on the mailing list.
- [ ] Every commit has proper `Signed-off-by` line as described in our [DCO](https://github.com/phpmyadmin/phpmyadmin/blob/master/DCO). This ensures that the work you're submitting is your own creation.
- [ ] Every commit has a descriptive commit message.
- [ ] Every commit is needed on its own, if you have just minor fixes to previous commits, you can squash them.
- [ ] Any new functionality is covered by tests.

View File

@ -1,85 +0,0 @@
name: Daily snapshots
on:
pull_request:
paths:
- '.github/workflows/daily-snapshots.yml'
- 'bin/**'
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
permissions:
contents: read
jobs:
generate-snapshots:
name: Generate ${{ matrix.version }} snapshots
runs-on: ubuntu-latest
if: (github.event_name == 'schedule' && github.repository == 'phpmyadmin/phpmyadmin') || (github.event_name != 'schedule')
strategy:
fail-fast: false
matrix:
include:
- { version: '5.2', branch: 'QA_5_2', php-version: '7.2', node-version: '12', python-version: '3.11' }
- { version: '6.0', branch: 'master', php-version: '8.2', node-version: '20', python-version: '3.11' }
steps:
- name: Check out code
uses: actions/checkout@v6
with:
ref: ${{ matrix.branch }}
- name: Install Gettext
run: sudo apt-get install -y gettext
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, iconv, mysqli, zip, gd
coverage: none
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Install Yarn modules
run: yarn install --non-interactive
- name: Install Sphinx for the documentation build
run: pip install 'Sphinx'
- name: Build the release
if: matrix.branch == 'master'
run: ./bin/internal/create-release.sh --daily ${{ matrix.version }}+snapshot ${{ matrix.branch }}
- name: Build the release
if: matrix.branch != 'master'
run: ./scripts/create-release.sh --daily ${{ matrix.version }}+snapshot ${{ matrix.branch }}
- name: Check release excludes
if: matrix.branch == 'master'
run: ./bin/internal/check-release-excludes.sh release/phpMyAdmin-${{ matrix.version }}+snapshot-all-languages.tar.gz
continue-on-error: true
- name: Check release excludes
if: matrix.branch != 'master'
run: ./scripts/check-release-excludes.sh release/phpMyAdmin-${{ matrix.version }}+snapshot-all-languages.tar.gz
continue-on-error: true
- name: Upload snapshots
uses: actions/upload-artifact@v6
with:
name: phpMyAdmin-${{ matrix.version }}-snapshots
path: release/*
retention-days: 1

View File

@ -1,76 +0,0 @@
name: Frontend analysis and tests
on:
push:
pull_request:
paths:
- 'resources/js/**'
- '**.s?css'
- 'tests/javascript/**'
- '.browserslistrc'
- '.eslint*'
- '*.cjs'
- 'package.json'
- 'tsconfig.json'
- 'yarn.lock'
permissions:
contents: read
jobs:
javascript-test:
name: Test JavaScript files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'yarn'
- name: Install modules
run: yarn install --non-interactive
- name: Run tests
run: yarn test
javascript-lint:
name: Lint JavaScript files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'yarn'
- name: Install modules
run: yarn install --non-interactive
- name: Lint JavaScript files
run: yarn run js-lint --quiet
css-lint:
name: Lint CSS files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'yarn'
- name: Install modules
run: yarn install --non-interactive
- name: Lint CSS files
run: yarn run css-lint

View File

@ -1,87 +0,0 @@
name: Lint and analyse php files
on:
push:
pull_request:
types: [opened, synchronize, reopened]
branches:
- master
- QA_**
permissions:
contents: read
jobs:
lint-php-files:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ["8.2"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
- name: Validate composer.json and composer.lock
run: composer validate --strict
- name: Install Composer dependencies
# Allow the previous check to fail but not abort
if: always()
uses: ramsey/composer-install@v3
with:
# Ignore zip for php-webdriver/webdriver
composer-options: "--ignore-platform-req=ext-zip"
- name: Cache coding-standard
# Allow the previous check to fail but not abort
if: always()
uses: actions/cache@v5
with:
path: .phpcs-cache
key: phpcs-cache
- name: Lint PHP files
# Allow the previous check to fail but not abort
if: always()
run: ./tests/ci-phplint
- name: Check coding-standard
# Allow the previous check to fail but not abort
if: always()
run: composer phpcs
- name: Check Twig templates
# Allow the previous check to fail but not abort
if: always()
run: composer run twig-lint
analyse-php:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ["8.2"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, iconv, mysqli, zip, gd, bz2
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Analyse files with PHPStan
run: composer phpstan -- --memory-limit 2G
- name: Analyse files with Psalm
# Allow the previous check to fail but not abort
if: always()
run: composer psalm -- --shepherd

View File

@ -1,26 +0,0 @@
name: Lint php documentation
on:
push:
pull_request:
types: [opened, synchronize, reopened]
branches:
- master
- QA_**
permissions:
contents: read
jobs:
lint-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Lint phpdoc blocks
uses: sudo-bot/action-doctum@v5
with:
config-file: tests/doctum-config.php
method: "parse"
cli-args: "--output-format=github --no-ansi --no-progress -v --ignore-parse-errors"

View File

@ -1,20 +0,0 @@
name: 'Lock threads'
on:
schedule:
- cron: '0 0 * * *'
permissions:
contents: read
jobs:
lock:
permissions:
issues: write # for dessant/lock-threads to lock issues
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
process-only: 'issues'
issue-inactive-days: 365

View File

@ -1,76 +0,0 @@
# https://docs.github.com/en/actions
name: Mutation tests
on:
push:
branches:
- master
paths:
- 'src/**.php'
- 'tests/unit/**.php'
pull_request:
branches:
- master
paths:
- 'src/**.php'
- 'tests/unit/**.php'
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
permissions:
contents: read
jobs:
infection:
name: Infection
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
php-version:
- "8.2"
operating-system:
- ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Checkout base ref code
if: github.event_name == 'pull_request'
uses: actions/checkout@v6
with:
ref: ${{ github.base_ref }}
- name: Install Gettext
run: sudo apt-get install -y gettext
- name: Generate mo files
run: ./bin/generate-mo --quiet
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: pcov
tools: composer:v2, infection:0.27.11
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Run Infection for changed files only
if: github.event_name == 'push' || github.event_name == 'pull_request'
run: |
if [ "$GITHUB_EVENT_NAME" = "push" ]; then \
INFECTION_GIT_DIFF_BASE="origin/$GITHUB_REF_NAME^"; else \
INFECTION_GIT_DIFF_BASE="origin/$GITHUB_BASE_REF"; fi
infection --threads=max --git-diff-lines --git-diff-base="$INFECTION_GIT_DIFF_BASE" \
--logger-github --ignore-msi-with-no-mutations --only-covered --no-interaction --no-progress
- name: Run Infection for all files
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
env:
INFECTION_BADGE_API_KEY: ${{ secrets.INFECTION_BADGE_API_KEY }}
run: infection --threads=max --no-interaction --log-verbosity=none --logger-github=false

View File

@ -1,66 +0,0 @@
name: Check other tools and scripts
on:
push:
pull_request:
types: [opened, synchronize, reopened]
branches:
- master
- QA_**
permissions:
contents: read
jobs:
build-documentation:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Sphinx for the documentation build
run: |
sudo apt-get update
sudo apt-get install -y sphinx-doc python3-sphinx
- name: Build the documentation
run: make -C docs html SPHINXOPTS='-n -W -a'
build-release:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ["8.2"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install gettext
run: sudo apt-get install -y gettext
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, iconv, mysqli, zip, gd
tools: composer:v2
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'yarn'
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install Sphinx for the documentation build
run: pip install 'Sphinx'
- name: Build the release
run: ./bin/internal/create-release.sh --ci

View File

@ -1,27 +0,0 @@
name: ShellCheck
on:
push:
paths:
- 'bin/**'
pull_request:
paths:
- 'bin/**'
permissions:
contents: read
jobs:
shellcheck:
name: ShellCheck
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Run ShellCheck
uses: reviewdog/action-shellcheck@v1
with:
path: bin
check_all_files_with_shebangs: true
fail_on_error: true

View File

@ -1,24 +0,0 @@
name: "Manage stale PRs/issues"
permissions:
issues: write
on:
schedule:
- cron: "30 1 * * *"
jobs:
run-stale-check:
name: Check for stale PRs/issues
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/stale@v9
with:
days-before-stale: 15
days-before-close: -1
only-issue-labels: "Awaiting Author Updates"
close-issue-message: >
The phpMyAdmin team is awaiting an update on this issue.
Please check that all the questions have been answered.

View File

@ -1,152 +0,0 @@
name: "End-to-End tests"
on:
push:
pull_request:
types: [opened, synchronize, reopened]
branches:
- master
- QA_**
permissions:
contents: read
env:
php-version: "8.2"
node-version: "20"
jobs:
generate-matrix:
name: Generate the matrix of Selenium tests
if: "!contains(github.event.head_commit.message, '[ci selenium skip]')"
runs-on: ubuntu-latest
outputs:
tests: ${{ steps.tests-list.outputs.tests }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- id: tests-list
name: Send test names to outputs
run: |
set -euo pipefail
TEST_NAMES="[$(find $PWD/tests/end-to-end/ -type f -name '*Test.php' -print |sed -E "s,$PWD/tests/end-to-end/(.*)Test.php,{\"test-name\": \"\1\"}," | paste -sd ",")]"
echo "tests=$(printf "$TEST_NAMES")" >> $GITHUB_OUTPUT
selenium:
name: "Selenium"
if: "!contains(github.event.head_commit.message, '[ci selenium skip]')"
needs: generate-matrix
runs-on: "ubuntu-latest"
services:
database-server:
image: "mysql:5.7"
env:
MYSQL_ROOT_PASSWORD: testbench
ports:
- "3306:3306"
options: >-
--health-cmd="mysqladmin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
selenium-server:
image: selenium/standalone-chrome:4
volumes:
- /dev/shm:/dev/shm
options: >-
--health-cmd "/opt/bin/check-grid.sh"
env:
SCREEN_WIDTH: 1920
SCREEN_HEIGHT: 1080
ports:
- "4444:4444"
docker-host-bridge:
# Allow accessing localhost ports from docker containers.
# See https://github.com/qoomon/docker-host
image: qoomon/docker-host
options: >-
--name docker-host-bridge
--hostname docker-host-bridge
--add-host docker-host-bridge:127.0.0.1
--cap-add=NET_ADMIN
--cap-add=NET_RAW
--restart on-failure
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.generate-matrix.outputs.tests) }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install gettext
run: sudo apt-get update && sudo apt-get install -y gettext
- name: Generate mo files
run: ./bin/generate-mo --quiet
- name: Set up PHP ${{ env.php-version }}
uses: shivammathur/setup-php@v2
with:
coverage: "none"
php-version: ${{ env.php-version }}
extensions: :opcache, mbstring, iconv, mysqli, zip, gd, bz2
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: '${{ env.node-version }}'
cache: 'yarn'
- name: Install modules
run: yarn install --non-interactive --production
- name: Copy the config
run: cp tests/config.e2e.inc.php config.inc.php
- name: Start server
env:
CI_MODE: selenium
FPM_PATH: php-fpm${{ env.php-version }}
SKIP_STANDALONE: 1
run: |
sudo chown -R runner:docker /var/lib/nginx/
sudo chown -R runner:docker /var/log/nginx/
./tests/start-local-server
echo "SELENIUM_TEMPDIR=$(cat /tmp/last_temp_dir_phpMyAdminTests)" >> $GITHUB_OUTPUT
id: start-local-server
- name: Run Selenium tests
env:
CI_MODE: selenium
TESTSUITE_SELENIUM_BROWSER: chrome
TESTSUITE_USER: root
TESTSUITE_PASSWORD: testbench
# Port defined in tests/nginx.conf
TESTSUITE_URL: http://docker-host-bridge:8000
TESTSUITE_DATABASE_PREFIX: "selenium"
TESTSUITE_SELENIUM_HOST: "127.0.0.1"
TESTSUITE_SELENIUM_PORT: "4444"
run: ./vendor/bin/phpunit --testsuite end-to-end --no-logging --no-coverage --stop-on-skipped --testdox tests/end-to-end/${{ matrix.test-name }}Test.php
- name: Output logs and stop server
env:
CI_MODE: selenium
SELENIUM_TEMPDIR: ${{ steps.start-local-server.outputs.SELENIUM_TEMPDIR }}
if: ${{ success() || failure() }}
run: |
if [ -f "${SELENIUM_TEMPDIR}/php.log" ] ; then cat "${SELENIUM_TEMPDIR}/php.log" ; fi
if [ -f "${SELENIUM_TEMPDIR}/nginx-error.log" ] ; then cat "${SELENIUM_TEMPDIR}/nginx-error.log" ; fi
./tests/stop-local-server
- name: Upload screenshots
uses: actions/upload-artifact@v6
if: ${{ failure() }}
with:
name: selenium-screenshots-${{ strategy.job-index }}
path: ${{ github.workspace }}/build/selenium/**/*
retention-days: 3

View File

@ -1,188 +0,0 @@
name: Run tests
on:
push:
pull_request:
types: [opened, synchronize, reopened]
branches:
- master
- QA_**
permissions:
contents: read
jobs:
multi-arch-tests-php:
name: Test on PHP ${{ matrix.php-version }} (${{ matrix.arch }})
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
include:
- { php-version: '82', experimental: false, arch: 'amd64', exclude-phpunit-groups: '--exclude-group extension-iconv' }
- { php-version: '82', experimental: false, arch: 'arm64/v8', exclude-phpunit-groups: '--exclude-group extension-iconv' }
- { php-version: '82', experimental: false, arch: 'arm/v7', exclude-phpunit-groups: '--exclude-group extension-iconv --exclude-group 32bit-incompatible' }
- { php-version: '82', experimental: false, arch: 'i386', exclude-phpunit-groups: '--exclude-group extension-iconv --exclude-group 32bit-incompatible' }
- { php-version: '82', experimental: true, arch: 'ppc64le', exclude-phpunit-groups: '--exclude-group extension-iconv' }
- { php-version: '82', experimental: false, arch: 's390x', exclude-phpunit-groups: '--exclude-group extension-iconv --exclude-group 32bit-incompatible' }
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Write script
# tcpdf allowed memory exhausted needs the memory_limit workaround
# musl-locales and musl-locales-lang are needed to run some locale specific tests
# gettext is needed to run generate-mo
# git is needed to work around a version detection issue with composer, see: https://github.com/Roave/SecurityAdvisories/issues/76
# ctype for psalm
run: |
printf "set -exu && \
export V='%s' && \
apk add --update --no-cache \
php\$V-cli php\$V-mysqli php\$V-session php\$V-mbstring php\$V-ctype php\$V-sodium \
php\$V-iconv php\$V-xml php\$V-tokenizer php\$V-xmlwriter php\$V-simplexml \
php\$V-dom php\$V-json php\$V-bz2 php\$V-curl php\$V-gd php\$V-zip php\$V-bcmath \
musl-locales musl-locales-lang \
gettext composer git && \
composer config version "$(php -r "define('VERSION_SUFFIX', ''); require_once('src/Version.php'); echo \PhpMyAdmin\Version::VERSION;")" && \
composer install && \
./bin/generate-mo && \
php\$V -d memory_limit=512M ./vendor/bin/phpunit --no-logging --no-coverage --testsuite unit %s" \
"${{ matrix.php-version }}" "${{ matrix.exclude-phpunit-groups }}" > ./do-tests.sh
- name: Set up multi arch support
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Print arch
run: docker run --rm --platform linux/${{ matrix.arch }} alpine:3.19 uname -a
- name: Run tests on php ${{ matrix.php-version }}
run: docker run -v $PWD:/app --workdir /app --rm --platform linux/${{ matrix.arch }} alpine:3.19 sh /app/do-tests.sh
test-php:
name: Test on PHP ${{ matrix.php-version }}, ${{ matrix.composer-dependency }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.php-version == '8.5' }}
strategy:
matrix:
php-version: ['8.2', '8.3', '8.4']
os: [ubuntu-latest]
composer-dependency: [locked, highest]
php-extensions: ['mbstring, iconv, mysqli, zip, gd, bz2']
include:
- php-version: '8.5'
os: ubuntu-latest
composer-dependency: locked
composer-options: '--ignore-platform-req=php+'
php-extensions: 'mbstring, iconv, mysqli, zip, bz2'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
# Fetch some commits for Scrutinizer coverage upload
fetch-depth: 15
- name: Install gettext
run: sudo apt-get install -y gettext
- name: Generate mo files
run: ./bin/generate-mo --quiet
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ matrix.php-extensions }}
coverage: xdebug
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
with:
dependency-versions: ${{ matrix.composer-dependency }}
composer-options: ${{ matrix.composer-options }}
- name: Run PHP tests
run: composer run phpunit -- --testsuite unit --display-deprecations --display-notices --display-warnings --display-errors
- name: Send coverage
uses: codecov/codecov-action@v3
with:
flags: unit-${{ matrix.php-version }}-${{ matrix.os }}
name: phpunit-${{ matrix.php-version }}-${{ matrix.os }}
- name: Send coverage to Scrutinizer
uses: sudo-bot/action-scrutinizer@latest
# Do not run this step on forked versions of the main repository (example: contributor forks)
if: github.repository == 'phpmyadmin/phpmyadmin'
continue-on-error: true
with:
cli-args: "--format=php-clover build/logs/clover.xml --revision=${{ github.event.pull_request.head.sha || github.sha }}"
- name: Send coverage to Codacy
uses: codacy/codacy-coverage-reporter-action@v1
# Do not run this step on forked versions of the main repository (example: contributor forks)
if: github.repository == 'phpmyadmin/phpmyadmin'
# Upload can fail on forks or if the secret is missing
continue-on-error: true
with:
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
coverage-reports: build/logs/clover.xml
test-php-optional-extensions:
name: Test on PHP (+ ext-${{ matrix.extension }}) ${{ matrix.php-version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
php-version: ["8.2"]
os: [ubuntu-latest]
extension: ["dbase"]
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
# Fetch some commits for Scrutinizer coverage upload
fetch-depth: 15
- name: Install gettext
run: sudo apt-get install -y gettext
- name: Generate mo files
run: ./bin/generate-mo --quiet
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: ${{ matrix.extension }}, mbstring, iconv, mysqli, zip, gd
coverage: xdebug
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Run PHP tests
run: composer run phpunit -- --testsuite unit
- name: Send coverage
uses: codecov/codecov-action@v3
with:
flags: ${{ matrix.extension }}-extension
name: php-${{ matrix.php-version }}-${{ matrix.extension }}-enabled
- name: Send coverage to Scrutinizer
uses: sudo-bot/action-scrutinizer@latest
# Do not run this step on forked versions of the main repository (example: contributor forks)
if: github.repository == 'phpmyadmin/phpmyadmin'
continue-on-error: true
with:
cli-args: "--format=php-clover build/logs/clover.xml --revision=${{ github.event.pull_request.head.sha || github.sha }}"
- name: Send coverage to Codacy
uses: codacy/codacy-coverage-reporter-action@v1
# Do not run this step on forked versions of the main repository (example: contributor forks)
if: github.repository == 'phpmyadmin/phpmyadmin'
# Upload can fail on forks or if the secret is missing
continue-on-error: true
with:
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
coverage-reports: build/logs/clover.xml

View File

@ -1,50 +0,0 @@
name: Update translation files
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0'
permissions:
contents: read
jobs:
update-po:
permissions:
contents: write # for Git to git push
name: Update po files
runs-on: ubuntu-latest
# Source: https://github.community/t/do-not-run-cron-workflows-in-forks/17636/2?u=williamdes
if: (github.event_name == 'schedule' && github.repository == 'phpmyadmin/phpmyadmin') || (github.event_name != 'schedule')
strategy:
matrix:
php-version: ["8.2"]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Install Gettext
run: |
sudo apt-get install -y gettext
- name: Set up PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: composer:v2
- name: Install Composer dependencies
uses: ramsey/composer-install@v3
- name: Set up git config
run: |
git config user.name "phpMyAdmin bot"
git config user.email bot@phpmyadmin.net
- name: Update PO files
run: |
./bin/update-po
- name: Push changes
run: |
git push

81
.gitignore vendored
View File

@ -1,22 +1,16 @@
# Directory for creating releases
/release/
# Configuration files
/config.inc.php
/config.header.inc.php
/config.footer.inc.php
# Upload/save dirs
/upload/
/save/
/tmp/
# For setup script
/config/
# ctags
tags
# Editor files
phpmyadmin.wpj
.projectOptions
@ -27,88 +21,19 @@ phpmyadmin.wpj
.cache
.idea
.netbeans
.vscode
*.sw[op]
# Web server files
web.config
.htaccess
# Locales
/locale/
/resources/locale/
# Temporary files to generate locales for Twig
/twig-templates/
# Backups
*~
# Javascript sources
/sources/
# API documentation
/apidoc/
/docs/_build
/docs/doctrees
/docs/html
/docs/linkcheck/
/docs/locale
/docs/**/*.pyc
# Demo server
revision-info.php
# PHP_CodeSniffer
phpcs.xml
.phpcs-cache
# PHPUnit
.phpunit.result.cache
phpunit.xml
/tests/bootstrap.php
/tests/gis/*-actual.json
/tests/gis/*-actual.pdf
/tests/gis/*-actual.png
/tests/gis/*-actual.svg
/test/bootstrap.php
# Jenkins
/build/
# Netbeans ide stuff
/nbproject/
# Eclipse ide stuff
/.pydevproject
# Ant cache
cache.properties
# Composer
/vendor/
# NPM
/node_modules/
phpstan.neon
# Infection
infection.json5
/js/
/setup/
/themes/
# App
/app/cache/*
!/app/cache/.gitkeep
/app/language_stats_inc.php
# public
/public/js/*
!/public/js/.gitkeep
/public/setup/*.css
/public/setup/*.css.map
/public/themes/*
!/public/themes/dot.gif
!/public/themes/bootstrap/
!/public/themes/metro/
!/public/themes/original/
!/public/themes/pmahomme/
/public/themes/*/css/*.css
/public/themes/*/css/*.css.map

View File

@ -1,24 +0,0 @@
{
"esversion" : 6,
// Show more errors
"maxerr" : 1000,
// Globals
"jquery" : true,
// Stricter checking
"curly" : true,
"immed" : true,
"indent" : 4,
"latedef" : true,
"noarg" : true,
"noempty" : true,
"unused" : false,
"trailing" : true,
// Relaxing rules
"sub" : false,
"funcscope" : false,
"laxbreak" : false
}

View File

@ -1,5 +0,0 @@
<?php
namespace PHPSTORM_META {
override(\Psr\Container\ContainerInterface::get(0), map(['@']));
}

View File

@ -1,35 +0,0 @@
# scrutinizer-ci.com configuration
imports:
- javascript
- php
filter:
excluded_paths:
- build/
- node_modules/
- public/js/
- tmp/
- vendor/
- tests/doctum-config.php
checks:
javascript: true
php: true
tools:
external_code_coverage:
runs: 4 # php 7.x versions
timeout: 900 # 15 min
build:
image: default-jammy # New NodeJS versions require newer versions of glibc (noble was not available on 12/09/2025)
nodes:
analysis:
environment:
php: 8.2
node: 20 # Scrutinizer uses nvm
dependencies:
before:
- composer config --unset repositories.0
- composer install
- composer require tecnickcom/tcpdf pragmarx/google2fa-qrcode bacon/bacon-qr-code code-lts/u2f-php-server
tests:
override:
- php-scrutinizer-run
- phpcs-run

View File

@ -1,38 +0,0 @@
{
"extends": [
"stylelint-config-standard",
"stylelint-config-recommended-scss"
],
"rules": {
"selector-class-pattern": null,
"import-notation": null,
"selector-attribute-quotes": null,
"shorthand-property-no-redundant-values": null,
"function-url-quotes": null,
"selector-id-pattern": null,
"alpha-value-notation": null,
"color-function-notation": null,
"scss/no-global-function-names": null,
"scss/function-quote-no-quoted-strings-inside": null,
"property-no-vendor-prefix": null,
"declaration-block-no-redundant-longhand-properties": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null,
"at-rule-empty-line-before": ["always", {
"except": [
"blockless-after-same-name-blockless",
"first-nested"
],
"ignore": ["after-comment"],
"ignoreAtRules": ["else"]
}],
"value-keyword-case": [
"lower",
{
"ignoreProperties": [
"$font-family-monospace"
]
}
]
}
}

17
.travis.yml Normal file
View File

@ -0,0 +1,17 @@
language: php
php:
- "5.4"
- "5.3"
- "5.2"
sudo: false
before_script:
- export PATH=~/.composer/vendor/bin/:$PATH
- mysql -uroot -e "CREATE DATABASE test;"
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then composer install --dev --no-interaction ; fi
- ./scripts/generate-mo --quiet
script:
- if [ $TRAVIS_PHP_VERSION != "5.2" ] ; then ./vendor/bin/phpunit --configuration phpunit.xml.nocoverage ; else phpunit --configuration phpunit.xml.nocoverage ; fi
- git ls-files | grep '\.php$' | xargs -n1 php -l
cache:
directories:
- $HOME/.composer/cache/

View File

@ -1,3 +0,0 @@
[weblate]
url = https://hosted.weblate.org/api/
translation = phpmyadmin/master

View File

@ -1,102 +0,0 @@
# Changes in phpMyAdmin 6.0
All notable changes of the phpMyAdmin 6.0 release series are documented in this file following the [Keep a Changelog](https://keepachangelog.com/) format.
## [6.0.0] - YYYY-MM-DD
### Added
* [#17029](https://github.com/phpmyadmin/phpmyadmin/pull/17029): Enable Twig's `strict_variables` option in development environment
* [#17361](https://github.com/phpmyadmin/phpmyadmin/pull/17361): Add webpack bundler
* [#16500](https://github.com/phpmyadmin/phpmyadmin/pull/16500): Add paging to Routines page
* [#17753](https://github.com/phpmyadmin/phpmyadmin/pull/17753): Adding `inputmode` numeric to integer fields
* [#17765](https://github.com/phpmyadmin/phpmyadmin/pull/17765): Make search input field types match columns types (integer and float)
* [#17809](https://github.com/phpmyadmin/phpmyadmin/pull/17809): Adds support for SHA2 function
* [#18098](https://github.com/phpmyadmin/phpmyadmin/pull/18098): Added reCaptcha example for Cloudflare Turnstile
* [#18223](https://github.com/phpmyadmin/phpmyadmin/pull/18223): Add a configuration option to (dis)allow shared bookmarks: `$cfg['AllowSharedBookmarks'] = true;`
* [#18225](https://github.com/phpmyadmin/phpmyadmin/pull/18225): Make database and web server info separately configurable on `$cfg['ShowServerInfo']`
* [#18257](https://github.com/phpmyadmin/phpmyadmin/pull/18257): Add support for theme color modes
* [#17009](https://github.com/phpmyadmin/phpmyadmin/issues/17009): Implement the security header `Permissions-Policy`
* [#18349](https://github.com/phpmyadmin/phpmyadmin/pull/18349): Allow rollbacking SET queries
* [#18589](https://github.com/phpmyadmin/phpmyadmin/pull/18589): Add support for PSR-15 middleware
* [#18649](https://github.com/phpmyadmin/phpmyadmin/pull/18649): Add color mode toggle at the top navigation bar
* [#18668](https://github.com/phpmyadmin/phpmyadmin/pull/18668): Add number formatting to Total on Browse
* [#18747](https://github.com/phpmyadmin/phpmyadmin/pull/18747): Add `composer.lock` to version control
* [#18799](https://github.com/phpmyadmin/phpmyadmin/pull/18799): Add an user account menu button at top right
* [#18812](https://github.com/phpmyadmin/phpmyadmin/pull/18812): Add role based auth for MySQL 8.x and compatibles
* [#18916](https://github.com/phpmyadmin/phpmyadmin/pull/18916): Add format button to routine, event and trigger
* [#18537](https://github.com/phpmyadmin/phpmyadmin/pull/18537): Add copy to clipboard for export as text
* [#19287](https://github.com/phpmyadmin/phpmyadmin/pull/19287): Add optional support for binary data in database search
* [#19308](https://github.com/phpmyadmin/phpmyadmin/pull/19308): Added an option in the SQL box to "Format as a single line"
* [#19352](https://github.com/phpmyadmin/phpmyadmin/pull/19352): Added support for `BETWEEN` and `NOT BETWEEN` on the query generator
* [#19525](https://github.com/phpmyadmin/phpmyadmin/pull/19525): Add support for `INSERT IGNORE` into for non table imports
* [#19555](https://github.com/phpmyadmin/phpmyadmin/pull/19555): Add button for Copy Query in Query Generator
* [#19691](https://github.com/phpmyadmin/phpmyadmin/pull/19691): Show hostname on main page
* [#19751](https://github.com/phpmyadmin/phpmyadmin/pull/19751): Add Go button at the top of the insert row table
* [#19812](https://github.com/phpmyadmin/phpmyadmin/pull/19812): Add show create table shortcuts when viewing tables
### Changed
* [#17116](https://github.com/phpmyadmin/phpmyadmin/pull/17116): Replace Change Password dialog to modal
* [#17125](https://github.com/phpmyadmin/phpmyadmin/pull/17125): Replace Add Index dialog with modal
* [#17127](https://github.com/phpmyadmin/phpmyadmin/pull/17127): Replace Page settings dialog with modal
* [#17278](https://github.com/phpmyadmin/phpmyadmin/pull/17278): Improve NULL div design
* [#17280](https://github.com/phpmyadmin/phpmyadmin/pull/17280): Improve theme card heights
* [#17399](https://github.com/phpmyadmin/phpmyadmin/pull/17399): Handle connection errors with Exception instead of warnings
* [#17515](https://github.com/phpmyadmin/phpmyadmin/pull/17515): Bump js-cookie version from 2.2.1 to 3.0.1
* [#17561](https://github.com/phpmyadmin/phpmyadmin/pull/17561): Improve Change Password modal UI
* [#17676](https://github.com/phpmyadmin/phpmyadmin/pull/17676): Extract `url.php` entry point into a route
* [#17677](https://github.com/phpmyadmin/phpmyadmin/pull/17677): Extract `js/messages.php` entry point into `/messages` route
* [#17801](https://github.com/phpmyadmin/phpmyadmin/pull/17801): Export page of Settings is not responsive
* [#17842](https://github.com/phpmyadmin/phpmyadmin/issues/17842): Change js.cookie.js to js.cookie.min.js
* [#17632](https://github.com/phpmyadmin/phpmyadmin/issues/17632): Improve tab keypress to text fields on the login form
* [#18124](https://github.com/phpmyadmin/phpmyadmin/pull/18124): Invert svg gis viewer mouse wheel zoom direction
* [#18136](https://github.com/phpmyadmin/phpmyadmin/pull/18136): Force a full page reload for top menu links
* [#18145](https://github.com/phpmyadmin/phpmyadmin/pull/18145): Move public files to the public directory
* [#18300](https://github.com/phpmyadmin/phpmyadmin/pull/18300): Convert JavaScript files to TypeScript
* [#18310](https://github.com/phpmyadmin/phpmyadmin/pull/18310): Minimize form label column width in Routine, Event and Trigger modals
* [#18311](https://github.com/phpmyadmin/phpmyadmin/pull/18311): Only allow resizing textarea vertically
* [#18365](https://github.com/phpmyadmin/phpmyadmin/pull/18365): Change 'reCaptcha' text to 'Captcha'
* [#18439](https://github.com/phpmyadmin/phpmyadmin/pull/18439): Redesign the SQL message card
* [#18576](https://github.com/phpmyadmin/phpmyadmin/pull/18576): Wrap the Application::run() code with an HTTP handler
* [#18652](https://github.com/phpmyadmin/phpmyadmin/pull/18652): Disable AJAX for navigation sidebar links
* [#18658](https://github.com/phpmyadmin/phpmyadmin/pull/18658): Update OpenLayers
* [#18703](https://github.com/phpmyadmin/phpmyadmin/pull/18703): Limit label width in create-view table
* [#18512](https://github.com/phpmyadmin/phpmyadmin/issues/18512): New directory structure
* [#18994](https://github.com/phpmyadmin/phpmyadmin/pull/18994): Refactor name generation of file imports
* [#19110](https://github.com/phpmyadmin/phpmyadmin/pull/19110): Refactor recent/favorite tables buttons
* [#19182](https://github.com/phpmyadmin/phpmyadmin/pull/19182): Refactor GIS editor modal
* [#19214](https://github.com/phpmyadmin/phpmyadmin/pull/19214): Replace jqPlot library with Chart.js library
* [#19294](https://github.com/phpmyadmin/phpmyadmin/pull/19294): Simplify IN, NOT IN criteria text in Query Generator
* [#19327](https://github.com/phpmyadmin/phpmyadmin/pull/19327): Prevent IN / NOT IN duplicates in Query Generator
* [835fc27](https://github.com/phpmyadmin/phpmyadmin/commit/835fc2715d6f7330fa5ed680e8315b98eaa96cec): Redesign the User Groups form page
* [624126e](https://github.com/phpmyadmin/phpmyadmin/commit/624126edc8ea629ebbb222496bb4dad6cac9c6dd): Redesign the database and table privileges pages
* [#19398](https://github.com/phpmyadmin/phpmyadmin/issues/19398): Use `application/json` instead of `text/plain` for JSON export
* [#19496](https://github.com/phpmyadmin/phpmyadmin/pull/19496): Update CODE_OF_CONDUCT.md
* [#19513](https://github.com/phpmyadmin/phpmyadmin/pull/19513): Hide unwanted input depending on chosen Op type in Query Generator
* [#19536](https://github.com/phpmyadmin/phpmyadmin/pull/19536): Disable Search input on unary operators
* [#19542](https://github.com/phpmyadmin/phpmyadmin/pull/19542): Made Search operators `= ''`/`!= ''` more obvious
* [#19651](https://github.com/phpmyadmin/phpmyadmin/pull/19651): Stay the on same page when deleting a foreign key
* [#19712](https://github.com/phpmyadmin/phpmyadmin/pull/19712): Import OpenLayers and Bootstrap directly using Webpack
* [#19794](https://github.com/phpmyadmin/phpmyadmin/pull/19794): Use `jquery-ui-timepicker-addon.min.js` instead of `jquery-ui-timepicker-addon.js`
* [#19795](https://github.com/phpmyadmin/phpmyadmin/pull/19795): Use `additional-methods.min.js` instead of `additional-methods.js`
* [#19564](https://github.com/phpmyadmin/phpmyadmin/pull/19564): Update the table comment field to a textarea
* [#19947](https://github.com/phpmyadmin/phpmyadmin/pull/19947): Export ODS column headers by default
### Removed
* [#17351](https://github.com/phpmyadmin/phpmyadmin/pull/17351): Drop `stripslashes`
* [#17516](https://github.com/phpmyadmin/phpmyadmin/pull/17516): Remove `jquery-debounce-throttle` JavaScript dependency
* [#17752](https://github.com/phpmyadmin/phpmyadmin/pull/17752): Remove Sodium polyfill and require the PHP sodium extension
* [#18430](https://github.com/phpmyadmin/phpmyadmin/pull/18430): Remove Query-By-Example feature
* [#18547](https://github.com/phpmyadmin/phpmyadmin/pull/18547): Remove support for the Recode extension
* [#18587](https://github.com/phpmyadmin/phpmyadmin/pull/18587): Remove the `public/show_config_errors.php` file
* [#19128](https://github.com/phpmyadmin/phpmyadmin/pull/19128): Remove the `phpmyadmin/twig-i18n-extension` package
* [#19243](https://github.com/phpmyadmin/phpmyadmin/pull/19243): Bump minimum PHP version to 8.2.0
* [#19408](https://github.com/phpmyadmin/phpmyadmin/pull/19408): Removed the popup that warned about having an auto-saved query
* [#19409](https://github.com/phpmyadmin/phpmyadmin/pull/19409): Drop Protocol version
* [#19550](https://github.com/phpmyadmin/phpmyadmin/pull/19550): Replace jQuery UI's tooltip with Bootstrap's Tooltip
* [#19852](https://github.com/phpmyadmin/phpmyadmin/pull/19852): Bump Node version to 20
* [#19854](https://github.com/phpmyadmin/phpmyadmin/pull/19854): Drop support for BaconQrCode v2
[6.0.0]: https://github.com/phpmyadmin/phpmyadmin/compare/QA_5_2...master

View File

@ -1,132 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
info@phpmyadmin.net.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@ -1,52 +0,0 @@
# Contributing to phpMyAdmin
As an open-source project, phpMyAdmin welcomes contributions of many forms.
## Bug reporting
We appreciate your effort to improve phpMyAdmin by submitting a bug report. Before doing so, please check the following things:
1. Check whether the bug you face **hasn't been already reported**. Duplicate reports take us time, that we could be used to fix other bugs or make improvements.
2. Please specify the phpMyAdmin, server, PHP, MySQL, and browser information that may be helpful in resolving the issue, especially the exact **version numbers**.
3. If you got some error, please **describe what happened** and add an error message. Reports like "I get an error when I clicked on some link" are useless.
4. Provide easy steps to reproduce and if possible include your table structure (``SHOW CREATE TABLE `tbl_name`;``); if your problem implies specific data, attach a small export file for sample rows.
5. **Security problems** should not be reported here. See [our security page](https://www.phpmyadmin.net/security/).
Thanks for your help!
Please report [bugs on GitHub][1].
[1]: https://github.com/phpmyadmin/phpmyadmin/issues/new
## Patches submission
Patches are welcome as [pull requests on GitHub][2]. Please include a
Signed-off-by tag in the commit message (you can do this by passing [`--signoff`][4] parameter to Git).
When creating the commit on GitHub or using some other tool which does not have
direct support for this, it is the same as adding `Signed-off-by: Your name <email@example.com>`
as the last line of the commit message.
Example: `Signed-off-by: Jane Smith <jane.smith@example.org>`
Note that by submitting patches with the Signed-off-by tag, you are giving
permission to license the patch as GPLv2-or-later. See [the DCO file][3] for details.
[2]: https://github.com/phpmyadmin/phpmyadmin/pulls
[3]: https://github.com/phpmyadmin/phpmyadmin/blob/master/DCO
[4]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff
## Triage issues [![Open Source Helpers](https://www.codetriage.com/phpmyadmin/phpmyadmin/badges/users.svg)](https://www.codetriage.com/phpmyadmin/phpmyadmin)
You can triage issues, which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to phpMyAdmin on CodeTriage](https://www.codetriage.com/phpmyadmin/phpmyadmin).
## More information
You can find more information on our website:
https://www.phpmyadmin.net/contribute/

471
ChangeLog Normal file
View File

@ -0,0 +1,471 @@
phpMyAdmin - ChangeLog
======================
4.0.10.20 (2017-03-28)
- issue #12881 Fix database search when locale is not 'en'
- issue [security] Possible to bypass $cfg['Servers'][$i]['AllowNoPassword'], see PMASA-2017-08
4.0.10.19 (2017-01-23)
- issue [security] Multiple vulnerabilities in setup script, see PMASA-2016-44.
- issue [security] Open redirect, see PMASA-2017-1.
- issue [security] php-gettext code execution, see PMASA-2017-2.
- issue [security] DOS vulnerabiltiy in table editing, see PMASA-2017-3.
- issue [security] CSS injection in themes, see PMASA-2017-4.
- issue [security] SSRF in replication, see PMASA-2017-6.
- issue [security] DOS in replication status, see PMASA-2017-7.
4.0.10.18 (2016-11-24)
- issue #12485 Do not show warning about short blowfish_secret if none is set
- issue [security] Open redirection issue, see PMASA-2016-57
- issue [security] Unsafe generation of $cfg['blowfish_secret'], see PMASA-2016-58
- issue [security] phpMyAdmin's phpinfo functionality is removed, see PMASA-2016-59
- issue [security] AllowRoot and allow/deny rule bypass with specially-crafted username, see PMASA-2016-60
- issue [security] Username matching weaknesses with allow/deny rules, see PMASA-2016-61
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
- issue [security] Multiple cross-site scripting (XSS) weaknesses, see PMASA-2016-64
- issue [security] Multiple denial-of-service (DOS) vulnerabilities, see PMASA-2016-65
- issue [security] Possible to bypass white-list protection for URL redirection, see PMASA-2016-66
- issue [security] Multiple SQL injection vulnerabilities, see PMASA-2016-69
- issue [security] Incorrect serialized string parsing, see PMASA-2016-70
- issue [security] CSRF token not stripped from the URL, see PMASA-2016-71
4.0.10.17 (2016-08-16)
- issue [security] Weaknesses with cookie encryption, see PMASA-2016-29
- issue [security] Improve session cookie code for openid.php and signon.php example files
- issue [security] Full path disclosure in openid.php and signon.php example files
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-30
- issue [security] Unsafe generation of BlowfishSecret (when not supplied by the user)
- issue [security] Referrer leak when phpinfo is enabled
- issue [security] PHP code injection, see PMASA-2016-32
- issue [security] Full path disclosure, see PMASA-2016-33
- issue [security] SQL injection attack, see PMASA-2016-34
- issue [security] Local file exposure through LOAD DATA LOCAL INFILE, see PMASA-2016-35
- issue [security] Local file exposure through symlinks with UploadDir, see PMASA-2016-36
- issue [security] Path traversal with SaveDir and UploadDir, see PMASA-2016-37
- issue [security] Denial-of-service attack through transformation feature, see PMASA-2016-41
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-42
- issue [security] Verify data before unserializing, see PMASA-2016-43
- issue [security] Use HTTPS for wiki links
- issue Remove Swekey support
- issue [security] Denial-of-service attack with $cfg['AllowArbitraryServer'] = true and persistent connections, see PMASA-2016-45
- issue [security] Improve SSL certificate handling
- issue [security] Fix full path disclosure in debugging code
- issue [security] Possible circumvention of IP-based allow/deny rules with IPv6 and proxy server, see PMASA-2016-47
- issue [security] Detect if user is logged in, see PMASA-2016-48
- issue [security] Bypass URL redirection protection, see PMASA-2016-49
- issue [security] Referrer leak, see PMASA-2016-50
- issue [security] Reflected File Download, see PMASA-2016-51
- issue [security] ArbitraryServerRegexp bypass, see PMASA-2016-52
- issue [security] Denial-of-service attack by entering long password, see PMASA-2016-53
- issue [security] Remote code execution vulnerability when running as CGI, see PMASA-2016-54
- issue [security] Denial-of-service attack when PHP uses dbase extension, see PMASA-2016-55
- issue [security] Remove tode execution vulnerability when PHP uses dbase extension, see PMASA-2016-56
- issue [security] Denial-of-service attack by using for loops, see PMASA-2016-46
4.0.10.16 (2016-06-23)
- issue [security] User SQL queries can be revealed through URL GET parameters, see PMASA-2016-14
- issue [security] Limit list of sites which can be passwd through url.php.
- issue [security] BBCode injection in setup script, see PMASA-2016-17
- issue [security] DOS attack vulnerability, see PMASA-2016-22
- issue [security] Multiple full path disclosure vulnerabilities, see PMASA-2016-26
- issue [security] XSS attack when checking database privileges, see PMASA-2016-21
- issue [security] XSS attack when MySQL server is using a specific payload log_bin directive, see PMASA-2016-26
- issue [security] XSS vulnerabilities in Transformation feature, PMASA-2016-28
4.0.10.15 (2016-02-29)
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-11.
4.0.10.14 (2016-01-29)
- issue #11891 Error with PMA 4.0.10.13 with PHP 5.2
4.0.10.13 (2016-01-28)
- issue [Security] Multiple full path disclosure vulnerabilities, see PMASA-2016-1
- issue [Security] Unsafe generation of CSRF token, see PMASA-2016-2
- issue [Security] Multiple XSS vulnerabilities, see PMASA-2016-3
- issue [Security] Insecure password generation in JavaScript, see PMASA-2016-4
- issue [Security] Unsafe comparison of CSRF token, see PMASA-2016-5
4.0.10.12 (2015-12-25)
- issue [Security] Path disclosure, see PMASA-2015-6
4.0.10.11 (2015-09-23)
- issue #11464 phpMyAdmin suggests upgrading to newer version not usable on that system
4.0.10.10 (2015-05-13)
- bug #4899 [security] CSRF vulnerability in setup
- bug #4900 [security] Vulnerability allowing Man-in-the-middle attack
4.0.10.9 (2015-03-04)
- bug [security] Risk of BREACH attack, see PMASA-2015-1
4.0.10.8 (2015-01-07)
- rfe #1588 recursive function too deep - operator change suggestion
- rfe #1589 support early versions of PHP5.2 (register_shutdown_function)
4.0.10.7 (2014-12-03)
- bug #4611 [security] DOS attack with long passwords
4.0.10.6 (2014-11-20)
- bug #4578 [security] XSS vulnerability in table print view
- bug #4579 [security] XSS vulnerability in zoom search page
- bug #4594 [security] Path traversal in file inclusion of GIS factory
- bug #4598 [security] XSS in multi submit
- bug #4597 [security] XSS through pma_fontsize cookie
4.0.10.5 (2014-10-21)
- bug #4562 [security] XSS in debug SQL output
- bug #4563 [security] XSS in monitor query analyzer
4.0.10.4 (2014-10-01)
- bug #4544 [security] XSS vulnerabilities in table search and table structure pages
4.0.10.3 (2014-09-13)
- bug #4530 [security] DOM based XSS that results to a CSRF that creates a
ROOT account in certain conditions
4.0.10.2 (2014-08-17)
- bug #4501 [security] XSS in table browse page
- bug #4502 [security] Self-XSS in enum value editor
- bug #4503 [security] Self-XSSes in monitor
- bug #4504 [security] Self-XSS in query charts
- bug #4517 [security] XSS in relation view
4.0.10.1 (2014-07-17)
- bug #4488 [security] XSS injection due to unescaped table name (triggers)
- bug #4492 [security] XSS in AJAX confirmation messages
4.0.10.0 (2013-12-04)
- bug #4150 Clicking database name in query window opens a new tab
- bug #4141 Wrong page is shown after editing; also, do not show a modal
dialog for multi-row edit
- bug #3939 PHP NavigationTree error when paging through list
- bug #4075 Support A10 Networks load balancer
- bug #4083 row deleting isn't binlogs friendly
- bug #4163 Setup script does not recognize manually-configured server
- bug #4158 Events page says no privileges with ALL PRIVILEGES
4.0.9.0 (2013-11-04)
- bug #4104 Can't edit updatable view when searching
- bug #4108 Missing refresh by deleting databases
- bug #3995 Drizzle server charset notice
- bug #3911 Filtering database names includes empty groupings
- bug #3678 Does not display or manipulate bit(64) fields appropriately
- bug #4129 Unneeded navi panel refresh
- bug #4120 SSL redirects to port 80
- bug #4144 DROP DATABASE displays wrong database name
- bug #4059 Running delete query asks for confirmation but says it was already executed
- bug #4147 Accessibility: Images without Alt nor title attribute
4.0.8.0 (2013-10-06)
- bug #3988 Rename view is not working
- bug #4041 Interaction between linkified fields and grid editing
- bug #3975 Table grouping isn't implemented properly
- bug #4060 Browser tries to remember wrong password when creating new user
- bug #4002 Edit Index on big table doesn't show "Loading" or any message
- bug #4098 Default table tab is ignored
- bug #4099 Server/library difference warning: setting is ignored
- bug #4100 table tree group strategy
- bug #4102 ALTER TABLE ORDER BY and InnoDB
- bug #4103 Tracking report: cannot delete a statement
- bug #3996 Drizzle navigation doesn't expand
- bug #4074 GIS column editor: point not displayed
- bug #4109 Drizzle tables in navigation are shown as views
- bug #4095 NUL symbols added to the end of database dump file
- bug #4105 More disappears in table Structure
- bug #3992 Multi-row edit doesn't clear values when checking NULL
4.0.7.0 (2013-09-23)
- bug #3993 Sorting in database overview with statistics doesn't work
- bug Handle the situation where PHP_SELF is not set
- bug #4080 Overwrite existing file not obeyed
- bug #3929 Database-specific privileges are not copied when cloning user
- bug #3997 Error handling in case MySQL extension is missing
- bug #4089 Moving Columns will alter column definition
- bug #4091 Insert ignore option does not work
- bug #4090 Downloading BLOB downloads page template
- bug #4092 Clicking on table name in view of information_schema redirects to wrong page
- bug #4079 Copy Table Add AUTO_INCREMENT value checkbox not working
- bug #4088 MySQL server version at index.php incorrect w/ controlhost
- bug #4001 Import error: Class 'ImportOds' not found
- bug #3986 Missing DROP VIEW button
4.0.6.0 (2013-09-05)
- bug #4036 Call to undefined function mb_detect_encoding (clarify the doc)
- bug Missing hints when changing a column's structure
- bug #4048 Cannot select foreign value in Search
- bug #4025 gzip export is not actually compressed with mod_deflate
- bug #4054 query analysis doesn't launch in status monitor
+ Add pmahomme icon credits (FamFamFam silk icon set)
- bug #4064 Table structure statistics "Space usage" caption too small for l10n
- bug #4051 Wrong tabindex when inserting rows
- bug #4066 varchar field not truncated in table browse mode
+ rfe #1435 Opening database should expand it in the navigation menu
- (performance) Removed ShowTooltip directive
- bug #4046 Exporting huge Tables causes memory-Problems
4.0.5.0 (2013-08-04)
- bug #3977 Not detected configuration storage
- bug #3970 Pressing enter in the filter field reloads page
- bug #3984 Cannot insert in this table (PHP < 5.4)
- bug #3989 Reloading privileges does not update the interface
- bug #3960 NavigationBarIconic config not honored
- bug #3985 Call to undefined function mb_detect_encoding
- bug #4007 Analyze option not shown for InnoDB tables
- bug #4015 Forcing a storage engine for configuration storage
- bug Incorrect Drizzle 7 detection
- bug #4019 Create database if not exists (export): add an option to the
interface to enable generating CREATE DATABASE and USE (false by default)
- bug #4012 Crash on CSV file import
- bug #4009 Statistic Monitor shows only last 3 digits in graph
- bug #3998 Non-permanent SQL history not working
- bug #3578 Transformations for text/plain on a BLOB column
- [security] Improved protection against cross framing, see PMASA-2013-10
+ Reinstated configuration directive: AllowThirdPartyFraming
4.0.4.2 (2013-07-28)
- [security] fix unescaped parameter, see PMASA-2013-8
- [security] Fix stored XSS in Server status monitor, see PMASA-2013-9
- [security] Fix stored XSS in navigation panel logo link, see PMASA-2013-9
- [security] Fix self-XSS in setup, trusted proxies validation, see PMASA-2013-9
- [security] Fix full path disclosure, see PMASA-2013-12
- [security] Fix control user SQL injection in pmd_pdf.php, see PMASA-2013-15
- [security] Fix control user SQL injection in schema_export.php, see PMASA-2013-15
- [security] Fix self-XSS in schema export, see PMASA-2013-14
- [security] Fix unencoded json object, see PMASA-2013-11
- [security] Fix stored XSS in link transformation plugin, see PMASA-2013-13
4.0.4.1 (2013-06-30)
- [security] Global variables scope injection vulnerability (see PMASA-2013-7)
4.0.4.0 (2013-06-17)
- bug #3959 Using DefaultTabDatabase in NavigationTree for Database Click
- bug #3961 Avoid Suhosin warning when in simulation mode
- bug #3897 Row Statistics and Space usage bugs
- bug #3966 Only display "table has no unique column" message when applicable
- bug #3965 Default language wrong with zh-TW
- bug #3921 Call to undefined function PMA_isSuperuser() if default server is
not set
- bug #3971 Ctrl/shift + click opens links in same window
- bug #3964 Import using https does not work
- bug Missing removeCRLF option in ExportCsv and ExportExcel plugins
- bug #3631 Drop not working Visio schema export.
- bug #3645 Better handling of invalid ODS documents
- bug #3976 Number of pages
- bug #3922 User privileges, database name unescaped
4.0.3.0 (2013-06-05)
- bug #3941 Recent tables list always empty
- bug #3933 Do not translate "Open Document" in export settings
- bug #3927 List of tables is missing after expanding in the navigation frame
- bug #3942 Warnings about reserved word for many non reserved words
- bug #3912 Exporting row selection, resulted by ORDER BY query
- bug #3957 Cookies must be enabled past this point
- bug #3956 "Browse foreign values" search filter / page selector not working
- bug #3579 NOW() function incorrectly selected (partial regression)
- [security] Javascript execution vulnerability in Create view,
reported by Maxim Rupp (see PMASA-2013-6)
4.0.2.0 (2013-05-24)
- bug #3902 Cannot browse when table name contains keyword "call"
+ center loading indicator for navigation refresh, related to bug #3920
- bug #3925 Table sorting in navigation panel is case-sensitive
- bug #3915 Import of CSV file (Replace table data with file) with duplicate values
- bug #3907 undefined variables, function parameter problems
- bug #3898 Structure not refreshed after column drop
- bug #3926 View is not updatable
- bug #3919 PropertiesIconic not honored
- bug #3930 Databases to choose for specific privileges show up escaped
- bug #3910 Export database with empty table as a php array, does not produce valid PHP
- bug #3936 Query profiler chart not loading from SQL Query page
- bug #3946 Missing CSV import option "Do not abort on INSERT error"
- bug #3943 Missing Operations>Table options>AUTO_INCREMENT
- bug Missing CREATE DATABASE statement when exporting at database level
- bug #3924 Show warning when CSV file does not contain data for all columns
- bug #3947 Missing Sql Query after modify structure
- bug #3948 Server export problems
- bug #3917 CountTables directive is deprecated
4.0.1.0 (2013-05-14)
- bug #3879 Import broken for CSV using LOAD DATA
- bug #3889 When login fails and error display is active, login data is displayed
- bug #3890 [import] Web server upload directory import fails
- bug #3891 [import] Server upload folder import file name missing in success message
+ rfe #1421 [auth] Add retry button on connection failure with config auth
- bug #3894 [interface] Provide feedback if no columns selected for multi-submit
- bug #3799 [interface] Incorrect select field change on ctrl key navigation in Firefox
- bug #3885 [browse] display_binary_as_hex option causes unexpected behavior
- bug #3899 Git commit links to Github missing
- bug #3900 CSP WARN in Firefox console
- bug #3901 Setup script warning for config auth (stored login data) shows link BBcode
- bug #3895 [browse] Fixed getting BLOB data
- bug #3905 [export] Custom Exporting exports all databases
- bug #3909 [import] Import of CSV FIle to selected table doesn't work
- bug #3904 Browsing an empty table should not display its Structure
- bug #3908 Calendar widget improperly redirects to home
- bug #3918 Greyed out tabs when there are no rows fixed
- bug #3916 [interface] Missing scrollbar (original theme)
+ [vendor] add tcpdf path to vendor_config.php
- bug fix compat with tcpdf >= 6.0 (tested with 6.0.012)
4.0.0.0 (2013-05-03)
+ Patch #3481047 for rfe #3480477 Insert as new row enhancement
+ Patch #3480999 Activate codemirror in the query window
- Patch #3495284 XML Import - fix message and redirect
+ rfe #3484063 Null checkbox behavior
+ Patch #3497179 Contest-5: Add user: Allow create DB w/same name + grant u_%
+ Patch #3498201 Contest-6: Export all privileges
+ Patch #3502814 for rfe #3187077 Change password buttons should match
+ rfe #3488640 Expand table-group in non-light navigation frame if only one
+ Patch #3509360 Contest-3: Option "Truncate table" before "insert"
+ Patch #3506552 Contest-2: Show index information in the data dictionary
+ Patch #3510656 Contest-1: Ignoring foreign keys while dropping tables
- Bug #3509686 Reverting sort on joined column does not work
+ New transformation: append string
+ rfe #3507804 Session upload progress (PHP 5.4)
+ rfe #3488185 draggable columns vs copy column name
+ Patch #3507001 Contest-4: Textarea for large character columns
+ Removed the PHP version of the ENUM editor
+ Patch #3507111 Display distinct results, linked to corresponding data rows
- bug #3507917 [export] JSON has unescaped values for allegedly numeric columns
+ rfe #3516187 show tables creation, last update, last check timestamps in db_structure
- bug #3059806 Supporting running from CIFS/Samba shares
- bug #3516341 [export] Open Document Text, Word and Texy! Text show table structure twice
- bug [export] Texy! Text: Columns containing Pipe Character don't export properly
+ [export] Show triggers in Open Document Text, Word and Texy! Text
- Patch #3415061 [auth] Login screen appears under the page
+ rfe #3517354 [interface] Allow disabling CodeMirror with $cfg['CodemirrorEnable'] = false
+ rfe #3475567 [interface] New directive $cfg['HideStructureActions']
- bug #3468272 [import] Fixed import of ODS with more paragraphs in a cell
- bug #3510196 [core] Improved redirecting with ForceSSL option
+ rfe #3518852 [edit] edit blob but not other binary, new option $cfg['ProtectBinary'] = 'noblob'
+ Hide language select box if there are no locales installed
+ Removed some directives: verbose_check, SuggestDBName, LightTabs,
VerboseMultiSubmit, ReplaceHelpImg
- Patch #3500882 Fixing checkbox behaviour while editing identical rows
+ rfe #3441722 [interface] Display description of datatypes
+ rfe #3517835 [structure] Move columns easily
+ Ajaxified "Create View" functionality
+ [import] New plugin: import mediawiki
+ New navigation system
+ Discontinued the use of a frame-based layout
+ rfe #3528994 [interface] Allow wrapping possibly long values in replication-status table
+ [interface] Autoselect username input on cookie login page
- bug #3563799 [interface] Grid editing destroying huge amount of data
+ [import] Remove support for the unactive docSQL import format
- bug #3577443 [edit] "Browse foreign values" does not show on ajax edit
+ rfe #3522109 [browse] Grid editing: action to trigger it (or disable)
- bug #3526598 [interface] SQL query not shown when creating table
+ Dropped configuration directive: AllowThirdPartyFraming
+ Dropped configuration directive: LeftFrameLight
+ Dropped configuration directive: DisplayDatabasesList
+ Dropped configuration directives: ShowTooltipAliasDB and ShowTooltipAliasTB
+ Dropped configuration directive: NaviDatabaseNameColor
+ Added configuration directive: MaxNavigationItems
+ Renamed configuration directive: LeftFrameDBTree => NavigationTreeEnableGrouping
+ Renamed configuration directive: LeftFrameDBSeparator => NavigationTreeDbSeparator
+ Renamed configuration directive: LeftFrameTableSeparator => NavigationTreeTableSeparator
+ Renamed configuration directive: LeftFrameTableLevel => NavigationTreeTableLevel
+ Renamed configuration directive: LeftPointerEnable => NavigationTreePointerEnable
+ Renamed configuration directive: LeftDefaultTabTable => NavigationTreeDefaultTabTable
+ Renamed configuration directive: LeftDisplayTableFilterMinimum => NavigationTreeDisplayTableFilterMinimum
+ Renamed configuration directive: LeftDisplayLogo => NavigationDisplayLogo
+ Renamed configuration directive: LeftLogoLink => NavigationLogoLink
+ Renamed configuration directive: LeftLogoLinkWindow => NavigationLogoLinkWindow
+ Renamed configuration directive: LeftDisplayServers => NavigationDisplayServers
+ Renamed configuration directive: LeftRecentTable => NumRecentTables
+ Renamed configuration directive: LeftDisplayDatabaseFilterMinimum => NavigationTreeDisplayDbFilterMinimum
+ Removed the "Mark row on click" feature; must now click the checkbox to mark
+ Removed the "Synchronize" feature
+ Improved layout of server variables page
+ rfe #1052091 [config] Double-underscores in PMA table names
+ Improved the "More" dropdown on the table structure page
+ [interface] Added "scroll to top" link in menubar
+ [designer] Fullscreen mode for the designer
+ Upgraded jquery to v1.8.3 and jquery-ui to v1.9.2
+ Patch #3597529 [status] Add raw value as title on server status page
+ Support MySQL 5.6 partitioning
+ Removed the AjaxEnable directive
+ rfe #3542567 Accept IPv6 ranges and IPv6 CIDR notations in $cfg['Servers'][$i]['AllowDeny']['rules']
- Bug #3576788 Grid editing shows the value before silent truncation
- Upgraded jqPlot to 1.0.4 r1121
- Upgraded to jquery-ui-timepicker-addon 1.1.1
+ rfe #3599046 [interface] Added comments for indexes
- Replaced qtip with jQuery UI tooltip
- Upgraded CodeMirror to 2.37
- bug #2951 [export] Correctly export decimal fields.
- bug #3762 [core] Make Advisor work on Windows withou COM extension.
- bug #3519 [export] Prevent infinite recursion in PDF export.
- bug #3827 Table specific privileges not displayed for db name containing
underscore
- rfe #1386 Add IF NOT EXISTS clause when copying database
- No longer package .travis.yml configuration file when creating a release.
- bug #3830 Can't export custom query because it lowercases table names
- bug #3829 Enabling query profiling crashes javascript based navigation
+ rfe #879 Reserved word warning
+ Remove the database ordering sub-feature of the only_db directive
- bug #3840 When exporting to gzip format, the data is compressed 2 times
+ rfe #1319 Permit to create index when creating foreign key
- bug #3703 Incorrect updating of the list of users
- bug #3853 Blowfish implementation might be broken (replace with phpseclib)
- bug #3865 Using like operator on each backslash needs 4 backslash protection
- bug #3860 Displayed git revision info is not set
- bug #3871 Check referential integrity broken across databases
- bug #3874 [export] No preselected option when exporting table
- bug #3873 Can't copy table to target database if table exists there
- bug #3683 Incorrect listing of records from to count
- bug #3876 [import] PHP 5.2 - unexpected T_PAAMAYIM_NEKUDOTAYIM
- [security] Local file inclusion vulnerability, reported by Janek Vind
(see PMASA-2013-4)
- [security] Global variables overwrite in export.php, reported by Janek Vind
(see PMASA-2013-5)
- bug #3892 [export] SQL Export files are empty
3.5.8.2 (2013-07-28)
- [security] Fix self-XSS in "Showing rows", see PMASA-2013-8
- [security] Fix self-XSS in Display chart, see PMASA-2013-9
- [security] Fix stored XSS in Server status monitor, see PMASA-2013-9
- [security] Fix stored XSS in navigation panel logo link, see PMASA-2013-9
- [security] Fix self-XSS in setup, trusted proxies validation, see PMASA-2013-9
+ [security] JSON content type header for version_check.php, see PMASA-2013-9
+ [security] Backport fix for jQuery issue #9521 from jQuery 1.6.3, see PMASA-2013-9
+ [security] Fix full path disclosure, see PMASA-2013-12
+ [security] Fix control user SQL injection in pmd_pdf.php, see PMASA-2013-15
+ [security] Fix control user SQL injection in schema_export.php, see PMASA-2013-15
- [security] Fix self-XSS in schema export, see PMASA-2013-14
- [security] Fix unencoded json object, see PMASA-2013-11
3.5.8.1 (2013-04-24)
- [security] Remote code execution (preg_replace), reported by Janek Vind
(see PMASA-2013-2)
- [security] Locally Saved SQL Dump File Multiple File Extension Remote Code
Execution, reported by Janek Vind (see PMASA-2013-3)
3.5.8.0 (2013-04-08)
- bug #3828 MariaDB reported as MySQL
- bug #3854 Incorrect header for Safari 6.0
- bug #3705 Attempt to open trigger for edit gives NULL
- Use HTML5 DOCTYPE
- [security] Self-XSS on GIS visualisation page, reported by Janek Vind
- bug #3800 Incorrect keyhandler behaviour #2
3.5.7.0 (2013-02-15)
- bug #3779 [core] Problem with backslash in enum fields
- bug #3816 Missing server_processlist.php
- bug #3821 Safari: white page
- Correct detection of the Chrome browser
3.5.6.0 (2013-01-28)
- bug #3593604 [status] Erroneous advisor rule
- bug #3596070 [status] localStorage broken in server status monitor
- bug #3598736 [routines] Editing a procedure with special characters
- bug #3600322 [core] Visualize GIS data throws Fatal Error
- bug #3599362 [core] Double-escaped error message
- bug #3776 [cookies] Login without auth on second server
--- 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

44
DCO
View File

@ -1,44 +0,0 @@
If you would like to make a contribution to the phpMyAdmin Project, please
certify to the following:
***
phpMyAdmin Developer's Certificate of Origin. Version 1.0
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I have the
right to submit it under the license of "GNU General Public License or
any later version" ("GPLv2-or-later"); or
(b) The contribution is based upon previous work that, to the best of my
knowledge, is covered under an appropriate open source license and I have
the right under that license to submit that work with modifications,
whether created in whole or in part by me, under GPLv2-or-later; or
(c) The contribution was provided directly to me by some other person who
certified (a) or (b) and I have not modified it.
(d) I understand and agree that this project and the contribution are public
and that a record of the contribution (including all metadata and
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
phpMyAdmin's policies and the requirements of the GPLv2-or-later where
they are relevant.
(e) I am granting this work to this project under the terms of the
GPLv2-or-later.
https://www.gnu.org/licenses/gpl-2.0.html
***
***
And please confirm your certification to the above by adding the following
line to your patch:
Signed-off-by: Jane Smith <jane.smith@example.org>
using your real name (sorry, no pseudonyms or anonymous contributions).
If you are a developer who is authorized to contribute to phpMyAdmin on
behalf of your employer, then please use your corporate email address in the
Signed-off-by tag. If not, then please use a personal email address.

39
LICENSE
View File

@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@ -303,9 +303,10 @@ the "copyright" line and a pointer to where the full notice is found.
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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
@ -335,5 +336,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,233 @@
<?php
/**
* Parses and verifies the doc comments for classes.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {
$error = 'Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found';
throw new PHP_CodeSniffer_Exception($error);
}
if (class_exists('PMAStandard_Sniffs_Commenting_FileCommentSniff', true) === false) {
$error = 'Class PMAStandard_Sniffs_Commenting_FileCommentSniff not found';
throw new PHP_CodeSniffer_Exception($error);
}
/**
* Parses and verifies the doc comments for classes.
*
* Verifies that :
* <ul>
* <li>A doc comment exists.</li>
* <li>There is a blank newline after the short description.</li>
* <li>There is a blank newline between the long and short description.</li>
* <li>There is a blank newline between the long description and tags.</li>
* <li>Check the order of the tags.</li>
* <li>Check the indentation of each tag.</li>
* <li>Check required and optional tags and the format of their content.</li>
* </ul>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: 1.3.3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PMAStandard_Sniffs_Commenting_ClassCommentSniff extends PMAStandard_Sniffs_Commenting_FileCommentSniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(
T_CLASS,
T_INTERFACE,
);
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token
* in the stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$this->currentFile = $phpcsFile;
$tokens = $phpcsFile->getTokens();
$type = strtolower($tokens[$stackPtr]['content']);
$errorData = array($type);
$find = array(
T_ABSTRACT,
T_WHITESPACE,
T_FINAL,
);
// Extract the class comment docblock.
$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);
if ($commentEnd !== false && $tokens[$commentEnd]['code'] === T_COMMENT) {
$error = 'You must use "/**" style comments for a %s comment';
$phpcsFile->addError($error, $stackPtr, 'WrongStyle', $errorData);
return;
} else if ($commentEnd === false
|| $tokens[$commentEnd]['code'] !== T_DOC_COMMENT
) {
$phpcsFile->addError('Missing %s doc comment', $stackPtr, 'Missing', $errorData);
return;
}
$commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1);
$commentNext = $phpcsFile->findPrevious(T_WHITESPACE, ($commentEnd + 1), $stackPtr, false, $phpcsFile->eolChar);
// Distinguish file and class comment.
$prevClassToken = $phpcsFile->findPrevious(T_CLASS, ($stackPtr - 1));
if ($prevClassToken === false) {
// This is the first class token in this file, need extra checks.
$prevNonComment = $phpcsFile->findPrevious(T_DOC_COMMENT, ($commentStart - 1), null, true);
if ($prevNonComment !== false) {
$prevComment = $phpcsFile->findPrevious(T_DOC_COMMENT, ($prevNonComment - 1));
if ($prevComment === false) {
// There is only 1 doc comment between open tag and class token.
$newlineToken = $phpcsFile->findNext(T_WHITESPACE, ($commentEnd + 1), $stackPtr, false, $phpcsFile->eolChar);
if ($newlineToken !== false) {
$newlineToken = $phpcsFile->findNext(
T_WHITESPACE,
($newlineToken + 1),
$stackPtr,
false,
$phpcsFile->eolChar
);
if ($newlineToken !== false) {
// Blank line between the class and the doc block.
// The doc block is most likely a file comment.
$error = 'Missing %s doc comment';
$phpcsFile->addError($error, ($stackPtr + 1), 'Missing', $errorData);
return;
}
}//end if
}//end if
}//end if
}//end if
$comment = $phpcsFile->getTokensAsString(
$commentStart,
($commentEnd - $commentStart + 1)
);
// Parse the class comment.docblock.
try {
$this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);
$this->commentParser->parse();
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
$line = ($e->getLineWithinComment() + $commentStart);
$phpcsFile->addError($e->getMessage(), $line, 'FailedParse');
return;
}
$comment = $this->commentParser->getComment();
if (is_null($comment) === true) {
$error = 'Doc comment is empty for %s';
$phpcsFile->addError($error, $commentStart, 'Empty', $errorData);
return;
}
// No extra newline before short description.
$short = $comment->getShortComment();
$newlineCount = 0;
$newlineSpan = strspn($short, $phpcsFile->eolChar);
if ($short !== '' && $newlineSpan > 0) {
$error = 'Extra newline(s) found before %s comment short description';
$phpcsFile->addError($error, ($commentStart + 1), 'SpacingBeforeShort', $errorData);
}
$newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1);
// Exactly one blank line between short and long description.
$long = $comment->getLongComment();
if (empty($long) === false) {
$between = $comment->getWhiteSpaceBetween();
$newlineBetween = substr_count($between, $phpcsFile->eolChar);
if ($newlineBetween !== 2) {
$error = 'There must be exactly one blank line between descriptions in %s comments';
$phpcsFile->addError($error, ($commentStart + $newlineCount + 1), 'SpacingAfterShort', $errorData);
}
$newlineCount += $newlineBetween;
}
// Exactly one blank line before tags.
$tags = $this->commentParser->getTagOrders();
if (count($tags) > 1) {
$newlineSpan = $comment->getNewlineAfter();
if ($newlineSpan !== 2) {
$error = 'There must be exactly one blank line before the tags in %s comments';
if ($long !== '') {
$newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1);
}
$phpcsFile->addError($error, ($commentStart + $newlineCount), 'SpacingBeforeTags', $errorData);
$short = rtrim($short, $phpcsFile->eolChar.' ');
}
}
// Check each tag.
$this->processTags($commentStart, $commentEnd);
}//end process()
/**
* Process the version tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processVersion($errorPos)
{
$version = $this->commentParser->getVersion();
if ($version !== null) {
$content = $version->getContent();
$matches = array();
if (empty($content) === true) {
$error = 'Content missing for @version tag in doc comment';
$this->currentFile->addError($error, $errorPos, 'EmptyVersion');
} else if ((strstr($content, 'Release:') === false)) {
$error = 'Invalid version "%s" in doc comment; consider "Release: <package_version>" instead';
$data = array($content);
$this->currentFile->addWarning($error, $errorPos, 'InvalidVersion', $data);
}
}
}//end processVersion()
}//end class
?>

View File

@ -0,0 +1,768 @@
<?php
/**
* Parses and verifies the doc comments for files.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found');
}
/**
* Parses and verifies the doc comments for files.
*
* Verifies that :
* <ul>
* <li>A doc comment exists.</li>
* <li>There is a blank newline after the short description.</li>
* <li>There is a blank newline between the long and short description.</li>
* <li>There is a blank newline between the long description and tags.</li>
* <li>Check the order of the tags.</li>
* <li>Check the indentation of each tag.</li>
* <li>Check required and optional tags and the format of their content.</li>
* </ul>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: 1.3.3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PMAStandard_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff
{
/**
* The header comment parser for the current file.
*
* @var PHP_CodeSniffer_Comment_Parser_ClassCommentParser
*/
protected $commentParser = null;
/**
* The current PHP_CodeSniffer_File object we are processing.
*
* @var PHP_CodeSniffer_File
*/
protected $currentFile = null;
/**
* Tags in correct order and related info.
*
* @var array
*/
protected $tags = array(
'category' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'precedes @package',
),
'package' => array(
'required' => true,
'allow_multiple' => false,
'order_text' => 'follows @category',
),
'subpackage' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'follows @package',
),
'author' => array(
'required' => false,
'allow_multiple' => true,
'order_text' => 'follows @subpackage (if used) or @package',
),
'copyright' => array(
'required' => false,
'allow_multiple' => true,
'order_text' => 'follows @author',
),
'license' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'follows @copyright (if used) or @author',
),
'version' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'follows @license',
),
'link' => array(
'required' => false,
'allow_multiple' => true,
'order_text' => 'follows @version',
),
'see' => array(
'required' => false,
'allow_multiple' => true,
'order_text' => 'follows @link',
),
'since' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'follows @see (if used) or @link',
),
'deprecated' => array(
'required' => false,
'allow_multiple' => false,
'order_text' => 'follows @since (if used) or @see (if used) or @link',
),
);
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_OPEN_TAG);
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token
* in the stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$this->currentFile = $phpcsFile;
// We are only interested if this is the first open tag.
if ($stackPtr !== 0) {
if ($phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1)) !== false) {
return;
}
}
$tokens = $phpcsFile->getTokens();
// Find the next non whitespace token.
$commentStart
= $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
// Allow declare() statements at the top of the file.
if ($tokens[$commentStart]['code'] === T_DECLARE) {
$semicolon = $phpcsFile->findNext(T_SEMICOLON, ($commentStart + 1));
$commentStart
= $phpcsFile->findNext(T_WHITESPACE, ($semicolon + 1), null, true);
}
// Ignore vim header.
if ($tokens[$commentStart]['code'] === T_COMMENT) {
if (strstr($tokens[$commentStart]['content'], 'vim:') !== false) {
$commentStart = $phpcsFile->findNext(
T_WHITESPACE,
($commentStart + 1),
null,
true
);
}
}
$errorToken = ($stackPtr + 1);
if (isset($tokens[$errorToken]) === false) {
$errorToken--;
}
if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
// We are only interested if this is the first open tag.
return;
} else if ($tokens[$commentStart]['code'] === T_COMMENT) {
$error = 'You must use "/**" style comments for a file comment';
$phpcsFile->addError($error, $errorToken, 'WrongStyle');
return;
} else if ($commentStart === false
|| $tokens[$commentStart]['code'] !== T_DOC_COMMENT
) {
$phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
return;
} else {
// Extract the header comment docblock.
$commentEnd = $phpcsFile->findNext(
T_DOC_COMMENT,
($commentStart + 1),
null,
true
);
$commentEnd--;
// Check if there is only 1 doc comment between the
// open tag and class token.
$nextToken = array(
T_ABSTRACT,
T_CLASS,
T_FUNCTION,
T_DOC_COMMENT,
);
$commentNext = $phpcsFile->findNext($nextToken, ($commentEnd + 1));
if ($commentNext !== false
&& $tokens[$commentNext]['code'] !== T_DOC_COMMENT
) {
// Found a class token right after comment doc block.
$newlineToken = $phpcsFile->findNext(
T_WHITESPACE,
($commentEnd + 1),
$commentNext,
false,
$phpcsFile->eolChar
);
if ($newlineToken !== false) {
$newlineToken = $phpcsFile->findNext(
T_WHITESPACE,
($newlineToken + 1),
$commentNext,
false,
$phpcsFile->eolChar
);
if ($newlineToken === false) {
// No blank line between the class token and the doc block.
// The doc block is most likely a class comment.
$error = 'Missing file doc comment';
$phpcsFile->addError($error, $errorToken, 'Missing');
return;
}
}
}//end if
$comment = $phpcsFile->getTokensAsString(
$commentStart,
($commentEnd - $commentStart + 1)
);
// Parse the header comment docblock.
try {
$this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);
$this->commentParser->parse();
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
$line = ($e->getLineWithinComment() + $commentStart);
$phpcsFile->addError($e->getMessage(), $line, 'FailedParse');
return;
}
$comment = $this->commentParser->getComment();
if (is_null($comment) === true) {
$error = 'File doc comment is empty';
$phpcsFile->addError($error, $commentStart, 'Empty');
return;
}
// No extra newline before short description.
$short = $comment->getShortComment();
$newlineCount = 0;
$newlineSpan = strspn($short, $phpcsFile->eolChar);
if ($short !== '' && $newlineSpan > 0) {
$error = 'Extra newline(s) found before file comment short description';
$phpcsFile->addError($error, ($commentStart + 1), 'SpacingBefore');
}
$newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1);
// Exactly one blank line between short and long description.
$long = $comment->getLongComment();
if (empty($long) === false) {
$between = $comment->getWhiteSpaceBetween();
$newlineBetween = substr_count($between, $phpcsFile->eolChar);
if ($newlineBetween !== 2) {
$error = 'There must be exactly one blank line between descriptions in file comment';
$phpcsFile->addError($error, ($commentStart + $newlineCount + 1), 'DescriptionSpacing');
}
$newlineCount += $newlineBetween;
}
// Exactly one blank line before tags.
$tags = $this->commentParser->getTagOrders();
if (count($tags) > 1) {
$newlineSpan = $comment->getNewlineAfter();
if ($newlineSpan !== 2) {
$error = 'There must be exactly one blank line before the tags in file comment';
if ($long !== '') {
$newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1);
}
$phpcsFile->addError($error, ($commentStart + $newlineCount), 'SpacingBeforeTags');
$short = rtrim($short, $phpcsFile->eolChar.' ');
}
}
// Check each tag.
$this->processTags($commentStart, $commentEnd);
}//end if
}//end process()
/**
* Processes each required or optional tag.
*
* @param int $commentStart Position in the stack where the comment started.
* @param int $commentEnd Position in the stack where the comment ended.
*
* @return void
*/
protected function processTags($commentStart, $commentEnd)
{
$docBlock = (get_class($this) === 'PMAStandard_Sniffs_Commenting_FileCommentSniff') ? 'file' : 'class';
$foundTags = $this->commentParser->getTagOrders();
$orderIndex = 0;
$indentation = array();
$longestTag = 0;
$errorPos = 0;
foreach ($this->tags as $tag => $info) {
// Required tag missing.
if ($info['required'] === true && in_array($tag, $foundTags) === false) {
$error = 'Missing @%s tag in %s comment';
$data = array(
$tag,
$docBlock,
);
$this->currentFile->addError($error, $commentEnd, 'MissingTag', $data);
continue;
}
// Get the line number for current tag.
$tagName = ucfirst($tag);
if ($info['allow_multiple'] === true) {
$tagName .= 's';
}
$getMethod = 'get'.$tagName;
$tagElement = $this->commentParser->$getMethod();
if (is_null($tagElement) === true || empty($tagElement) === true) {
continue;
}
$errorPos = $commentStart;
if (is_array($tagElement) === false) {
$errorPos = ($commentStart + $tagElement->getLine());
}
// Get the tag order.
$foundIndexes = array_keys($foundTags, $tag);
if (count($foundIndexes) > 1) {
// Multiple occurance not allowed.
if ($info['allow_multiple'] === false) {
$error = 'Only 1 @%s tag is allowed in a %s comment';
$data = array(
$tag,
$docBlock,
);
$this->currentFile->addError($error, $errorPos, 'DuplicateTag', $data);
} else {
// Make sure same tags are grouped together.
$i = 0;
$count = $foundIndexes[0];
foreach ($foundIndexes as $index) {
if ($index !== $count) {
$errorPosIndex
= ($errorPos + $tagElement[$i]->getLine());
$error = '@%s tags must be grouped together';
$data = array($tag);
$this->currentFile->addError($error, $errorPosIndex, 'TagsNotGrouped', $data);
}
$i++;
$count++;
}
}
}//end if
// Check tag order.
if ($foundIndexes[0] > $orderIndex) {
$orderIndex = $foundIndexes[0];
} else {
if (is_array($tagElement) === true && empty($tagElement) === false) {
$errorPos += $tagElement[0]->getLine();
}
$error = 'The @%s tag is in the wrong order; the tag %s';
$data = array(
$tag,
$info['order_text'],
);
$this->currentFile->addError($error, $errorPos, 'WrongTagOrder', $data);
}
// Store the indentation for checking.
$len = strlen($tag);
if ($len > $longestTag) {
$longestTag = $len;
}
if (is_array($tagElement) === true) {
foreach ($tagElement as $key => $element) {
$indentation[] = array(
'tag' => $tag,
'space' => $this->getIndentation($tag, $element),
'line' => $element->getLine(),
);
}
} else {
$indentation[] = array(
'tag' => $tag,
'space' => $this->getIndentation($tag, $tagElement),
);
}
$method = 'process'.$tagName;
if (method_exists($this, $method) === true) {
// Process each tag if a method is defined.
call_user_func(array($this, $method), $errorPos);
} else {
if (is_array($tagElement) === true) {
foreach ($tagElement as $key => $element) {
$element->process(
$this->currentFile,
$commentStart,
$docBlock
);
}
} else {
$tagElement->process(
$this->currentFile,
$commentStart,
$docBlock
);
}
}
}//end foreach
foreach ($indentation as $indentInfo) {
if ($indentInfo['space'] !== 0
&& $indentInfo['space'] !== ($longestTag + 1)
) {
$expected = (($longestTag - strlen($indentInfo['tag'])) + 1);
$space = ($indentInfo['space'] - strlen($indentInfo['tag']));
$error = '@%s tag comment indented incorrectly; expected %s spaces but found %s';
$data = array(
$indentInfo['tag'],
$expected,
$space,
);
$getTagMethod = 'get'.ucfirst($indentInfo['tag']);
if ($this->tags[$indentInfo['tag']]['allow_multiple'] === true) {
$line = $indentInfo['line'];
} else {
$tagElem = $this->commentParser->$getTagMethod();
$line = $tagElem->getLine();
}
$this->currentFile->addError($error, ($commentStart + $line), 'TagIndent', $data);
}
}
}//end processTags()
/**
* Get the indentation information of each tag.
*
* @param string $tagName The name of the
* doc comment
* element.
* @param PHP_CodeSniffer_CommentParser_DocElement $tagElement The doc comment
* element.
*
* @return void
*/
protected function getIndentation($tagName, $tagElement)
{
if ($tagElement instanceof PHP_CodeSniffer_CommentParser_SingleElement) {
if ($tagElement->getContent() !== '') {
return (strlen($tagName) + substr_count($tagElement->getWhitespaceBeforeContent(), ' '));
}
} else if ($tagElement instanceof PHP_CodeSniffer_CommentParser_PairElement) {
if ($tagElement->getValue() !== '') {
return (strlen($tagName) + substr_count($tagElement->getWhitespaceBeforeValue(), ' '));
}
}
return 0;
}//end getIndentation()
/**
* Process the category tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processCategory($errorPos)
{
$category = $this->commentParser->getCategory();
if ($category !== null) {
$content = $category->getContent();
if ($content !== '') {
if (PHP_CodeSniffer::isUnderscoreName($content) !== true) {
$newContent = str_replace(' ', '_', $content);
$nameBits = explode('_', $newContent);
$firstBit = array_shift($nameBits);
$newName = ucfirst($firstBit).'_';
foreach ($nameBits as $bit) {
$newName .= ucfirst($bit).'_';
}
$error = 'Category name "%s" is not valid; consider "%s" instead';
$validName = trim($newName, '_');
$data = array(
$content,
$validName,
);
$this->currentFile->addError($error, $errorPos, 'InvalidCategory', $data);
}
} else {
$error = '@category tag must contain a name';
$this->currentFile->addError($error, $errorPos, 'EmptyCategory');
}
}
}//end processCategory()
/**
* Process the package tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processPackage($errorPos)
{
$package = $this->commentParser->getPackage();
if ($package !== null) {
$content = $package->getContent();
if ($content !== '') {
if (PHP_CodeSniffer::isUnderscoreName($content) !== true) {
$newContent = str_replace(' ', '_', $content);
$nameBits = explode('_', $newContent);
$firstBit = array_shift($nameBits);
$newName = strtoupper($firstBit{0}).substr($firstBit, 1).'_';
foreach ($nameBits as $bit) {
$newName .= strtoupper($bit{0}).substr($bit, 1).'_';
}
$error = 'Package name "%s" is not valid; consider "%s" instead';
$validName = trim($newName, '_');
$data = array(
$content,
$validName,
);
$this->currentFile->addError($error, $errorPos, 'InvalidPackage', $data);
}
} else {
$error = '@package tag must contain a name';
$this->currentFile->addError($error, $errorPos, 'EmptyPackage');
}
}
}//end processPackage()
/**
* Process the subpackage tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processSubpackage($errorPos)
{
$package = $this->commentParser->getSubpackage();
if ($package !== null) {
$content = $package->getContent();
if ($content !== '') {
if (PHP_CodeSniffer::isUnderscoreName($content) !== true) {
$newContent = str_replace(' ', '_', $content);
$nameBits = explode('_', $newContent);
$firstBit = array_shift($nameBits);
$newName = strtoupper($firstBit{0}).substr($firstBit, 1).'_';
foreach ($nameBits as $bit) {
$newName .= strtoupper($bit{0}).substr($bit, 1).'_';
}
$error = 'Subpackage name "%s" is not valid; consider "%s" instead';
$validName = trim($newName, '_');
$data = array(
$content,
$validName,
);
$this->currentFile->addError($error, $errorPos, 'InvalidSubpackage', $data);
}
} else {
$error = '@subpackage tag must contain a name';
$this->currentFile->addError($error, $errorPos, 'EmptySubpackage');
}
}
}//end processSubpackage()
/**
* Process the author tag(s) that this header comment has.
*
* This function is different from other _process functions
* as $authors is an array of SingleElements, so we work out
* the errorPos for each element separately
*
* @param int $commentStart The position in the stack where
* the comment started.
*
* @return void
*/
protected function processAuthors($commentStart)
{
$authors = $this->commentParser->getAuthors();
// Report missing return.
if (empty($authors) === false) {
foreach ($authors as $author) {
$errorPos = ($commentStart + $author->getLine());
$content = $author->getContent();
if ($content !== '') {
$local = '\da-zA-Z-_+';
// Dot character cannot be the first or last character
// in the local-part.
$localMiddle = $local.'.\w';
if (preg_match('/^([^<]*)\s+<(['.$local.']['.$localMiddle.']*['.$local.']@[\da-zA-Z][-.\w]*[\da-zA-Z]\.[a-zA-Z]{2,7})>$/', $content) === 0) {
$error = 'Content of the @author tag must be in the form "Display Name <username@example.com>"';
$this->currentFile->addError($error, $errorPos, 'InvalidAuthors');
}
} else {
$error = 'Content missing for @author tag in %s comment';
$docBlock = (get_class($this) === 'PMAStandard_Sniffs_Commenting_FileCommentSniff') ? 'file' : 'class';
$data = array($docBlock);
$this->currentFile->addError($error, $errorPos, 'EmptyAuthors', $data);
}
}
}
}//end processAuthors()
/**
* Process the copyright tags.
*
* @param int $commentStart The position in the stack where
* the comment started.
*
* @return void
*/
protected function processCopyrights($commentStart)
{
$copyrights = $this->commentParser->getCopyrights();
foreach ($copyrights as $copyright) {
$errorPos = ($commentStart + $copyright->getLine());
$content = $copyright->getContent();
if ($content !== '') {
$matches = array();
if (preg_match('/^([0-9]{4})((.{1})([0-9]{4}))? (.+)$/', $content, $matches) !== 0) {
// Check earliest-latest year order.
if ($matches[3] !== '') {
if ($matches[3] !== '-') {
$error = 'A hyphen must be used between the earliest and latest year';
$this->currentFile->addError($error, $errorPos, 'CopyrightHyphen');
}
if ($matches[4] !== '' && $matches[4] < $matches[1]) {
$error = "Invalid year span \"$matches[1]$matches[3]$matches[4]\" found; consider \"$matches[4]-$matches[1]\" instead";
$this->currentFile->addWarning($error, $errorPos, 'InvalidCopyright');
}
}
} else {
$error = '@copyright tag must contain a year and the name of the copyright holder';
$this->currentFile->addError($error, $errorPos, 'EmptyCopyright');
}
} else {
$error = '@copyright tag must contain a year and the name of the copyright holder';
$this->currentFile->addError($error, $errorPos, 'EmptyCopyright');
}//end if
}//end if
}//end processCopyrights()
/**
* Process the license tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processLicense($errorPos)
{
$license = $this->commentParser->getLicense();
if ($license !== null) {
$value = $license->getValue();
$comment = $license->getComment();
if ($value === '' || $comment === '') {
$error = '@license tag must contain a URL and a license name';
$this->currentFile->addError($error, $errorPos, 'EmptyLicense');
}
}
}//end processLicense()
/**
* Process the version tag.
*
* @param int $errorPos The line number where the error occurs.
*
* @return void
*/
protected function processVersion($errorPos)
{
$version = $this->commentParser->getVersion();
if ($version !== null) {
$content = $version->getContent();
$matches = array();
if (empty($content) === true) {
$error = 'Content missing for @version tag in file comment';
$this->currentFile->addError($error, $errorPos, 'EmptyVersion');
} else if (strstr($content, 'CVS:') === false
&& strstr($content, 'SVN:') === false
&& strstr($content, 'GIT:') === false
) {
$error = 'Invalid version "%s" in file comment; consider "CVS: <cvs_id>" or "SVN: <svn_id>" or "GIT: <git_id>" instead';
$data = array($content);
$this->currentFile->addWarning($error, $errorPos, 'InvalidVersion', $data);
}
}
}//end processVersion()
}//end class
?>

View File

@ -0,0 +1,490 @@
<?php
/**
* Parses and verifies the doc comments for functions.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
if (class_exists('PHP_CodeSniffer_CommentParser_FunctionCommentParser', true) === false) {
throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CommentParser_FunctionCommentParser not found');
}
/**
* Parses and verifies the doc comments for functions.
*
* Verifies that :
* <ul>
* <li>A comment exists</li>
* <li>There is a blank newline after the short description.</li>
* <li>There is a blank newline between the long and short description.</li>
* <li>There is a blank newline between the long description and tags.</li>
* <li>Parameter names represent those in the method.</li>
* <li>Parameter comments are in the correct order</li>
* <li>Parameter comments are complete</li>
* <li>A space is present before the first and after the last parameter</li>
* <li>A return type exists</li>
* <li>There must be one blank line between body and headline comments.</li>
* <li>Any throw tag must have an exception class.</li>
* </ul>
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: 1.3.3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PMAStandard_Sniffs_Commenting_FunctionCommentSniff implements PHP_CodeSniffer_Sniff
{
/**
* The name of the method that we are currently processing.
*
* @var string
*/
private $_methodName = '';
/**
* The position in the stack where the fucntion token was found.
*
* @var int
*/
private $_functionToken = null;
/**
* The position in the stack where the class token was found.
*
* @var int
*/
private $_classToken = null;
/**
* The function comment parser for the current method.
*
* @var PHP_CodeSniffer_Comment_Parser_FunctionCommentParser
*/
protected $commentParser = null;
/**
* The current PHP_CodeSniffer_File object we are processing.
*
* @var PHP_CodeSniffer_File
*/
protected $currentFile = null;
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_FUNCTION);
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token
* in the stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$find = array(
T_COMMENT,
T_DOC_COMMENT,
T_CLASS,
T_FUNCTION,
T_OPEN_TAG,
);
$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1));
if ($commentEnd === false) {
return;
}
$this->currentFile = $phpcsFile;
$tokens = $phpcsFile->getTokens();
// If the token that we found was a class or a function, then this
// function has no doc comment.
$code = $tokens[$commentEnd]['code'];
if ($code === T_COMMENT) {
$error = 'You must use "/**" style comments for a function comment';
$phpcsFile->addError($error, $stackPtr, 'WrongStyle');
return;
} else if ($code !== T_DOC_COMMENT) {
$phpcsFile->addError('Missing function doc comment', $stackPtr, 'Missing');
return;
}
// If there is any code between the function keyword and the doc block
// then the doc block is not for us.
$ignore = PHP_CodeSniffer_Tokens::$scopeModifiers;
$ignore[] = T_STATIC;
$ignore[] = T_WHITESPACE;
$ignore[] = T_ABSTRACT;
$ignore[] = T_FINAL;
$prevToken = $phpcsFile->findPrevious($ignore, ($stackPtr - 1), null, true);
if ($prevToken !== $commentEnd) {
$phpcsFile->addError('Missing function doc comment', $stackPtr, 'Missing');
return;
}
$this->_functionToken = $stackPtr;
$this->_classToken = null;
foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condition) {
if ($condition === T_CLASS || $condition === T_INTERFACE) {
$this->_classToken = $condPtr;
break;
}
}
// If the first T_OPEN_TAG is right before the comment, it is probably
// a file comment.
$commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1);
$prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($commentStart - 1), null, true);
if ($tokens[$prevToken]['code'] === T_OPEN_TAG) {
// Is this the first open tag?
if ($stackPtr === 0 || $phpcsFile->findPrevious(T_OPEN_TAG, ($prevToken - 1)) === false) {
$phpcsFile->addError('Missing function doc comment', $stackPtr, 'Missing');
return;
}
}
$comment = $phpcsFile->getTokensAsString($commentStart, ($commentEnd - $commentStart + 1));
$this->_methodName = $phpcsFile->getDeclarationName($stackPtr);
try {
$this->commentParser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($comment, $phpcsFile);
$this->commentParser->parse();
} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
$line = ($e->getLineWithinComment() + $commentStart);
$phpcsFile->addError($e->getMessage(), $line, 'FailedParse');
return;
}
$comment = $this->commentParser->getComment();
if (is_null($comment) === true) {
$error = 'Function doc comment is empty';
$phpcsFile->addError($error, $commentStart, 'Empty');
return;
}
$this->processParams($commentStart);
$this->processReturn($commentStart, $commentEnd);
$this->processThrows($commentStart);
// No extra newline before short description.
$short = $comment->getShortComment();
$newlineCount = 0;
$newlineSpan = strspn($short, $phpcsFile->eolChar);
if ($short !== '' && $newlineSpan > 0) {
$error = 'Extra newline(s) found before function comment short description';
$phpcsFile->addError($error, ($commentStart + 1), 'SpacingBeforeShort');
}
$newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1);
// Exactly one blank line between short and long description.
$long = $comment->getLongComment();
if (empty($long) === false) {
$between = $comment->getWhiteSpaceBetween();
$newlineBetween = substr_count($between, $phpcsFile->eolChar);
if ($newlineBetween !== 2) {
$error = 'There must be exactly one blank line between descriptions in function comment';
$phpcsFile->addError($error, ($commentStart + $newlineCount + 1), 'SpacingAfterShort');
}
$newlineCount += $newlineBetween;
}
// Exactly one blank line before tags.
$params = $this->commentParser->getTagOrders();
if (count($params) > 1) {
$newlineSpan = $comment->getNewlineAfter();
if ($newlineSpan !== 2) {
$error = 'There must be exactly one blank line before the tags in function comment';
if ($long !== '') {
$newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1);
}
$phpcsFile->addError($error, ($commentStart + $newlineCount), 'SpacingBeforeTags');
$short = rtrim($short, $phpcsFile->eolChar.' ');
}
}
}//end process()
/**
* Process any throw tags that this function comment has.
*
* @param int $commentStart The position in the stack where the
* comment started.
*
* @return void
*/
protected function processThrows($commentStart)
{
if (count($this->commentParser->getThrows()) === 0) {
return;
}
foreach ($this->commentParser->getThrows() as $throw) {
$exception = $throw->getValue();
$errorPos = ($commentStart + $throw->getLine());
if ($exception === '') {
$error = '@throws tag must contain the exception class name';
$this->currentFile->addError($error, $errorPos, 'EmptyThrows');
}
}
}//end processThrows()
/**
* Process the return comment of this function comment.
*
* @param int $commentStart The position in the stack where the comment started.
* @param int $commentEnd The position in the stack where the comment ended.
*
* @return void
*/
protected function processReturn($commentStart, $commentEnd)
{
// Skip constructor and destructor.
$className = '';
if ($this->_classToken !== null) {
$className = $this->currentFile->getDeclarationName($this->_classToken);
$className = strtolower(ltrim($className, '_'));
}
$methodName = strtolower(ltrim($this->_methodName, '_'));
$isSpecialMethod = ($this->_methodName === '__construct' || $this->_methodName === '__destruct');
if ($isSpecialMethod === false && $methodName !== $className) {
// Report missing return tag.
if ($this->commentParser->getReturn() === null) {
$error = 'Missing @return tag in function comment';
$this->currentFile->addError($error, $commentEnd, 'MissingReturn');
} else if (trim($this->commentParser->getReturn()->getRawContent()) === '') {
$error = '@return tag is empty in function comment';
$errorPos = ($commentStart + $this->commentParser->getReturn()->getLine());
$this->currentFile->addError($error, $errorPos, 'EmptyReturn');
}
}
}//end processReturn()
/**
* Process the function parameter comments.
*
* @param int $commentStart The position in the stack where
* the comment started.
*
* @return void
*/
protected function processParams($commentStart)
{
$realParams = $this->currentFile->getMethodParameters($this->_functionToken);
$params = $this->commentParser->getParams();
$foundParams = array();
if (empty($params) === false) {
$lastParm = (count($params) - 1);
if (substr_count($params[$lastParm]->getWhitespaceAfter(), $this->currentFile->eolChar) !== 2) {
$error = 'Last parameter comment requires a blank newline after it';
$errorPos = ($params[$lastParm]->getLine() + $commentStart);
$this->currentFile->addError($error, $errorPos, 'SpacingAfterParams');
}
// Parameters must appear immediately after the comment.
if ($params[0]->getOrder() !== 2) {
$error = 'Parameters must appear immediately after the comment';
$errorPos = ($params[0]->getLine() + $commentStart);
$this->currentFile->addError($error, $errorPos, 'SpacingBeforeParams');
}
$previousParam = null;
$spaceBeforeVar = 10000;
$spaceBeforeComment = 10000;
$longestType = 0;
$longestVar = 0;
foreach ($params as $param) {
$paramComment = trim($param->getComment());
$errorPos = ($param->getLine() + $commentStart);
// Make sure that there is only one space before the var type.
if ($param->getWhitespaceBeforeType() !== ' ') {
$error = 'Expected 1 space before variable type';
$this->currentFile->addError($error, $errorPos, 'SpacingBeforeParamType');
}
$spaceCount = substr_count($param->getWhitespaceBeforeVarName(), ' ');
if ($spaceCount < $spaceBeforeVar) {
$spaceBeforeVar = $spaceCount;
$longestType = $errorPos;
}
$spaceCount = substr_count($param->getWhitespaceBeforeComment(), ' ');
if ($spaceCount < $spaceBeforeComment && $paramComment !== '') {
$spaceBeforeComment = $spaceCount;
$longestVar = $errorPos;
}
// Make sure they are in the correct order,
// and have the correct name.
$pos = $param->getPosition();
$paramName = ($param->getVarName() !== '') ? $param->getVarName() : '[ UNKNOWN ]';
if ($previousParam !== null) {
$previousName = ($previousParam->getVarName() !== '') ? $previousParam->getVarName() : 'UNKNOWN';
// Check to see if the parameters align properly.
if ($param->alignsVariableWith($previousParam) === false) {
$error = 'The variable names for parameters %s (%s) and %s (%s) do not align';
$data = array(
$previousName,
($pos - 1),
$paramName,
$pos,
);
$this->currentFile->addError($error, $errorPos, 'ParameterNamesNotAligned', $data);
}
if ($param->alignsCommentWith($previousParam) === false) {
$error = 'The comments for parameters %s (%s) and %s (%s) do not align';
$data = array(
$previousName,
($pos - 1),
$paramName,
$pos,
);
$this->currentFile->addError($error, $errorPos, 'ParameterCommentsNotAligned', $data);
}
}//end if
// Make sure the names of the parameter comment matches the
// actual parameter.
if (isset($realParams[($pos - 1)]) === true) {
$realName = $realParams[($pos - 1)]['name'];
$foundParams[] = $realName;
// Append ampersand to name if passing by reference.
if ($realParams[($pos - 1)]['pass_by_reference'] === true) {
$realName = '&'.$realName;
}
if ($realName !== $paramName) {
$code = 'ParamNameNoMatch';
$data = array(
$paramName,
$realName,
$pos,
);
$error = 'Doc comment for var %s does not match ';
if (strtolower($paramName) === strtolower($realName)) {
$error .= 'case of ';
$code = 'ParamNameNoCaseMatch';
}
$error .= 'actual variable name %s at position %s';
$this->currentFile->addError($error, $errorPos, $code, $data);
}
} else {
// We must have an extra parameter comment.
$error = 'Superfluous doc comment at position '.$pos;
$this->currentFile->addError($error, $errorPos, 'ExtraParamComment');
}
if ($param->getVarName() === '') {
$error = 'Missing parameter name at position '.$pos;
$this->currentFile->addError($error, $errorPos, 'MissingParamName');
}
if ($param->getType() === '') {
$error = 'Missing type at position '.$pos;
$this->currentFile->addError($error, $errorPos, 'MissingParamType');
}
if ($paramComment === '') {
$error = 'Missing comment for param "%s" at position %s';
$data = array(
$paramName,
$pos,
);
$this->currentFile->addError($error, $errorPos, 'MissingParamComment', $data);
}
$previousParam = $param;
}//end foreach
if ($spaceBeforeVar !== 1 && $spaceBeforeVar !== 10000 && $spaceBeforeComment !== 10000) {
$error = 'Expected 1 space after the longest type';
$this->currentFile->addError($error, $longestType, 'SpacingAfterLongType');
}
if ($spaceBeforeComment !== 1 && $spaceBeforeComment !== 10000) {
$error = 'Expected 1 space after the longest variable name';
$this->currentFile->addError($error, $longestVar, 'SpacingAfterLongName');
}
}//end if
$realNames = array();
foreach ($realParams as $realParam) {
$realNames[] = $realParam['name'];
}
// Report and missing comments.
$diff = array_diff($realNames, $foundParams);
foreach ($diff as $neededParam) {
if (count($params) !== 0) {
$errorPos = ($params[(count($params) - 1)]->getLine() + $commentStart);
} else {
$errorPos = $commentStart;
}
$error = 'Doc comment for "%s" missing';
$data = array($neededParam);
$this->currentFile->addError($error, $errorPos, 'MissingParamTag', $data);
}
}//end processParams()
}//end class
?>

View File

@ -0,0 +1,70 @@
<?php
/**
* PHP_CodeSniffer_Sniffs_PEAR_Commenting_InlineCommentSniff.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
/**
* PHP_CodeSniffer_Sniffs_PEAR_Commenting_InlineCommentSniff.
*
* Checks that no perl-style comments are used.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: 1.3.3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PMAStandard_Sniffs_Commenting_InlineCommentSniff implements PHP_CodeSniffer_Sniff
{
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_COMMENT);
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token
* in the stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['content']{0} === '#') {
$error = 'Perl-style comments are not allowed. Use "// Comment."';
$error .= ' or "/* comment */" instead.';
$phpcsFile->addError($error, $stackPtr, 'WrongStyle');
}
}//end process()
}//end class
?>

View File

@ -0,0 +1,169 @@
<?php
/**
* PMAStandard_Sniffs_Files_LineLengthSniff.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
/**
* PMAStandard_Sniffs_Files_LineLengthSniff.
*
* Checks all lines in the file, and throws warnings if they are over 80
* characters in length and errors if they are over 100. Both these
* figures can be changed by extending this sniff in your own standard.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Greg Sherwood <gsherwood@squiz.net>
* @author Marc McIntyre <mmcintyre@squiz.net>
* @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
* @version Release: 1.3.3
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PMAStandard_Sniffs_Files_LineLengthSniff implements PHP_CodeSniffer_Sniff
{
/**
* The limit that the length of a line should not exceed.
*
* @var int
*/
public $lineLimit = 85;
/**
* The limit that the length of a line must not exceed.
*
* Set to zero (0) to disable.
*
* @var int
*/
public $absoluteLineLimit = 0;
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return array(T_OPEN_TAG);
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in
* the stack passed in $tokens.
*
* @return void
*/
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
// Make sure this is the first open tag.
$previousOpenTag = $phpcsFile->findPrevious(T_OPEN_TAG, ($stackPtr - 1));
if ($previousOpenTag !== false) {
return;
}
$tokenCount = 0;
$currentLineContent = '';
$currentLine = 1;
$trim = (strlen($phpcsFile->eolChar) * -1);
for (; $tokenCount < $phpcsFile->numTokens; $tokenCount++) {
if ($tokens[$tokenCount]['line'] === $currentLine) {
$currentLineContent .= $tokens[$tokenCount]['content'];
} else {
$currentLineContent = substr($currentLineContent, 0, $trim);
$this->checkLineLength($phpcsFile, ($tokenCount - 1), $currentLineContent);
$currentLineContent = $tokens[$tokenCount]['content'];
$currentLine++;
}
}
$currentLineContent = substr($currentLineContent, 0, $trim);
$this->checkLineLength($phpcsFile, ($tokenCount - 1), $currentLineContent);
}//end process()
/**
* Checks if a line is too long.
*
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The token at the end of the line.
* @param string $lineContent The content of the line.
*
* @return void
*/
protected function checkLineLength(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $lineContent)
{
// If the content is a CVS or SVN id in a version tag, or it is
// a license tag with a name and URL, there is nothing the
// developer can do to shorten the line, so don't throw errors.
if (preg_match('|@version[^\$]+\$Id|', $lineContent) !== 0) {
return;
}
if (preg_match('|@license|', $lineContent) !== 0) {
return;
}
if (preg_match('|__\("[^"]{40,999}"\)|', $lineContent) !== 0) {
return;
}
if (preg_match("|__\('[^']{40,999}'\)|", $lineContent) !== 0) {
return;
}
if (PHP_CODESNIFFER_ENCODING !== 'iso-8859-1') {
// Not using the detault encoding, so take a bit more care.
$lineLength = iconv_strlen($lineContent, PHP_CODESNIFFER_ENCODING);
if ($lineLength === false) {
// String contained invalid characters, so revert to default.
$lineLength = strlen($lineContent);
}
} else {
$lineLength = strlen($lineContent);
}
if ($this->absoluteLineLimit > 0
&& $lineLength > $this->absoluteLineLimit
) {
$data = array(
$this->absoluteLineLimit,
$lineLength,
);
$error = 'Line exceeds maximum limit of %s characters; contains %s characters';
$phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data);
} else if ($lineLength > $this->lineLimit) {
$data = array(
$this->lineLimit,
$lineLength,
);
$warning = 'Line exceeds %s characters; contains %s characters';
$phpcsFile->addWarning($warning, $stackPtr, 'TooLong', $data);
}
}//end checkLineLength()
}//end class

14
PMAStandard/ruleset.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<ruleset name="phpMyAdmin Standard">
<!-- http://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php -->
<description>phpMyAdmin custom coding standard</description>
<rule ref="PEAR">
<exclude name="PEAR.Commenting.FileComment" />
<exclude name="PEAR.Commenting.ClassComment" />
<exclude name="PEAR.Commenting.FunctionComment" />
<exclude name="PEAR.Commenting.InlineComment" />
<exclude name="Generic.Files.LineLength" />
</rule>
</ruleset>

74
README
View File

@ -1,28 +1,28 @@
phpMyAdmin - Readme
===================
Version 6.0.0-dev
Version 4.0.10.20
A web interface for MySQL and MariaDB.
A set of PHP-scripts to manage MySQL over the web.
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 ./docs/ folder or at https://docs.phpmyadmin.net/
Copyright
---------
Copyright © 1998 onwards -- the phpMyAdmin team
Copyright (C) 1998-2000
Tobias Ratschiller <tobias_at_ratschiller.com>
Certain libraries are copyrighted by their respective authors;
see the full copyright list for details.
For full copyright information, please see ./docs/copyright.rst
Copyright (C) 2001-2014
Marc Delisle <marc_at_infomarc.info>
Olivier Müller <om_at_omnis.ch>
Robin Johnson <robbat2_at_users.sourceforge.net>
Alexander M. Turek <me_at_derrabus.de>
Michal Čihař <michal_at_cihar.com>
Garvin Hicking <me_at_supergarv.de>
Michael Keck <mkkeck_at_users.sourceforge.net>
Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
[check documentation for more details]
License
-------
@ -37,16 +37,48 @@ 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/>.
along with this program. If not, see <http://www.gnu.org/licenses/>.
Licensing of current contributions
----------------------------------
Requirements
------------
* PHP 5.2 or later
* MySQL 5.0 or later
* a web-browser (doh!)
Summary
-------
phpMyAdmin is intended to handle the administration of MySQL over the web.
For a summary of features, please see the documentation in the doc folder.
Download
--------
You can get the newest version at https://www.phpmyadmin.net/.
More Information
----------------
Please see the documentation in the doc folder.
Support
-------
See reference about support forums under https://www.phpmyadmin.net/
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
The phpMyAdmin Devel team
PS:
Please, don't send us emails with question like "How do I compile PHP with
MySQL-support". We just don't have the time to be your free help desk.
Please send your questions to the appropriate mailing lists / forums. Before
contacting us, please read the documentation (especially the FAQ part).

View File

@ -1,72 +1,36 @@
phpMyAdmin
==========
A web interface for MySQL and MariaDB.
A set of PHP-scripts to manage MySQL over the web.
https://www.phpmyadmin.net/
Code status
-----------
Status
------
.. image:: https://github.com/phpmyadmin/phpmyadmin/actions/workflows/tests.yml/badge.svg?branch=master
:alt: Testsuite
:target: https://github.com/phpmyadmin/phpmyadmin/actions/workflows/tests.yml?query=branch%3Amaster
Continuous integration:
.. image:: https://github.com/phpmyadmin/phpmyadmin/actions/workflows/test-selenium.yml/badge.svg?branch=master
:alt: End-to-End tests
:target: https://github.com/phpmyadmin/phpmyadmin/actions/workflows/test-selenium.yml?query=branch%3Amaster
.. image:: https://secure.travis-ci.org/phpmyadmin/phpmyadmin.png?branch=master
:alt: Build status
:target: https://travis-ci.org/phpmyadmin/phpmyadmin
.. image:: https://readthedocs.org/projects/phpmyadmin/badge/?version=master
:target: https://docs.phpmyadmin.net/en/master/
:alt: Documentation build status
Translations:
.. image:: https://hosted.weblate.org/widgets/phpmyadmin/-/master/svg-badge.svg
.. image:: https://l10n.cihar.com/widgets/phpmyadmin/287x66/white/
:alt: Translation status
:target: https://hosted.weblate.org/engage/phpmyadmin/?utm_source=widget
.. image:: https://codecov.io/gh/phpmyadmin/phpmyadmin/branch/master/graph/badge.svg
:alt: Coverage percentage
:target: https://codecov.io/gh/phpmyadmin/phpmyadmin
.. image:: https://scrutinizer-ci.com/g/phpmyadmin/phpmyadmin/badges/quality-score.png
:alt: Code quality score
:target: https://scrutinizer-ci.com/g/phpmyadmin/phpmyadmin/
.. image:: https://bestpractices.coreinfrastructure.org/projects/213/badge
:alt: CII Best Practices
:target: https://bestpractices.coreinfrastructure.org/projects/213
.. image:: https://shepherd.dev/github/phpmyadmin/phpmyadmin/coverage.svg
:alt: Type coverage
:target: https://shepherd.dev/github/phpmyadmin/phpmyadmin
.. image:: https://img.shields.io/endpoint?url=https://badge-api.stryker-mutator.io/github.com/phpmyadmin/phpmyadmin/master
:alt: Infection MSI
:target: https://infection.github.io
:target: http://l10n.cihar.com/engage/phpmyadmin/?utm_source=widget
Download
--------
You can get the newest release at https://www.phpmyadmin.net/.
If you prefer to follow the Git repository, the following branch and tag names may be of interest:
* ``STABLE`` is the current stable release.
* ``master`` is the development branch.
* Releases are tagged; for example, version 5.0.1 was tagged as ``RELEASE_5_0_1``.
Note that phpMyAdmin uses `Composer <https://getcomposer.org/>`_ to manage library dependencies; when using Git
development versions, you must manually run Composer.
Please see `the documentation <https://docs.phpmyadmin.net/en/latest/setup.html#installing-from-git>`_ for details.
You can get the newest version at https://www.phpmyadmin.net/.
More Information
----------------
Please see https://docs.phpmyadmin.net/, or browse the documentation in the docs folder.
Please see the documentation in the doc folder or at https://docs.phpmyadmin.net/.
For `support <https://www.phpmyadmin.net/support/>`_ or `security issues, <https://www.phpmyadmin.net/security/>`_ you can visit https://www.phpmyadmin.net/
Support
-------
Translations are welcome. You can `translate phpMyAdmin into your language <https://hosted.weblate.org/projects/phpmyadmin/>`_.
If you would like to contribute to the phpMyAdmin's codebase, you can read the `code contribution file <CONTRIBUTING.md>`_ or browse our website's `contributing page <https://www.phpmyadmin.net/contribute/>`_.
See reference about support forums under https://www.phpmyadmin.net/

View File

@ -1,49 +0,0 @@
<?php
declare(strict_types=1);
$vendorConfig = require_once ROOT_PATH . 'app/vendor_config.php';
if (
! is_array($vendorConfig) || ! isset(
$vendorConfig['autoloadFile'],
$vendorConfig['tempDir'],
$vendorConfig['changeLogFile'],
$vendorConfig['licenseFile'],
$vendorConfig['sqlDir'],
$vendorConfig['configFile'],
$vendorConfig['customHeaderFile'],
$vendorConfig['customFooterFile'],
$vendorConfig['versionCheckDefault'],
$vendorConfig['localePath'],
$vendorConfig['cacheDir'],
$vendorConfig['versionSuffix'],
)
) {
exit;
}
// phpcs:disable PSR1.Files.SideEffects
define('AUTOLOAD_FILE', (string) $vendorConfig['autoloadFile']);
define('TEMP_DIR', (string) $vendorConfig['tempDir']);
define('CHANGELOG_FILE', (string) $vendorConfig['changeLogFile']);
define('LICENSE_FILE', (string) $vendorConfig['licenseFile']);
define('SQL_DIR', (string) $vendorConfig['sqlDir']);
define('CONFIG_FILE', (string) $vendorConfig['configFile']);
define('CUSTOM_HEADER_FILE', (string) $vendorConfig['customHeaderFile']);
define('CUSTOM_FOOTER_FILE', (string) $vendorConfig['customFooterFile']);
define('VERSION_CHECK_DEFAULT', (bool) $vendorConfig['versionCheckDefault']);
define('LOCALE_PATH', (string) $vendorConfig['localePath']);
define('CACHE_DIR', (string) $vendorConfig['cacheDir']);
define('VERSION_SUFFIX', (string) $vendorConfig['versionSuffix']);
/**
* TCPDF workaround. Avoid referring to nonexistent files (causes warnings when open_basedir is used).
* This is defined to avoid the TCPDF code to search for a directory outside of open_basedir.
* This value if not used but is useful, no header logic is used for PDF exports.
*
* @see https://github.com/phpmyadmin/phpmyadmin/issues/16709
*/
define('K_PATH_IMAGES', ROOT_PATH);
// phpcs:enable
unset($vendorConfig);

View File

@ -1,416 +0,0 @@
<?php
declare(strict_types=1);
use PhpMyAdmin\Advisory\Advisor;
use PhpMyAdmin\Application;
use PhpMyAdmin\Bookmarks\BookmarkRepository;
use PhpMyAdmin\BrowseForeigners;
use PhpMyAdmin\Clock\Clock;
use PhpMyAdmin\Config;
use PhpMyAdmin\Config\UserPreferences;
use PhpMyAdmin\Config\UserPreferencesHandler;
use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\ConfigStorage\RelationCleanup;
use PhpMyAdmin\Console\Console;
use PhpMyAdmin\Console\History;
use PhpMyAdmin\CreateAddField;
use PhpMyAdmin\Database\CentralColumns;
use PhpMyAdmin\Database\Designer;
use PhpMyAdmin\Database\Designer\Common;
use PhpMyAdmin\Database\Events;
use PhpMyAdmin\Database\Routines;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\DbTableExists;
use PhpMyAdmin\Error\ErrorHandler;
use PhpMyAdmin\Error\ErrorReport;
use PhpMyAdmin\Export\Export;
use PhpMyAdmin\Export\Options;
use PhpMyAdmin\Export\OutputHandler;
use PhpMyAdmin\Export\TemplateModel;
use PhpMyAdmin\FileListing;
use PhpMyAdmin\FlashMessenger;
use PhpMyAdmin\Footer;
use PhpMyAdmin\Header;
use PhpMyAdmin\Http\Factory\ResponseFactory;
use PhpMyAdmin\Http\Middleware;
use PhpMyAdmin\I18n\LanguageManager;
use PhpMyAdmin\Import\Import;
use PhpMyAdmin\Import\SimulateDml;
use PhpMyAdmin\InsertEdit;
use PhpMyAdmin\Navigation\Navigation;
use PhpMyAdmin\Normalization;
use PhpMyAdmin\Operations;
use PhpMyAdmin\Partitioning\Maintenance;
use PhpMyAdmin\Plugins\AuthenticationPluginFactory;
use PhpMyAdmin\Replication\Replication;
use PhpMyAdmin\Replication\ReplicationGui;
use PhpMyAdmin\ResponseRenderer;
use PhpMyAdmin\Server\Plugins;
use PhpMyAdmin\Server\Privileges;
use PhpMyAdmin\Server\Privileges\AccountLocking;
use PhpMyAdmin\Server\Status\Data;
use PhpMyAdmin\Server\Status\Monitor;
use PhpMyAdmin\Server\Status\Processes;
use PhpMyAdmin\Sql;
use PhpMyAdmin\SqlQueryForm;
use PhpMyAdmin\Table\ColumnsDefinition;
use PhpMyAdmin\Table\Indexes;
use PhpMyAdmin\Table\Search;
use PhpMyAdmin\Table\TableMover;
use PhpMyAdmin\Template;
use PhpMyAdmin\Theme\ThemeManager;
use PhpMyAdmin\Tracking\Tracking;
use PhpMyAdmin\Tracking\TrackingChecker;
use PhpMyAdmin\Transformations;
use PhpMyAdmin\Triggers\Triggers;
use PhpMyAdmin\UrlRedirector;
use PhpMyAdmin\UserPassword;
use PhpMyAdmin\UserPrivilegesFactory;
use PhpMyAdmin\Utils\HttpRequest;
use PhpMyAdmin\VersionInformation;
use Psr\Clock\ClockInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
return [
Advisor::class => ['class' => Advisor::class, 'arguments' => [DatabaseInterface::class, ExpressionLanguage::class]],
Application::class => [
'class' => Application::class,
'arguments' => [ResponseFactory::class, ResponseRenderer::class],
],
BrowseForeigners::class => [
'class' => BrowseForeigners::class,
'arguments' => [Template::class, Config::class, ThemeManager::class],
],
Config::class => ['class' => Config::class, 'factory' => [Config::class, 'getInstance']],
Config\PageSettings::class => [
'class' => Config\PageSettings::class,
'arguments' => [UserPreferences::class, ResponseRenderer::class],
],
CentralColumns::class => ['class' => CentralColumns::class, 'arguments' => [DatabaseInterface::class]],
CreateAddField::class => ['class' => CreateAddField::class, 'arguments' => [DatabaseInterface::class]],
DatabaseInterface::class => [
'class' => DatabaseInterface::class,
'factory' => [DatabaseInterface::class, 'getInstance'],
'arguments' => [Config::class],
],
DbTableExists::class => ['class' => DbTableExists::class, 'arguments' => [DatabaseInterface::class]],
Designer::class => [
'class' => Designer::class,
'arguments' => [DatabaseInterface::class, Relation::class, Template::class, Config::class],
],
Common::class => [
'class' => Common::class,
'arguments' => [DatabaseInterface::class, Relation::class, Config::class],
],
ErrorHandler::class => ['class' => ErrorHandler::class, 'factory' => [ErrorHandler::class, 'getInstance']],
ErrorReport::class => [
'class' => ErrorReport::class,
'arguments' => [HttpRequest::class, Relation::class, Template::class, Config::class],
],
Events::class => ['class' => Events::class, 'arguments' => [DatabaseInterface::class, Config::class]],
Export::class => ['class' => Export::class, 'arguments' => [DatabaseInterface::class, OutputHandler::class]],
Options::class => [
'class' => Options::class,
'arguments' => [Relation::class, TemplateModel::class, UserPreferencesHandler::class],
],
TemplateModel::class => ['class' => TemplateModel::class, 'arguments' => [DatabaseInterface::class]],
ExpressionLanguage::class => ['class' => ExpressionLanguage::class],
FileListing::class => ['class' => FileListing::class],
FlashMessenger::class => ['class' => FlashMessenger::class],
Header::class => [
'class' => Header::class,
'arguments' => [
Template::class,
Console::class,
Config::class,
DatabaseInterface::class,
Relation::class,
UserPreferences::class,
UserPreferencesHandler::class,
],
],
HttpRequest::class => ['class' => HttpRequest::class],
ResponseFactory::class => ['class' => ResponseFactory::class, 'factory' => [ResponseFactory::class, 'create']],
Import::class => [
'class' => Import::class,
'arguments' => [DatabaseInterface::class, ResponseRenderer::class, Config::class],
],
SimulateDml::class => ['class' => SimulateDml::class, 'arguments' => [DatabaseInterface::class]],
InsertEdit::class => [
'class' => InsertEdit::class,
'arguments' => [
DatabaseInterface::class,
Relation::class,
Transformations::class,
FileListing::class,
Template::class,
Config::class,
ResponseRenderer::class,
],
],
Middleware\ErrorHandling::class => [
'class' => Middleware\ErrorHandling::class,
'arguments' => [ErrorHandler::class],
],
Middleware\OutputBuffering::class => ['class' => Middleware\OutputBuffering::class],
Middleware\PhpExtensionsChecking::class => [
'class' => Middleware\PhpExtensionsChecking::class,
'arguments' => [Template::class, ResponseFactory::class],
],
Middleware\ServerConfigurationChecking::class => [
'class' => Middleware\ServerConfigurationChecking::class,
'arguments' => [Template::class, ResponseFactory::class],
],
Middleware\PhpSettingsConfiguration::class => ['class' => Middleware\PhpSettingsConfiguration::class],
Middleware\RouteParsing::class => ['class' => Middleware\RouteParsing::class],
Middleware\ConfigLoading::class => [
'class' => Middleware\ConfigLoading::class,
'arguments' => [Config::class, Template::class, ResponseFactory::class],
],
Middleware\UriSchemeUpdating::class => [
'class' => Middleware\UriSchemeUpdating::class,
'arguments' => [Config::class],
],
Middleware\SessionHandling::class => [
'class' => Middleware\SessionHandling::class,
'arguments' => [Config::class, ErrorHandler::class, Template::class, ResponseFactory::class],
],
Middleware\EncryptedQueryParamsHandling::class => ['class' => Middleware\EncryptedQueryParamsHandling::class],
Middleware\UrlParamsSetting::class => [
'class' => Middleware\UrlParamsSetting::class,
'arguments' => [Config::class],
],
Middleware\TokenRequestParamChecking::class => [
'class' => Middleware\TokenRequestParamChecking::class,
'arguments' => [ResponseRenderer::class],
],
Middleware\DatabaseAndTableSetting::class => ['class' => Middleware\DatabaseAndTableSetting::class],
Middleware\SqlQueryGlobalSetting::class => ['class' => Middleware\SqlQueryGlobalSetting::class],
Middleware\LanguageLoading::class => ['class' => Middleware\LanguageLoading::class],
Middleware\ConfigErrorAndPermissionChecking::class => [
'class' => Middleware\ConfigErrorAndPermissionChecking::class,
'arguments' => [Config::class, Template::class, ResponseFactory::class],
],
Middleware\RequestProblemChecking::class => [
'class' => Middleware\RequestProblemChecking::class,
'arguments' => [Template::class, ResponseFactory::class],
],
Middleware\CurrentServerGlobalSetting::class => [
'class' => Middleware\CurrentServerGlobalSetting::class,
'arguments' => [Config::class],
],
Middleware\ThemeInitialization::class => ['class' => Middleware\ThemeInitialization::class],
Middleware\UrlRedirection::class => [
'class' => Middleware\UrlRedirection::class,
'arguments' => [UrlRedirector::class, UserPreferencesHandler::class],
],
Middleware\SetupPageRedirection::class => [
'class' => Middleware\SetupPageRedirection::class,
'arguments' => [Config::class, ResponseFactory::class, UserPreferencesHandler::class, ResponseRenderer::class],
],
Middleware\MinimumCommonRedirection::class => [
'class' => Middleware\MinimumCommonRedirection::class,
'arguments' => [ResponseFactory::class, UserPreferencesHandler::class, ResponseRenderer::class],
],
Middleware\LanguageAndThemeCookieSaving::class => [
'class' => Middleware\LanguageAndThemeCookieSaving::class,
'arguments' => [Config::class],
],
Middleware\LoginCookieValiditySetting::class => [
'class' => Middleware\LoginCookieValiditySetting::class,
'arguments' => [Config::class, UserPreferencesHandler::class],
],
Middleware\Authentication::class => [
'class' => Middleware\Authentication::class,
'arguments' => [
Config::class,
Template::class,
ResponseFactory::class,
AuthenticationPluginFactory::class,
DatabaseInterface::class,
Relation::class,
ResponseRenderer::class,
],
],
Middleware\DatabaseServerVersionChecking::class => [
'class' => Middleware\DatabaseServerVersionChecking::class,
'arguments' => [Config::class, Template::class, ResponseFactory::class],
],
Middleware\SqlDelimiterSetting::class => [
'class' => Middleware\SqlDelimiterSetting::class,
'arguments' => [Config::class],
],
Middleware\ResponseRendererLoading::class => [
'class' => Middleware\ResponseRendererLoading::class,
'arguments' => [Config::class, ResponseRenderer::class],
],
Middleware\ProfilingChecking::class => [
'class' => Middleware\ProfilingChecking::class,
'arguments' => [ResponseRenderer::class, DatabaseInterface::class],
],
Middleware\UserPreferencesLoading::class => [
'class' => Middleware\UserPreferencesLoading::class,
'arguments' => [UserPreferencesHandler::class],
],
Middleware\RecentTableHandling::class => [
'class' => Middleware\RecentTableHandling::class,
'arguments' => [Config::class],
],
Middleware\StatementHistory::class => [
'class' => Middleware\StatementHistory::class,
'arguments' => [Config::class, History::class],
],
Navigation::class => [
'class' => Navigation::class,
'arguments' => [Template::class, Relation::class, DatabaseInterface::class, Config::class],
],
Normalization::class => [
'class' => Normalization::class,
'arguments' => [DatabaseInterface::class, Relation::class, Transformations::class, Template::class],
],
Operations::class => [
'class' => Operations::class,
'arguments' => [DatabaseInterface::class, Relation::class, TableMover::class],
],
OutputHandler::class => ['class' => OutputHandler::class],
Maintenance::class => ['class' => Maintenance::class, 'arguments' => [DatabaseInterface::class]],
AuthenticationPluginFactory::class => [
'class' => AuthenticationPluginFactory::class,
'arguments' => [ResponseRenderer::class],
],
Relation::class => ['class' => Relation::class, 'arguments' => [DatabaseInterface::class, Config::class]],
RelationCleanup::class => [
'class' => RelationCleanup::class,
'arguments' => [DatabaseInterface::class, Relation::class],
],
Replication::class => ['class' => Replication::class, 'arguments' => [DatabaseInterface::class]],
ReplicationGui::class => ['class' => ReplicationGui::class, 'arguments' => [Replication::class, Template::class]],
ResponseRenderer::class => [
'class' => ResponseRenderer::class,
'factory' => [ResponseRenderer::class, 'getInstance'],
'arguments' => [
Config::class,
Template::class,
Header::class,
Footer::class,
ErrorHandler::class,
DatabaseInterface::class,
ResponseFactory::class,
],
],
Routines::class => ['class' => Routines::class, 'arguments' => [DatabaseInterface::class, Config::class]],
Plugins::class => ['class' => Plugins::class, 'arguments' => [DatabaseInterface::class]],
Privileges::class => [
'class' => Privileges::class,
'arguments' => [
Template::class,
DatabaseInterface::class,
Relation::class,
RelationCleanup::class,
Plugins::class,
Config::class,
],
],
AccountLocking::class => ['class' => AccountLocking::class, 'arguments' => [DatabaseInterface::class]],
Sql::class => [
'class' => Sql::class,
'arguments' => [
DatabaseInterface::class,
Relation::class,
RelationCleanup::class,
Transformations::class,
Template::class,
BookmarkRepository::class,
Config::class,
ResponseRenderer::class,
],
],
SqlQueryForm::class => [
'class' => SqlQueryForm::class,
'arguments' => [Template::class, DatabaseInterface::class, BookmarkRepository::class],
],
Data::class => ['class' => Data::class, 'arguments' => [DatabaseInterface::class, Config::class]],
Monitor::class => ['class' => Monitor::class, 'arguments' => [DatabaseInterface::class]],
Processes::class => ['class' => Processes::class, 'arguments' => [DatabaseInterface::class]],
ColumnsDefinition::class => [
'class' => ColumnsDefinition::class,
'arguments' => [DatabaseInterface::class, Relation::class, Transformations::class],
],
Indexes::class => ['class' => Indexes::class, 'arguments' => [DatabaseInterface::class]],
\PhpMyAdmin\Table\Maintenance::class => [
'class' => \PhpMyAdmin\Table\Maintenance::class,
'arguments' => [DatabaseInterface::class],
],
Search::class => ['class' => Search::class, 'arguments' => [DatabaseInterface::class]],
Template::class => ['class' => Template::class, 'arguments' => [Config::class]],
ThemeManager::class => ['class' => ThemeManager::class],
Tracking::class => [
'class' => Tracking::class,
'arguments' => [
SqlQueryForm::class,
Template::class,
Relation::class,
DatabaseInterface::class,
TrackingChecker::class,
],
],
TrackingChecker::class => [
'class' => TrackingChecker::class,
'arguments' => [DatabaseInterface::class, Relation::class],
],
Transformations::class => [
'class' => Transformations::class,
'arguments' => [DatabaseInterface::class, Relation::class],
],
Triggers::class => ['class' => Triggers::class, 'arguments' => [DatabaseInterface::class]],
UserPassword::class => [
'class' => UserPassword::class,
'arguments' => [Privileges::class, AuthenticationPluginFactory::class, DatabaseInterface::class],
],
UserPreferences::class => [
'class' => UserPreferences::class,
'arguments' => [
DatabaseInterface::class,
Relation::class,
Template::class,
Config::class,
ClockInterface::class,
],
],
UserPrivilegesFactory::class => [
'class' => UserPrivilegesFactory::class,
'arguments' => [DatabaseInterface::class],
],
VersionInformation::class => ['class' => VersionInformation::class],
BookmarkRepository::class => [
'class' => BookmarkRepository::class,
'arguments' => [DatabaseInterface::class, Relation::class, Config::class],
],
Console::class => [
'class' => Console::class,
'arguments' => [Relation::class, Template::class, BookmarkRepository::class, History::class],
],
TableMover::class => ['class' => TableMover::class, 'arguments' => [DatabaseInterface::class, Relation::class]],
History::class => [
'class' => History::class,
'arguments' => [DatabaseInterface::class, Relation::class, Config::class],
],
UserPreferencesHandler::class => [
'class' => UserPreferencesHandler::class,
'arguments' => [
Config::class,
DatabaseInterface::class,
UserPreferences::class,
LanguageManager::class,
ThemeManager::class,
],
],
LanguageManager::class => ['class' => LanguageManager::class, 'factory' => [LanguageManager::class, 'getInstance']],
ClockInterface::class => ['class' => Clock::class],
Footer::class => ['class' => Footer::class, 'arguments' => [Template::class, Config::class]],
UrlRedirector::class => [
'class' => UrlRedirector::class,
'arguments' => [ResponseRenderer::class, Template::class, ResponseFactory::class],
],
];

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
use PhpMyAdmin\Container\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $configurator): void {
$services = $configurator->services();
/** @var array<string, array{class: string, arguments?: array<string>, factory?: callable}> $servicesFile */
$servicesFile = include ROOT_PATH . 'app/services.php';
ContainerBuilder::loadServices($servicesFile, $services);
/** @var array<string, array{class: string, arguments?: array<string>, factory?: callable}> $servicesFile */
$servicesFile = include ROOT_PATH . 'app/services_controllers.php';
ContainerBuilder::loadServices($servicesFile, $services);
};

View File

@ -1,73 +0,0 @@
<?php
/**
* File for vendor customization, you can change here paths or some behaviour,
* which vendors such as Linux distributions might want to change.
*
* For changing this file you should know what you are doing. For this reason
* options here are not part of normal configuration.
*/
declare(strict_types=1);
return [
/**
* Path to vendor autoload file. Useful when you want to have vendor dependencies somewhere else.
*/
'autoloadFile' => ROOT_PATH . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php',
/**
* Directory where cache files are stored.
*/
'tempDir' => ROOT_PATH . 'tmp' . DIRECTORY_SEPARATOR,
/**
* Path to changelog file, can be gzip compressed.
* Useful when you want to have documentation somewhere else, e.g. /usr/share/doc.
*/
'changeLogFile' => ROOT_PATH . 'CHANGELOG-6.0.md',
/**
* Path to license file. Useful when you want to have documentation somewhere else, e.g. /usr/share/doc.
*/
'licenseFile' => ROOT_PATH . 'LICENSE',
/**
* Directory where SQL scripts to create/upgrade configuration storage reside.
*/
'sqlDir' => ROOT_PATH . 'resources' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR,
/**
* Filename of a configuration file.
*/
'configFile' => ROOT_PATH . 'config.inc.php',
/**
* Filename of custom header file.
*/
'customHeaderFile' => ROOT_PATH . 'config.header.inc.php',
/**
* Filename of custom footer file.
*/
'customFooterFile' => ROOT_PATH . 'config.footer.inc.php',
/**
* Default value for check for version upgrades.
*/
'versionCheckDefault' => true,
/**
* Path to files with compiled locales (*.mo)
*/
'localePath' => ROOT_PATH . 'resources' . DIRECTORY_SEPARATOR . 'locale' . DIRECTORY_SEPARATOR,
/**
* Define the cache directory for routing cache and other cache files
*/
'cacheDir' => ROOT_PATH . 'app' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR,
/**
* Suffix to add to the phpMyAdmin version
*/
'versionSuffix' => '',
];

View File

@ -1,13 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "current"
}
}
],
"@babel/preset-typescript"
]
}

View File

@ -1,43 +0,0 @@
#!/usr/bin/env php
<?php
use PhpMyAdmin\Command\CacheWarmupCommand;
use PhpMyAdmin\Command\FixPoTwigCommand;
use PhpMyAdmin\Command\SetVersionCommand;
use PhpMyAdmin\Command\TwigLintCommand;
use PhpMyAdmin\Command\WriteGitRevisionCommand;
use PhpMyAdmin\Config;
use PhpMyAdmin\Container\ContainerBuilder;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Tests\Stubs\DbiDummy;
use Symfony\Component\Console\Application;
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', dirname(__DIR__) . DIRECTORY_SEPARATOR);
}
require_once ROOT_PATH . 'app/constants.php';
require_once AUTOLOAD_FILE;
if (! class_exists(Application::class)) {
echo 'Be sure to have dev-dependencies installed.' . PHP_EOL;
echo 'Command aborted.' . PHP_EOL;
exit(1);
}
$containerBuilder = ContainerBuilder::getContainer();
$cfg['environment'] = 'production';
$config = new Config();
$config->loadFromFile(CONFIG_FILE);
$config->set('environment', $cfg['environment']);
$dbi = DatabaseInterface::getInstanceForTest(new DbiDummy());
$application = new Application('phpMyAdmin Console Tool');
$application->add(new CacheWarmupCommand());
$application->add(new TwigLintCommand());
$application->add(new SetVersionCommand());
$application->add(new WriteGitRevisionCommand());
$application->add(new FixPoTwigCommand());
$application->run();

View File

@ -1,40 +0,0 @@
#!/bin/sh
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
if [ "$1" = --quiet ] ; then
stats=""
shift
else
stats="--statistics"
fi
compile() {
lang=$(echo "$1" | sed 's@resources/po/\(.*\)\.po@\1@')
if [ -n "$stats" ] ; then
printf "%s: " "$lang"
fi
mkdir -p resources/locale/"$lang"/LC_MESSAGES
msgfmt $stats --check -o resources/locale/"$lang"/LC_MESSAGES/phpmyadmin.mo "$1"
return $?
}
if [ -n "$1" ] ; then
compile resources/po/"$1".po
exit $?
fi
result=0
for x in resources/po/*.po ; do
compile "$x"
ret=$?
if [ $ret != 0 ] ; then
echo Error when compiling "$x" >&2
result=$ret
fi
done
exit $result

View File

@ -1,358 +0,0 @@
#!/bin/bash
set -e
FILE="$1"
if [ ! -f "${FILE}" ]; then
echo 'Please provide a file as a first argument.'
exit 1
fi
FILE_LIST="$(tar --list --file="${FILE}")"
found=0;
echo 'Searching for files'
foundFile() {
found=1
printf "Found: %s\n" "${filePath}"
}
foundFileExt() {
found=1
printf "Found unexpected file: %s with extension %s\n" "${pathWithoutFirst}" "${extension}"
}
validateExtension() {
if [ "${filePath: -1}" = "/" ]; then
return;
fi
pathWithoutFirst="$(echo "$filePath" | cut -d / -f 2-)"
filename=$(basename -- "$pathWithoutFirst")
extension="${filename##*.}"
case $pathWithoutFirst in
public/docs/*)
if [ "${extension}" != "png" ] && [ "${extension}" != "txt" ] &&
[ "${extension}" != "html" ] && [ "${extension}" != "js" ] &&
[ "${extension}" != "css" ] && [ "${extension}" != "gif" ]; then
foundFileExt
fi
;;
resources/js/global.d.ts)
;;
public/js/vendor/*)
if [ "${extension}" != "js" ] && [ "${extension}" != "map" ] &&
[ "${extension}" != "css" ] && [ "${filename}" != "LICENSE" ] &&
[ "${extension}" != "txt" ]; then
foundFileExt
fi
;;
public/js/*)
if [ "${extension}" != "js" ] && [ "${extension}" != "map" ]; then
foundFileExt
fi
;;
resources/js/*)
if [ "${extension}" != "ts" ]; then
foundFileExt
fi
;;
resources/sql/*)
if [ "${extension}" != "sql" ]; then
foundFileExt
fi
;;
examples/*)
if [ "${extension}" != "php" ]; then
foundFileExt
fi
;;
resources/locale/*)
if [ "${extension}" != "mo" ]; then
foundFileExt
fi
;;
public/setup/*)
if [ "${extension}" != "php" ] && [ "${extension}" != "twig" ] &&
[ "${extension}" != "css" ] && [ "${extension}" != "scss" ] &&
[ "${extension}" != "gif" ] && [ "${extension}" != "map" ]; then
foundFileExt
fi
;;
resources/templates/*)
if [ "${extension}" != "twig" ]; then
foundFileExt
fi
;;
app/*)
if [ "${extension}" != "php" ]; then
foundFileExt
fi
;;
src/*)
if [ "${extension}" != "php" ] && [ "${extension}" != "md" ] &&
[ "${filename}" != "README" ] && [ "${filename}" != "TEMPLATE" ] &&
[ "${filename}" != "TEMPLATE_ABSTRACT" ]; then
foundFileExt
fi
;;
public/themes/*)
if [ "${extension}" != "css" ] && [ "${extension}" != "png" ] &&
[ "${extension}" != "scss" ] && [ "${extension}" != "map" ] &&
[ "${extension}" != "svg" ] && [ "${extension}" != "ico" ] &&
[ "${extension}" != "gif" ] && [ "${extension}" != "json" ]; then
foundFileExt
fi
;;
vendor/phpmyadmin/sql-parser/locale/*)
if [ "${extension}" != "mo" ]; then
foundFileExt
fi
;;
vendor/composer/ca-bundle/res/cacert.pem)
;;
vendor/pragmarx/google2fa-qrcode/composer.lock)
;;
vendor/williamdes/mariadb-mysql-kbs/cliff.toml)
;;
vendor/williamdes/mariadb-mysql-kbs/dist/merged-ultraslim.json)
;;
vendor/composer/installed.json)
;;
vendor/tecnickcom/tcpdf/*)
if [ "${extension}" != "php" ] && [ "${filename}" != "LICENSE.TXT" ] &&
[ "${filename}" != "README.md" ] && [ "${filename}" != "CHANGELOG.TXT" ] &&
[ "${filename}" != "VERSION" ] && [ "${filename}" != "composer.json" ] &&
[ "${extension}" != "z" ]; then
foundFileExt
fi
;;
vendor/*)
if [ "${extension}" != "php" ] && [ "${filename}" != "LICENSE" ] &&
[ "${filename}" != "README" ] && [ "${filename}" != "CHANGELOG" ] &&
[ "${filename}" != "composer.json" ] && [ "${filename}" != "CHANGELOG.md" ] &&
[ "${filename}" != "README.md" ] && [ "${filename}" != "BACKERS.md" ] &&
[ "${filename}" != "LICENSE.md" ] && [ "${filename}" != "ARCHITECTURE.md" ] &&
[ "${filename}" != "LICENSE.txt" ] && [ "${filename}" != "AUTHORS" ] &&
[ "${filename}" != "LICENCE.md" ] && [ "${filename}" != "LICENCE" ] &&
[ "${filename}" != "COPYRIGHT.md" ]; then
foundFileExt
fi
;;
CHANGELOG-[5-9].[0-9].md)
;;
LICENSE)
;;
RELEASE-DATE-[1-9].[0-9].[0-9])
;;
RELEASE-DATE-[1-9].[0-9].[0-9]-dev)
;;
RELEASE-DATE-[1-9].[0-9]+snapshot)
;;
CONTRIBUTING.md)
;;
README)
;;
public/favicon.ico)
;;
tsconfig.json)
;;
webpack.config.cjs)
;;
babel.config.json)
;;
package.json)
;;
composer.json)
;;
composer.lock)
;;
yarn.lock)
;;
public/robots.txt)
;;
index.php)
;;
public/index.php)
;;
config.sample.inc.php)
;;
*)
foundFileExt
;;
esac
}
for filePath in ${FILE_LIST}; do
validateExtension
case $filePath in
*/composer-require-checker.json)
foundFile;;
*/CLAUDE.MD)
foundFile;;
*/Readme.php)
foundFile;;
*/rector*.php)
foundFile;;
*/.editorconfig)
foundFile;;
*/easy-coding-standard.neon)
foundFile;;
*/.travis.yml)
foundFile;;
*/psalm.xml.dist)
foundFile;;
*/phpdoc.xml)
foundFile;;
*/phpdoc.dist.xml)
foundFile;;
*/.coveralls.yml)
foundFile;;
*/.yamllint.yaml)
foundFile;;
*/appveyor.yml)
foundFile;;
*/phpunit.xml)
foundFile;;
*/phpunit.xml.dist)
foundFile;;
*/phive.xml)
foundFile;;
*/Makefile)
foundFile;;
*/splitsh.json)
foundFile;;
*/phpbench.json)
foundFile;;
*/phpbench.json.dist)
foundFile;;
*/.php-cs-fixer.dist.php)
foundFile;;
*/.php_cs)
foundFile;;
*/.php_cs.dist)
foundFile;;
*/.php_cs.cache)
foundFile;;
*/.php-cs-fixer.php)
foundFile;;
*/psalm.xml)
foundFile;;
*/phpcs.xml)
foundFile;;
*/phpcs.xml.dist)
foundFile;;
*/ecs.php)
foundFile;;
*/.scrutinizer.yml)
foundFile;;
*/.phpstorm.meta.php)
foundFile;;
*/codecov.yml)
foundFile;;
*/.gitattributes)
foundFile;;
*/.gitignore)
foundFile;;
*/.gitkeep)
foundFile;;
*/.mailmap)
foundFile;;
*/.env)
foundFile;;
*/infection.json.dist)
foundFile;;
*/infection.json)
foundFile;;
*/infection.json5.dist)
foundFile;;
*/infection.json5)
foundFile;;
*/makefile)
foundFile;;
*/.phpunit.result.cache)
foundFile;;
*/phpstan.neon)
foundFile;;
*/phpstan.neon.dist)
foundFile;;
*/phpstan-baseline.neon)
foundFile;;
*/phpmd.xml.dist)
foundFile;;
*/.travis.php.ini)
foundFile;;
*/vendor/*/tests/*)
foundFile;;
*/vendor/*/Tests/*)
foundFile;;
*/vendor/*/test/*)
foundFile;;
*/twig/twig/lib/Twig/Node/Expression/Test/*)
;;
*/twig/twig/lib/Twig/Test/*)
;;
*twig/twig/src/Node/Expression/Test/*)
;;
*/vendor/*/Test/*)
foundFile;;
*/.dependabot/*)
foundFile;;
*/.github/*)
foundFile;;
*/.circleci/*)
foundFile;;
*/vendor/examples/*)
foundFile;;
*/.git/*)
foundFile;;
*vendor/*.rst)
foundFile;;
*vendor/*.po)
foundFile;;
*vendor/*.pot)
foundFile;;
*vendor/*.m4)
foundFile;;
*vendor/*.c)
foundFile;;
*vendor/*.h)
foundFile;;
*vendor/*.sh)
foundFile;;
*vendor/*.w32)
foundFile;;
*.hhconfig)
foundFile;;
*.hhi)
foundFile;;
*.xsd)
foundFile;;
*.xml)
foundFile;;
*vendor/*CONTRIBUTING.md*)
foundFile;;
*CODE_OF_CONDUCT.md*)
foundFile;;
*PERFORMANCE.md*)
foundFile;;
*phar*)
foundFile;;
*) ;;
esac
done
if [ ${found} -gt 0 ]; then
echo 'Some new files to be excluded were found.'
echo 'Please update create-release.sh'
exit 1
else
echo 'Everything looks okay'
exit 0
fi

View File

@ -1,755 +0,0 @@
#!/bin/sh
#
# vim: expandtab sw=4 ts=4 sts=4:
#
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
# More documentation about making a release is available at:
# https://wiki.phpmyadmin.net/pma/Releasing
# Fail on undefined variables
set -u
# Fail on failure
set -e
KITS="all-languages english source"
COMPRESSIONS="zip-7z txz tgz"
# The version series this script is allowed to handle
VERSION_SERIES="6.0"
# Process parameters
version=""
branch=""
do_tag=0
do_stable=0
do_test=0
do_ci=0
do_sign=1
do_pull=0
do_daily=0
do_revision=0
while [ $# -gt 0 ] ; do
case "$1" in
--tag)
do_tag=1
;;
--stable)
do_stable=1
;;
--test)
do_test=1
;;
--revision-info)
do_revision=1
;;
--daily)
do_sign=0
do_pull=1
do_daily=1
do_test=1
;;
--ci)
do_test=1
do_ci=1
if [ -z "$branch" ] ; then
git branch ci
branch="ci"
fi
;;
--no-sign)
do_sign=0
;;
--kits)
KITS="$2"
# Skip one position, the value
shift
;;
--compressions)
COMPRESSIONS="$2"
# Skip one position, the value
shift
;;
--help)
echo "Usages:"
echo " create-release.sh <version> <from_branch> [--tag] [--stable] [--test] [--ci] [--daily] [--revision-info] [--compressions] [--kits] [--no-sign]"
echo ""
echo "If --tag is specified, release tag is automatically created (use this for all releases including pre-releases)"
echo "If --stable is specified, the STABLE branch is updated with this release"
echo "If --test is specified, the testsuite is executed before creating the release"
echo "If --ci is specified, the testsuite is executed and no actual release is created"
echo "If --no-sign is specified, the output files will not be signed"
echo "If --daily is specified, the output files will have snapshot information"
echo "If --revision-info is specified, the output files will contain git revision info"
echo "If --compressions is specified, it changes the compressions available. Space separated values. Valid values: $COMPRESSIONS"
echo "If --kits is specified, it changes the kits to be built. Space separated values. Valid values: $KITS"
echo ""
echo "Examples:"
echo " create-release.sh 5.2.2-dev QA_5_2"
echo " create-release.sh 5.2.2 QA_5_2 --tag --stable"
exit 65
;;
*)
do_test=1
if [ -z "$version" ] ; then
version=$(echo "$1" | tr -d -c '0-9a-z.+-')
if [ "x$version" != "x$1" ] ; then
echo "Invalid version: $1"
exit 1
fi
elif [ -z "$branch" ] ; then
branch=$(echo "$1" | tr -d -c '/0-9A-Za-z_-')
if [ "x$branch" != "x$1" ] ; then
echo "Invalid branch: $1"
exit 1
fi
else
echo "Unknown parameter: $1!"
echo "Use --help to check the syntax."
exit 1
fi
esac
shift
done
if [ -z "$version" ] && [ $do_ci -eq 0 ]; then
echo "Version must be specified!"
exit 1
fi
if [ -z "$branch" ]; then
echo "Branch must be specified!"
exit 1
fi
kit_prefix="phpMyAdmin-$version"
# Checks whether remote branch has local tracking branch
ensure_local_branch() {
if ! git branch | grep -q '^..'"$1"'$' ; then
git branch --track "$1" origin/"$1"
fi
}
# Marks current head of given branch as head of other branch
# Used for STABLE tracking
mark_as_release() {
branch=$1
rel_branch=$2
echo "* Marking release as $rel_branch"
ensure_local_branch "$rel_branch"
git checkout "$rel_branch"
git merge -s recursive -X theirs "$branch"
git checkout master
}
cleanup_composer_vendors() {
echo "* Cleanup of composer packages"
rm -r \
vendor/phpmyadmin/sql-parser/tests/ \
vendor/phpmyadmin/sql-parser/src/Tools/ \
vendor/phpmyadmin/sql-parser/locale/sqlparser.pot \
vendor/phpmyadmin/sql-parser/locale/*/LC_MESSAGES/sqlparser.po \
vendor/phpmyadmin/sql-parser/bin/ \
vendor/phpmyadmin/sql-parser/phpunit.xml.dist \
vendor/phpmyadmin/motranslator/phpunit.xml.dist \
vendor/phpmyadmin/motranslator/psalm-baseline.xml \
vendor/phpmyadmin/motranslator/psalm.xml \
vendor/phpmyadmin/motranslator/tests/ \
vendor/phpmyadmin/shapefile/phpunit.xml.dist \
vendor/phpmyadmin/shapefile/tests/ \
vendor/phpmyadmin/shapefile/examples/ \
vendor/phpmyadmin/shapefile/data/ \
vendor/symfony/service-contracts/Test/ \
vendor/symfony/expression-language/Resources/ \
vendor/symfony/dependency-injection/Loader/schema/services.schema.json \
vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd \
vendor/tecnickcom/tcpdf/tools/ \
vendor/tecnickcom/tcpdf/fonts/ae_fonts_*/ \
vendor/tecnickcom/tcpdf/fonts/dejavu-fonts-ttf-2.*/ \
vendor/tecnickcom/tcpdf/fonts/freefont-*/ \
vendor/tecnickcom/tcpdf/include/sRGB.icc \
vendor/williamdes/mariadb-mysql-kbs/schemas/ \
vendor/williamdes/mariadb-mysql-kbs/dist/merged-raw.json \
vendor/williamdes/mariadb-mysql-kbs/dist/merged-raw.md \
vendor/williamdes/mariadb-mysql-kbs/dist/merged-slim.json \
vendor/williamdes/mariadb-mysql-kbs/dist/merged-ultraslim.php \
vendor/google/recaptcha/app.yaml \
vendor/laminas/laminas-httphandlerrunner/.laminas-ci.json \
vendor/nikic/fast-route/.travis.yml \
vendor/nikic/fast-route/.hhconfig \
vendor/nikic/fast-route/FastRoute.hhi \
vendor/nikic/fast-route/phpunit.xml \
vendor/nikic/fast-route/psalm.xml \
vendor/nikic/fast-route/test/ \
vendor/twig/twig/README.rst \
vendor/webmozart/assert/.php-cs-fixer.php \
vendor/twig/twig/src/Test/ \
vendor/psr/event-dispatcher/.editorconfig \
vendor/psr/http-message/docs/ \
vendor/pragmarx/google2fa/.github/ \
vendor/pragmarx/google2fa-qrcode/.scrutinizer.yml \
vendor/pragmarx/google2fa-qrcode/.travis.yml \
vendor/pragmarx/google2fa-qrcode/phpunit.xml \
vendor/pragmarx/google2fa-qrcode/tests \
vendor/slim/psr7/phpunit.xml.dist \
vendor/slim/psr7/tests/
rm \
vendor/phpmyadmin/motranslator/CODE_OF_CONDUCT.md \
vendor/phpmyadmin/motranslator/CONTRIBUTING.md \
vendor/phpmyadmin/motranslator/PERFORMANCE.md \
vendor/phpmyadmin/shapefile/CONTRIBUTING.md \
vendor/spomky-labs/cbor-php/CODE_OF_CONDUCT.md \
vendor/spomky-labs/cbor-php/RELEASES.md \
vendor/spomky-labs/cbor-php/SECURITY.md \
vendor/spomky-labs/pki-framework/SECURITY.md \
vendor/web-auth/cose-lib/CODE_OF_CONDUCT.md \
vendor/web-auth/cose-lib/RELEASES.md \
vendor/web-auth/cose-lib/SECURITY.md
find vendor/tecnickcom/tcpdf/fonts/ -maxdepth 1 -type f \
-not -name 'dejavusans.*' \
-not -name 'dejavusansb.*' \
-not -name 'helvetica.php' \
-print0 | xargs -0 rm
}
backup_vendor_folder() {
TEMP_FOLDER="$(mktemp -d /tmp/phpMyAdmin.XXXXXXXXX)"
cp -rp ./vendor "${TEMP_FOLDER}"
}
restore_vendor_folder() {
if [ ! -d "${TEMP_FOLDER}" ]; then
echo 'No backup to restore'
exit 1;
fi
rm -r ./vendor
mv "${TEMP_FOLDER}/vendor" ./vendor
rmdir "${TEMP_FOLDER}"
}
get_composer_package_version() {
awk '/require-dev/ {printline = 1; print; next } printline' composer.json | grep "$1" | awk -F [\"] '{print $4}'
}
create_phpunit_sandbox() {
PHPUNIT_VERSION="$(get_composer_package_version 'phpunit/phpunit')"
TEMP_PHPUNIT_FOLDER="$(mktemp -d /tmp/phpMyAdmin-phpunit.XXXXXXXXX)"
cd "${TEMP_PHPUNIT_FOLDER}"
composer require --no-interaction --dev "phpunit/phpunit:${PHPUNIT_VERSION}"
cd -
}
delete_phpunit_sandbox() {
if [ ! -d "${TEMP_PHPUNIT_FOLDER}" ]; then
echo 'No phpunit sandbox to delete'
exit 1;
fi
rm -r "${TEMP_PHPUNIT_FOLDER}"
}
security_checkup() {
if [ ! -f vendor/tecnickcom/tcpdf/tcpdf.php ]; then
echo 'TCPDF should be installed, detection failed !'
exit 1;
fi
if [ ! -f vendor/web-auth/webauthn-lib/src/PublicKeyCredential.php ]; then
echo 'Webauthn-lib should be installed, detection failed !'
exit 1;
fi
if [ ! -f vendor/code-lts/u2f-php-server/src/U2FServer.php ]; then
echo 'U2F-server should be installed, detection failed !'
exit 1;
fi
if [ ! -f vendor/pragmarx/google2fa-qrcode/src/Google2FA.php ]; then
echo 'Google 2FA should be installed, detection failed !'
exit 1;
fi
}
autoload_checkup() {
php <<'CODE'
<?php
$classMapFiles = require __DIR__ . '/vendor/composer/autoload_classmap.php';
$foundFiles = 0;
$notFoundFiles = 0;
foreach ($classMapFiles as $classMapFile) {
if (! file_exists($classMapFile)) {
echo 'Does not exist: ' . $classMapFile . PHP_EOL;
$notFoundFiles++;
continue;
}
$foundFiles++;
}
echo '[autoload class map checkup] Found files: ' . $foundFiles . PHP_EOL;
echo '[autoload class map checkup] NOT found files: ' . $notFoundFiles . PHP_EOL;
$minFilesToHave = 1100;// An arbitrary value based on how many files the autoload has on average
if ($foundFiles < $minFilesToHave) {
echo '[autoload class map checkup] The project expects at least ' . $minFilesToHave . ' in the autoload class map' . PHP_EOL;
exit(1);
}
if ($notFoundFiles > 0) {
echo '[autoload class map checkup] There is some missing files documented in the class map' . PHP_EOL;
exit(1);
}
echo '[autoload class map checkup] The autoload class map seems okay' . PHP_EOL;
CODE
}
# Ensure we have tracking branch
ensure_local_branch "$branch"
VERSION_FILE=src/Version.php
# Keep in sync with update-po script
fetchReleaseFromFile() {
SUFFIX="${1:-}"
php -r "define('VERSION_SUFFIX', '$SUFFIX'); require_once('$VERSION_FILE'); echo \PhpMyAdmin\Version::VERSION;"
}
fetchVersionSeriesFromFile() {
php -r "define('VERSION_SUFFIX', ''); require_once('$VERSION_FILE'); echo \PhpMyAdmin\Version::SERIES;"
}
VERSION_FROM_FILE="$(fetchReleaseFromFile)"
VERSION_SERIES_FROM_FILE="$(fetchVersionSeriesFromFile)"
if [ $do_ci -eq 1 ]; then
VERSION_FROM_FILE="$(fetchReleaseFromFile '+ci')"
version="${VERSION_FROM_FILE}"
fi
if [ "${VERSION_SERIES_FROM_FILE}" != "${VERSION_SERIES}" ]; then
echo "This script can not handle ${VERSION_SERIES_FROM_FILE} version series."
echo "Only ${VERSION_SERIES} version series are allowed, please use your target branch directly or another branch."
echo "By changing branches you will have a release script that was designed for your version series."
exit 1;
fi
echo "The actual configured release is: $VERSION_FROM_FILE"
echo "The actual configured release series is: $VERSION_SERIES_FROM_FILE"
if [ $do_ci -eq 0 ] && [ $do_daily -eq 0 ] ; then
cat <<END
Please ensure you have incremented rc count or version in the repository :
- run ./bin/console set-version $version
- in $VERSION_FILE Version class:
- check that VERSION, MAJOR, MINOR and PATCH are correct.
- in docs/conf.py the line
" version = '$version' "
- in README the "Version" line
- in package.json the line
" "version": "$version", "
- set release date in ChangeLog
Continue (y/n)?
END
read -r do_release
if [ "$do_release" != 'y' ]; then
exit 100
fi
echo "The actual configured release is now: $(fetchReleaseFromFile)"
fi
# Create working copy
mkdir -p release
git worktree prune
workdir_name=phpMyAdmin-$version
workdir=release/$workdir_name
if [ -d "$workdir" ] ; then
echo "Working directory '$workdir' already exists, please move it out of the way"
exit 1
fi
# Add worktree with chosen branch
git worktree add --force "$workdir" "$branch"
cd "$workdir"
if [ $do_pull -eq 1 ] ; then
git pull -q
fi
if [ $do_daily -eq 1 ] ; then
git_head=$(git log -n 1 --format=%H)
git_head_short=$(git log -n 1 --format=%h)
today_date=$(date +'%Y%m%d' -u)
fi
if [ $do_daily -eq 1 ] ; then
echo '* setting the version suffix for the snapshot'
sed -i "s/'versionSuffix' => '.*'/'versionSuffix' => '+$today_date.$git_head_short'/" app/vendor_config.php
php -l app/vendor_config.php
# Fetch it back and refresh $version
VERSION_FROM_FILE="$(fetchReleaseFromFile "+$today_date.$git_head_short")"
version="${VERSION_FROM_FILE}"
echo "The actual configured release is: $VERSION_FROM_FILE"
fi
# Check release version
if [ $do_ci -eq 0 ] && [ -$do_daily -eq 0 ] ; then
if ! grep -q "VERSION = '$version'" $VERSION_FILE ; then
echo "There seems to be wrong version in $VERSION_FILE!"
exit 2
fi
if ! grep -q "version = '$version'" docs/conf.py ; then
echo "There seems to be wrong version in docs/conf.py"
exit 2
fi
if ! grep -q "Version $version\$" README ; then
echo "There seems to be wrong version in README"
exit 2
fi
if ! grep -q "\"version\": \"$version\"," package.json ; then
echo "There seems to be wrong version in package.json"
exit 2
fi
fi
# Save the build date
if [ $do_daily -eq 1 ] ; then
LC_ALL=C date -u > RELEASE-DATE-"$VERSION_SERIES_FROM_FILE"+snapshot
else
LC_ALL=C date -u > RELEASE-DATE-"$version"
fi
# Building documentation
echo "* Running sphinx-build (version: $(sphinx-build --version))"
echo "* Generating documentation"
LC_ALL=C make -C docs html
find docs -name '*.pyc' -print0 | xargs -0 -r rm -f
# Check for gettext support
if [ -d resources/po ] ; then
echo "* Generating mo files"
./bin/generate-mo
if [ -f ./bin/remove-incomplete-mo ] ; then
echo "* Removing incomplete translations"
./bin/remove-incomplete-mo
fi
fi
if [ -f ./bin/line-counts.sh ] ; then
echo "* Generating line counts"
./bin/line-counts.sh
fi
echo "* Removing unneeded files"
# Remove developer information
rm -r .github CODE_OF_CONDUCT.md DCO
# Testsuite setup
rm .scrutinizer.yml .weblate codecov.yml
# Remove Doctum config file
rm tests/doctum-config.php
# Remove readme for github
rm README.rst
if [ -f ./bin/console ]; then
# Update the vendors to have the dev vendors
composer install --no-interaction
# Warm up the routing cache for 5.1+ releases
./bin/console cache:warmup --routing
if [ $do_revision -eq 1 ] ; then
./bin/console write-revision-info
fi
fi
echo "* Writing the version to composer.json (version: $version)"
composer config version "$version"
# Okay, there is no way to tell composer to install
# suggested package. Let's require it and then revert
# composer.json to original state.
cp composer.json composer.json.backup
COMPOSER_VERSION="$(composer --version)"
echo "* Running composer (version: $COMPOSER_VERSION)"
composer install --no-interaction --no-dev
# Parse the required versions from composer.json
PACKAGE_LIST='tecnickcom/tcpdf pragmarx/google2fa-qrcode bacon/bacon-qr-code code-lts/u2f-php-server web-auth/webauthn-lib'
set --
for PACKAGES in $PACKAGE_LIST
do
PKG_VERSION="$(get_composer_package_version "$PACKAGES")"
set -- "$@" "$PACKAGES:$PKG_VERSION"
done
echo "* Installing composer packages '$*'"
# Allows word splitting
# shellcheck disable=SC2086
composer require --no-interaction --update-no-dev "$@"
echo "* Running a security checkup"
security_checkup
echo "* Cleaning up vendor folders"
mv composer.json.backup composer.json
cleanup_composer_vendors
echo "* Re-generating the autoload class map"
# https://getcomposer.org/doc/articles/autoloader-optimization.md#what-does-it-do-
# We removed some files, we also need that composer removes them from autoload class maps
# If the class is in the class map (as explained in the link above) then it is assumed to exist as a file
composer dump-autoload --no-interaction --optimize --dev
echo "* Running an autoload checkup"
autoload_checkup
echo "* Running a security checkup"
security_checkup
if [ -f package.json ] ; then
echo "* Running Yarn"
yarn install --production
fi
# Remove git metadata
rm .git
find . -name .gitignore -print0 | xargs -0 -r rm
find . -name .gitkeep -print0 | xargs -0 -r rm
find . -name .gitattributes -print0 | xargs -0 -r rm
if [ $do_test -eq 1 ] ; then
# Move the folder out and install dev vendors
create_phpunit_sandbox
# Backup the files because the new autoloader will change the composer vendor
backup_vendor_folder
# Generate an autoload for test class files (and include dev namespaces)
composer dump-autoload --dev || php -r "echo 'Requires: composer >= v2.1.2' . PHP_EOL; exit(1);"
"${TEMP_PHPUNIT_FOLDER}/vendor/bin/phpunit" --no-coverage --testsuite unit
test_ret=$?
if [ $do_ci -eq 1 ] ; then
cd ../..
rm -r "$workdir"
git worktree prune
if [ "$branch" = "ci" ] ; then
git branch -D ci
fi
exit $test_ret
fi
if [ $test_ret -ne 0 ] ; then
exit $test_ret
fi
# Remove PHPUnit cache file
rm -f .phpunit.result.cache
# Generate an normal autoload (this is just a security, because normally the vendor folder will be restored)
composer dump-autoload
# Remove libs installed for testing
rm -r build
delete_phpunit_sandbox
restore_vendor_folder
fi
security_checkup
cd ..
SIGN_FILES=""
# Prepare all kits
for kit in $KITS ; do
echo "* Building kit: $kit"
# Copy all files
name=$kit_prefix-$kit
cp -r "$workdir_name" "$name"
# Cleanup translations
cd "$name"
./bin/internal/lang-cleanup.sh "$kit"
# Remove tests, source code,...
if [ "$kit" != source ] ; then
echo "* Removing source files"
# Testsuite
rm -r tests/
# Template test files
rm -r resources/templates/test/
rm phpunit.xml.*
rm .editorconfig .browserslistrc .eslintignore .jshintrc .eslintrc.json .stylelintrc.json psalm.xml psalm-baseline.xml phpstan.neon.dist phpstan-baseline.neon phpcs.xml.dist jest.config.cjs infection.json5.dist .phpstorm.meta.php
# Gettext po files (if they were not removed by ./bin/internal/lang-cleanup.sh)
rm -rf resources/po
# Documentation source code
mv docs/html htmldoc
rm -r docs
mkdir public/docs
mv htmldoc public/docs/html
rm public/docs/html/.buildinfo public/docs/html/objects.inv
rm -r node_modules
# Remove bin files for non source version
# https://github.com/phpmyadmin/phpmyadmin/issues/16033
rm -r vendor/bin
# Remove developer scripts
rm -r bin
fi
# Remove possible tmp folder
rm -rf tmp
cd ..
# Remove tar file possibly left from previous run
rm -f "$name".tar
# Prepare distributions
for comp in $COMPRESSIONS ; do
case $comp in
tbz|tgz|txz)
if [ ! -f "$name".tar ] ; then
echo "* Creating $name.tar"
tar --owner=root --group=root --numeric-owner --sort=name -cf "$name".tar "$name"
fi
if [ "$comp" = txz ] ; then
echo "* Creating $name.tar.xz"
xz -9k "$name".tar
SIGN_FILES="$SIGN_FILES $name.tar.xz"
fi
if [ "$comp" = tgz ] ; then
echo "* Creating $name.tar.gz"
gzip -9c "$name".tar > "$name".tar.gz
SIGN_FILES="$SIGN_FILES $name.tar.gz"
fi
;;
zip-7z)
echo "* Creating $name.zip"
7za a -bd -tzip "$name".zip "$name" > /dev/null
SIGN_FILES="$SIGN_FILES $name.zip"
;;
*)
echo "WARNING: ignoring compression '$comp', not known!"
;;
esac
done
# Cleanup
rm -f "$name".tar
# Remove directory with current dist set
rm -r "$name"
done
# Cleanup
rm -r "$workdir_name"
git worktree prune
# Signing of files with default GPG key
if [ $do_sign -eq 1 ] ; then
echo "* Signing and making .sha{1,256} files"
else
echo "* Making .sha{1,256} files"
fi
for file in $SIGN_FILES; do
if [ $do_sign -eq 1 ] ; then
gpg --detach-sign --armor "$file"
fi
sha1sum "$file" > "$file".sha1
sha256sum "$file" > "$file".sha256
done
if [ $do_daily -eq 1 ] ; then
cat > "$kit_prefix".json << EOT
{
"date": "$(date --iso-8601=seconds)",
"commit": "$git_head"
}
EOT
exit 0
fi
echo ""
echo ""
echo ""
echo "Files:"
echo "------"
ls -la $SIGN_FILES
cd ..
# Tag as release
if [ $do_tag -eq 1 ] ; then
echo
echo "Additional tasks:"
tagname=RELEASE_$(echo "$version" | tr . _ | tr '[:lower:]' '[:upper:]' | tr -d -)
echo "* Tagging release as $tagname"
git tag -s -a -m "Released $version" "$tagname" "$branch"
echo " Dont forget to push tags using: git push --tags"
fi
# Mark as stable release
if [ $do_stable -eq 1 ] ; then
mark_as_release "$branch" STABLE
fi
cat <<END
Todo now:
---------
1. Push the new tag upstream, with a command like git push origin --tags
2. Push the new STABLE branch upstream
3. prepare a release/phpMyAdmin-$version-notes.html explaining in short the goal of
this release and paste into it the ChangeLog for this release, followed
by the notes of all previous incremental versions (i.e. 4.4.9 through 4.4.0)
4. upload the files to our file server, use bin/internal/upload-release, eg.:
./bin/internal/upload-release $version release
5. add a news item to our website; a good idea is to include a link to the release notes such as https://www.phpmyadmin.net/files/4.4.10/
6. send a short mail (with list of major changes) to
developers@phpmyadmin.net
news@phpmyadmin.net
Don't forget to update the Description section in the announcement,
based on documentation.
7. increment rc count or version in the repository :
- run ./bin/console set-version $version
- in $VERSION_FILE Version class:
- check that VERSION, MAJOR, MINOR and PATCH are correct.
- in README the "Version" line
" Version 2.7.1-dev "
- in package.json the line
" "version": " 2.7.1-dev", "
- in docs/conf.py (if it exists) the line
" version = '2.7.1-dev' "
8. on https://github.com/phpmyadmin/phpmyadmin/milestones close the milestone corresponding to the released version (if this is a stable release) and open a new one for the next minor release
9. for a major release, update demo/php/versions.ini in the scripts repository so that the demo server shows current versions
10. in case of a new major release ('y' in x.y.0), update the pmaweb/settings.py in website repository to include the new major releases
11. update the Dockerfile in the docker repository to reflect the new version and create a new annotated tag (such as with git tag -s -a 4.7.9-1 -m "Version 4.7.9-1"). Remember to push the tag with git push origin {tagName}
END

View File

@ -1,52 +0,0 @@
#!/bin/sh
#
# vim: expandtab sw=4 ts=4 sts=4:
#
# Script for removing language selection from phpMyAdmin
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
if [ $# -lt 1 ] ; then
echo "Usage: lang-cleanup.sh type"
echo "Type can be one of:"
echo " all-languages - nothing will be done"
echo " source - nothing will be done"
echo " english - no translations will be kept"
echo " langcode - keeps language"
echo
echo "Languages can be specified multiple times"
exit 1
fi
# Expression for find
match=""
for type in "$@" ; do
case $type in
all-languages|source)
exit 0
;;
english)
rm -rf resources/po
rm -rf resources/locale
rm -rf vendor/phpmyadmin/sql-parser/locale
exit 0
;;
*)
match="$match -and -not -name $type.po -and -not -path resources/locale/$type/LC_MESSAGES/phpmyadmin.mo -and -not -path vendor/phpmyadmin/sql-parser/locale/$type/LC_MESSAGES/sqlparser.mo"
;;
esac
done
# Delete unwanted languages
# shellcheck disable=SC2086
find resources/po resources/locale vendor/phpmyadmin/sql-parser/locale -type f $match -print0 | xargs -0r rm
# Delete empty directories
rmdir --ignore-fail-on-non-empty resources/locale/*/*
rmdir --ignore-fail-on-non-empty resources/locale/*
rmdir --ignore-fail-on-non-empty vendor/phpmyadmin/sql-parser/locale/*/*
rmdir --ignore-fail-on-non-empty vendor/phpmyadmin/sql-parser/locale/*

View File

@ -1,11 +0,0 @@
#!/bin/sh
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
for x in resources/po/*.po ; do
grep 'Team' "$x" | sed 's/.*: \(.*\)<.*/\1/'
git shortlog -sne --no-merges -- "$x" | grep '^ [ 0-9][0-9]\{3\}'
done

View File

@ -1,76 +0,0 @@
#!/bin/bash
#
# vim: expandtab sw=4 ts=4 sts=4:
#
# This requires Bash for the search and replace substitution to escape dots
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
# Fail on undefined variables
set -u
# Fail on failure
set -e
printHelp () {
echo
echo "Please pass the new version number as a command line argument such as"
echo "$0 -v 5.0.0-dev"
echo
}
if [ $# -eq 0 ]
then
printHelp
exit 1
fi
if [ "$1" = '-v' ]
then
newVersion=$2
else
printHelp
exit 2
fi
# If we're in the scripts directory, we need to do all our work up a directory level
if [ "$(basename "$(pwd)")" = 'bin' ]
then
dir='../'
else
dir=''
fi
# There are half a dozen ways to do this, including individually recreating the line of
# each file (search for 'version =' in conf.py and replace it with 'version = 5.0.0-dev'
# for instance), and while that's more precise this should work with less to fix if a line changes.
# This method wasn't selected for any particular strength.
oldVersion="$(grep 'version =' "${dir}"docs/conf.py | cut -d "'" -f2)"
echo "Changing from ${oldVersion} to ${newVersion}..."
# Escape the dot for sed
oldVersion=${oldVersion//./\.}
newVersion=${newVersion//./\.}
for f in README docs/conf.py package.json
do
if ! grep --quiet "${oldVersion}" "${dir}${f}"
then
# There may be a better way to test for a failure of the substitution itself, such as using the 'q' directive with sed
# See https://stackoverflow.com/questions/15965073/return-code-of-sed-for-no-match
echo "FAILED! Substitution string ${oldVersion} not found in ${dir}${f}"
fi
sed -i "s/${oldVersion}/${newVersion}/g" "${dir}${f}"
done
echo
echo "- Next, you need to manually edit ChangeLog to manually change the version number and set the release date, and verify the changes with 'git diff'."
echo "- You will probably want to call: \"./bin/console set-version ${newVersion}\" afterwards"
echo "- You should check if you need to change the composer.json file and the theme.json file for each bundled theme."
echo " To change the composer.json file you can call something like: \"composer config extra.branch-alias.dev-master \"5.2.x-dev\"\""
echo "- Suggested commit message: Prepare for version ${newVersion}"

View File

@ -1,69 +0,0 @@
#!/bin/sh
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
set -e
set -u
if [ $# -lt 2 ] ; then
echo 'Usage: upload-release VERSION [DIR]'
echo 'Must be called in directory with binaries or with path'
exit 1
fi
REL=$(echo "$1" | tr -d -c '0-9a-z.-')
if [ "x$REL" != "x$1" ] ; then
echo "Invalid version: $1"
exit 1
fi
if [ $# -gt 1 ] ; then
cd "$2"
fi
BATCH=$(mktemp)
cat > "$BATCH" <<EOT
cd /mnt/storage/files/phpMyAdmin
mkdir $REL
cd $REL
put phpMyAdmin-$REL-all-languages.tar.xz
put phpMyAdmin-$REL-english.tar.xz
put phpMyAdmin-$REL-all-languages.tar.gz
put phpMyAdmin-$REL-english.tar.gz
put phpMyAdmin-$REL-all-languages.zip
put phpMyAdmin-$REL-english.zip
put phpMyAdmin-$REL-all-languages.tar.xz.asc
put phpMyAdmin-$REL-english.tar.xz.asc
put phpMyAdmin-$REL-all-languages.tar.gz.asc
put phpMyAdmin-$REL-english.tar.gz.asc
put phpMyAdmin-$REL-all-languages.zip.asc
put phpMyAdmin-$REL-english.zip.asc
put phpMyAdmin-$REL-all-languages.tar.xz.sha256
put phpMyAdmin-$REL-english.tar.xz.sha256
put phpMyAdmin-$REL-all-languages.tar.gz.sha256
put phpMyAdmin-$REL-english.tar.gz.sha256
put phpMyAdmin-$REL-all-languages.zip.sha256
put phpMyAdmin-$REL-english.zip.sha256
put phpMyAdmin-$REL-all-languages.tar.xz.sha1
put phpMyAdmin-$REL-english.tar.xz.sha1
put phpMyAdmin-$REL-all-languages.tar.gz.sha1
put phpMyAdmin-$REL-english.tar.gz.sha1
put phpMyAdmin-$REL-all-languages.zip.sha1
put phpMyAdmin-$REL-english.zip.sha1
put phpMyAdmin-$REL-notes.html
put phpMyAdmin-$REL-source.tar.xz
put phpMyAdmin-$REL-source.tar.xz.asc
put phpMyAdmin-$REL-source.tar.xz.sha256
put phpMyAdmin-$REL-source.tar.xz.sha1
EOT
# Upload to our file server
sftp -P 11022 -f -b "$BATCH" files@hertz.phpmyadmin.net
rm "$BATCH"
# Sync files to CDN
ssh -xka2 -p 11022 files@hertz.phpmyadmin.net ./bin/sync-files-cdn

View File

@ -1,30 +0,0 @@
#!/usr/bin/env php
<?php
/* vim: set expandtab sw=4 ts=4 sts=4 ft=php: */
declare(strict_types=1);
if (! defined('ROOT_PATH')) {
define('ROOT_PATH', dirname(__DIR__) . DIRECTORY_SEPARATOR);
}
$tmpDir = ROOT_PATH . 'twig-templates';
/* Read replacements file */
$replacements = json_decode(file_get_contents($tmpDir . '/replace.json'), true);
/* Read files list */
$filesList = file_get_contents($tmpDir . '/filesList');
$options = getopt('', ['reverse::']);
foreach ($replacements as $templateName => $data) {
if (isset($options['reverse'])) {
$filesList = str_replace($data[0], $templateName, $filesList);
} else {
$filesList = str_replace($templateName, $data[0], $filesList);
}
}
/* Write back files list */
file_put_contents($tmpDir . '/filesList', $filesList);

View File

@ -1,75 +0,0 @@
#!/bin/sh
#
# Removes mo files for incomplete translations
#
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
set -e
#
# How many percent needs to be translated
#
THRESHOLD=40
#
# Generated output file
#
TMPOUTPUTFILE=app/language_stats.inc.php.tmp
OUTPUTFILE=app/language_stats.inc.php
if [ -n "$1" ] ; then
THRESHOLD=$1
fi
{
echo '<?php'
echo '/**'
echo ' * Automatically generated file, do not edit!'
echo ' * Generated by bin/remove-incomplete-mo'
echo ' */'
echo ''
echo "return ["
} > $TMPOUTPUTFILE
check() {
TMPOUTPUTFILE=$2
lang=$(echo "$1" | sed 's@resources/po/\(.*\)\.po@\1@')
STATS=$(LC_ALL=C msgfmt --statistics -o /dev/null "$1" 2>&1)
if echo "$STATS" | grep -q ' translated ' ; then
TRANSLATED=$(echo "$STATS" | sed 's/\(^\|.* \)\([0-9]*\) translated.*/\2/')
else
TRANSLATED=0
fi
if echo "$STATS" | grep -q ' fuzzy ' ; then
FUZZY=$(echo "$STATS" | sed 's/\(^\|.* \)\([0-9]*\) fuzzy.*/\2/')
else
FUZZY=0
fi
if echo "$STATS" | grep -q ' untranslated ' ; then
UNTRANSLATED=$(echo "$STATS" | sed 's/\(^\|.* \)\([0-9]*\) untranslated.*/\2/')
else
UNTRANSLATED=0
fi
PERCENT=$((100 * TRANSLATED / ( TRANSLATED + FUZZY + UNTRANSLATED )))
echo " '$lang' => $PERCENT," >> "$TMPOUTPUTFILE"
if [ "$PERCENT" -lt "$THRESHOLD" ] ; then
echo "Removing $lang, only $PERCENT%"
rm -f resources/locale/"$lang"/LC_MESSAGES/phpmyadmin.mo
rmdir resources/locale/"$lang"/LC_MESSAGES
rmdir resources/locale/"$lang"
fi
}
for x in resources/po/*.po ; do
check "$x" "$TMPOUTPUTFILE"
done
echo '];' >> "$TMPOUTPUTFILE"
mv "$TMPOUTPUTFILE" $OUTPUTFILE

View File

@ -1,63 +0,0 @@
#!/bin/bash
#
# Shell script that creates a new transformation plug-in (both main and
# abstract class) using a template.
#
# The 'description' parameter will add a new entry in the language file.
# Watch out for special escaping.
#
# $1: MIMEType
# $2: MIMESubtype
# $3: Transformation Name
# $4: (optional) Description
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
if [ $# -ne 3 ] && [ $# -ne 4 ]; then
echo -e "Usage: ./generator_plugin.sh MIMEType MIMESubtype TransformationName [Description]\n"
exit 65
fi
# make sure that the MIME Type, MIME Subtype and Transformation names
# are in the correct format
# make all names lowercase
MT="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
MS="$(echo "$2" | tr '[:upper:]' '[:lower:]')"
TN="$(echo "$3" | tr '[:upper:]' '[:lower:]')"
# make first letter uppercase
MT="${MT^}"
MS="${MS^}"
TN="${TN^}"
# make the first letter after each underscore uppercase
# define the name of the main class file and of its template
CLASS_NAME=$(echo "$MT"_"$MS"_"$TN" | sed -e 's/_./\U&\E/g')
BASE_DIR="./src/Plugins/Transformations"
ClassFile="$BASE_DIR"/"$CLASS_NAME".php
Template="$BASE_DIR"/TEMPLATE
# define the name of the abstract class file and its template
AbstractClassFile="$BASE_DIR"/Abs/"$TN"TransformationsPlugin.php
AbstractTemplate="$BASE_DIR"/TEMPLATE_ABSTRACT
# replace template names with argument names
sed "s/\[MIMEType]/$MT/; s/\[MIMESubtype\]/$MS/; s/\[TransformationName\]/$TN/;" < $Template > "$ClassFile"
echo "Created $ClassFile"
GenerateAbstractClass=1
if [ -n "$4" ]; then
if [ "$4" == "--generate_only_main_class" ]; then
if [ -e "$AbstractClassFile" ]; then
GenerateAbstractClass=0
fi
fi
fi
if [ $GenerateAbstractClass -eq 1 ]; then
# replace template names with argument names
sed "s/\[TransformationName\]/$TN/; s/Description of the transformation./$4/;" < $AbstractTemplate > "$AbstractClassFile"
echo "Created $AbstractClassFile"
fi

View File

@ -1,79 +0,0 @@
#!/bin/sh
# vim: expandtab sw=4 ts=4 sts=4:
export LC_ALL=C
# Do not run as CGI
if [ -n "$GATEWAY_INTERFACE" ] ; then
echo 'Can not invoke as CGI!'
exit 1
fi
# Exit on failure
set -e
# Generate Twig template cache in clean dir
rm -rf twig-templates/
php bin/console cache:warmup --twig-po --env development
# Update pot (template), ensure that advisor is at the end
LOCS=$(find resources/po -name '*.po' | sed 's@.*/\(.*\)\.po@\1@')
find . -name '*.php' -not -path './tests/*' -not -path './resources/po/*' -not -path './tmp/*' -not -path './release/*' -not -path './node_modules/*' -not -path './vendor/*' > twig-templates/filesList
php ./bin/match-twig-cache
sort --dictionary-order --ignore-case --output ./twig-templates/filesListTemp < ./twig-templates/filesList
mv ./twig-templates/filesListTemp ./twig-templates/filesList
php ./bin/match-twig-cache --reverse
# Allows word splitting for files list.
# shellcheck disable=SC2046
xgettext \
-d phpmyadmin \
--msgid-bugs-address=translators@phpmyadmin.net \
-o resources/po/phpmyadmin.pot \
--language=PHP \
--add-comments=l10n \
--add-location \
--debug \
--from-code=utf-8 \
--keyword=__ --keyword=_gettext --keyword=_pgettext:1c,2 --keyword=_ngettext:1,2 \
--copyright-holder="phpMyAdmin devel team" \
$(cat ./twig-templates/filesList)
# Fixup filenames for Twig templates
php bin/console fix-po-twig
# Remote twig templates
rm -rf twig-templates/
# Keep in sync with create-release.sh
fetchReleaseFromFile() {
php -r "define('VERSION_SUFFIX', ''); require_once('src/Version.php'); echo \PhpMyAdmin\Version::VERSION;"
}
ver="$(fetchReleaseFromFile)"
sed -i.~ '
s/SOME DESCRIPTIVE TITLE/phpMyAdmin translation/;
s/PACKAGE/phpMyAdmin/;
s/(C) YEAR/(C) 2003 - '"$(date +%Y)"'/;
s/VERSION/'"$ver"'/;
' resources/po/phpmyadmin.pot
# Update po files (translations)
for loc in $LOCS ; do
sed -i.~ '
s/SOME DESCRIPTIVE TITLE/phpMyAdmin translation/;
s/PACKAGE/phpMyAdmin/;
s/(C) YEAR/(C) 2003 - '"$(date +%Y)"'/;
s/VERSION/'"$ver"'/;
s/Project-Id-Version: phpMyAdmin .*/Project-Id-Version: phpMyAdmin '"$ver"'\\n"/;
' resources/po/"$loc".po
msgmerge --previous -U resources/po/"$loc".po resources/po/phpmyadmin.pot
done
# Commit changes
git add resources/po/*.po resources/po/phpmyadmin.pot
git commit -s -m 'Update po files
[ci skip]'

347
browse_foreigners.php Normal file
View File

@ -0,0 +1,347 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* display selection for relational field values
*
* @package PhpMyAdmin
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/transformations.lib.php';
/**
* Sets globals from $_REQUEST
*/
$request_params = array(
'field',
'fieldkey',
'foreign_filter',
'pos',
'rownumber'
);
foreach ($request_params as $one_request_param) {
if (isset($_REQUEST[$one_request_param])) {
$GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
}
}
PMA_Util::checkParameters(array('db', 'table', 'field'));
$response = PMA_Response::getInstance();
$response->getFooter()->setMinimal();
$header = $response->getHeader();
$header->disableMenu();
$header->setBodyId('body_browse_foreigners');
/**
* Displays the frame
*/
$cfgRelation = PMA_getRelationsParam();
$foreigners = ($cfgRelation['relwork'] ? PMA_getForeigners($db, $table) : false);
$override_total = true;
if (! isset($pos)) {
$pos = 0;
}
$foreign_limit = 'LIMIT ' . $pos . ', ' . $GLOBALS['cfg']['MaxRows'] . ' ';
if (isset($foreign_navig) && $foreign_navig == __('Show all')) {
unset($foreign_limit);
}
$foreignData = PMA_getForeignData(
$foreigners, $field, $override_total,
isset($foreign_filter) ? $foreign_filter : '', $foreign_limit
);
if (isset($rownumber)) {
$rownumber_param = '&amp;rownumber=' . urlencode($rownumber);
} else {
$rownumber_param = '';
}
$gotopage = '';
$showall = '';
if (is_array($foreignData['disp_row'])) {
if ($cfg['ShowAll']
&& ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows'])
) {
$showall = '<input type="submit" name="foreign_navig" value="'
. __('Show all') . '" />';
}
$session_max_rows = $GLOBALS['cfg']['MaxRows'];
$pageNow = @floor($pos / $session_max_rows) + 1;
$nbTotalPage = @ceil($foreignData['the_total'] / $session_max_rows);
if ($foreignData['the_total'] > $GLOBALS['cfg']['MaxRows']) {
$gotopage = PMA_Util::pageselector(
'pos',
$session_max_rows,
$pageNow,
$nbTotalPage,
200,
5,
5,
20,
10,
__('Page number:')
);
}
}
// When coming from Table/Zoom search
if (isset($_REQUEST['fromsearch'])) {
// In table or zoom search, input fields are named "criteriaValues"
$element_name = " var field = 'criteriaValues';\n";
} else {
// In insert/edit, input fields are named "fields"
$element_name = " var field = 'fields';\n";
}
if (isset($rownumber)) {
$element_name .= " var element_name = field + '[multi_edit]["
. htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n"
. " var null_name = field_null + '[multi_edit]["
. htmlspecialchars($rownumber) . "][' + fieldmd5 + ']';\n";
} else {
$element_name .= "var element_name = field + '[]'";
}
$error = PMA_jsFormat(
__(
'The target browser window could not be updated. '
. 'Maybe you have closed the parent window, or '
. 'your browser\'s security settings are '
. 'configured to block cross-window updates.'
)
);
if (! isset($fieldkey) || ! is_numeric($fieldkey)) {
$fieldkey = 0;
}
$code = <<<EOC
self.focus();
function formupdate(fieldmd5, key) {
var \$inline = window.opener.jQuery('.browse_foreign_clicked');
if (\$inline.length != 0) {
\$inline.removeClass('browse_foreign_clicked')
// for grid editing,
// puts new value in the previous element which is
// a span with class curr_value, and trigger .change()
.prev('.curr_value').text(key).change();
// for zoom-search editing, puts new value in the previous
// element which is an input field
\$inline.prev('input[type=text]').val(key);
self.close();
return false;
}
if (opener && opener.document && opener.document.insertForm) {
var field = 'fields';
var field_null = 'fields_null';
$element_name
var element_name_alt = field + '[$fieldkey]';
if (opener.document.insertForm.elements[element_name]) {
// Edit/Insert form
opener.document.insertForm.elements[element_name].value = key;
if (opener.document.insertForm.elements[null_name]) {
opener.document.insertForm.elements[null_name].checked = false;
}
self.close();
return false;
} else if (opener.document.insertForm.elements[element_name_alt]) {
// Search form
opener.document.insertForm.elements[element_name_alt].value = key;
self.close();
return false;
}
}
alert('$error');
}
EOC;
$header->getScripts()->addCode($code);
// HTML output
$output = '<form action="browse_foreigners.php" method="post">'
. '<fieldset>'
. PMA_generate_common_hidden_inputs($db, $table)
. '<input type="hidden" name="field" value="' . htmlspecialchars($field) . '" />'
. '<input type="hidden" name="fieldkey" value="'
. (isset($fieldkey) ? htmlspecialchars($fieldkey) : '') . '" />';
if (isset($rownumber)) {
$output .= '<input type="hidden" name="rownumber" value="'
. htmlspecialchars($rownumber) . '" />';
}
$output .= '<span class="formelement">'
. '<label for="input_foreign_filter">' . __('Search') . ':' . '</label>'
. '<input type="text" name="foreign_filter" id="input_foreign_filter" value="'
. (isset($foreign_filter) ? htmlspecialchars($foreign_filter) : '') . '" />'
. '<input type="submit" name="submit_foreign_filter" value="'
. __('Go') . '" />'
. '</span>'
. '<span class="formelement">' . $gotopage . '</span>'
. '<span class="formelement">' . $showall . '</span>'
. '</fieldset>'
. '</form>';
$output .= '<table width="100%">';
if (is_array($foreignData['disp_row'])) {
$header = '<tr>
<th>' . __('Keyname') . '</th>
<th>' . __('Description') . '</th>
<td width="20%"></td>
<th>' . __('Description') . '</th>
<th>' . __('Keyname') . '</th>
</tr>';
$output .= '<thead>' . $header . '</thead>' . "\n"
. '<tfoot>' . $header . '</tfoot>' . "\n"
. '<tbody>' . "\n";
$values = array();
$keys = array();
foreach ($foreignData['disp_row'] as $relrow) {
if ($foreignData['foreign_display'] != false) {
$values[] = $relrow[$foreignData['foreign_display']];
} else {
$values[] = '';
}
$keys[] = $relrow[$foreignData['foreign_field']];
}
asort($keys);
$hcount = 0;
$odd_row = true;
$val_ordered_current_row = 0;
$val_ordered_current_equals_data = false;
$key_ordered_current_equals_data = false;
foreach ($keys as $key_ordered_current_row => $value) {
$hcount++;
if ($cfg['RepeatCells'] > 0 && $hcount > $cfg['RepeatCells']) {
$output .= $header;
$hcount = 0;
$odd_row = true;
}
$key_ordered_current_key = $keys[$key_ordered_current_row];
$key_ordered_current_val = $values[$key_ordered_current_row];
$val_ordered_current_key = $keys[$val_ordered_current_row];
$val_ordered_current_val = $values[$val_ordered_current_row];
$val_ordered_current_row++;
if (PMA_strlen($val_ordered_current_val) <= $cfg['LimitChars']) {
$val_ordered_current_val = htmlspecialchars(
$val_ordered_current_val
);
$val_ordered_current_val_title = '';
} else {
$val_ordered_current_val_title = htmlspecialchars(
$val_ordered_current_val
);
$val_ordered_current_val = htmlspecialchars(
PMA_substr($val_ordered_current_val, 0, $cfg['LimitChars'])
. '...'
);
}
if (PMA_strlen($key_ordered_current_val) <= $cfg['LimitChars']) {
$key_ordered_current_val = htmlspecialchars(
$key_ordered_current_val
);
$key_ordered_current_val_title = '';
} else {
$key_ordered_current_val_title = htmlspecialchars(
$key_ordered_current_val
);
$key_ordered_current_val = htmlspecialchars(
PMA_substr(
$key_ordered_current_val, 0, $cfg['LimitChars']
) . '...'
);
}
if (! empty($data)) {
$val_ordered_current_equals_data = $val_ordered_current_key == $data;
$key_ordered_current_equals_data = $key_ordered_current_key == $data;
}
$output .= '<tr class="noclick ' . ($odd_row ? 'odd' : 'even') . '">';
$odd_row = ! $odd_row;
$output .= '<td class="nowrap">'
. ($key_ordered_current_equals_data ? '<strong>' : '')
. '<a href="#" title="' . __('Use this value')
. ($key_ordered_current_val_title != ''
? ': ' . $key_ordered_current_val_title
: '') . '"'
. ' onclick="formupdate(\'' . md5($field) . '\', \''
. PMA_jsFormat($key_ordered_current_key, false) . '\'); return false;">'
. htmlspecialchars($key_ordered_current_key)
. '</a>' . ($key_ordered_current_equals_data ? '</strong>' : '')
. '</td>';
$output .= '<td>'
. ($key_ordered_current_equals_data ? '<strong>' : '')
. '<a href="#" title="' . __('Use this value')
. ($key_ordered_current_val_title != '' ? ': '
. $key_ordered_current_val_title : '') . '" onclick="formupdate(\''
. md5($field) . '\', \''
. PMA_jsFormat($key_ordered_current_key, false)
. '\'); return false;">'
. $key_ordered_current_val . '</a>'
. ($key_ordered_current_equals_data ? '</strong>' : '')
. '</td>';
$output .= '<td width="20%">'
. '<img src="' . $GLOBALS['pmaThemeImage'] . 'spacer.png" alt=""'
. ' width="1" height="1" /></td>';
$output .= '<td>'
. ($val_ordered_current_equals_data ? '<strong>' : '')
. '<a href="#" title="' . __('Use this value')
. ($val_ordered_current_val_title != '' ? ': '
. $val_ordered_current_val_title : '') . '" onclick="formupdate(\''
. md5($field) . '\', \''
. PMA_jsFormat($val_ordered_current_key, false)
. '\'); return false;">'
. $val_ordered_current_val . '</a>'
. ($val_ordered_current_equals_data ? '</strong>' : '')
. '</td>';
$output .= '<td class="nowrap">'
. ($val_ordered_current_equals_data ? '<strong>' : '')
. '<a href="#" title="' . __('Use this value')
. ($val_ordered_current_val_title != ''
? ': ' . $val_ordered_current_val_title : '')
. '" onclick="formupdate(\'' . md5($field) . '\', \''
. PMA_jsFormat($val_ordered_current_key, false) . '\'); return false;">'
. htmlspecialchars($val_ordered_current_key)
. '</a>' . ($val_ordered_current_equals_data ? '</strong>' : '')
. '</td>';
$output .= '</tr>';
} // end while
}
$output .= '</tbody>'
. '</table>';
$response->addHtml($output);
?>

115
build.xml Normal file
View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="phpMyAdmin" default="build" basedir=".">
<property name="source" value="."/>
<property name="source_comma_sep" value="."/>
<fileset dir="${source}" includes="js/*.js" id="jsfiles" />
<pathconvert pathsep=" " property="js-list" refid="jsfiles" />
<target name="clean" description="Clean up and create artifact directories">
<delete dir="${basedir}/build/api"/>
<delete dir="${basedir}/build/code-browser"/>
<delete dir="${basedir}/build/coverage"/>
<delete dir="${basedir}/build/logs"/>
<delete dir="${basedir}/build/pdepend"/>
<mkdir dir="${basedir}/build/api"/>
<mkdir dir="${basedir}/build/code-browser"/>
<mkdir dir="${basedir}/build/coverage"/>
<mkdir dir="${basedir}/build/logs"/>
<mkdir dir="${basedir}/build/pdepend"/>
</target>
<target name="phpunit" description="Run unit tests using PHPUnit and generates junit.xml and clover.xml">
<exec executable="phpunit">
<arg line="--configuration phpunit.xml.dist"/>
</exec>
</target>
<target name="phpunit-nocoverage" description="Run unit tests using PHPUnit and generates junit.xml">
<exec executable="phpunit">
<arg line="--configuration phpunit.xml.nocoverage"/>
</exec>
</target>
<target name="pdepend" description="Generate jdepend.xml and software metrics charts using PHP_Depend">
<exec executable="pdepend">
<arg line="'--jdepend-xml=${basedir}/build/logs/jdepend.xml'
'--jdepend-chart=${basedir}/build/pdepend/dependencies.svg'
'--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg'
${source_comma_sep}" />
</exec>
</target>
<target name="phpmd" description="Generate pmd.xml using PHPMD">
<exec executable="phpmd">
<arg line="${source_comma_sep}
xml
codesize,design,naming,unusedcode
--exclude test,build,tcpdf,php-gettext,bfShapeFiles,PMAStandard,phpseclib
--reportfile '${basedir}/build/logs/pmd.xml'" />
</exec>
</target>
<target name="phpcpd" description="Generate pmd-cpd.xml using PHPCPD">
<exec executable="phpcpd">
<arg line="--log-pmd '${basedir}/build/logs/pmd-cpd.xml'
--exclude test
--exclude PMAStandard
--exclude build
--exclude libraries/tcpdf
--exclude libraries/php-gettext
--exclude libraries/bfShapeFiles
--exclude libraries/phpseclib
${source}" />
</exec>
</target>
<target name="phploc" description="Generate phploc.csv">
<exec executable="phploc">
<arg line="--log-csv '${basedir}/build/logs/phploc.csv'
--exclude test
--exclude PMAStandard
--exclude build
--exclude libraries/tcpdf
--exclude libraries/php-gettext
--exclude libraries/bfShapeFiles
--exclude libraries/phpseclib
${source}" />
</exec>
</target>
<target name="phpcs" description="Generate checkstyle.xml using PHP_CodeSniffer excluding test, tcpdf directories">
<exec executable="phpcs">
<arg line="
--ignore=*/php-gettext/*,*/tcpdf/*,*/canvg/*,*/codemirror/*,*/openlayers/*,*/jquery/*,*/jqplot/*,*/build/*,*/bfShapeFiles/*,*/PMAStandard/*,*/phpseclib/*
--report=checkstyle
--report-file='${basedir}/build/logs/checkstyle.xml'
--standard=PMAStandard
${source}" />
</exec>
</target>
<target name="phpdoc" description="Generate API documentation using PHPDocumentor">
<exec executable="phpdoc">
<arg line="-d ${source} -t '${basedir}/build/api'" />
</exec>
</target>
<target name="phpcb" description="Aggregate tool output with PHP_CodeBrowser">
<exec executable="phpcb">
<arg line="--log '${basedir}/build/logs'
--source '${source}'
--output '${basedir}/build/code-browser'" />
</exec>
</target>
<target name="jshint" description="Javascript checks">
<exec executable="jshint" output="${basedir}/build/logs/jslint.xml">
<arg line="--jslint-reporter ${js-list}" />
</exec>
</target>
<target name="build" depends="clean,phpunit,pdepend,phpmd,phpcpd,phpcs,phpdoc,phploc,phpcb"/>
</project>

153
changelog.php Normal file
View File

@ -0,0 +1,153 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Simple script to set correct charset for changelog
*
* @package PhpMyAdmin
*/
/**
* Gets core libraries and defines some variables
*/
require 'libraries/common.inc.php';
$response = PMA_Response::getInstance();
$response->disable();
$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 www.phpmyadmin.net for more information.'),
$filename
);
exit;
}
/**
* Whole changelog in variable.
*/
$changelog = htmlspecialchars($changelog);
$tracker_url = 'https://sourceforge.net/support/tracker.php?aid=\\1';
$tracker_url_bug = 'https://sourceforge.net/p/phpmyadmin/bugs/\\1/';
$tracker_url_rfe = 'https://sourceforge.net/p/phpmyadmin/feature-requests/\\1/';
$tracker_url_patch = 'https://sourceforge.net/p/phpmyadmin/patches/\\1/';
$github_url = 'https://github.com/phpmyadmin/phpmyadmin/';
$replaces = array(
'@(http://[./a-zA-Z0-9.-_-]*[/a-zA-Z0-9_])@'
=> '<a href="./url.php?url=\\1">\\1</a>',
// sourceforge users
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*)@users.sourceforge.net&gt;/i'
=> '\\1 <a href="./url.php?url=https://sourceforge.net/users/\\3/">\\2</a>',
'/thanks to ([^\(\r\n]+) \(([-\w]+)\)/i'
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
'/thanks to ([^\(\r\n]+) -\s+([-\w]+)/i'
=> 'thanks to <a href="./url.php?url=https://sourceforge.net/users/\\2/">\\1</a>',
// mail address
'/([0-9]{4}-[0-9]{2}-[0-9]{2}) (.+[^ ]) +&lt;(.*@.*)&gt;/i'
=> '\\1 <a href="mailto:\\3">\\2</a>',
// linking patches
'/patch\s*#?([0-9]{6,})/i'
=> '<a href="./url.php?url=' . $tracker_url . '">patch #\\1</a>',
// linking RFE
'/(?:rfe|feature)\s*#?([0-9]{6,})/i'
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">RFE #\\1</a>',
// linking files
'/(\s+)([\\/a-z_0-9\.]+\.(?:php3?|html|pl|js|sh))/i'
=> '\\1<a href="./url.php?url=' . $github_url . 'commits/HEAD/\\2">\\2</a>',
// FAQ entries
'/FAQ ([0-9]+)\.([0-9a-z]+)/i'
=> '<a href="./url.php?url=https://docs.phpmyadmin.net/en/latest/faq.html#faq\\1-\\2">FAQ \\1.\\2</a>',
// linking bugs
'/bug\s*#?([0-9]{6,})/i'
=> '<a href="./url.php?url=https://sourceforge.net/support/tracker.php?aid=\\1">bug #\\1</a>',
// all other 6+ digit numbers are treated as bugs
'/(?<!bug|RFE|patch) #?([0-9]{6,})/i'
=> '<a href="./url.php?url=' . $tracker_url . '">bug #\\1</a>',
// transitioned SF.net project bug/rfe/patch links
// by the time we reach 6-digit numbers, we can probably retire the above links
'/patch\s*#?([0-9]{4,5}) /i'
=> '<a href="./url.php?url=' . $tracker_url_patch . '">patch #\\1</a> ',
'/(?:rfe|feature)\s*#?([0-9]{4,5}) /i'
=> '<a href="./url.php?url=' . $tracker_url_rfe . '">RFE #\\1</a> ',
'/bug\s*#?([0-9]{4,5}) /i'
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
'/(?<!bug|RFE|patch) #?([0-9]{4,5}) /i'
=> '<a href="./url.php?url=' . $tracker_url_bug . '">bug #\\1</a> ',
// CVE/CAN entries
'/((CAN|CVE)-[0-9]+-[0-9]+)/'
=> '<a href="./url.php?url=http://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 name="\\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 name="\\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>',
);
header('Content-type: text/html; charset=utf-8');
?>
<!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" />
<title>phpMyAdmin - ChangeLog</title>
<meta charset="utf-8" />
</head>
<body>
<h1>phpMyAdmin - ChangeLog</h1>
<?php
echo '<pre>';
echo preg_replace(array_keys($replaces), $replaces, $changelog);
echo '</pre>';
?>
<script type="text/javascript">
var links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
links[i].target = "_blank";
links[i].rel = "noopener noreferrer";
}
</script>
</body>
</html>

15
chk_rel.php Normal file
View File

@ -0,0 +1,15 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Displays status of phpMyAdmin configuration storage
*
* @package PhpMyAdmin
*/
require_once 'libraries/common.inc.php';
$response = PMA_Response::getInstance();
$response->addHTML(
PMA_getRelationsParamDiagnostic(PMA_getRelationsParam())
);
?>

View File

@ -1,2 +0,0 @@
github_checks:
annotations: false

View File

@ -1,162 +1,29 @@
{
"name": "phpmyadmin/phpmyadmin",
"type": "project",
"description": "A web interface for MySQL and MariaDB",
"type": "application",
"description": "MySQL web administration tool",
"keywords": ["phpmyadmin","mysql","web"],
"homepage": "https://www.phpmyadmin.net/",
"support": {
"security": "https://www.phpmyadmin.net/security/",
"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",
"license": "GPL-2.0+",
"authors": [
{
"name": "The phpMyAdmin Team",
"email": "developers@phpmyadmin.net",
"email": "phpmyadmin-devel@lists.sourceforge.net",
"homepage": "https://www.phpmyadmin.net/team/"
}
],
"non-feature-branches": ["RELEASE_.*"],
"autoload": {
"psr-4": {
"PhpMyAdmin\\": "src"
},
"exclude-from-classmap": [
"/tests/",
"/vendor/tecnickcom/tcpdf/tcpdf_barcodes_*.php",
"/vendor/tecnickcom/tcpdf/tcpdf_import.php",
"/vendor/tecnickcom/tcpdf/tcpdf_parser.php",
"/vendor/tecnickcom/tcpdf/include/tcpdf_filters.php",
"/vendor/tecnickcom/tcpdf/include/barcodes"
]
"support": {
"forum": "https://sourceforge.net/p/phpmyadmin/discussion/Help",
"issues": "https://sourceforge.net/p/phpmyadmin/bugs/",
"wiki": "https://wiki.phpmyadmin.net/",
"source": "https://github.com/phpmyadmin/phpmyadmin"
},
"autoload-dev": {
"psr-4": {
"PhpMyAdmin\\Tests\\": "tests/unit",
"PhpMyAdmin\\Tests\\Selenium\\": "tests/end-to-end/"
}
},
"repositories": [
{
"type": "composer",
"url": "https://www.phpmyadmin.net"
}
],
"require": {
"php": "^8.2",
"ext-hash": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mysqli": "*",
"ext-openssl": "*",
"ext-pcre": "*",
"ext-sodium": "*",
"ext-xml": "*",
"composer/ca-bundle": "^1.2",
"fig/http-message-util": "^1.1",
"google/recaptcha": "^1.3",
"laminas/laminas-httphandlerrunner": "^2.6",
"nikic/fast-route": "^1.3",
"phpmyadmin/motranslator": "^6.0",
"phpmyadmin/shapefile": "^4.0",
"phpmyadmin/sql-parser": "^6.0",
"psr/clock": "^1.0",
"psr/container": "^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^2",
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"slim/psr7": "^1.6.1",
"symfony/config": "^7.1",
"symfony/dependency-injection": "^7.1",
"symfony/expression-language": "^7.1",
"symfony/polyfill-ctype": "^1.24",
"symfony/polyfill-iconv": "^1.33",
"symfony/polyfill-mbstring": "^1.24",
"symfony/polyfill-php84": "^1.33",
"twig/twig": "^3.21",
"webmozart/assert": "^1.10",
"williamdes/mariadb-mysql-kbs": "^1.2"
},
"conflict": {
"bacon/bacon-qr-code": "<2.0",
"pragmarx/google2fa-qrcode": "<2.1",
"tecnickcom/tcpdf": "<6.4.4"
},
"suggest": {
"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": "^2.1 or ^3.0 - For 2FA authentication",
"bacon/bacon-qr-code": "^3.0 - For 2FA authentication",
"code-lts/u2f-php-server": "For FIDO U2F authentication",
"web-auth/webauthn-lib": "For better WebAuthn/FIDO2 authentication support"
"php": ">=5.2.0"
},
"require-dev": {
"bacon/bacon-qr-code": "^3.0",
"code-lts/u2f-php-server": "^1.2",
"guzzlehttp/psr7": "^2.5",
"httpsoft/http-message": "^1.1",
"laminas/laminas-diactoros": "^3.0",
"nyholm/psr7": "^1.8",
"php-webdriver/webdriver": "^1.14",
"phpmyadmin/coding-standard": "^4.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpstan/phpstan-webmozart-assert": "^2.0",
"phpunit/phpunit": "^11.5",
"pragmarx/google2fa-qrcode": "^3.0",
"psalm/plugin-phpunit": "^0.19",
"symfony/console": "^7.1",
"tecnickcom/tcpdf": "^6.4.4",
"vimeo/psalm": "^6.0",
"web-auth/webauthn-lib": "^4.9"
},
"extra": {
"branch-alias": {
"dev-master": "6.0.x-dev"
}
},
"scripts": {
"phpcbf": "@php phpcbf",
"phpcs": "@php phpcs",
"phpstan": "@php phpstan analyse",
"psalm": "@php psalm --no-diff",
"phpunit": "@php phpunit --color=always",
"test": [
"@phpcs",
"@phpstan",
"@psalm",
"@phpunit"
],
"update:baselines": [
"@php phpstan analyse --generate-baseline",
"@php psalm --no-cache --threads=max --set-baseline=psalm-baseline.xml"
],
"twig-lint": "@php bin/console lint:twig --ansi --show-deprecations"
},
"config":{
"sort-packages": true,
"discard-changes": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"phpstan/extension-installer": true,
"composer/package-versions-deprecated": true
},
"platform": {
"php": "8.2.99"
}
"satooshi/php-coveralls": ">=0.6",
"phpunit/phpunit": "<4.2",
"phpunit/phpunit-selenium": ">=1.2"
}
}

8949
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,27 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* phpMyAdmin sample configuration, you can use it as base for
* manual configuration. For easier setup you can use setup/
*
* All directives are explained in documentation in the docs/ folder
* All directives are explained in documentation in the doc/ folder
* or at <https://docs.phpmyadmin.net/>.
*
* @package PhpMyAdmin
*/
declare(strict_types=1);
/**
* This is needed for cookie based authentication to encrypt the cookie.
* Needs to be a 32-bytes long string of random bytes. See FAQ 2.10.
/*
* This is needed for cookie based authentication to encrypt password in
* cookie. Needs to be 32 chars long.
*/
$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
$cfg['blowfish_secret'] = 'a8b7c6d'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
/**
/*
* Servers configuration
*/
$i = 0;
/**
/*
* First server
*/
$i++;
@ -28,16 +29,18 @@ $i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysql if your server does not have mysqli */
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
/**
/*
* phpMyAdmin configuration storage settings.
*/
/* User used to manipulate with storage */
// $cfg['Servers'][$i]['controlhost'] = '';
// $cfg['Servers'][$i]['controlport'] = '';
// $cfg['Servers'][$i]['controluser'] = 'pma';
// $cfg['Servers'][$i]['controlpass'] = 'pmapass';
@ -52,34 +55,20 @@ $cfg['Servers'][$i]['AllowNoPassword'] = false;
// $cfg['Servers'][$i]['history'] = 'pma__history';
// $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
// $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
// $cfg['Servers'][$i]['designer_coords'] = 'pma__designer_coords';
// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
// $cfg['Servers'][$i]['recent'] = 'pma__recent';
// $cfg['Servers'][$i]['favorite'] = 'pma__favorite';
// $cfg['Servers'][$i]['users'] = 'pma__users';
// $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
// $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
// $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
// $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
// $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
// $cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';
/**
/*
* End of servers configuration
*/
/**
/*
* Directories for saving/loading files from server
*/
$cfg['UploadDir'] = '';
$cfg['SaveDir'] = '';
/**
* Whether to display icons or text or both icons and text in table row
* action segment. Value can be either of 'icons', 'text' or 'both'.
* default = 'both'
*/
//$cfg['RowActionType'] = 'icons';
/**
* Defines whether a user should be displayed a "show all (records)"
* button in browse mode or not.
@ -90,31 +79,36 @@ $cfg['SaveDir'] = '';
/**
* Number of rows displayed when browsing a result set. If the result
* set contains more rows, "Previous" and "Next".
* Possible values: 25, 50, 100, 250, 500
* default = 25
* default = 30
*/
//$cfg['MaxRows'] = 50;
/**
* Disallow editing of binary fields
* disallow editing of binary fields
* valid values are:
* false allow editing
* 'blob' allow editing except for BLOB fields
* 'noblob' disallow editing except for BLOB fields
* 'all' disallow editing
* default = 'blob'
* default = blob
*/
//$cfg['ProtectBinary'] = false;
//$cfg['ProtectBinary'] = 'false';
/**
* Default language to use, if not browser-defined or user-defined
* (you find all languages in the 'resources/locale' folder)
* (you find all languages in the locale folder)
* uncomment the desired line:
* default = 'en'
*/
//$cfg['DefaultLang'] = 'en';
//$cfg['DefaultLang'] = 'de';
/**
* default display direction (horizontal|vertical|horizontalflipped)
*/
//$cfg['DefaultDisplay'] = 'vertical';
/**
* How many columns should be used for table display of a database?
* (a value larger than 1 results in some information being hidden)
@ -133,28 +127,13 @@ $cfg['SaveDir'] = '';
/**
* When using DB-based query history, how many entries should be kept?
*
* default = 25
*/
//$cfg['QueryHistoryMax'] = 100;
/**
* Whether or not to query the user before sending the error report to
* the phpMyAdmin team when a JavaScript error occurs
*
* Available options
* ('ask' | 'always' | 'never')
* default = 'ask'
*/
//$cfg['SendErrorReports'] = 'always';
/**
* 'URLQueryEncryption' defines whether phpMyAdmin will encrypt sensitive data from the URL query string.
* 'URLQueryEncryptionSecretKey' is a 32 bytes long secret key used to encrypt/decrypt the URL query string.
*/
//$cfg['URLQueryEncryption'] = true;
//$cfg['URLQueryEncryptionSecretKey'] = '';
/**
/*
* You can find more configuration options in the documentation
* in the docs/ folder or at <https://docs.phpmyadmin.net/>.
* in the doc/ folder or at <https://docs.phpmyadmin.net/>.
*/
?>

148
db_create.php Normal file
View File

@ -0,0 +1,148 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
* Gets some core libraries
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/mysql_charsets.lib.php';
if (! PMA_DRIZZLE) {
include_once 'libraries/replication.inc.php';
}
require 'libraries/build_html_for_db.lib.php';
/**
* Sets globals from $_POST
*/
$post_params = array(
'db_collation',
'new_db'
);
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
PMA_Util::checkParameters(array('new_db'));
/**
* Defines the url to return to in case of error in a sql statement
*/
$err_url = 'index.php?' . PMA_generate_common_url();
/**
* Builds and executes the db creation sql query
*/
$sql_query = 'CREATE DATABASE ' . PMA_Util::backquote($new_db);
if (! empty($db_collation)) {
list($db_charset) = explode('_', $db_collation);
if (in_array($db_charset, $mysql_charsets)
&& in_array($db_collation, $mysql_collations[$db_charset])
) {
$sql_query .= ' DEFAULT' . PMA_generateCharsetQueryPart($db_collation);
}
$db_collation_for_ajax = $db_collation;
unset($db_charset, $db_collation);
}
$sql_query .= ';';
$result = PMA_DBI_try_query($sql_query);
if (! $result) {
$message = PMA_Message::rawError(PMA_DBI_getError());
// avoid displaying the not-created db name in header or navi panel
$GLOBALS['db'] = '';
$GLOBALS['table'] = '';
/**
* If in an Ajax request, just display the message with {@link PMA_Response}
*/
if ($GLOBALS['is_ajax_request'] == true) {
$response = PMA_Response::getInstance();
$response->isSuccess(false);
$response->addJSON('message', $message);
} else {
include_once 'index.php';
}
} else {
$message = PMA_Message::success(__('Database %1$s has been created.'));
$message->addParam($new_db);
$GLOBALS['db'] = $new_db;
/**
* If in an Ajax request, build the output and send it
*/
if ($GLOBALS['is_ajax_request'] == true) {
//Construct the html for the new database, so that it can be appended to
// the list of databases on server_databases.php
/**
* Build the array to be passed to {@link PMA_generate_common_url}
* to generate the links
*
* @global array $GLOBALS['db_url_params']
* @name $db_url_params
*/
$db_url_params['db'] = $new_db;
$is_superuser = PMA_isSuperuser();
$column_order = PMA_getColumnOrder();
$url_query = PMA_generate_common_url($new_db);
/**
* String that will contain the output HTML
* @name $new_db_string
*/
$new_db_string = '<tr>';
if (empty($db_collation_for_ajax)) {
$db_collation_for_ajax = PMA_getServerCollation();
}
// $dbstats comes from the create table dialog
if (! empty($dbstats)) {
$current = array(
'SCHEMA_NAME' => $new_db,
'DEFAULT_COLLATION_NAME' => $db_collation_for_ajax,
'SCHEMA_TABLES' => '0',
'SCHEMA_TABLE_ROWS' => '0',
'SCHEMA_DATA_LENGTH' => '0',
'SCHEMA_MAX_DATA_LENGTH' => '0',
'SCHEMA_INDEX_LENGTH' => '0',
'SCHEMA_LENGTH' => '0',
'SCHEMA_DATA_FREE' => '0'
);
} else {
$current = array(
'SCHEMA_NAME' => $new_db
);
}
list($column_order, $generated_html) = PMA_buildHtmlForDb(
$current, $is_superuser, $url_query,
$column_order, $replication_types, $replication_info
);
$new_db_string .= $generated_html;
$new_db_string .= '</tr>';
$response = PMA_Response::getInstance();
$response->addJSON('message', $message);
$response->addJSON('new_db_string', $new_db_string);
$response->addJSON(
'sql_query',
PMA_Util::getMessage(
null, $sql_query, 'success'
)
);
} else {
include_once '' . $cfg['DefaultTabDatabase'];
}
}
?>

291
db_datadict.php Normal file
View File

@ -0,0 +1,291 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
* Gets the variables sent or posted to this script, then displays headers
*/
require_once 'libraries/common.inc.php';
if (! isset($selected_tbl)) {
include 'libraries/db_common.inc.php';
include 'libraries/db_info.inc.php';
}
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$header->enablePrintView();
/**
* Gets the relations settings
*/
$cfgRelation = PMA_getRelationsParam();
require_once 'libraries/transformations.lib.php';
require_once 'libraries/Index.class.php';
/**
* Check parameters
*/
PMA_Util::checkParameters(array('db'));
/**
* Defines the url to return to in case of error in a sql statement
*/
if (strlen($table)) {
$err_url = 'tbl_sql.php?' . PMA_generate_common_url($db, $table);
} else {
$err_url = 'db_sql.php?' . PMA_generate_common_url($db);
}
if ($cfgRelation['commwork']) {
$comment = PMA_getDbComment($db);
/**
* Displays DB comment
*/
if ($comment) {
echo '<p>' . __('Database comment: ')
. '<i>' . htmlspecialchars($comment) . '</i></p>';
} // end if
}
/**
* Selects the database and gets tables names
*/
PMA_DBI_select_db($db);
$tables = PMA_DBI_get_tables($db);
$count = 0;
foreach ($tables as $table) {
$comments = PMA_getComments($db, $table);
echo '<div>' . "\n";
echo '<h2>' . htmlspecialchars($table) . '</h2>' . "\n";
/**
* Gets table informations
*/
$show_comment = PMA_Table::sGetStatusInfo($db, $table, 'TABLE_COMMENT');
/**
* Gets table keys and retains them
*/
PMA_DBI_select_db($db);
$indexes = PMA_DBI_get_table_indexes($db, $table);
$primary = '';
$indexes = array();
$lastIndex = '';
$indexes_info = array();
$indexes_data = array();
$pk_array = array(); // will be use to emphasis prim. keys in the table
// view
foreach ($indexes as $row) {
// Backups the list of primary keys
if ($row['Key_name'] == 'PRIMARY') {
$primary .= $row['Column_name'] . ', ';
$pk_array[$row['Column_name']] = 1;
}
// Retains keys informations
if ($row['Key_name'] != $lastIndex) {
$indexes[] = $row['Key_name'];
$lastIndex = $row['Key_name'];
}
$indexes_info[$row['Key_name']]['Sequences'][] = $row['Seq_in_index'];
$indexes_info[$row['Key_name']]['Non_unique'] = $row['Non_unique'];
if (isset($row['Cardinality'])) {
$indexes_info[$row['Key_name']]['Cardinality'] = $row['Cardinality'];
}
// I don't know what does following column mean....
// $indexes_info[$row['Key_name']]['Packed'] = $row['Packed'];
$indexes_info[$row['Key_name']]['Comment'] = $row['Comment'];
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Column_name'] = $row['Column_name'];
if (isset($row['Sub_part'])) {
$indexes_data[$row['Key_name']][$row['Seq_in_index']]['Sub_part'] = $row['Sub_part'];
}
} // end while
/**
* Gets columns properties
*/
$columns = PMA_DBI_get_columns($db, $table);
$fields_cnt = count($columns);
if (PMA_MYSQL_INT_VERSION < 50025) {
// We need this to correctly learn if a TIMESTAMP is NOT NULL, since
// SHOW FULL COLUMNS or INFORMATION_SCHEMA incorrectly says NULL
// and SHOW CREATE TABLE says NOT NULL
// http://bugs.mysql.com/20910.
$show_create_table_query = 'SHOW CREATE TABLE '
. PMA_Util::backquote($db) . '.'
. PMA_Util::backquote($table);
$show_create_table = PMA_DBI_fetch_value(
$show_create_table_query, 0, 1
);
$analyzed_sql = PMA_SQP_analyze(PMA_SQP_parse($show_create_table));
}
// Check if we can use Relations
if (!empty($cfgRelation['relation'])) {
// Find which tables are related with the current one and write it in
// an array
$res_rel = PMA_getForeigners($db, $table);
if (count($res_rel) > 0) {
$have_rel = true;
} else {
$have_rel = false;
}
} else {
$have_rel = false;
} // end if
/**
* Displays the comments of the table if MySQL >= 3.23
*/
if (!empty($show_comment)) {
echo __('Table comments') . ': ' . htmlspecialchars($show_comment) . '<br /><br />';
}
/**
* Displays the table structure
*/
?>
<table width="100%" class="print">
<tr><th width="50"><?php echo __('Column'); ?></th>
<th width="80"><?php echo __('Type'); ?></th>
<?php /* <th width="50"><?php echo __('Attributes'); ?></th>*/ ?>
<th width="40"><?php echo __('Null'); ?></th>
<th width="70"><?php echo __('Default'); ?></th>
<?php /* <th width="50"><?php echo __('Extra'); ?></th>*/ ?>
<?php
if ($have_rel) {
echo ' <th>' . __('Links to') . '</th>' . "\n";
}
echo ' <th>' . __('Comments') . '</th>' . "\n";
if ($cfgRelation['mimework']) {
echo ' <th>MIME</th>' . "\n";
}
?>
</tr>
<?php
$odd_row = true;
foreach ($columns as $row) {
if ($row['Null'] == '') {
$row['Null'] = 'NO';
}
$extracted_columnspec
= PMA_Util::extractColumnSpec($row['Type']);
// reformat mysql query output
// set or enum types: slashes single quotes inside options
if ('set' == $extracted_columnspec['type'] || 'enum' == $extracted_columnspec['type']) {
$type_nowrap = '';
} else {
$type_nowrap = ' class="nowrap"';
}
$type = htmlspecialchars($extracted_columnspec['print_type']);
$attribute = $extracted_columnspec['attribute'];
if (! isset($row['Default'])) {
if ($row['Null'] != 'NO') {
$row['Default'] = '<i>NULL</i>';
}
} else {
$row['Default'] = htmlspecialchars($row['Default']);
}
$field_name = $row['Field'];
if (PMA_MYSQL_INT_VERSION < 50025
&& ! empty($analyzed_sql[0]['create_table_fields'][$field_name]['type'])
&& $analyzed_sql[0]['create_table_fields'][$field_name]['type'] == 'TIMESTAMP'
&& $analyzed_sql[0]['create_table_fields'][$field_name]['timestamp_not_null']
) {
// here, we have a TIMESTAMP that SHOW FULL COLUMNS reports as having the
// NULL attribute, but SHOW CREATE TABLE says the contrary. Believe
// the latter.
/**
* @todo merge this logic with the one in tbl_structure.php
* or move it in a function similar to PMA_DBI_get_columns_full()
* but based on SHOW CREATE TABLE because information_schema
* cannot be trusted in this case (MySQL bug)
*/
$row['Null'] = 'NO';
}
?>
<tr class="<?php echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row; ?>">
<td class="nowrap">
<?php
if (isset($pk_array[$row['Field']])) {
echo '<u>' . htmlspecialchars($field_name) . '</u>';
} else {
echo htmlspecialchars($field_name);
}
?>
</td>
<td<?php echo $type_nowrap; ?> lang="en" dir="ltr"><?php echo $type; ?></td>
<?php /* <td<?php echo $type_nowrap; ?>><?php echo $attribute; ?></td>*/ ?>
<td><?php echo (($row['Null'] == 'NO') ? __('No') : __('Yes')); ?></td>
<td class="nowrap"><?php
if (isset($row['Default'])) {
echo $row['Default'];
}
?></td>
<?php /* <td<?php echo $type_nowrap; ?>><?php echo $row['Extra']; ?></td>*/ ?>
<?php
if ($have_rel) {
echo ' <td>';
if (isset($res_rel[$field_name])) {
echo htmlspecialchars($res_rel[$field_name]['foreign_table'] . ' -> ' . $res_rel[$field_name]['foreign_field']);
}
echo '</td>' . "\n";
}
echo ' <td>';
if (isset($comments[$field_name])) {
echo htmlspecialchars($comments[$field_name]);
}
echo '</td>' . "\n";
if ($cfgRelation['mimework']) {
$mime_map = PMA_getMIME($db, $table, true);
echo ' <td>';
if (isset($mime_map[$field_name])) {
echo htmlspecialchars(str_replace('_', '/', $mime_map[$field_name]['mimetype']));
}
echo '</td>' . "\n";
}
?>
</tr>
<?php
} // end foreach
$count++;
?>
</table>
<?php
// display indexes information
if (count(PMA_Index::getFromTable($table, $db)) > 0) {
echo PMA_Index::getView($table, $db, true);
}
?>
</div>
<?php
} //ends main while
/**
* Displays the footer
*/
echo PMA_Util::getButton();
?>

26
db_events.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Events management.
*
* @package PhpMyAdmin
*/
/**
* Include required files
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/Util.class.php';
/**
* Include all other files
*/
require_once 'libraries/rte/rte_events.lib.php';
/**
* Do the magic
*/
$_PMA_RTE = 'EVN';
require_once 'libraries/rte/rte_main.inc.php';
?>

90
db_export.php Normal file
View File

@ -0,0 +1,90 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* dumps a database
*
* @package PhpMyAdmin
*/
/**
* Gets some core libraries
*/
require_once 'libraries/common.inc.php';
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('export.js');
// $sub_part is also used in db_info.inc.php to see if we are coming from
// db_export.php, in which case we don't obey $cfg['MaxTableList']
$sub_part = '_export';
require_once 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_export.php';
require_once 'libraries/db_info.inc.php';
/**
* Displays the form
*/
$export_page_title = __('View dump (schema) of database');
// exit if no tables in db found
if ($num_tables < 1) {
PMA_Message::error(__('No tables found in database.'))->display();
exit;
} // end if
$multi_values = '<div>';
$multi_values .= '<a href="#"';
$multi_values .= ' onclick="setSelectOptions(\'dump\', \'table_select[]\', true); return false;">';
$multi_values .= __('Select All');
$multi_values .= '</a>';
$multi_values .= ' / ';
$multi_values .= '<a href="#"';
$multi_values .= ' onclick="setSelectOptions(\'dump\', \'table_select[]\', false); return false;">';
$multi_values .= __('Unselect All');
$multi_values .= '</a><br />';
$multi_values .= '<select name="table_select[]" id="table_select" size="10" multiple="multiple">';
$multi_values .= "\n";
if (!empty($selected_tbl) && empty($table_select)) {
$table_select = $selected_tbl;
}
// Check if the selected tables are defined in $_GET
// (from clicking Back button on export.php)
if (isset($_GET['table_select'])) {
$_GET['table_select'] = urldecode($_GET['table_select']);
$_GET['table_select'] = explode(",", $_GET['table_select']);
}
foreach ($tables as $each_table) {
if (isset($_GET['table_select'])) {
if (in_array($each_table['Name'], $_GET['table_select'])) {
$is_selected = ' selected="selected"';
} else {
$is_selected = '';
}
} elseif (isset($table_select)) {
if (in_array($each_table['Name'], $table_select)) {
$is_selected = ' selected="selected"';
} else {
$is_selected = '';
}
} else {
$is_selected = ' selected="selected"';
}
$table_html = htmlspecialchars($each_table['Name']);
$multi_values .= ' <option value="' . $table_html . '"'
. $is_selected . '>'
. str_replace(' ', '&nbsp;', $table_html) . '</option>' . "\n";
} // end for
$multi_values .= "\n";
$multi_values .= '</select></div>';
$export_type = 'database';
require_once 'libraries/display_export.lib.php';
?>

28
db_import.php Normal file
View File

@ -0,0 +1,28 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
*/
require_once 'libraries/common.inc.php';
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('import.js');
/**
* Gets tables informations and displays top links
*/
require 'libraries/db_common.inc.php';
require 'libraries/db_info.inc.php';
$import_type = 'database';
require 'libraries/display_import.lib.php';
?>

294
db_operations.php Normal file
View File

@ -0,0 +1,294 @@
<?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
*/
/**
* requirements
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/mysql_charsets.lib.php';
/**
* functions implementation for this script
*/
require_once 'libraries/operations.lib.php';
// add a javascript file for jQuery functions to handle Ajax actions
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_operations.js');
/**
* Rename/move or copy database
*/
if (strlen($db)
&& (! empty($_REQUEST['db_rename']) || ! empty($_REQUEST['db_copy']))
) {
if (! empty($_REQUEST['db_rename'])) {
$move = true;
} else {
$move = false;
}
if (! isset($_REQUEST['newname']) || ! strlen($_REQUEST['newname'])) {
$message = PMA_Message::error(__('The database name is empty!'));
} else {
$sql_query = ''; // in case target db exists
$_error = false;
if ($move
|| (isset($_REQUEST['create_database_before_copying'])
&& $_REQUEST['create_database_before_copying'])
) {
$sql_query = PMA_getSqlQueryAndCreateDbBeforeCopy();
}
// 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
PMA_runProcedureAndFunctionDefinitions($db);
// go back to current db, just in case
PMA_DBI_select_db($db);
$tables_full = PMA_DBI_get_tables_full($db);
include_once "libraries/plugin_interface.lib.php";
// remove all foreign key constraints, otherwise we can get errors
$export_sql_plugin = PMA_getPlugin(
"export",
"sql",
'libraries/plugins/export/',
array(
'single_table' => isset($single_table),
'export_type' => 'database'
)
);
$GLOBALS['sql_constraints_query_full_db']
= PMA_getSqlConstraintsQueryForFullDb(
$tables_full, $export_sql_plugin, $move, $db
);
$views = PMA_getViewsAndCreateSqlViewStandIn(
$tables_full, $export_sql_plugin, $db
);
list($sql_query, $_error) = PMA_getSqlQueryForCopyTable(
$tables_full, $sql_query, $move, $db
);
// handle the views
if (! $_error) {
$_error = PMA_handleTheViews($views, $move, $db);
}
unset($views);
// now that all tables exist, create all the accumulated constraints
if (! $_error && count($GLOBALS['sql_constraints_query_full_db']) > 0) {
PMA_createAllAccumulatedConstraints();
}
if (! PMA_DRIZZLE && PMA_MYSQL_INT_VERSION >= 50100) {
// here DELIMITER is not used because it's not part of the
// language; each statement is sent one by one
PMA_runEventDefinitionsForDb($db);
}
// go back to current db, just in case
PMA_DBI_select_db($db);
// Duplicate the bookmarks for this db (done once for each db)
PMA_duplicateBookmarks($_error, $db);
if (! $_error && $move) {
/**
* cleanup pmadb stuff for this db
*/
include_once 'libraries/relation_cleanup.lib.php';
PMA_relationsCleanupDatabase($db);
// if someday the RENAME DATABASE reappears, do not DROP
$local_query = 'DROP DATABASE ' . PMA_Util::backquote($db) . ';';
$sql_query .= "\n" . $local_query;
PMA_DBI_query($local_query);
$message = PMA_Message::success(__('Database %1$s has been renamed to %2$s'));
$message->addParam($db);
$message->addParam($_REQUEST['newname']);
} elseif (! $_error) {
$message = PMA_Message::success(__('Database %1$s has been copied to %2$s'));
$message->addParam($db);
$message->addParam($_REQUEST['newname']);
}
$reload = true;
/* Change database to be used */
if (! $_error && $move) {
$db = $_REQUEST['newname'];
} elseif (! $_error) {
if (isset($_REQUEST['switch_to_new'])
&& $_REQUEST['switch_to_new'] == 'true'
) {
$GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', 'true');
$db = $_REQUEST['newname'];
} else {
$GLOBALS['PMA_Config']->setCookie('pma_switch_to_new', '');
}
}
if ($_error && ! isset($message)) {
$message = PMA_Message::error();
}
}
/**
* Database has been successfully renamed/moved. If in an Ajax request,
* generate the output with {@link PMA_Response} and exit
*/
if ($GLOBALS['is_ajax_request'] == true) {
$response = PMA_Response::getInstance();
$response->isSuccess($message->isSuccess());
$response->addJSON('message', $message);
$response->addJSON('newname', $_REQUEST['newname']);
$response->addJSON(
'sql_query',
PMA_Util::getMessage(null, $sql_query)
);
$response->addJSON('db', $db);
exit;
}
}
/**
* Settings for relations stuff
*/
$cfgRelation = PMA_getRelationsParam();
/**
* Check if comments were updated
* (must be done before displaying the menu tabs)
*/
if (isset($_REQUEST['comment'])) {
PMA_setDbComment($db, $_REQUEST['comment']);
}
/**
* Prepares the tables list if the user where not redirected to this script
* because there is no table in the database ($is_info is true)
*/
if (empty($is_info)) {
include 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_operations.php';
// Gets the database structure
$sub_part = '_structure';
include 'libraries/db_info.inc.php';
echo "\n";
if (isset($message)) {
echo PMA_Util::getMessage($message, $sql_query);
unset($message);
}
}
$_REQUEST['db_collation'] = PMA_getDbCollation($db);
$is_information_schema = PMA_is_system_schema($db);
if (!$is_information_schema) {
if ($cfgRelation['commwork']) {
/**
* database comment
*/
$response->addHTML(PMA_getHtmlForDatabaseComment($db));
}
$response->addHTML('<div class="operations_half_width">');
ob_start();
include 'libraries/display_create_table.lib.php';
$content = ob_get_contents();
ob_end_clean();
$response->addHTML($content);
$response->addHTML('</div>');
/**
* rename database
*/
if ($db != 'mysql') {
$response->addHTML(PMA_getHtmlForRenameDatabase($db));
}
// 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 (($is_superuser || $GLOBALS['cfg']['AllowUserDropDatabase'])
&& ! $db_is_information_schema
&& (PMA_DRIZZLE || $db != 'mysql')
) {
$response->addHTML(PMA_getHtmlForDropDatabaseLink($db));
}
/**
* Copy database
*/
$response->addHTML(PMA_getHtmlForCopyDatabase($db));
/**
* Change database charset
*/
$response->addHTML(PMA_getHtmlForChangeDatabaseCharset($db, $table));
if ($num_tables > 0
&& ! $cfgRelation['allworks']
&& $cfg['PmaNoRelation_DisableWarning'] == false
) {
$message = PMA_Message::notice(
__('The phpMyAdmin configuration storage has been deactivated. To find out why click %shere%s.')
);
$message->addParam(
'<a href="' . $cfg['PmaAbsoluteUri'] . 'chk_rel.php?' . $url_query . '">',
false
);
$message->addParam('</a>', false);
/* Show error if user has configured something, notice elsewhere */
if (!empty($cfg['Servers'][$server]['pmadb'])) {
$message->isError(true);
}
$response->addHTML('<div class="operations_full_width">');
$response->addHTML($message->getDisplay());
$response->addHTML('</div>');
} // end if
} // end if (!$is_information_schema)
// not sure about displaying the PDF dialog in case db is information_schema
if ($cfgRelation['pdfwork'] && $num_tables > 0) {
// We only show this if we find something in the new pdf_pages table
$test_query = '
SELECT *
FROM ' . PMA_Util::backquote($GLOBALS['cfgRelation']['db'])
. '.' . PMA_Util::backquote($cfgRelation['pdf_pages']) . '
WHERE db_name = \'' . PMA_Util::sqlAddSlashes($db) . '\'';
$test_rs = PMA_queryAsControlUser($test_query, null, PMA_DBI_QUERY_STORE);
/*
* Export Relational Schema View
*/
$response->addHTML(PMA_getHtmlForExportRelationalSchemaView($url_query));
} // end if
?>

252
db_printview.php Normal file
View File

@ -0,0 +1,252 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
*/
require_once 'libraries/common.inc.php';
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$header->enablePrintView();
PMA_Util::checkParameters(array('db'));
/**
* Defines the url to return to in case of error in a sql statement
*/
$err_url = 'db_sql.php?' . PMA_generate_common_url($db);
/**
* Settings for relations stuff
*/
$cfgRelation = PMA_getRelationsParam();
/**
* Gets the list of the table in the current db and informations about these
* tables if possible
*
* @todo merge this speedup _optionaly_ into PMA_DBI_get_tables_full()
*
// speedup view on locked tables
// Special speedup for newer MySQL Versions (in 4.0 format changed)
if ($cfg['SkipLockedTables'] == true) {
$result = PMA_DBI_query('SHOW OPEN TABLES FROM ' . PMA_Util::backquote($db) . ';');
// Blending out tables in use
if ($result != false && PMA_DBI_num_rows($result) > 0) {
while ($tmp = PMA_DBI_fetch_row($result)) {
// if in use memorize tablename
if (preg_match('@in_use=[1-9]+@i', $tmp[0])) {
$sot_cache[$tmp[0]] = true;
}
}
PMA_DBI_free_result($result);
if (isset($sot_cache)) {
$result = PMA_DBI_query('SHOW TABLES FROM ' . PMA_Util::backquote($db) . ';', null, PMA_DBI_QUERY_STORE);
if ($result != false && PMA_DBI_num_rows($result) > 0) {
while ($tmp = PMA_DBI_fetch_row($result)) {
if (! isset($sot_cache[$tmp[0]])) {
$sts_result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ' LIKE \'' . sqlAddSlashes($tmp[0], true) . '\';');
$sts_tmp = PMA_DBI_fetch_assoc($sts_result);
$tables[] = $sts_tmp;
} else { // table in use
$tables[] = array('Name' => $tmp[0]);
}
}
PMA_DBI_free_result($result);
$sot_ready = true;
}
}
unset($tmp, $result);
}
}
if (! isset($sot_ready)) {
$result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_Util::backquote($db) . ';');
if (PMA_DBI_num_rows($result) > 0) {
while ($sts_tmp = PMA_DBI_fetch_assoc($result)) {
$tables[] = $sts_tmp;
}
PMA_DBI_free_result($result);
unset($res);
}
}
*/
/**
* If there is at least one table, displays the printer friendly view, else
* an error message
*/
$tables = PMA_DBI_get_tables_full($db);
$num_tables = count($tables);
echo '<br />';
// 1. No table
if ($num_tables == 0) {
echo __('No tables found in database.');
} else {
// 2. Shows table information
?>
<table>
<thead>
<tr>
<th><?php echo __('Table'); ?></th>
<th><?php echo __('Rows'); ?></th>
<th><?php echo __('Type'); ?></th>
<?php
if ($cfg['ShowStats']) {
echo '<th>' . __('Size') . '</th>';
}
?>
<th><?php echo __('Comments'); ?></th>
</tr>
</thead>
<tbody>
<?php
$sum_entries = $sum_size = 0;
$odd_row = true;
foreach ($tables as $sts_data) {
if (PMA_Table::isMerge($db, $sts_data['TABLE_NAME'])
|| strtoupper($sts_data['ENGINE']) == 'FEDERATED'
) {
$merged_size = true;
} else {
$merged_size = false;
}
$sum_entries += $sts_data['TABLE_ROWS'];
?>
<tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>">
<th>
<?php echo htmlspecialchars($sts_data['TABLE_NAME']); ?>
</th>
<?php
if (isset($sts_data['TABLE_ROWS'])) {
?>
<td class="right">
<?php
if ($merged_size) {
echo '<i>' . PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . '</i>' . "\n";
} else {
echo PMA_Util::formatNumber($sts_data['TABLE_ROWS'], 0) . "\n";
}
?>
</td>
<td class="nowrap">
<?php echo $sts_data['ENGINE']; ?>
</td>
<?php
if ($cfg['ShowStats']) {
$tblsize = $sts_data['Data_length'] + $sts_data['Index_length'];
$sum_size += $tblsize;
list($formated_size, $unit)
= PMA_Util::formatByteDown($tblsize, 3, 1);
?>
<td class="right nowrap">
<?php echo $formated_size . ' ' . $unit; ?>
</td>
<?php
} // end if
} else {
?>
<td colspan="3" class="center">
<?php echo __('in use'); ?>
</td>
<?php
}
?>
<td>
<?php
if (! empty($sts_data['Comment'])) {
echo htmlspecialchars($sts_data['Comment']);
$needs_break = '<br />';
} else {
$needs_break = '';
}
if (! empty($sts_data['Create_time'])
|| ! empty($sts_data['Update_time'])
|| ! empty($sts_data['Check_time'])
) {
echo $needs_break;
?>
<table width="100%">
<?php
if (! empty($sts_data['Create_time'])) {
?>
<tr>
<td class="right"><?php echo __('Creation') . ': '; ?></td>
<td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Create_time'])); ?></td>
</tr>
<?php
}
if (! empty($sts_data['Update_time'])) {
?>
<tr>
<td class="right"><?php echo __('Last update') . ': '; ?></td>
<td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Update_time'])); ?></td>
</tr>
<?php
}
if (! empty($sts_data['Check_time'])) {
?>
<tr>
<td class="right"><?php echo __('Last check') . ': '; ?></td>
<td class="right"><?php echo PMA_Util::localisedDate(strtotime($sts_data['Check_time'])); ?></td>
</tr>
<?php
}
?>
</table>
<?php
}
?>
</td>
</tr>
<?php
}
?>
<tr>
<th class="center">
<?php echo sprintf(_ngettext('%s table', '%s tables', $num_tables), PMA_Util::formatNumber($num_tables, 0)); ?>
</th>
<th class="right nowrap">
<?php echo PMA_Util::formatNumber($sum_entries, 0); ?>
</th>
<th class="center">
--
</th>
<?php
if ($cfg['ShowStats']) {
list($sum_formated, $unit)
= PMA_Util::formatByteDown($sum_size, 3, 1);
?>
<th class="right nowrap">
<?php echo $sum_formated . ' ' . $unit; ?>
</th>
<?php
}
?>
<th></th>
</tr>
</tbody>
</table>
<?php
}
/**
* Displays the footer
*/
echo PMA_Util::getButton();
echo "<div id='PMA_disable_floating_menubar'></div>\n";
?>

68
db_qbe.php Normal file
View File

@ -0,0 +1,68 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* query by example the whole database
*
* @package PhpMyAdmin
*/
/**
* requirements
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/DBQbe.class.php';
$response = PMA_Response::getInstance();
// Gets the relation settings
$cfgRelation = PMA_getRelationsParam();
/**
* A query has been submitted -> (maybe) execute it
*/
$message_to_display = false;
if (isset($_REQUEST['submit_sql']) && ! empty($sql_query)) {
if (! preg_match('@^SELECT@i', $sql_query)) {
$message_to_display = true;
} else {
$goto = 'db_sql.php';
include 'sql.php';
exit;
}
}
$sub_part = '_qbe';
require 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_qbe.php';
$url_params['goto'] = 'db_qbe.php';
require 'libraries/db_info.inc.php';
if ($message_to_display) {
PMA_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 PMA_DBQbe($GLOBALS['db']);
/**
* Displays the Query by example form
*/
if ($cfgRelation['designerwork']) {
$url = 'pmd_general.php' . PMA_generate_common_url(
array_merge(
$url_params,
array('query' => 1)
)
);
$response->addHTML(
PMA_Message::notice(
sprintf(
__('Switch to %svisual builder%s'),
'<a href="' . $url . '">',
'</a>'
)
)
);
}
$response->addHTML($db_qbe->getSelectionForm($cfgRelation));
?>

27
db_routines.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Routines management.
*
* @package PhpMyAdmin
*/
/**
* Include required files
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/Util.class.php';
require_once 'libraries/mysql_charsets.lib.php';
/**
* Include all other files
*/
require_once 'libraries/rte/rte_routines.lib.php';
/**
* Do the magic
*/
$_PMA_RTE = 'RTN';
require_once 'libraries/rte/rte_main.inc.php';
?>

57
db_search.php Normal file
View File

@ -0,0 +1,57 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* searchs the entire database
*
* @todo make use of UNION when searching multiple tables
* @todo display executed query, optional?
* @package PhpMyAdmin
*/
/**
* Gets some core libraries
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/DbSearch.class.php';
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_search.js');
$scripts->addFile('sql.js');
$scripts->addFile('makegrid.js');
$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
require 'libraries/db_common.inc.php';
// If config variable $GLOBALS['cfg']['Usedbsearch'] is on false : exit.
if (! $GLOBALS['cfg']['UseDbSearch']) {
PMA_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 PMA_DbSearch($GLOBALS['db']);
// Display top links if we are not in an Ajax request
if ( $GLOBALS['is_ajax_request'] != true) {
include 'libraries/db_info.inc.php';
}
$response->addHTML('<div id="searchresults">');
// Main search form has been submitted, get results
if (isset($_REQUEST['submit_search'])) {
$response->addHTML($db_search->getSearchResults());
}
// If we are in an Ajax request, we need to exit after displaying all the HTML
if ($GLOBALS['is_ajax_request'] == true && empty($_REQUEST['ajax_page_request'])) {
exit;
}
// Display the search form
$response->addHTML($db_search->getSelectionForm($url_params));
?>

65
db_sql.php Normal file
View File

@ -0,0 +1,65 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
*/
require_once 'libraries/common.inc.php';
/**
* Runs common work
*/
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('functions.js');
$scripts->addFile('makegrid.js');
$scripts->addFile('sql.js');
require 'libraries/db_common.inc.php';
require_once 'libraries/sql_query_form.lib.php';
// After a syntax error, we return to this script
// with the typed query in the textarea.
$goto = 'db_sql.php';
$back = 'db_sql.php';
/**
* Sets globals from $_GET
*/
$get_params = array(
'db_query_force'
);
foreach ($get_params as $one_get_param) {
if (isset($_GET[$one_get_param])) {
$GLOBALS[$one_get_param] = $_GET[$one_get_param];
}
}
/**
* Gets informations about the database and, if it is empty, move to the
* "db_structure.php" script where table can be created
*/
require 'libraries/db_info.inc.php';
if ($num_tables == 0 && empty($db_query_force)) {
$sub_part = '';
$is_info = true;
include 'db_structure.php';
exit();
}
/**
* Query box, bookmark, insert data from textfile
*/
PMA_sqlQueryForm(
true, false,
isset($_REQUEST['delimiter']) ? htmlspecialchars($_REQUEST['delimiter']) : ';'
);
?>

335
db_structure.php Normal file
View File

@ -0,0 +1,335 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
*
* @package PhpMyAdmin
*/
/**
*
*/
require_once 'libraries/common.inc.php';
/**
* Function implementations for this script
*/
require_once 'libraries/structure.lib.php';
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_structure.js');
$scripts->addFile('tbl_change.js');
$scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
$post_params = array(
'error',
'is_info',
'message',
'mult_btn',
'selected_tbl',
'submit_mult'
);
foreach ($post_params as $one_post_param) {
if (isset($_POST[$one_post_param])) {
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
}
}
/**
* Prepares the tables list if the user where not redirected to this script
* because there is no table in the database ($is_info is true)
*/
if (empty($_POST['is_info'])) {
// Drops/deletes/etc. multiple tables if required
if ((!empty($_POST['submit_mult']) && isset($_POST['selected_tbl']))
|| isset($_POST['mult_btn'])
) {
$action = 'db_structure.php';
$err_url = 'db_structure.php?'. PMA_generate_common_url($db);
// see bug #2794840; in this case, code path is:
// db_structure.php -> libraries/mult_submits.inc.php -> sql.php
// -> db_structure.php and if we got an error on the multi submit,
// we must display it here and not call again mult_submits.inc.php
if (! isset($_POST['error']) || false === $_POST['error']) {
include 'libraries/mult_submits.inc.php';
}
if (empty($_POST['message'])) {
$_POST['message'] = PMA_Message::success();
}
}
include 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=db_structure.php';
// Gets the database structure
$sub_part = '_structure';
include 'libraries/db_info.inc.php';
if (!PMA_DRIZZLE) {
include_once 'libraries/replication.inc.php';
} else {
$server_slave_status = false;
}
}
require_once 'libraries/bookmark.lib.php';
require_once 'libraries/mysql_charsets.lib.php';
$db_collation = PMA_getDbCollation($db);
$titles = PMA_Util::buildActionTitles();
// 1. No tables
if ($num_tables == 0) {
$response->addHTML(
'<p>' . __('No tables found in database') . '</p>' . "\n"
);
if (empty($db_is_information_schema)) {
ob_start();
include 'libraries/display_create_table.lib.php';
$content = ob_get_contents();
ob_end_clean();
$response->addHTML($content);
unset($content);
} // end if (Create Table dialog)
exit;
}
// else
// 2. Shows table informations
/**
* Displays the tables list
*/
$response->addHTML('<div id="tableslistcontainer">');
$_url_params = array(
'pos' => $pos,
'db' => $db);
// Add the sort options if they exists
if (isset($_REQUEST['sort'])) {
$_url_params['sort'] = $_REQUEST['sort'];
}
if (isset($_REQUEST['sort_order'])) {
$_url_params['sort_order'] = $_REQUEST['sort_order'];
}
$response->addHTML(
PMA_Util::getListNavigator(
$total_num_tables, $pos, $_url_params, 'db_structure.php',
'frame_content', $GLOBALS['cfg']['MaxTableList']
)
);
// tables form
$response->addHTML(
'<form method="post" action="db_structure.php" '
. 'name="tablesForm" id="tablesForm">'
);
$response->addHTML(PMA_generate_common_hidden_inputs($db));
$response->addHTML(
PMA_TableHeader($db_is_information_schema, $server_slave_status)
);
$i = $sum_entries = 0;
$overhead_check = '';
$create_time_all = '';
$update_time_all = '';
$check_time_all = '';
$num_columns = $cfg['PropertiesNumColumns'] > 1
? ceil($num_tables / $cfg['PropertiesNumColumns']) + 1
: 0;
$row_count = 0;
$sum_size = (double) 0;
$overhead_size = (double) 0;
$hidden_fields = array();
$odd_row = true;
$sum_row_count_pre = '';
foreach ($tables as $keyname => $current_table) {
// Get valid statistics whatever is the table type
$drop_query = '';
$drop_message = '';
$overhead = '';
$table_is_view = false;
$table_encoded = urlencode($current_table['TABLE_NAME']);
// Sets parameters for links
$tbl_url_query = $url_query . '&amp;table=' . $table_encoded;
// do not list the previous table's size info for a view
list($current_table, $formatted_size, $unit, $formatted_overhead,
$overhead_unit, $overhead_size, $table_is_view, $sum_size)
= PMA_getStuffForEngineTypeTable(
$current_table, $db_is_information_schema,
$is_show_stats, $table_is_view, $sum_size, $overhead_size
);
if (! PMA_Table::isMerge($db, $current_table['TABLE_NAME'])) {
$sum_entries += $current_table['TABLE_ROWS'];
}
if (isset($current_table['Collation'])) {
$collation = '<dfn title="'
. PMA_getCollationDescr($current_table['Collation']) . '">'
. $current_table['Collation'] . '</dfn>';
} else {
$collation = '---';
}
if ($is_show_stats) {
if ($formatted_overhead != '') {
$overhead = '<a href="tbl_structure.php?'
. $tbl_url_query . '#showusage">'
. '<span>' . $formatted_overhead . '</span>'
. '<span class="unit">' . $overhead_unit . '</span>'
. '</a>' . "\n";
$overhead_check .=
"markAllRows('row_tbl_" . ($i + 1) . "');";
} else {
$overhead = '-';
}
} // end if
unset($showtable);
if ($GLOBALS['cfg']['ShowDbStructureCreation']) {
list($create_time, $create_time_all) = PMA_getTimeForCreateUpdateCheck(
$current_table, 'Create_time', $create_time_all
);
}
if ($GLOBALS['cfg']['ShowDbStructureLastUpdate']) {
// $showtable might already be set from ShowDbStructureCreation, see above
list($update_time, $update_time_all) = PMA_getTimeForCreateUpdateCheck(
$current_table, 'Update_time', $update_time_all
);
}
if ($GLOBALS['cfg']['ShowDbStructureLastCheck']) {
// $showtable might already be set from ShowDbStructureCreation, see above
list($check_time, $check_time_all) = PMA_getTimeForCreateUpdateCheck(
$current_table, 'Check_time', $check_time_all
);
}
list($alias, $truename) = PMA_getAliasAndTrueName(
$tooltip_aliasname, $current_table, $tooltip_truename
);
$i++;
$row_count++;
if ($table_is_view) {
$hidden_fields[] = '<input type="hidden" name="views[]" value="'
. htmlspecialchars($current_table['TABLE_NAME']) . '" />';
}
/*
* Always activate links for Browse, Search and Empty, even if
* the icons are greyed, because
* 1. for views, we don't know the number of rows at this point
* 2. for tables, another source could have populated them since the
* page was generated
*
* I could have used the PHP ternary conditional operator but I find
* the code easier to read without this operator.
*/
list($browse_table, $search_table, $browse_table_label, $empty_table,
$tracking_icon) = PMA_getHtmlForActionLinks(
$current_table, $table_is_view, $tbl_url_query,
$titles, $truename, $db_is_information_schema, $url_query
);
if (! $db_is_information_schema) {
list($drop_query, $drop_message)
= PMA_getTableDropQueryAndMessage($table_is_view, $current_table);
}
if ($num_columns > 0
&& $num_tables > $num_columns
&& ($row_count % $num_columns) == 0
) {
$row_count = 1;
$odd_row = true;
$response->addHTML(
'</tr></tbody></table>'
);
$response->addHTML(PMA_TableHeader(false, $server_slave_status));
}
list($do, $ignored) = PMA_getServerSlaveStatus(
$server_slave_status, $truename
);
list($html_output, $odd_row) = PMA_getHtmlForStructureTableRow(
$i, $odd_row, $table_is_view, $current_table,
$browse_table_label, $tracking_icon, $server_slave_status,
$browse_table, $tbl_url_query, $search_table, $db_is_information_schema,
$titles, $empty_table, $drop_query, $drop_message, $collation,
$formatted_size, $unit, $overhead,
(isset ($create_time) ? $create_time : ''),
(isset ($update_time) ? $update_time : ''),
(isset ($check_time) ? $check_time : ''),
$is_show_stats, $ignored, $do, $colspan_for_structure
);
$response->addHTML($html_output);
} // end foreach
// Show Summary
$response->addHTML('</tbody>');
$response->addHTML(
PMA_getHtmlBodyForTableSummary(
$num_tables, $server_slave_status, $db_is_information_schema, $sum_entries,
$db_collation, $is_show_stats, $sum_size, $overhead_size, $create_time_all,
$update_time_all, $check_time_all, $sum_row_count_pre
)
);
$response->addHTML('</table>');
//check all
$response->addHTML(
PMA_getHtmlForCheckAllTables(
$pmaThemeImage, $text_dir, $overhead_check,
$db_is_information_schema, $hidden_fields
)
);
$response->addHTML('</form>'); //end of form
// display again the table list navigator
$response->addHTML(
PMA_Util::getListNavigator(
$total_num_tables, $pos, $_url_params, 'db_structure.php',
'frame_content', $GLOBALS['cfg']['MaxTableList']
)
);
$response->addHTML('</div><hr />');
/**
* Work on the database
*/
/* DATABASE WORK */
/* Printable view of a table */
$response->addHTML(
PMA_getHtmlForTablePrintViewLink($url_query)
. PMA_getHtmlForDataDictionaryLink($url_query)
);
if (empty($db_is_information_schema)) {
ob_start();
include 'libraries/display_create_table.lib.php';
$content = ob_get_contents();
ob_end_clean();
$response->addHTML($content);
} // end if (Create Table dialog)
?>

249
db_tracking.php Normal file
View File

@ -0,0 +1,249 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* @package PhpMyAdmin
*/
/**
* Run common work
*/
require_once 'libraries/common.inc.php';
//Get some js files needed for Ajax requests
$response = PMA_Response::getInstance();
$header = $response->getHeader();
$scripts = $header->getScripts();
$scripts->addFile('db_structure.js');
/**
* If we are not in an Ajax request, then do the common work and show the links etc.
*/
require 'libraries/db_common.inc.php';
$url_query .= '&amp;goto=tbl_tracking.php&amp;back=db_tracking.php';
// Get the database structure
$sub_part = '_structure';
require 'libraries/db_info.inc.php';
// Work to do?
// (here, do not use $_REQUEST['db] as it can be crafted)
if (isset($_REQUEST['delete_tracking']) && isset($_REQUEST['table'])) {
PMA_Tracker::deleteTracking($GLOBALS['db'], $_REQUEST['table']);
/**
* If in an Ajax request, generate the success message and use
* {@link PMA_Response()} to send the output
*/
if ($GLOBALS['is_ajax_request'] == true) {
$response = PMA_Response::getInstance();
$response->addJSON('message', PMA_Message::success());
exit;
}
}
// Get tracked data about the database
$data = PMA_Tracker::getTrackedData($_REQUEST['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_information_schema)) {
include 'libraries/display_create_table.lib.php';
}
exit;
}
// ---------------------------------------------------------------------------
// Prepare statement to get HEAD version
$all_tables_query = ' SELECT table_name, MAX(version) as version FROM ' .
PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . '.' .
PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
' WHERE db_name = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db']) . '\' ' .
' GROUP BY table_name' .
' ORDER BY table_name ASC';
$all_tables_result = PMA_queryAsControlUser($all_tables_query);
// If a HEAD version exists
if (PMA_DBI_num_rows($all_tables_result) > 0) {
?>
<div id="tracked_tables">
<h3><?php echo __('Tracked tables');?></h3>
<table id="versions" class="data">
<thead>
<tr>
<th><?php echo __('Database');?></th>
<th><?php echo __('Table');?></th>
<th><?php echo __('Last version');?></th>
<th><?php echo __('Created');?></th>
<th><?php echo __('Updated');?></th>
<th><?php echo __('Status');?></th>
<th><?php echo __('Action');?></th>
<th><?php echo __('Show');?></th>
</tr>
</thead>
<tbody>
<?php
// Print out information about versions
$drop_image_or_text = '';
if (in_array(
$GLOBALS['cfg']['ActionLinksMode'],
array('icons', 'both')
)
) {
$drop_image_or_text .= PMA_Util::getImage(
'b_drop.png',
__('Delete tracking data for this table')
);
}
if (in_array(
$GLOBALS['cfg']['ActionLinksMode'],
array('text', 'both')
)
) {
$drop_image_or_text .= __('Drop');
}
$style = 'odd';
while ($one_result = PMA_DBI_fetch_array($all_tables_result)) {
list($table_name, $version_number) = $one_result;
$table_query = ' SELECT * FROM ' .
PMA_Util::backquote($GLOBALS['cfg']['Server']['pmadb']) . '.' .
PMA_Util::backquote($GLOBALS['cfg']['Server']['tracking']) .
' WHERE `db_name` = \'' . PMA_Util::sqlAddSlashes($_REQUEST['db'])
. '\' AND `table_name` = \'' . PMA_Util::sqlAddSlashes($table_name)
. '\' AND `version` = \'' . $version_number . '\'';
$table_result = PMA_queryAsControlUser($table_query);
$version_data = PMA_DBI_fetch_array($table_result);
if ($version_data['tracking_active'] == 1) {
$version_status = __('active');
} else {
$version_status = __('not active');
}
$tmp_link = 'tbl_tracking.php?' . $url_query . '&amp;table='
. htmlspecialchars($version_data['table_name']);
$delete_link = 'db_tracking.php?' . $url_query . '&amp;table='
. htmlspecialchars($version_data['table_name'])
. '&amp;delete_tracking=true&amp';
?>
<tr class="noclick <?php echo $style;?>">
<td><?php echo htmlspecialchars($version_data['db_name']);?></td>
<td><?php echo htmlspecialchars($version_data['table_name']);?></td>
<td><?php echo $version_data['version'];?></td>
<td><?php echo $version_data['date_created'];?></td>
<td><?php echo $version_data['date_updated'];?></td>
<td><?php echo $version_status;?></td>
<td><a class="drop_tracking_anchor ajax" href="<?php echo $delete_link;?>" ><?php echo $drop_image_or_text; ?></a></td>
<td> <a href="<?php echo $tmp_link; ?>"><?php echo __('Versions');?></a>
| <a href="<?php echo $tmp_link; ?>&amp;report=true&amp;version=<?php echo $version_data['version'];?>"><?php echo __('Tracking report');?></a>
| <a href="<?php echo $tmp_link; ?>&amp;snapshot=true&amp;version=<?php echo $version_data['version'];?>"><?php echo __('Structure snapshot');?></a></td>
</tr>
<?php
if ($style == 'even') {
$style = 'odd';
} else {
$style = 'even';
}
}
unset($tmp_link);
?>
</tbody>
</table>
</div>
<?php
}
$sep = $GLOBALS['cfg']['NavigationTreeTableSeparator'];
// Get list of tables
$table_list = PMA_Util::getTableList($GLOBALS['db']);
// For each table try to get the tracking version
foreach ($table_list as $key => $value) {
// If $value is a table group.
if (array_key_exists(('is' . $sep . 'group'), $value)
&& $value['is' . $sep . 'group']
) {
foreach ($value as $temp_table) {
// If $temp_table is a table with the value for 'Name' is set,
// rather than a propery of the table group.
if (is_array($temp_table)
&& array_key_exists('Name', $temp_table)
) {
$tracking_version = PMA_Tracker::getVersion(
$GLOBALS['db'],
$temp_table['Name']
);
if ($tracking_version == -1) {
$my_tables[] = $temp_table['Name'];
}
}
}
} else { // If $value is a table.
if (PMA_Tracker::getVersion($GLOBALS['db'], $value['Name']) == -1) {
$my_tables[] = $value['Name'];
}
}
}
// If untracked tables exist
if (isset($my_tables)) {
?>
<h3><?php echo __('Untracked tables');?></h3>
<table id="noversions" class="data">
<thead>
<tr>
<th style="width: 300px"><?php echo __('Table');?></th>
<th></th>
</tr>
</thead>
<tbody>
<?php
// Print out list of untracked tables
$style = 'odd';
foreach ($my_tables as $key => $tablename) {
if (PMA_Tracker::getVersion($GLOBALS['db'], $tablename) == -1) {
$my_link = '<a href="tbl_tracking.php?' . $url_query
. '&amp;table=' . htmlspecialchars($tablename) .'">';
$my_link .= PMA_Util::getIcon('eye.png', __('Track table'));
$my_link .= '</a>';
?>
<tr class="noclick <?php echo $style;?>">
<td><?php echo htmlspecialchars($tablename);?></td>
<td><?php echo $my_link;?></td>
</tr>
<?php
if ($style == 'even') {
$style = 'odd';
} else {
$style = 'even';
}
}
}
?>
</tbody>
</table>
<?php
}
// 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 PMA_Util::getMessage(__('Database Log'), $log);
}
?>

25
db_triggers.php Normal file
View File

@ -0,0 +1,25 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Triggers management.
*
* @package PhpMyAdmin
*/
/**
* Include required files
*/
require_once 'libraries/common.inc.php';
/**
* Include all other files
*/
require_once 'libraries/rte/rte_triggers.lib.php';
/**
* Do the magic
*/
$_PMA_RTE = 'TRI';
require_once 'libraries/rte/rte_main.inc.php';
?>

6
doc/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*.swp
/_build
/doctrees
/html
/locale
*.pyc

View File

@ -7,11 +7,6 @@ SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = .
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://www.sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
@ -34,40 +29,17 @@ help:
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/doctrees
-rm -rf $(BUILDDIR)/html
-rm -rf $(BUILDDIR)/dirhtml
-rm -rf $(BUILDDIR)/singlehtml
-rm -rf $(BUILDDIR)/pickle
-rm -rf $(BUILDDIR)/json
-rm -rf $(BUILDDIR)/htmlhelp
-rm -rf $(BUILDDIR)/qthelp
-rm -rf $(BUILDDIR)/devhelp
-rm -rf $(BUILDDIR)/epub
-rm -rf $(BUILDDIR)/latex
-rm -rf $(BUILDDIR)/text
-rm -rf $(BUILDDIR)/man
-rm -rf $(BUILDDIR)/texinfo
-rm -rf $(BUILDDIR)/info
-rm -rf $(BUILDDIR)/gettext
-rm -rf $(BUILDDIR)/changes
-rm -rf $(BUILDDIR)/linkcheck
-rm -rf $(BUILDDIR)/doctest
-rm -rf $(BUILDDIR)/xml
-rm -rf $(BUILDDIR)/pseudoxml
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@ -136,12 +108,6 @@ latexpdf:
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@ -185,13 +151,3 @@ doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

View File

@ -1,3 +1,4 @@
from sphinx.locale import l_, _
from sphinx.domains import Domain, ObjType
from sphinx.roles import XRefRole
from sphinx.domains.std import GenericObject, StandardDomain
@ -22,15 +23,15 @@ def get_id_from_cfg(text):
class ConfigOption(ObjectDescription):
indextemplate = 'configuration option; %s'
indextemplate = l_('configuration option; %s')
parse_node = None
has_arguments = True
doc_field_types = [
Field('default', label='Default value', has_arg=False,
Field('default', label=l_('Default value'), has_arg=False,
names=('default', )),
Field('type', label='Type', has_arg=False,
Field('type', label=l_('Type'), has_arg=False,
names=('type',)),
]
@ -52,21 +53,21 @@ class ConfigOption(ObjectDescription):
# Generic index entries
indexentry = self.indextemplate % (name,)
self.indexnode['entries'].append((indextype, indexentry,
targetname, targetname, None))
targetname, targetname))
self.indexnode['entries'].append((indextype, name,
targetname, targetname, None))
targetname, targetname))
# Server section
if targetparts[0] == 'Servers' and len(targetparts) > 1:
indexname = ', '.join(targetparts[1:])
self.indexnode['entries'].append((indextype, 'server configuration; %s' % indexname,
targetname, targetname, None))
self.indexnode['entries'].append((indextype, l_('server configuration; %s') % indexname,
targetname, targetname))
self.indexnode['entries'].append((indextype, indexname,
targetname, targetname, None))
targetname, targetname))
else:
indexname = ', '.join(targetparts)
self.indexnode['entries'].append((indextype, indexname,
targetname, targetname, None))
targetname, targetname))
self.env.domaindata['config']['objects'][self.objtype, name] = \
self.env.docname, targetname
@ -84,15 +85,15 @@ class ConfigSectionXRefRole(XRefRole):
tgtid = 'index-%s' % env.new_serialno('index')
indexnode = addnodes.index()
indexnode['entries'] = [
('single', varname, tgtid, varname, None),
('single', 'configuration section; %s' % varname, tgtid, varname, None)
('single', varname, tgtid, varname),
('single', _('configuration section; %s') % varname, tgtid, varname)
]
targetnode = nodes.target('', '', ids=[tgtid])
document.note_explicit_target(targetnode)
return [indexnode, targetnode, node], []
class ConfigSection(ObjectDescription):
indextemplate = 'configuration section; %s'
indextemplate = l_('configuration section; %s')
parse_node = None
def handle_signature(self, sig, signode):
@ -118,7 +119,7 @@ class ConfigSection(ObjectDescription):
indextype = 'single'
indexentry = self.indextemplate % (name,)
self.indexnode['entries'].append((indextype, indexentry,
targetname, targetname, None))
targetname, targetname))
self.env.domaindata['config']['objects'][self.objtype, name] = \
self.env.docname, targetname
@ -135,8 +136,8 @@ class ConfigOptionXRefRole(XRefRole):
tgtid = 'index-%s' % env.new_serialno('index')
indexnode = addnodes.index()
indexnode['entries'] = [
('single', varname, tgtid, varname, None),
('single', 'configuration option; %s' % varname, tgtid, varname, None)
('single', varname, tgtid, varname),
('single', _('configuration option; %s') % varname, tgtid, varname)
]
targetnode = nodes.target('', '', ids=[tgtid])
document.note_explicit_target(targetnode)
@ -148,8 +149,8 @@ class ConfigFileDomain(Domain):
label = 'Config'
object_types = {
'option': ObjType('config option', 'option'),
'section': ObjType('config section', 'section'),
'option': ObjType(l_('config option'), 'option'),
'section': ObjType(l_('config section'), 'section'),
}
directives = {
'option': ConfigOption,
@ -165,12 +166,9 @@ class ConfigFileDomain(Domain):
}
def clear_doc(self, docname):
toremove = []
for key, (fn, _) in self.data['objects'].items():
if fn == docname:
toremove.append(key)
for key in toremove:
del self.data['objects'][key]
del self.data['objects'][key]
def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
@ -182,9 +180,10 @@ class ConfigFileDomain(Domain):
labelid, contnode)
def get_objects(self):
for (type, name), info in self.data['objects'].items():
for (type, name), info in self.data['objects'].iteritems():
yield (name, name, type, info[0], info[1],
self.object_types[type].attrs['searchprio'])
def setup(app):
app.add_domain(ConfigFileDomain)

View File

@ -11,8 +11,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
import os
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@ -20,14 +19,13 @@ import os
#sys.path.insert(0, os.path.abspath('.'))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "_ext")))
# -- General configuration ------------------------------------------------
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['configext']
# Add any paths that contain templates here, relative to this directory.
@ -44,14 +42,14 @@ master_doc = 'index'
# General information about the project.
project = u'phpMyAdmin'
copyright = u'2012 - 2026, The phpMyAdmin devel team'
copyright = u'2012 - 2013, The phpMyAdmin devel team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '6.0.0-dev'
version = '4.0.10.20'
# The full version, including alpha/beta/rc tags.
release = version
@ -69,8 +67,7 @@ release = version
# directories to ignore when looking for source files.
exclude_patterns = ['_build', 'html', 'doctrees']
# The reST default role (used for this markup: `text`) to use for all
# documents.
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
@ -90,22 +87,13 @@ pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
try:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
except:
print('WARNING: The python module sphinx_rtd_theme was not found, using the default theme. Debian package: python3-sphinx-rtd-theme')
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
@ -133,12 +121,7 @@ except:
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
@ -185,7 +168,7 @@ except:
htmlhelp_basename = 'phpMyAdmindoc'
# -- Options for LaTeX output ---------------------------------------------
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
@ -199,8 +182,7 @@ latex_elements = {
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'phpMyAdmin.tex', u'phpMyAdmin Documentation',
u'The phpMyAdmin devel team', 'manual'),
@ -227,7 +209,7 @@ latex_documents = [
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
@ -240,7 +222,7 @@ man_pages = [
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
@ -302,23 +284,3 @@ epub_copyright = copyright
# Allow duplicate toc entries.
#epub_tocdup = True
# Highlight PHP without starting <?php tag
from sphinx.highlighting import lexers
from pygments.lexers.web import PhpLexer
lexers['php'] = PhpLexer(startinline=True)
# Number of retries and timeout for linkcheck
linkcheck_retries = 10
linkcheck_timeout = 10
linkcheck_anchors = False
linkcheck_ignore = [
# Site is often down
r'https://software.opensuse.org/package/.*',
r'https://pecl.php.net/.*',
# 403 Client Error: Forbidden
r'https://authy.com/.*',
# Site often changes links and reverts changes (9362bde02d0535a2f8cb74a18797249cb734c4b0)
r'https://www.yubico.com/.*',
]

2769
doc/config.rst Normal file

File diff suppressed because it is too large Load Diff

30
doc/copyright.rst Normal file
View File

@ -0,0 +1,30 @@
.. _copyright:
Copyright
=========
.. code-block:: none
Copyright (C) 1998-2000 Tobias Ratschiller <tobias_at_ratschiller.com>
Copyright (C) 2001-2013 Marc Delisle <marc_at_infomarc.info>
Olivier Müller <om_at_omnis.ch>
Robin Johnson <robbat2_at_users.sourceforge.net>
Alexander M. Turek <me_at_derrabus.de>
Michal Čihař <michal_at_cihar.com>
Garvin Hicking <me_at_supergarv.de>
Michael Keck <mkkeck_at_users.sourceforge.net>
Sebastian Mendel <cybot_tm_at_users.sourceforge.net>
[check credits for more details]
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 `http://www.gnu.org/licenses/
<http://www.gnu.org/licenses/>`_.

597
doc/credits.rst Normal file
View File

@ -0,0 +1,597 @@
.. _credits:
Credits
=======
Credits, in chronological order
+++++++++++++++++++++++++++++++
* Tobias Ratschiller <tobias\_at\_ratschiller.com>
* creator of the phpmyadmin project
* maintainer from 1998 to summer 2000
* Marc Delisle <marc\_at\_infomarc.info>
* multi-language version in December 1998
* various fixes and improvements
* :term:`SQL` analyser (most of it)
* current project maintainer
* Olivier Müller <om\_at\_omnis.ch>
* started SourceForge phpMyAdmin project in March 2001
* sync'ed different existing CVS trees with new features and bugfixes
* multi-language improvements, dynamic language selection
* many bugfixes and improvements
* Loïc Chapeaux <lolo\_at\_phpheaven.net>
* rewrote and optimized javascript, DHTML and DOM stuff
* rewrote the scripts so they fit the :term:`PEAR` coding standards and
generate XHTML1.0 and CSS2 compliant codes
* improved the language detection system
* many bugfixes and improvements
* Robin Johnson <robbat2\_at\_users.sourceforge.net>
* database maintenance controls
* table type code
* Host authentication :term:`IP` Allow/Deny
* DB-based configuration (Not completed)
* :term:`SQL` parser and pretty-printer
* :term:`SQL` validator
* many bugfixes and improvements
* Armel Fauveau <armel.fauveau\_at\_globalis-ms.com>
* bookmarks feature
* multiple dump feature
* gzip dump feature
* zip dump feature
* Geert Lund <glund\_at\_silversoft.dk>
* various fixes
* moderator of the phpMyAdmin former users forum at phpwizard.net
* Korakot Chaovavanich <korakot\_at\_iname.com>
* "insert as new row" feature
* Pete Kelly <webmaster\_at\_trafficg.com>
* rewrote and fix dump code
* bugfixes
* Steve Alberty <alberty\_at\_neptunlabs.de>
* rewrote dump code for PHP4
* mySQL table statistics
* bugfixes
* Benjamin Gandon <gandon\_at\_isia.cma.fr>
* main author of the version 2.1.0.1
* bugfixes
* Alexander M. Turek <me\_at\_derrabus.de>
* MySQL 4.0 / 4.1 / 5.0 compatibility
* abstract database interface (PMA\_DBI) with MySQLi support
* privileges administration
* :term:`XML` exports
* various features and fixes
* German language file updates
* Mike Beck <mike.beck\_at\_web.de>
* automatic joins in QBE
* links column in printview
* Relation view
* Michal Čihař <michal\_at\_cihar.com>
* enhanced index creation/display feature
* feature to use a different charset for HTML than for MySQL
* improvements of export feature
* various features and fixes
* Czech language file updates
* Christophe Gesché from the "MySQL Form Generator for PHPMyAdmin"
(http://sf.net/projects/phpmysqlformgen/)
* suggested the patch for multiple table printviews
* Garvin Hicking <me\_at\_supergarv.de>
* built the patch for vertical display of table rows
* built the Javascript based Query window + :term:`SQL` history
* Improvement of column/db comments
* (MIME)-Transformations for columns
* Use custom alias names for Databases in left frame
* hierarchical/nested table display
* :term:`PDF`-scratchboard for WYSIWYG-
distribution of :term:`PDF` relations
* new icon sets
* vertical display of column properties page
* some bugfixes, features, support, German language additions
* Yukihiro Kawada <kawada\_at\_den.fujifilm.co.jp>
* japanese kanji encoding conversion feature
* Piotr Roszatycki <d3xter\_at\_users.sourceforge.net> and Dan Wilson
* the Cookie authentication mode
* Axel Sander <n8falke\_at\_users.sourceforge.net>
* table relation-links feature
* Maxime Delorme <delorme.maxime\_at\_free.fr>
* :term:`PDF` schema output, thanks also to
Olivier Plathey for the "FPDF" library (see <http://www.fpdf.org/>), Steven
Wittens for the "UFPDF" library (see <http://www.acko.net/node/56>) and
Nicola Asuni for the "TCPDF" library (see <http://www.tcpdf.org/>).
* Olof Edlund <olof.edlund\_at\_upright.se>
* :term:`SQL` validator server
* Ivan R. Lanin <ivanlanin\_at\_users.sourceforge.net>
* phpMyAdmin logo (until June 2004)
* Mike Cochrane <mike\_at\_graftonhall.co.nz>
* blowfish library from the Horde project (withdrawn in release 4.0)
* Marcel Tschopp <ne0x\_at\_users.sourceforge.net>
* mysqli support
* many bugfixes and improvements
* Nicola Asuni (Tecnick.com)
* TCPDF library (`http://www.tcpdf.org <http://www.tcpdf.org>`_)
* Michael Keck <mkkeck\_at\_users.sourceforge.net>
* redesign for 2.6.0
* phpMyAdmin sailboat logo (June 2004)
* Mathias Landhäußer
* Representation at conferences
* Sebastian Mendel <cybot\_tm\_at\_users.sourceforge.net>
* interface improvements
* various bugfixes
* Ivan A Kirillov
* new relations Designer
* Raj Kissu Rajandran (Google Summer of Code 2008)
* BLOBstreaming support (withdrawn in release 4.0)
* Piotr Przybylski (Google Summer of Code 2008, 2010 and 2011)
* improved setup script
* user preferences
* Drizzle support
* Derek Schaefer (Google Summer of Code 2009)
* Improved the import system
* Alexander Rutkowski (Google Summer of Code 2009)
* Tracking mechanism
* Zahra Naeem (Google Summer of Code 2009)
* Synchronization feature (removed in release 4.0)
* Tomáš Srnka (Google Summer of Code 2009)
* Replication support
* Muhammad Adnan (Google Summer of Code 2010)
* Relation schema export to multiple formats
* Lori Lee (Google Summer of Code 2010)
* User interface improvements
* ENUM/SET editor
* Simplified interface for export/import
* Ninad Pundalik (Google Summer of Code 2010)
* AJAXifying the interface
* Martynas Mickevičius (Google Summer of Code 2010)
* Charts
* Barrie Leslie
* BLOBstreaming support with PBMS PHP extension (withdrawn in release
4.0)
* Ankit Gupta (Google Summer of Code 2010)
* Visual query builder
* Madhura Jayaratne (Google Summer of Code 2011)
* OpenGIS support
* Ammar Yasir (Google Summer of Code 2011)
* Zoom search
* Aris Feryanto (Google Summer of Code 2011)
* Browse-mode improvements
* Thilanka Kaushalya (Google Summer of Code 2011)
* AJAXification
* Tyron Madlener (Google Summer of Code 2011)
* Query statistics and charts for the status page
* Zarubin Stas (Google Summer of Code 2011)
* Automated testing
* Rouslan Placella (Google Summer of Code 2011 and 2012)
* Improved support for Stored Routines, Triggers and Events
* Italian translation updates
* Removal of frames, new navigation
* Dieter Adriaenssens
* Various bugfixes
* Dutch translation updates
* Alex Marin (Google Summer of Code 2012)
* New plugins and properties system
* Thilina Buddika Abeyrathna (Google Summer of Code 2012)
* Refactoring
* Atul Pratap Singh (Google Summer of Code 2012)
* Refactoring
* Chanaka Indrajith (Google Summer of Code 2012)
* Refactoring
* Yasitha Pandithawatta (Google Summer of Code 2012)
* Automated testing
* Jim Wigginton (phpseclib.sourceforge.net)
* phpseclib
And also to the following people who have contributed minor changes,
enhancements, bugfixes or support for a new language since version
2.1.0:
Bora Alioglu, Ricardo ?, Sven-Erik Andersen, Alessandro Astarita,
Péter Bakondy, Borges Botelho, Olivier Bussier, Neil Darlow, Mats
Engstrom, Ian Davidson, Laurent Dhima, Kristof Hamann, Thomas Kläger,
Lubos Klokner, Martin Marconcini, Girish Nair, David Nordenberg,
Andreas Pauley, Bernard M. Piller, Laurent Haas, "Sakamoto", Yuval
Sarna, www.securereality.com.au, Alexis Soulard, Alvar Soome, Siu Sun,
Peter Svec, Michael Tacelosky, Rachim Tamsjadi, Kositer Uros, Luís V.,
Martijn W. van der Lee, Algis Vainauskas, Daniel Villanueva, Vinay,
Ignacio Vazquez-Abrams, Chee Wai, Jakub Wilk, Thomas Michael
Winningham, Vilius Zigmantas, "Manuzhai".
Translators
+++++++++++
Following people have contributed to translation of phpMyAdmin:
* Arabic
* Abdullah Al-Saedi <abdullah.10\_at\_windowslive.com>
* Bulgarian
* stoyanster <stoyanster\_at\_gmail.com>
* Catalan
* Xavier Navarro <xvnavarro\_at\_gmail.com>
* Czech
* Michal Čihař <michal\_at\_cihar.com>
* Danish
* opensource <opensource\_at\_jth.net>
* Jørgen Thomsen <opensource\_at\_jth.net>
* German
* mrbendig <mrbendig\_at\_mrbendig.com>
* torsten.funck <torsten.funck\_at\_googlemail.com>
* Sven Strickroth <email\_at\_cs-ware.de>
* typo3 <typo3\_at\_dirk-weise.de>
* Jo Michael <me\_at\_mynetx.net>
* Greek
* Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
* English (United Kingdom)
* Robert Readman <robert_readman\_at\_hotmail.com>
* Spanish
* Matías Bellone <matiasbellone\_at\_gmail.com>
* French
* Marc Delisle <marc\_at\_infomarc.info>
* Hindi
* u4663530 <u4663530\_at\_anu.edu.au>
* rsedwardian <rsedwardian\_at\_gmail.com>
* Hungarian
* gergo314 <gergo314\_at\_gmail.com>
* Italian
* Rouslan Placella <rouslan\_at\_placella.com>
* Japanese
* Yuichiro <yuichiro\_at\_pop07.odn.ne.jp>
* Lithuanian
* Kęstutis <forkik\_at\_gmail.com>
* Norwegian Bokmål
* Sven-Erik Andersen <sven.erik.andersen\_at\_gmail.com>
* Dutch
* Dieter Adriaenssens <ruleant\_at\_users.sourceforge.net>
* Herman van Rink <rink\_at\_initfour.nl>
* Polish
* Stanisław Krukowski <stankruk\_at\_neostrada.pl>
* Marcin Kozioł <lord_dark\_at\_wp.pl>
* Portuguese
* JoaoTMDias <contacto\_at\_joaodias.me>
* Portuguese (Brazil)
* wiltave <wiltave\_at\_gmail.com>
* emerson4br <emerson4br\_at\_gmail.com>
* Romanian
* alexukf <alex.ukf\_at\_gmail.com>
* Russian
* Victor Volkov <hanut\_at\_php-myadmin.ru>
* Sinhala
* Madhura Jayaratne <madhura.cj\_at\_gmail.com>
* Slovak
* Martin Lacina <martin\_at\_whistler.sk>
* Slovenian
* Domen <dbc334\_at\_gmail.com>
* Swedish
* stefan <stefan\_at\_inkopsforum.se>
* Tamil
* ysajeepan <ysajeepan\_at\_live.com>
* Telugu
* veeven <veeven\_at\_gmail.com>
* Thai
* kanitchet <kanichet\_at\_hotmail.com>
* Turkish
* Burak Yavuz <hitowerdigit\_at\_hotmail.com>
* Uighur
* gheni <gheni\_at\_yahoo.cn>
* Ukrainian
* typim <duke3d\_at\_ukr.net>
* oleg-ilnytskyi <ukraine.oleg\_at\_gmail.com>
* Urdu
* Mehbooob Khan <mehboobbugti\_at\_gmail.com>
* Simplified Chinese
* shanyan baishui <Siramizu\_at\_gmail.com>
* Traditional Chinese
* star <star\_at\_origin.club.tw>
Documentation translators
+++++++++++++++++++++++++
Following people have contributed to translation of phpMyAdmin documentation:
* Czech
* Michal Čihař <michal\_at\_cihar.com>
* Greek
* Panagiotis Papazoglou <papaz_p\_at\_yahoo.com>
* English (United Kingdom)
* Robert Readman <robert_readman\_at\_hotmail.com>
* French
* Cédric Corazza <cedric.corazza\_at\_wanadoo.fr>
* Japanese
* Yuichiro Takahashi <yuichiro\_at\_pop07.odn.ne.jp>
* Polish
* Stanisław Krukowski <stankruk\_at\_neostrada.pl>
* Portuguese (Brazil)
* mjaning <mjaning\_at\_gmail.com>
* Slovenian
* Domen <dbc334\_at\_gmail.com>
Original Credits of Version 2.1.0
+++++++++++++++++++++++++++++++++
This work is based on Peter Kuppelwieser's MySQL-Webadmin. It was his
idea to create a web-based interface to MySQL using PHP3. Although I
have not used any of his source-code, there are some concepts I've
borrowed from him. phpMyAdmin was created because Peter told me he
wasn't going to further develop his (great) tool.
Thanks go to
* Amalesh Kempf <ak-lsml\_at\_living-source.com> who contributed the
code for the check when dropping a table or database. He also
suggested that you should be able to specify the primary key on
tbl\_create.php3. To version 1.1.1 he contributed the ldi\_\*.php3-set
(Import text-files) as well as a bug-report. Plus many smaller
improvements.
* Jan Legenhausen <jan\_at\_nrw.net>: He made many of the changes that
were introduced in 1.3.0 (including quite significant ones like the
authentication). For 1.4.1 he enhanced the table-dump feature. Plus
bug-fixes and help.
* Marc Delisle <DelislMa\_at\_CollegeSherbrooke.qc.ca> made phpMyAdmin
language-independent by outsourcing the strings to a separate file. He
also contributed the French translation.
* Alexandr Bravo <abravo\_at\_hq.admiral.ru> who contributed
tbl\_select.php3, a feature to display only some columns from a table.
* Chris Jackson <chrisj\_at\_ctel.net> added support for MySQL functions
in tbl\_change.php3. He also added the "Query by Example" feature in
2.0.
* Dave Walton <walton\_at\_nordicdms.com> added support for multiple
servers and is a regular contributor for bug-fixes.
* Gabriel Ash <ga244\_at\_is8.nyu.edu> contributed the random access
features for 2.0.6.
The following people have contributed minor changes, enhancements,
bugfixes or support for a new language:
Jim Kraai, Jordi Bruguera, Miquel Obrador, Geert Lund, Thomas
Kleemann, Alexander Leidinger, Kiko Albiol, Daniel C. Chao, Pavel
Piankov, Sascha Kettler, Joe Pruett, Renato Lins, Mark Kronsbein,
Jannis Hermanns, G. Wieggers.
And thanks to everyone else who sent me email with suggestions, bug-
reports and or just some feedback.

View File

@ -8,5 +8,5 @@ great features have been written by other people and you too can help
to make phpMyAdmin a useful tool.
You can check out all the possibilities to contribute in the
`contribute section on our website
`contribute section on our website
<https://www.phpmyadmin.net/contribute/>`_.

2001
doc/faq.rst Normal file

File diff suppressed because it is too large Load Diff

406
doc/glossary.rst Normal file
View File

@ -0,0 +1,406 @@
.. _glossary:
Glossary
========
From Wikipedia, the free encyclopedia
.. glossary::
.htaccess
the default name of Apache's directory-level configuration file.
.. seealso:: <http://www.wikipedia.org/wiki/.htaccess>
ACL
Access Contol List
Blowfish
a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.
.. seealso:: <http://www.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:: <http://en.wikipedia.org/wiki/Web_browser>
bzip2
a free software/open source data compression algorithm and program developed by Julian Seward.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/CGI>
Changelog
a log or record of changes made to a project.
.. seealso:: <http://www.wikipedia.org/wiki/Changelog>
Client
a computer system that accesses a (remote) service on another computer by some kind of network.
.. seealso:: <http://www.wikipedia.org/wiki/Client_(computing)>
column
a set of data values of a particular simple type, one for each row of the table.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/HTTP_cookie>
CSV
Comma- separated values
.. seealso:: <http://www.wikipedia.org/wiki/Comma-separated_values>
DB
look at :term:`database`
database
an organized collection of data.
.. seealso:: <http://www.wikipedia.org/wiki/Database>
Engine
look at :term:`storage engines`
extension
a PHP module that extends PHP with additional functionality.
.. seealso:: <http://www.wikipedia.org/wiki/extension>
FAQ
Frequently Asked Questions is a list of commonly asked question and there
answers.
.. seealso:: <http://www.wikipedia.org/wiki/FAQ>
Field
one part of divided data/columns.
.. seealso:: <http://www.wikipedia.org/wiki/Field_(computer_science)>
foreign key
a column or group of columns in a database row that point to a key column
or group of columns forming a key of another database row in some
(usually different) table.
.. seealso:: <http://www.wikipedia.org/wiki/Foreign_key>
FPDF
the free :term:`PDF` library
.. seealso:: <http://www.fpdf.org/>
GD
Graphics Library by Thomas Boutell and others for dynamically manipulating images.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Gzip>
host
any machine connected to a computer network, a node that has a hostname.
.. seealso:: <http://www.wikipedia.org/wiki/Host>
hostname
the unique name by which a network attached device is known on a network.
.. seealso:: <http://www.wikipedia.org/wiki/Hostname>
HTTP
HyperText Transfer Protocol is the primary method used to transfer or
convey information on the World Wide Web.
.. seealso:: <http://www.wikipedia.org/wiki/HyperText_Transfer_Protocol>
https
a :term:`HTTP`-connection with additional security measures.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Internet_Information_Services>
Index
a feature that allows quick access to the rows in a table.
.. seealso:: <http://www.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:: <http://www.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:: <http://www.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 precedessor IPv4 running out of addresses.
.. seealso:: <http://www.wikipedia.org/wiki/IPv6>
ISAPI
Internet Server Application Programming Interface is the API of Internet Information Services (IIS).
.. seealso:: <http://www.wikipedia.org/wiki/ISAPI>
ISP
Internet service provider is a business or organization that offers users
access to the Internet and related services.
.. seealso:: <http://www.wikipedia.org/wiki/ISP>
ISO
International Standards Organisation
JPEG
a most commonly used standard method of lossy compression for photographic images.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/LaTeX>
Mac
Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Mac_OS_X>
MCrypt
a cryptographic library.
.. seealso:: <http://www.wikipedia.org/wiki/MCrypt>
mcrypt
the MCrypt PHP extension.
.. seealso:: <http://php.net/mcrypt>
MIME
Multipurpose Internet Mail Extensions is
an Internet Standard for the format of e-mail.
.. seealso:: <http://www.wikipedia.org/wiki/MIME>
module
some sort of extension for the Apache Webserver.
.. seealso:: <http://www.wikipedia.org/wiki/module>
MySQL
a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).
.. seealso:: <http://www.wikipedia.org/wiki/MySQL>
mysqli
the improved MySQL client PHP extension.
.. seealso:: <http://php.net/mysqli>
mysql
the MySQL client PHP extension.
.. seealso:: <http://php.net/mysql>
OpenDocument
open standard for office documents.
.. seealso:: <http://www.wikipedia.org/wiki/OpenDocument>
OS X
look at :term:`Mac OS X`.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Portable_Document_Format>
PEAR
the PHP Extension and Application Repository.
.. seealso:: <http://pear.php.net/>
PCRE
Perl Compatible Regular Expressions is the perl-compatible regular
expression functions for PHP
.. seealso:: <http://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:: <http://www.wikipedia.org/wiki/PHP>
port
a connection through which data is sent and received.
.. seealso:: <http://www.wikipedia.org/wiki/Port_(computing)>
RFC
Request for Comments (RFC) documents are a series of memoranda
encompassing new research, innovations, and methodologies applicable to
Internet technologies.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Row_(database)>
Server
a computer system that provides services to other computing systems over a network.
.. seealso:: <http://www.wikipedia.org/wiki/Server_(computing)>
Storage Engines
handlers for different table types
.. seealso:: <http://dev.mysql.com/doc/en/storage-engines.html>
SOAP
Simple Object Access Protocol is a protocol specification for exchanging
structured information in the implementation of Web Services in computer
networks.
.. seealso:: <http://en.wikipedia.org/wiki/SOAP>
socket
a form of inter-process communication.
.. seealso:: <http://www.wikipedia.org/wiki/Socket#Computer_sockets>
SSL
Secure Sockets Layer is a cryptographic protocol which provides secure
communication on the Internet.
.. seealso:: <http://www.wikipedia.org/wiki/Secure_Sockets_Layer>
Stored procedure
a subroutine available to applications accessing a relational database system
.. seealso:: <http://en.wikipedia.org/wiki/Stored_procedure>
SQL
Structured Query Language
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/Table_(database)>
tar
a type of archive file format: the Tape ARchive format.
.. seealso:: <http://www.wikipedia.org/wiki/Tar_(file_format)>
TCP
Transmission Control Protocol is one of the core protocols of the
Internet protocol suite.
.. seealso:: <http://www.wikipedia.org/wiki/TCP>
TCPDF
Rewrite of :term:`UFPDF` with various improvements.
.. seealso:: <http://www.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:: <http://en.wikipedia.org/wiki/Database_trigger>
UFPDF
Unicode/UTF-8 extension for :term:`FPDF`
.. seealso:: <http://www.acko.net/node/56>
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:: <http://www.wikipedia.org/wiki/URL>
Webserver
A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.
.. seealso:: <http://www.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:: <http://www.wikipedia.org/wiki/XML>
ZIP
a popular data compression and archival format.
.. seealso:: <http://www.wikipedia.org/wiki/ZIP_(file_format)>
zlib
an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.
.. seealso:: <http://www.wikipedia.org/wiki/Zlib>

View File

@ -18,12 +18,12 @@ Contents:
user
faq
developers
security
vendors
copyright
credits
glossary
Indices and tables
==================

68
doc/intro.rst Normal file
View File

@ -0,0 +1,68 @@
.. _intro:
Introduction
============
phpMyAdmin can manage a whole MySQL server (needs a super-user) as
well as a single database. To accomplish the latter you'll need a
properly set up MySQL user who can read/write only the desired
database. It's up to you to look up the appropriate part in the MySQL
manual.
Supported features
------------------
Currently phpMyAdmin can:
* browse and drop databases, tables, views, columns and indexes
* display multiple results sets through stored procedures or queries
* create, copy, drop, rename and alter databases, tables, columns and
indexes
* maintenance server, databases and tables, with proposals on server
configuration
* execute, edit and bookmark any :term:`SQL`-statement, even batch-queries
* load text files into tables
* create [#f1]_ and read dumps of tables
* export [#f1]_ data to various formats: :term:`CSV`, :term:`XML`, :term:`PDF`,
:term:`ISO`/:term:`IEC` 26300 - :term:`OpenDocument` Text and Spreadsheet, Microsoft
Word 2000, and LATEX formats
* import data and :term:`MySQL` structures from :term:`OpenDocument` spreadsheets, as
well as :term:`XML`, :term:`CSV`, and :term:`SQL` files
* administer multiple servers
* manage MySQL users and privileges
* check referential integrity in MyISAM tables
* using Query-by-example (QBE), create complex queries automatically
connecting required tables
* create :term:`PDF` graphics of your
database layout
* search globally in a database or a subset of it
* transform stored data into any format using a set of predefined
functions, like displaying BLOB-data as image or download-link
* track changes on databases, tables and views
* support InnoDB tables and foreign keys see :ref:`faq3_6`
* support mysqli, the improved MySQL extension see :ref:`faq1_17`
* create, edit, call, export and drop stored procedures and functions
* create, edit, export and drop events and triggers
* communicate in `62 different languages
<https://www.phpmyadmin.net/home_page/translations.php>`_
A word about users
------------------
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.
.. rubric:: Footnotes
.. [#f1]
phpMyAdmin can compress (:term:`Zip`, :term:`GZip` :term:`RFC 1952` or
:term:`Bzip2` formats) dumps and :term:`CSV` exports if you use PHP with
:term:`Zlib` support (``--with-zlib``) and/or :term:`Bzip2` support
(``--with-bz2``). Proper support may also need changes in :file:`php.ini`.

View File

@ -33,8 +33,6 @@ if "%1" == "help" (
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. xml to make Docutils-native XML files
echo. pseudoxml to make pseudoxml-XML files for display purposes
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
@ -46,20 +44,6 @@ if "%1" == "clean" (
goto end
)
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
@ -145,26 +129,6 @@ if "%1" == "latex" (
goto end
)
if "%1" == "latexpdf" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "latexpdfja" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
cd %BUILDDIR%/latex
make all-pdf-ja
cd %BUILDDIR%/..
echo.
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
@ -223,20 +187,4 @@ results in %BUILDDIR%/doctest/output.txt.
goto end
)
if "%1" == "xml" (
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The XML files are in %BUILDDIR%/xml.
goto end
)
if "%1" == "pseudoxml" (
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
goto end
)
:end

18
doc/other.rst Normal file
View File

@ -0,0 +1,18 @@
Other sources of information
============================
Printed Book
------------
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 `books at the phpMyAdmin site`_.
.. _books at the phpMyAdmin site: https://www.phpmyadmin.net/home_page/docs.php?books
Tutorials
---------
Third party tutorials and articles are listed on our `wiki page`_.
.. _wiki page: https://wiki.phpmyadmin.net/pma/Articles

50
doc/privileges.rst Normal file
View File

@ -0,0 +1,50 @@
User management
===============
User management is the process of controlling which users are allowed to
connect to the MySQL server and what permissions they have on each database.
phpMyAdmin does not handle user management, rather it passes the username and
password on to MySQL, which then determines whether a user is permitted to
perform a particular action. Within phpMyAdmin, administrators have full
control over creating users, viewing and editing privileges for existing users,
and removing users.
Within phpMyAdmin, user management is controlled via the :guilabel:`Users` link
from the main page. Users can be created, edited, and removed.
Creating a new user
-------------------
To create a new user, click the :guilabel:`Add a new user` link near the bottom
of the :guilabel:`Users` page (you must be a "superuser", e.g., user "root").
Use the textboxes and drop-downs to configure the user to your particular
needs. You can then select whether to create a database for that user and grant
specific global privileges. Once you've created the user (by clicking Go), you
can define that user's permissions on a specific database (don't grant global
privileges in that case). In general, users do not need any global privileges
(other than USAGE), only permissions for their specific database.
Editing an existing user
------------------------
To edit an existing user, simply click the pencil icon to the right of that
user in the :guilabel:`Users` page. You can then edit their global- and
database-specific privileges, change their password, or even copy those
privileges to a new user.
Deleting a user
---------------
From the :guilabel:`Users` page, check the checkbox for the user you wish to
remove, select whether or not to also remove any databases of the same name (if
they exist), and click Go.
Assigning privileges to user for a specific database
----------------------------------------------------
Users are assigned to databases by editing the user record (from the
:guilabel:`Users` link on the home page) not from within the :guilabel:`Users`
link under the table. If you are creating a user specifically for a given table
you will have to create the user first (with no global privileges) and then go
back and edit that user to add the table and privileges for the individual
table.

54
doc/require.rst Normal file
View File

@ -0,0 +1,54 @@
.. _require:
Requirements
============
Web server
----------
Since, phpMyAdmin's interface is based entirely in your browser, you'll need a
web server (such as Apache, :term:`IIS`) to install phpMyAdmin's files into.
PHP
---
* You need PHP 5.2.0 or newer, with ``session`` support, the Standard PHP Library
(SPL) extension, JSON support, and the ``mbstring`` extension.
* To support uploading of ZIP files, you need the PHP ``zip`` extension.
* You need GD2 support in PHP to display inline thumbnails of JPEGs
("image/jpeg: inline") with their original aspect ratio.
* When using the cookie authentication (the default), the `mcrypt
<http://www.php.net/mcrypt>`_ extension is strongly suggested for most
users and is **required** for 64bit machines. Not using mcrypt will
cause phpMyAdmin to load pages significantly slower.
* To support upload progress bars, see :ref:`faq2_9`.
* To support XML and Open Document Spreadsheet importing, you need PHP
5.2.17 or newer and the `libxml <http://www.php.net/libxml>`_
extension.
* Performance suggestion: install the ``ctype`` extension.
.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes`
Database
--------
phpMyAdmin support MySQL compatible databases.
* MySQL 5.0 or newer
* MariaDB 5.0 or newer
* Drizzle
.. seealso:: :ref:`faq1_17`
Web browser
-----------
To access phpMyAdmin you need a web browser with cookies and javascript
enabled.

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