Merge branch 'QA_4_7' into STABLE
26
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
### Steps to reproduce
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
### Expected behaviour
|
||||
Tell us what should happen
|
||||
|
||||
### Actual behaviour
|
||||
Tell us what happens instead
|
||||
|
||||
### Server configuration
|
||||
**Operating system**:
|
||||
|
||||
**Web server:**
|
||||
|
||||
**Database:**
|
||||
|
||||
**PHP version:**
|
||||
|
||||
**phpMyAdmin version:**
|
||||
|
||||
### Client configuration
|
||||
**Browser:**
|
||||
|
||||
**Operating system:**
|
||||
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
Before submitting pull request, please check that every commit:
|
||||
|
||||
- [ ] Has proper Signed-Off-By
|
||||
- [ ] Has commit message which describes it
|
||||
- [ ] Is needed on it's own, if you have just minor fixes to previous commits, you can squash them
|
||||
- [ ] Any new functionality is covered by tests
|
||||
2
.gitignore
vendored
@ -34,6 +34,7 @@ web.config
|
||||
/js/line_counts.php
|
||||
# API documentation
|
||||
/apidoc/
|
||||
/doc/linkcheck/
|
||||
# Demo server
|
||||
revision-info.php
|
||||
# PHPUnit
|
||||
@ -48,5 +49,4 @@ phpunit.xml
|
||||
# Ant cache
|
||||
cache.properties
|
||||
# Composer
|
||||
composer.lock
|
||||
/vendor/
|
||||
|
||||
@ -3,8 +3,16 @@ imports:
|
||||
- javascript
|
||||
- php
|
||||
filter:
|
||||
excluded_paths: [libraries/php-gettext/*, libraries/tcpdf/*, libraries/bfShapeFiles/*, libraries/phpseclib/*, libraries/plugins/auth/recaptchalib.php, libraries/sql-formatter/*, js/jquery/*, js/jqplot/*, js/openlayers/*, js/codemirror/*, js/canvg/*, js/tracekit/*, js/OpenStreetMap.js, js/sprintf.js, test/libraries/php-gettext/*, test/libraries/sql-formatter/*]
|
||||
tools:
|
||||
php_code_sniffer:
|
||||
config:
|
||||
standard: "PMAStandard"
|
||||
excluded_paths: [js/jquery/*, js/jqplot/*, js/openlayers/*, js/codemirror/*, js/canvg/*, js/tracekit/*, js/sprintf.js]
|
||||
build:
|
||||
dependencies:
|
||||
before:
|
||||
- composer install
|
||||
- ./vendor/bin/phpcs --config-set installed_paths `pwd`/vendor/phpmyadmin/coding-standard
|
||||
tests:
|
||||
override:
|
||||
-
|
||||
command: './vendor/bin/phpcs --standard=PMAStandard ./ --report=checkstyle --report-file=cs-data --ignore=*/vendor/*,*/canvg/*,*/codemirror/*,*/openlayers/*,*/jquery/*,*/jqplot/*,*/build/*'
|
||||
analysis:
|
||||
file: 'cs-data' # The reporter filename
|
||||
format: 'php-cs-checkstyle' # The supported format by Scrutinizer
|
||||
|
||||
80
.travis.yml
@ -3,66 +3,92 @@
|
||||
# - run lint for every PHP version
|
||||
# - run Selenium for single PHP version
|
||||
|
||||
dist: trusty
|
||||
|
||||
language: php
|
||||
|
||||
services:
|
||||
- mysql
|
||||
|
||||
php:
|
||||
- "7.1"
|
||||
- "7.0"
|
||||
- "5.6"
|
||||
- "5.5"
|
||||
- hhvm
|
||||
- hhvm-3.3
|
||||
- hhvm-3.12
|
||||
- hhvm-3.18
|
||||
|
||||
sudo: false
|
||||
sudo: required
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- PHPUNIT_ARGS="--exclude-group selenium"
|
||||
- CI_MODE=test
|
||||
global:
|
||||
- TESTSUITE_USER=root
|
||||
- TESTSUITE_PASSWORD=root
|
||||
- TESTSUITE_URL=http://127.0.0.1:8000
|
||||
|
||||
install:
|
||||
- pip install --user codecov
|
||||
- ./test/install-runkit
|
||||
- ./test/install-browserstack
|
||||
- composer install --dev --no-interaction
|
||||
- ./test/ci-install-$CI_MODE
|
||||
- if [[ "$TRAVIS_OS_NAME" != "osx" ]]; then case "$TRAVIS_PHP_VERSION" in hhvm*) ;; *) phpenv config-add test/php-noprofile.ini ;; esac ; fi
|
||||
|
||||
before_script:
|
||||
- if [ $TRAVIS_PHP_VERSION != "hhvm" ] ; then phpenv config-add test/php-noprofile.ini ; fi
|
||||
- export PATH=~/.composer/vendor/bin/:$PATH
|
||||
- mysql -uroot -e "CREATE DATABASE test"
|
||||
- mysql -uroot -e "CREATE DATABASE IF NOT EXISTS test"
|
||||
- mysql -uroot < sql/create_tables.sql
|
||||
- mysql -uroot -e "SET PASSWORD = PASSWORD('$TESTSUITE_PASSWORD')"
|
||||
- ./test/start-local-server
|
||||
|
||||
script:
|
||||
- ant clean
|
||||
- ant locales
|
||||
- ant lint
|
||||
- set -e;
|
||||
if [ $TRAVIS_PHP_VERSION == "hhvm" ] ; then
|
||||
ant phpunit-hhvm ;
|
||||
else
|
||||
if [ ! -z "$SELENIUM" ] ; then
|
||||
ant phpunit-nocoverage ;
|
||||
else
|
||||
ant phpunit ;
|
||||
fi ;
|
||||
fi
|
||||
- ./scripts/generate-mo --quiet
|
||||
- if [ $CI_MODE = test ] ; then ./test/ci-lint ; fi
|
||||
- ./test/ci-$CI_MODE
|
||||
|
||||
after_script:
|
||||
- if [ -f vendor/bin/coveralls ] ; then php vendor/bin/coveralls -v || true ; fi
|
||||
- if [ -f vendor/bin/codacycoverage ] ; then php vendor/bin/codacycoverage clover || true ; fi
|
||||
- codecov
|
||||
- if [ -f php.log ] ; then cat php.log ; fi
|
||||
- if [ -f build/logs/phpunit.json ] ; then ./scripts/phpunit-top-tests build/logs/phpunit.json ; fi
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: "7.0"
|
||||
env: CI_MODE=selenium
|
||||
fast_finish: true
|
||||
include:
|
||||
- php: "7.0"
|
||||
env: CI_MODE=selenium
|
||||
- php: "7.0"
|
||||
env: CI_MODE=release
|
||||
- php: "7.0"
|
||||
env: CI_MODE=docs
|
||||
- os: osx
|
||||
language: generic
|
||||
env: CI_MODE=test
|
||||
before_install:
|
||||
- brew tap homebrew/php
|
||||
- brew update
|
||||
- brew install gettext php70 mariadb
|
||||
- brew link --force gettext
|
||||
- curl https://getcomposer.org/installer | php
|
||||
- ln -s "`pwd`/composer.phar" /usr/local/bin/composer
|
||||
- mysql.server start
|
||||
|
||||
cache:
|
||||
pip: true
|
||||
directories:
|
||||
- $HOME/.composer/cache/
|
||||
- $HOME/browserstack
|
||||
- $HOME/runkit
|
||||
# trigger Buildtime Trend Service to parse Travis CI log
|
||||
notifications:
|
||||
webhooks:
|
||||
- https://buildtimetrend.herokuapp.com/travis
|
||||
# Install APT packages
|
||||
# - git > 2.5.1 needed for worktrees
|
||||
# - mysql server does not seem to be always present on Travis Trusty environment
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- git
|
||||
- mysql-server-5.6
|
||||
|
||||
2
.weblate
@ -1,3 +1,3 @@
|
||||
[weblate]
|
||||
url = https://hosted.weblate.org/api/
|
||||
translation = phpmyadmin/4-6
|
||||
translation = phpmyadmin/4-7
|
||||
|
||||
@ -20,9 +20,10 @@ Please report [bugs on GitHub][1].
|
||||
## Patches submission
|
||||
|
||||
Patches are welcome as [pull requests on GitHub][2]. Please include a
|
||||
Signed-off-by tag. 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.
|
||||
Signed-off-by tag in the commit message (you can do this by passing `--signoff`
|
||||
parameter to Git). 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
|
||||
|
||||
515
ChangeLog
@ -1,6 +1,115 @@
|
||||
phpMyAdmin - ChangeLog
|
||||
======================
|
||||
|
||||
4.7.0 (2017-03-28)
|
||||
- patch #12233 [Display] Improve message when renaming database to same name
|
||||
- issue #6146 Log authentication attempts to syslog
|
||||
- issue #11981 Remove support for Swekey authentication
|
||||
- issue #11987 Remove code for no longer supported MSIE versions
|
||||
+ issue #11962 Remove embedded PHP libraries, use composer to install them
|
||||
+ issue #12017 Cannot easily select multiple tables when exporting
|
||||
+ issue #12047 Add javascript filtering for databases
|
||||
- issue #12166 More compact rendering of navigation tree
|
||||
+ issue #12129 Improve performance with SkipLockedTables
|
||||
- issue #12173 Do not hide indexes under a slider
|
||||
- issue Improve performance of zip file import
|
||||
- issue #12196 Removed $cfg['ThemePath']
|
||||
- issue #6274 Add support for export user settings as config.inc.php snippet
|
||||
- issue #5555 Better report query errors while generating SQL exports
|
||||
- issue #12307 Produce valid JSON on export
|
||||
- issue #12325 Setup script icons broken
|
||||
- issue #12378 Support IPv6 proxies
|
||||
- issue Removed MySQL connection retry without password
|
||||
- issue #12218 Allow to specify further parameters for control connection
|
||||
- issue #12162 Show charset for each table on Database structure page
|
||||
- issue #12463 Incorrect link in the href of icon at Hide/Show unhide links
|
||||
- issue #12330 Shortcut for closing console
|
||||
- issue #12465 Improved handling of http requests
|
||||
- issue #12474 Broken links in Setup forms Navigation
|
||||
- issue #12494 Can't add a new User
|
||||
- issue #12523 Add 'token' Parameter in all POST requests (Fix 'Token mismatch' errors)
|
||||
- issue #12302 Improved usage of number_format
|
||||
- issue #12656 Server selection not working
|
||||
- issue #12543 NULL results in dataset are colored grey
|
||||
- issue #12664 Create Bookmark broken
|
||||
- issue #12688 Use unsigned int for storing bookmark ID
|
||||
- issue #12352 Added password strength indicator
|
||||
- issue #12713 Correctly handle HTTP status when doing requests
|
||||
- issue #12247 Add option to delete settings from browser storage
|
||||
- issue #12783 Remove unused PMA_addJSCode function
|
||||
- issue #12069 Add table filtering to database structure
|
||||
- issue #12799 Allow to configure signon session parameters
|
||||
- issue #12854 Drop database is broken
|
||||
- issue #12863 Can't toggle Event Scheduler on
|
||||
- issue #12742 Finish removing dead code references to xls/xlsx import and export, which was removed some time ago.
|
||||
- issue #12536 Rename "Relations" to "Relationships" in many places as it's the more proper term
|
||||
- issue #12834 Fixed margins in central columns feature
|
||||
- issue #12903 Document more export configuration options
|
||||
- issue #12897 Use consistent numeric format for table overhead
|
||||
- issue #12901 Use server returned table name on renaming table
|
||||
- issue #12918 Always use \r\n as newline when editing fields
|
||||
- issue #12923 Fixed server side search in navigation panel
|
||||
- issue #12929 Undefined index warning with ssl_ca_paths
|
||||
- issue #12924 Do not show errors from OpenSSL cookie encryption/decryption
|
||||
- issue #12945 Fixed hint rendering on adding new user
|
||||
- issue #12941 Fixed sorting of tables in relation view
|
||||
- issue #12936 Fixed tables pagination in navigation panel
|
||||
- issue #12904 Do not collapse add form for central columns if there are none
|
||||
- issue #12955 Fixed database renaming
|
||||
- issue #12954 Fixed export of tracking data
|
||||
- issue #12960 Enclose exports in transaction by default
|
||||
- issue #12966 After adding a column ADD INDEX option won't be displayed when enabling AI
|
||||
- issue #12972 Better error message when Composer has not been run
|
||||
- issue #12988 Do not show language selector without choices
|
||||
- issue #12993 Fixed external links to php documentation
|
||||
- issue #12990 Fixed error when loading favorite tables to console
|
||||
- issue #12981 Improved rendering of new version information
|
||||
- issue #12922 Fixed bookmarks ordering
|
||||
- issue #12964 Fixed table search in navigation
|
||||
- issue #12985 Fixed rendering of foreign key browsing
|
||||
- issue #12957 Fixed manipulation with GIS data having zero coordinates
|
||||
- issue #12804 Fixed various designer javascript errors
|
||||
- issue #12934 Fixed possible javascript error on server status page
|
||||
- issue #12927 Fixed javascript error on 3NF normalization
|
||||
- issue #12996 List all databses in navigation panel database dropdown
|
||||
- issue #12980 Better defaults when creating multi field foreign key
|
||||
- issue #12976 Improved foreign key editor behavior
|
||||
- issue #12958 Always show error reporting dialog on top
|
||||
- issue #12693 Improved support for TokuDB
|
||||
- issue #11231 Try harder to honor LoginCookieValidity setting
|
||||
- issue #13016 and #13017 Slight improvements to the table layout of Relation view
|
||||
- issue #12345 Correctly show affected rows for LOAD DATA queries
|
||||
- issue #13010 Copy database: SQL error for copying PMADB metadata
|
||||
- issue #13002 Fixed OpenDocument exports
|
||||
- issue #13000 Align NULL values according to the column alignment
|
||||
- issue #13021 Show phpMyAdmin errors even with error_reporting set to 0
|
||||
- issue #13020 Removed warning about client and server versions mismatch
|
||||
- issue Hide comments on table Structure tab when no comment is set
|
||||
- issue Fixed submission of error reports
|
||||
- issue #13033 Use Referrer-Policy header to specify referrer policy
|
||||
- issue Fixed javascript confirmation of dangerous queries
|
||||
- issue #13040 Compatibility with hhvm 3.18
|
||||
- issue #13031 Fixed displaying of all rows
|
||||
- issue #12967 Fixed related field selection for native relations
|
||||
- issue #13045 Properly escape MIME transformatoin names
|
||||
- issue #13028 Always show 100% in font selector
|
||||
- issue #13047 Fix query simulating for more servers
|
||||
- issue #12846 Fix new version check for sites with wrongly configured curl
|
||||
- issue #12951 When exporting to Excel, the default is now to include column names in the first row
|
||||
- issue #13059 Removed debugging code
|
||||
- issue #13029 Fixed table tracking for nested table groups
|
||||
- issue #13053 Fixed broken links in setup
|
||||
- issue #12708 Removed phpMyAdmin version from User-Agent header
|
||||
- issue #13084 Do not point users to setup when it is disabled
|
||||
- issue #12660 Delete only phpMyAdmin cookies on upgrade
|
||||
- issue #13088 Fixed editing of rows with text primary key
|
||||
- issue #13092 Do not try to sync favorite tables if configuration storage is not enabled
|
||||
- issue #13105 Fixed changing attribute for virtual field
|
||||
- issue #12757 Fixed setting password on recent MariaDB with non working plugins
|
||||
- issue #12349 Fixed undefined variable on import from some formats
|
||||
- issue #13103 Do not offer default names for copying/renaming databases
|
||||
- issue [security] Possible to bypass $cfg['Servers'][$i]['AllowNoPassword'], see PMASA-2017-08
|
||||
|
||||
4.6.6 (2017-01-23)
|
||||
- issue #12759 Fix Notice regarding 'Undefined index: old_usergroup'
|
||||
- issue #12760 Fix Notice regarding 'Undefined index: users'
|
||||
@ -48,412 +157,6 @@ phpMyAdmin - ChangeLog
|
||||
- issue [security] SSRF in replication, see PMASA-2017-6.
|
||||
- issue [security] DOS in replication status, see PMASA-2017-7.
|
||||
|
||||
4.6.5.2 (2016-12-05)
|
||||
- issue #12765 Fixed SQL export with newlines
|
||||
|
||||
4.6.5.1 (2016-11-25)
|
||||
- issue #12735 Incorrect parameters to escapeString in Node.php
|
||||
- issue #12734 Fix PHP error when mbstring is not installed
|
||||
- issue #12736 Don't force partition count to be specified when creating a new table
|
||||
|
||||
4.6.5 (2016-11-24)
|
||||
- issue Remove potentionally license problematic sRGB profile
|
||||
- issue #12459 Display read only fields as read only when editing
|
||||
- issue #12384 Fix expanding of navigation pane when clicking on database
|
||||
- issue #12430 Impove partitioning support
|
||||
- issue #12374 Reintroduced simplified PmaAbsoluteUri configuration directive
|
||||
- issue Always use UTC time in HTTP headers
|
||||
- issue #12479 Simplified validation of external links
|
||||
- issue #12483 Fix browsing tables with built in transformations
|
||||
- issue #12485 Do not show warning about short blowfish_secret if none is set
|
||||
- issue #12251 Fixed random logouts due to wrong cookie path
|
||||
- issue #12480 Fixed editing of ENUM/SET/DECIMAL fields structure
|
||||
- issue #12497 Missing escaping of configuration used in SQL (hide_db and only_db)
|
||||
- issue #12476 Add error checking in reading advisory rules file
|
||||
- issue #12477 Add checking missing elements and confirming element types from json_decode
|
||||
- issue #12251 Automatically save SQL query in browser local storage rather than in cookie
|
||||
- issue #12292 Unable to edit transformations
|
||||
- issue #12502 Remove unused paramenter when connecting to MySQLi
|
||||
- issue #12303 Fix number formatting with different settings of precision in PHP
|
||||
- issue #12405 Use single quotes in PHP code
|
||||
- issue #12534 Option for the dropped column is not removed from 'after_field' select, after the column is dropped
|
||||
- issue #12531 Properly detect DROP DATABASE queries
|
||||
- issue #12470 Fix possible race condition in setting URL hash
|
||||
- issue #11924 Remove caching of server information
|
||||
- issue #11628 Proper parsing of INSERT ... ON DUPLICATE KEY queries
|
||||
- issue #12545 Proper parsing of CREATE TABLE ... PARTITION queries
|
||||
- issue #12473 Code can throw unhandled exception
|
||||
- issue #12550 Do not try to keep alive session even after expiry
|
||||
- issue #12512 Fixed rendering BBCode links in setup
|
||||
- issue #12518 Fixed copy of table with generated columns
|
||||
- issue #12221 Fixed export of table with generated columns
|
||||
- issue #12320 Copying a user does not copy usergroup
|
||||
- issue #12272 Adding a new row with default enum goes to no selection when you want to add more then 2 rows
|
||||
- issue #12487 Drag and drop import prevents file dropping to blob column file selector on the insert tab
|
||||
- issue #12554 Absence of scrolling makes it impossible to read longer text values in grid editing
|
||||
- issue #12530 "Edit routine" crashes when the current user is not the definer, even if privileges are adequate
|
||||
- issue #12300 Export selective tables by-default dumps Events also
|
||||
- issue #12298 Fixed export of view definitions
|
||||
- issue #12242 Edit routine detail dialog does not fill "Return length" field in mysql functions
|
||||
- issue #12575 New index Confirm adds whitespace around the field name
|
||||
- issue #12382 Bug in zoom search
|
||||
- issue #12321 Assign LIMIT clause only to syntactically correct queries
|
||||
- issue #12461 Can't Execute SQL With Sub-Query Due To "LIMIT 0,25" Inserted At Wrong Place
|
||||
- issue #12511 Clarify documentation on ArbitraryServerRegexp
|
||||
- issue #12508 Remove duplicate code in SQL escaping
|
||||
- issue #12475 Cleanup code for getting table information
|
||||
- issue #12579 phpMyAdmin's export of a Select statment without a FROM clause generates Wrong SQL
|
||||
- issue #12316 Correct export of complex SELECT statements
|
||||
- issue #12080 Fixed parsing of subselect queries
|
||||
- issue #11740 Fixed handling DELETE ... USING queries
|
||||
- issue #12100 Fixed handling of CASE operator
|
||||
- issue #12455 Query history stores separate entry for every letter typed
|
||||
- issue #12327 Create PHP code no longer works
|
||||
- issue #12179 Fixed bookmarking of query with multiple statements
|
||||
- issue #12419 Wrong description on GRANT OPTION
|
||||
- issue #12615 Fixed regexp for matching browser versions
|
||||
- issue #12569 Avoid showing import errors twice
|
||||
- issue #12362 prefs_manage.php can leave an orphaned temporary file
|
||||
- issue #12619 Unable to export csv when using union select
|
||||
- issue #12625 Broken Edit links in query results of JOIN query
|
||||
- issue #12634 Drop DB error in import if DB doesn't exist
|
||||
- issue #12338 Designer reverts to first saved ER after EACH relation create or delete
|
||||
- issue #12639 'Show trace' in Console generates JS error for functions in query's trace called without any arguments
|
||||
- issue #12366 Fix user creation with certain MariaDB setups
|
||||
- issue #12616 Refuse to work with mbstring.func_overload enabled
|
||||
- issue #12472 Properly report connection without password in setup
|
||||
- issue #12365 Fix records count for large tables
|
||||
- issue #12533 Fix records count for complex queries
|
||||
- issue #12454 Query history not updated in console until page refresh
|
||||
- issue #12344 Fixed parsing of labels in loop
|
||||
- issue #12228 Fixed parsing of BEGIN labels
|
||||
- issue #12637 Fixed editing some timestamp values
|
||||
- issue #12622 Fixed javascript error in designer
|
||||
- issue #12334 Missing page indicator or VIEWs
|
||||
- issue #12610 Export of tables with Timestamp/Datetime/Time columns defined with ON UPDATE clause with precision fails
|
||||
- issue #12661 Error inserting into pma__history after timeout
|
||||
- issue #12195 Row_format = fixed not visible
|
||||
- issue #12665 Cannot add a foreign key - non-indexed fields not listed in InnoDB tables
|
||||
- issue #12674 Allow for proper MySQL-allowed strings as identifiers
|
||||
- issue #12651 Allow for partial dates on table insert page
|
||||
- issue #12681 Fixed designer with tables using special chars
|
||||
- issue #12652 Fixed visual query builder for foreign keys with more fields
|
||||
- issue #12257 Improved search page performance
|
||||
- issue #12322 Avoid selecting default function for foreign keys
|
||||
- issue #12453 Fixed escaping of SQL parts in some corner cases
|
||||
- issue #12542 Missing table name in account privileges editor
|
||||
- issue #12691 Remove ksort call on empty array in PMA_getPlugins function
|
||||
- issue #12443 Check parameter type before processing
|
||||
- issue #12299 Avoid generating too long URLs in search
|
||||
- issue #12361 Fix self SQL injection in table-specific privileges
|
||||
- issue #12698 Add link to release notes and download on new version notification
|
||||
- issue #12712 Error when trying to setup replication (fatal error in call to an old PMA_DBI_connect function)
|
||||
- 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] Possible to bypass logout timeout, see PMASA-2016-62
|
||||
- issue [security] Full path disclosure (FPD) weaknesses, see PMASA-2016-63
|
||||
- issue [security] Multiple 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] BBCode injection to login page, see PMASA-2016-67
|
||||
- issue [security] Denial-of-service (DOS) vulnerability in table partitioning, see PMASA-2016-68
|
||||
- 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.6.4 (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] Multiple XSS vulnerabilities, see PMASA-2016-31
|
||||
- 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] Multiple XSS vulnerabilities, see PMASA-2016-38
|
||||
- issue [security] SQL injection vulnerability as control user, see PMASA-2016-39
|
||||
- issue [security] SQL injection vulnerability, see PMASA-2016-40
|
||||
- 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-054
|
||||
- issue [security] Administrators could trigger SQL injection attack against users
|
||||
- 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
|
||||
- issue Include X-Robots-Tag header in responses
|
||||
- issue Enforce numeric field length when creating table
|
||||
- issue Fixed invalid Content-Length in some HTTP responses
|
||||
- issue #12394 Create view should require a view name
|
||||
- issue #12391 Message with 'Change password successfully' displayed, but does not take effect
|
||||
- issue Tighten control on PHP sessions and session cookies
|
||||
- issue #12409 Re-enable overhead on server databases view
|
||||
- issue #12414 Fixed rendering of Original theme
|
||||
- issue #12413 Fixed deleting users in non English locales
|
||||
- issue #12416 Fixed replication status output in Databases listing
|
||||
- issue #12303 Avoid typecasting to float when not needed
|
||||
- issue #12425 Duplicate message variable names in messages.inc.php
|
||||
- issue #12399 Adding index to table shows wrong top navigation
|
||||
- issue #12424 Fixed password change on MariaDB without auth plugin
|
||||
- issue #12339 Do not error on unset server port
|
||||
- issue #12422 Improvements to the original theme
|
||||
- issue #12395 Do not try to load old transformation plugins
|
||||
- issue #12423 Fixed replication status in database listing
|
||||
- issue #12433 Copy table with prefix does not copy the indexes
|
||||
- issue #12375 Search in database: Window content is not scrolling down when clicking first time on Browse link
|
||||
- issue #12346 SQL Editor textareas can have their size increased from the top, distorting the page view
|
||||
|
||||
4.6.3 (2016-06-23)
|
||||
- issue #12249 Fixed cookie path on Windows
|
||||
- issue #12279 Fixed error reporting on connect problems
|
||||
- issue #12290 Fixed export of tables without explicitly set engine
|
||||
- issue #12285 Designer JavaScript error: Show/Hide tables list
|
||||
- issue #12293 Fix MySQL SSL connection with some PHP versions
|
||||
- issue #12279 Fix MySQL connection error on version mismatch
|
||||
- issue #12281 Keep user attributes (privileges, authentication mode, etc) when copying a user
|
||||
- issue #12308 Fix division by zero in case of misconfigured MySQL server
|
||||
- issue #12317 Fix editing server variables
|
||||
- issue #12303 Fix table size calculation in some circumstances
|
||||
- issue #12310 Fix listing routines for non privileged user
|
||||
- issue Escape generated query in exporting a database
|
||||
- issue Setup script doesn't use input type 'password' in all relevant locations
|
||||
- issue [security] BBCode injection in setup script, see PMASA-2016-17
|
||||
- issue [security] Cookie attribute injection attack, see PMASA-2016-18
|
||||
- issue Redirect loop when directly calling url.php
|
||||
- issue [security] SQL injection attack, see PMASA-2016-19
|
||||
- issue [security] XSS attack in Table Structure page, see PMASA-2016-20
|
||||
- issue [security] XSS attack in Server Privileges page, see PMASA-2016-21
|
||||
- issue [security] DOS attack vulnerability, see PMASA-2016-22
|
||||
- issue [security] Multiple full path disclosure vulnerabilities, see PMASA-2016-23
|
||||
- issue [security] Full path disclosure when running in debug mode
|
||||
- issue [security] XSS attack with partition range and table structure, see PMASA-2016-25
|
||||
- issue [security] XSS attack when checking database privileges, see PMASA-2016-26
|
||||
- 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, see PMASA-2016-26
|
||||
|
||||
4.6.2 (2016-05-25)
|
||||
- issue [security] User SQL queries can be revealed through URL GET parameters, see PMASA-2016-14
|
||||
- issue [security] Self XSS vulneratbility, see PMASA-2016-16
|
||||
- issue #12225 Use https for documentation links
|
||||
- issue #12234 Fix schema export with too many tables
|
||||
- issue #12240 Avoid parsing non JSON responses as JSON
|
||||
- issue #12244 Avoid using too log URLs when getting javascripts
|
||||
- issue #12118 Fixed setting mixed case languages
|
||||
- issue #12229 Avoid storing objects in session when debugging SQL
|
||||
- issue #12249 Fix cookie path on IIS
|
||||
- issue #11705 Fix occassional 200 errors on Windows
|
||||
- issue #12219 Fix locking issues when importing SQL
|
||||
- issue #12231 Avoid confusing warning when mysql extension is missing
|
||||
- issue Improve handling of logout
|
||||
- issue Safer handling of sessions during authentication
|
||||
- issue #12209 Fix server selection on main page
|
||||
- issue #12192 Avoid storing full error data in session
|
||||
- issue #12082 Fixed export of ARCHIVE tables with keys
|
||||
- issue #11565 Add session reload for config authentication
|
||||
- issue #12229 Do not fail on errors stored in session
|
||||
- issue #12248 Fix loading of APC based upload progress bar
|
||||
|
||||
4.6.1 (2016-05-02)
|
||||
- issue #12120 PMA_Util not found in insert_edit.lib.php
|
||||
- issue #12118 Fixed activation of some languages
|
||||
- issue #12121 Fixed error in 3NF step of normalization
|
||||
- issue #12135 Fix offering JSON datatype in incompatible MySQL versions
|
||||
- issue #12132 Can not open table with JSON field
|
||||
- issue #12125 Cannot highlight a column if I scroll down from the top of the table
|
||||
- issue #12154 Fixed possible PHP error in SQL parser
|
||||
- issue #12029 Fixed SQL quoting in SQL export
|
||||
- issue #12129 Improve performance of database structure page
|
||||
- issue #12159 Fix PHP error if user did unpack new version over old one
|
||||
- issue #12165 Fix parsing of expression 0
|
||||
- issue #12146 Document setup with Google Cloud SQL
|
||||
- issue #12197 Fix parsing of queries with double \
|
||||
- issue #12202 Fixed setting of language from user configuration
|
||||
- issue #12200 Fixed check for ndb version
|
||||
- issue #12206 Fixed loading of configuration file
|
||||
- issue #12204 Check if sessions are working and report failures
|
||||
- issue #12211 non-clickable initial letter for users / and can't modify users with MySQL 5.7.12
|
||||
- issue #12215 Fixed config tab persistence errors
|
||||
- issue #12217 Fixed javascript erros on user creation
|
||||
- issue #12144 Fixed parsing of some AS clauses
|
||||
- issue #12205 Fixed parsing of FULL OUTER JOIN queries
|
||||
- issue #12171 Fixed editing of VIEW structure
|
||||
- issue #12208 Avoid printing executed queries on import
|
||||
|
||||
4.6.0.0 (2016-03-22)
|
||||
+ issue #11456 Disabled storage engines
|
||||
+ issue #11479 Allow setting routine wise privileges
|
||||
- issue Hide Insert tab for non-updatable views
|
||||
+ issue #11490 UI for defining partitioning in create table window
|
||||
+ issue #11438 Support JSON data type
|
||||
+ issue Editing partitions in table Structure
|
||||
- issue Tracking does not make sense for information_schema
|
||||
- issue #11550 Regression in Find and replace
|
||||
+ issue #11619 TokuDB Tables Show Size as "unknown"
|
||||
+ issue #11654 Use a slider for Internal relations
|
||||
+ issue #11641 Ability to disable the navigationhiding Feature
|
||||
- issue #11647 Restrict configuration NavigationTreeDbSeparator to strings
|
||||
- issue #11667 Disable the tooltip in the navigation panel's filter box
|
||||
+ issue Copy results to clipboard
|
||||
+ issue #11504 Reactivate cut&paste possibility in print view
|
||||
- issue #11702 Extraneous message after edit + grid-edit
|
||||
- issue #11668 Table header is empty with browsing an empty table
|
||||
+ issue #11701 Allow changing parameter order of routines
|
||||
- issue #11708 Remove no password warning
|
||||
+ issue #11711 Clarify the meaning of "Stand-in structure for view" in SQL export
|
||||
- issue HTML line break shown after a MySQL connection error message
|
||||
- issue #11728 CSV import skip row count after
|
||||
- issue Fixed displaying of SQL query on table operations
|
||||
- issue #6321 Display binary strings as text if they are valid UTF-8
|
||||
+ issue #11743 Display routine specific privileges
|
||||
+ issue #11538 Copy multiple tables to database
|
||||
+ issue Support Cloudflare Flexible SSL
|
||||
- issue Handle empty TABLE_COMMENT
|
||||
+ issue #11833 Drop support for old Internet Explorer versions
|
||||
+ issue #11796 Use modals for displaying forms in db structure page
|
||||
+ issue #11789 Show MySQL error messages in user language
|
||||
+ issue Add 'ssl_verify' configuration directive for self-signed certificates with mysqlnd and PHP >= 5.6
|
||||
+ issue #11874 Show more used PHP extensions
|
||||
- issue #11874 Report when version check and error reporting are disabled
|
||||
- issue #11849 Fix PDF schema export
|
||||
- issue #11412 Remove ForceSSL configuration directive
|
||||
- issue Remove support for Mozilla Prism
|
||||
- issue #11412 Remove PmaAbsoluteUri configuration directive
|
||||
- issue #11914 Fix autoloading of phpseclib
|
||||
- issue #11880 Fixed rendering of missing extension error
|
||||
- issue #11923 Errors on Structure tab when user only has select access on certain columns
|
||||
- issue #11972 Missing documentation for $cfg['Servers'][$i]['favorite'] and $cfg['NumFavoriteTables']
|
||||
- issue #11907 Avoid displaying UPDATE query twice
|
||||
- issue #11850 Fixed CSV import
|
||||
- issue Fix SQL syntax highlighting in database search page
|
||||
- issue #12056 Fix error when we can not generate random string
|
||||
- issue #12055 Fixed PHP syntax error in templates
|
||||
- issue #12054 Fixed processing of queries with escaped quotes
|
||||
- issue #12041 Fixed exporting tables with fields DEFAULT and COMMENT
|
||||
- issue #12073 Hide edit and delete buttons when the results are not related to a table
|
||||
- issue #12083 Fixed parsing of field definition
|
||||
- issue #12081 Fixed rendering of table stats
|
||||
- issue #11705 Fixed problems with PHP on Windows on table structure
|
||||
- issue #12085 Like search strings being escaped incorrectly
|
||||
- issue #12092 Rename exported databases/tables doesn't seem to work
|
||||
- issue #12099 Undefined index: controllink
|
||||
- issue #12094 PHP Fatal error: Call to undefined function __()
|
||||
- issue #12098 Fix login after logout with http authentication
|
||||
- issue #12074 Fixed possible invalid SQL export
|
||||
- issue #12026 Fixed parsing of UNION SELECT with brackets
|
||||
- issue #12109 Fixed parsing of CREATE TABLE [AS] SELECT
|
||||
- issue #12105 Multi-server drap-and-drop import always fails
|
||||
- issue #12116 Fulltext indexes are not copied when using copy database function
|
||||
|
||||
4.5.5.1 (2016-02-29)
|
||||
- issue #11971 CREATE UNIQUE INDEX index type is not recognized by parser.
|
||||
- issue #11982 Row count wrong when grouping joined tables.
|
||||
- issue #12012 Column definition with default value and comment in CREATE TABLE expoerted faulty.
|
||||
- issue #12020 New statement but no delimiter and unexpected token with REPLACE.
|
||||
- issue #12029 Fixed incorrect usage of SQL parser context in SQL export
|
||||
- issue [security] XSS vulnerability in SQL parser, see PMASA-2016-10.
|
||||
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-11.
|
||||
- issue [security] Multiple XSS vulnerabilities, see PMASA-2016-12.
|
||||
- issue [security] Vulnerability allowing man-in-the-middle attack on API call to GitHub, see PMASA-2016-13.
|
||||
- issue #12048 Fixed inclusion of gettext library from SQL parser
|
||||
|
||||
4.5.5.0 (2016-02-22)
|
||||
- issue Undefined index: is_ajax_request
|
||||
- issue #11855 Fix password change on MariaDB 10.1 and newer
|
||||
- issue #11874 Validate version information before further processing it
|
||||
- issue #11881 Full processlist lost on refresh
|
||||
- issue #11834 Adjust privileges fails if database name contains underscores
|
||||
- issue #11906 'Loading...' banner shows on login screen
|
||||
- issue #11930 Fixed changing of table parameters, eg. AUTO_INCREMENT
|
||||
- issue #11885 Call to undefined function SqlParser\ctype_alnum()
|
||||
- issue #11879 4.5.3.1 - NOW() function not recognized by parser
|
||||
- issue #11867 Gracefully handle the DESC statement
|
||||
- issue #11843 Fractional timestamp causes corrupted SQL export
|
||||
- issue #11836 Static analysis error for valid WHERE condition with IF keyword
|
||||
- issue #11800 Syntax Verifier error using REGEXP in SQL statement
|
||||
- issue #11799 Backslashes in comments are being interpreted as escape characters
|
||||
- issue #11909 Can't insert row into table that contains generated column
|
||||
- issue #11677 sql-parser and php-gettext collide.
|
||||
- issue #11920 Can't disable backquotes in export
|
||||
- issue #11911 Inserts via tbl_change.php in VARBINARY columns does not allow using HEX() and MD5()
|
||||
- issue #11939 Correct content type for uploaded error reports
|
||||
- issue #11940 Silent errors from checking local documentation
|
||||
- issue #11944 Fixed error on servers with disabled php_uname
|
||||
- issue #11946 Correctly store and report file upload errors
|
||||
- issue #11948 Avoid javascript errors on invalid location hash
|
||||
- issue #11950 Fix PHP warning on configuration errors
|
||||
- issue #11951 Silent errors on checking for writable folders
|
||||
- issue #11952 Silent warning on invalid file upload
|
||||
- issue #11953 Do not fail getting filename with open_basedir limitations
|
||||
- issue #11956 unrecognized keyword interval
|
||||
- issue Field names and aliases are being correctly parsed now.
|
||||
- issue #11959 Fix javascript error in setup
|
||||
- issue #11964 Undefined index: TABLE_COMMENT in database structure page
|
||||
- issue #11967 Fix PHP error on loading invalid XML or ODS file
|
||||
- issue #11969 Missing confirmation while dropping a view in view_operations.php
|
||||
- issue #11968 Fix export of index comments in SQL
|
||||
- issue #11979 DECLARE not accepted as valid SQL
|
||||
|
||||
4.5.4.1 (2016-01-29)
|
||||
- issue #11892 Error with PMA 4.4.15.3
|
||||
- issue #11896 Remove hard dependency on phpseclib
|
||||
|
||||
4.5.4.0 (2016-01-28)
|
||||
- issue #11724 live data edit of big sets is not working
|
||||
- issue Table list not saved in db QBE bookmarked search
|
||||
- issue #11777 While 'changing a column', query fails with a syntax error after the 'CHARSET=' keyword
|
||||
- issue #11783 Avoid syntax error in javascript messages on invalid PHP setting for max_input_vars
|
||||
- issue #11784 Properly handle errors in upacking zip archive
|
||||
- issue #11785 Set PHP's internal encoding to UTF-8
|
||||
- issue #11786 Fixed Kanji encoding in some specific cases
|
||||
- issue #11787 Check whether iconv works before using it
|
||||
- issue #11788 Avoid conversion of MySQL error messages
|
||||
- issue #11792 Undefined index: parameters
|
||||
- issue #11802 Undefined index: field_name_orig
|
||||
- issue Undefined index: host
|
||||
- issue #11810 'Add to central columns' (per column button) does nothing
|
||||
- issue #11727 SQL duplicate entry error trying to INSERT in designer_settings table
|
||||
- issue #11798 Fix handling of databases with dot in a name
|
||||
- issue #11820 Fix hiding of page content behind menu
|
||||
- issue #11780 FROM clause not generated after loading search bookmark
|
||||
- issue #11826 Fix creating/editing VIEW with DEFINER containing special chars
|
||||
- issue #11828 Do not invoke FLUSH PRIVILEGES when server in --skip-grant-tables
|
||||
- issue #11804 Misleading message for configuration storage
|
||||
- issue #11772 Table pagination does nothing when session expired
|
||||
- issue #11840 Index comments not working properly
|
||||
- issue #11791 Better handle local storage errors
|
||||
- issue #11752 Improve detection of privileges for privilege adjusting
|
||||
- issue #11854 Undefined property: stdClass::$releases at version check when disabled in config
|
||||
- issue #11814 SQL comment and variable stripped from bookmark on save
|
||||
- issue Gracefully handle errors in regex based javascript search
|
||||
- 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
|
||||
- issue [security] Multiple full path disclosure vulnerabilities, see PMASA-2016-6
|
||||
- issue [security] XSS vulnerability in normalization page, see PMASA-2016-7
|
||||
- issue [security] Full path disclosure vulnerability in SQL parser, see PMASA-2016-8
|
||||
- issue [security] XSS vulnerability in SQL editor, see PMASA-2016-9
|
||||
|
||||
--- Older ChangeLogs can be found on our project website ---
|
||||
https://www.phpmyadmin.net/old-stuff/ChangeLogs/
|
||||
|
||||
|
||||
2
README
@ -1,7 +1,7 @@
|
||||
phpMyAdmin - Readme
|
||||
===================
|
||||
|
||||
Version 4.6.6
|
||||
Version 4.7.0
|
||||
|
||||
A web interface for MySQL and MariaDB.
|
||||
|
||||
|
||||
11
README.rst
@ -8,7 +8,7 @@ https://www.phpmyadmin.net/
|
||||
Code status
|
||||
-----------
|
||||
|
||||
.. image:: https://secure.travis-ci.org/phpmyadmin/phpmyadmin.png?branch=master
|
||||
.. image:: https://travis-ci.org/phpmyadmin/phpmyadmin.svg?branch=master
|
||||
:alt: Build status
|
||||
:target: https://travis-ci.org/phpmyadmin/phpmyadmin
|
||||
|
||||
@ -22,14 +22,11 @@ Code status
|
||||
.. image:: https://scrutinizer-ci.com/g/phpmyadmin/phpmyadmin/badges/quality-score.png?s=93dfde29ffa5771d9c254b7ffb11c4e673315035
|
||||
:target: https://scrutinizer-ci.com/g/phpmyadmin/phpmyadmin/
|
||||
|
||||
.. image:: https://buildtimetrend.herokuapp.com/badge/phpmyadmin/phpmyadmin
|
||||
:alt: Buildtime Trend badge
|
||||
:target: https://buildtimetrend.herokuapp.com/dashboard/phpmyadmin/phpmyadmin
|
||||
|
||||
.. image:: https://bestpractices.coreinfrastructure.org/projects/213/badge
|
||||
:alt: CII Best Practices
|
||||
:target: https://bestpractices.coreinfrastructure.org/projects/213
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
@ -41,6 +38,10 @@ If you prefer to follow the git repository, the following branch and tag names m
|
||||
* ``master`` is the development branch.
|
||||
* Releases are tagged, for example version 4.0.1 was tagged as ``RELEASE_4_0_1``.
|
||||
|
||||
Note that phpMyAdmin uses Composer 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.
|
||||
|
||||
More Information
|
||||
----------------
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/transformations.lib.php';
|
||||
@ -26,7 +27,7 @@ foreach ($request_params as $one_request_param) {
|
||||
|
||||
PMA\libraries\Util::checkParameters(array('db', 'table', 'field'));
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->getFooter()->setMinimal();
|
||||
$header = $response->getHeader();
|
||||
$header->disableMenuAndConsole();
|
||||
@ -36,8 +37,7 @@ $header->setBodyId('body_browse_foreigners');
|
||||
* Displays the frame
|
||||
*/
|
||||
|
||||
$cfgRelation = PMA_getRelationsParam();
|
||||
$foreigners = ($cfgRelation['relwork'] ? PMA_getForeigners($db, $table) : false);
|
||||
$foreigners = PMA_getForeigners($db, $table);
|
||||
$foreign_limit = PMA_getForeignLimit(
|
||||
isset($_REQUEST['foreign_showAll']) ? $_REQUEST['foreign_showAll'] : null
|
||||
);
|
||||
|
||||
16
build.xml
@ -55,7 +55,7 @@
|
||||
<arg line="${source_comma_sep}
|
||||
xml
|
||||
codesize,design,naming,unusedcode
|
||||
--exclude test,build,tcpdf,php-gettext,bfShapeFiles,phpseclib,recaptchalib.php,vendor,sql-parser
|
||||
--exclude test,build,vendor
|
||||
--reportfile '${basedir}/build/logs/pmd.xml'" />
|
||||
</exec>
|
||||
</target>
|
||||
@ -66,12 +66,6 @@
|
||||
--exclude test
|
||||
--exclude build
|
||||
--exclude vendor
|
||||
--exclude libraries/tcpdf
|
||||
--exclude libraries/php-gettext
|
||||
--exclude libraries/bfShapeFiles
|
||||
--exclude libraries/phpseclib
|
||||
--exclude libraries/plugins/auth/recaptcha/recaptchalib.php
|
||||
--exclude libraries/sql-parser
|
||||
${source}" />
|
||||
</exec>
|
||||
</target>
|
||||
@ -82,12 +76,6 @@
|
||||
--exclude test
|
||||
--exclude build
|
||||
--exclude vendor
|
||||
--exclude libraries/tcpdf
|
||||
--exclude libraries/php-gettext
|
||||
--exclude libraries/bfShapeFiles
|
||||
--exclude libraries/phpseclib
|
||||
--exclude libraries/plugins/auth/recaptcha/recaptchalib.php
|
||||
--exclude libraries/sql-parser
|
||||
${source}" />
|
||||
</exec>
|
||||
</target>
|
||||
@ -101,7 +89,7 @@
|
||||
<target name="phpcs" description="Generate checkstyle.xml using PHP_CodeSniffer excluding third party libraries" depends="phpcs-config">
|
||||
<exec executable="phpcs">
|
||||
<arg line="
|
||||
--ignore=*/php-gettext/*,*/vendor/*,*/tcpdf/*,*/canvg/*,*/codemirror/*,*/openlayers/*,*/jquery/*,*/jqplot/*,*/build/*,*/bfShapeFiles/*,*/phpseclib/*,*/recaptcha/*,*/sql-parser/*
|
||||
--ignore=*/vendor/*,*/canvg/*,*/codemirror/*,*/openlayers/*,*/jquery/*,*/jqplot/*,*/build/*
|
||||
--report=checkstyle
|
||||
--extensions=php
|
||||
--report-file='${basedir}/build/logs/checkstyle.xml'
|
||||
|
||||
@ -5,13 +5,14 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
* Gets core libraries and defines some variables
|
||||
*/
|
||||
require 'libraries/common.inc.php';
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->disable();
|
||||
$response->getHeader()->sendHttpHeaders();
|
||||
|
||||
@ -35,10 +36,11 @@ if (@is_readable($filename)) {
|
||||
} else {
|
||||
printf(
|
||||
__(
|
||||
'The %s file is not available on this system, please visit '
|
||||
. 'www.phpmyadmin.net for more information.'
|
||||
'The %s file is not available on this system, please visit ' .
|
||||
'%s for more information.'
|
||||
),
|
||||
$filename
|
||||
$filename,
|
||||
'<a href="https://www.phpmyadmin.net/">phpmyadmin.net</a>'
|
||||
);
|
||||
exit;
|
||||
}
|
||||
@ -132,6 +134,9 @@ $replaces = array(
|
||||
'/( ### )(.*)/'
|
||||
=> '\\1<b>\\2</b>',
|
||||
|
||||
// Links target and rel
|
||||
'/a href="/' => 'a target="_blank" rel="noopener noreferrer" href="/'
|
||||
|
||||
);
|
||||
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
@ -151,12 +156,5 @@ 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>
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
|
||||
require_once 'libraries/common.inc.php';
|
||||
|
||||
@ -26,7 +27,7 @@ if (isset($_REQUEST['fix_pmadb'])) {
|
||||
PMA_fixPMATables($cfgRelation['db']);
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->addHTML(
|
||||
PMA_getRelationsParamDiagnostic($cfgRelation)
|
||||
);
|
||||
|
||||
3
codecov.yml
Normal file
@ -0,0 +1,3 @@
|
||||
comment:
|
||||
layout: header, changes, diff
|
||||
coverage: {}
|
||||
@ -20,13 +20,24 @@
|
||||
"source": "https://github.com/phpmyadmin/phpmyadmin"
|
||||
},
|
||||
"non-feature-branches": ["RELEASE_.*"],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PMA\\": "./"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"ext-mbstring": "*",
|
||||
"ext-mysqli": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"phpmyadmin/sql-parser": "^4.1.2",
|
||||
"phpmyadmin/motranslator": "^3.0",
|
||||
"phpmyadmin/shapefile": "^2.0",
|
||||
"tecnickcom/tcpdf": "^6.2",
|
||||
"phpseclib/phpseclib": "^2.0",
|
||||
"google/recaptcha": "^1.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Cookie encryption",
|
||||
@ -35,10 +46,11 @@
|
||||
"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-gd2": "For image transformations",
|
||||
"tecnickcom/tcpdf": "For PDF support"
|
||||
},
|
||||
"require-dev": {
|
||||
"satooshi/php-coveralls": "~0.6",
|
||||
"satooshi/php-coveralls": "^1.0",
|
||||
"phpunit/phpunit": "~4.1",
|
||||
"codacy/coverage": "dev-master",
|
||||
"phpunit/phpunit-selenium": "~1.2",
|
||||
|
||||
2580
composer.lock
generated
Normal file
@ -29,7 +29,6 @@ $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;
|
||||
$cfg['Servers'][$i]['AllowNoPassword'] = false;
|
||||
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\URL;
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
* Gets some core libraries
|
||||
*/
|
||||
@ -55,7 +58,7 @@ if (isset($_POST['add_column'])) {
|
||||
$selected_col[] = $_POST['column-select'];
|
||||
$tmp_msg = PMA_syncUniqueColumns($selected_col, false, $selected_tbl);
|
||||
}
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('jquery/jquery.uitablefilter.js');
|
||||
@ -97,7 +100,7 @@ if (PMA_isValid($_REQUEST['pos'], 'integer')) {
|
||||
} else {
|
||||
$pos = 0;
|
||||
}
|
||||
$addNewColumn = PMA_getHTMLforAddNewColumn($db);
|
||||
$addNewColumn = PMA_getHTMLforAddNewColumn($db, $total_rows);
|
||||
$response->addHTML($addNewColumn);
|
||||
if ($total_rows <= 0) {
|
||||
$response->addHTML(
|
||||
@ -114,7 +117,7 @@ $response->addHTML($table_navigation_html);
|
||||
$columnAdd = PMA_getHTMLforAddCentralColumn($total_rows, $pos, $db);
|
||||
$response->addHTML($columnAdd);
|
||||
$deleteRowForm = '<form method="post" id="del_form" action="db_central_columns.php">'
|
||||
. PMA_URL_getHiddenInputs(
|
||||
. URL::getHiddenInputs(
|
||||
$db
|
||||
)
|
||||
. '<input id="del_col_name" type="hidden" name="col_name" value="">'
|
||||
@ -131,14 +134,12 @@ $tableheader = PMA_getCentralColumnsTableHeader(
|
||||
);
|
||||
$response->addHTML($tableheader);
|
||||
$result = PMA_getColumnsList($db, $pos, $max_rows);
|
||||
$odd_row = true;
|
||||
$row_num = 0;
|
||||
foreach ($result as $row) {
|
||||
$tableHtmlRow = PMA_getHTMLforCentralColumnsTableRow(
|
||||
$row, $odd_row, $row_num, $db
|
||||
$row, $row_num, $db
|
||||
);
|
||||
$response->addHTML($tableHtmlRow);
|
||||
$odd_row = !$odd_row;
|
||||
$row_num++;
|
||||
}
|
||||
$response->addHTML('</table>');
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\URL;
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
* Gets the variables sent or posted to this script, then displays headers
|
||||
@ -26,7 +28,7 @@ if (! isset($selected_tbl)) {
|
||||
) = PMA\libraries\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$header->enablePrintView();
|
||||
|
||||
@ -45,7 +47,7 @@ PMA\libraries\Util::checkParameters(array('db'));
|
||||
/**
|
||||
* Defines the url to return to in case of error in a sql statement
|
||||
*/
|
||||
$err_url = 'db_sql.php' . PMA_URL_getCommon(array('db' => $db));
|
||||
$err_url = 'db_sql.php' . URL::getCommon(array('db' => $db));
|
||||
|
||||
if ($cfgRelation['commwork']) {
|
||||
$comment = PMA_getDbComment($db);
|
||||
@ -122,7 +124,6 @@ foreach ($tables as $table) {
|
||||
echo ' <th>MIME</th>' , "\n";
|
||||
}
|
||||
echo '</tr>';
|
||||
$odd_row = true;
|
||||
foreach ($columns as $row) {
|
||||
|
||||
if ($row['Null'] == '') {
|
||||
@ -145,9 +146,7 @@ foreach ($tables as $table) {
|
||||
}
|
||||
$column_name = $row['Field'];
|
||||
|
||||
echo '<tr class="';
|
||||
echo $odd_row ? 'odd' : 'even'; $odd_row = ! $odd_row;
|
||||
echo '">';
|
||||
echo '<tr>';
|
||||
echo '<td class="nowrap">';
|
||||
echo htmlspecialchars($column_name);
|
||||
|
||||
|
||||
@ -5,12 +5,13 @@
|
||||
*
|
||||
* @package PhpMyAdmin-Designer
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/pmd_common.php';
|
||||
require_once 'libraries/db_designer.lib.php';
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
|
||||
if (isset($_REQUEST['dialog'])) {
|
||||
|
||||
@ -113,7 +114,7 @@ if (isset($_GET['db'])) {
|
||||
$params['db'] = $_GET['db'];
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->getFooter()->setMinimal();
|
||||
$header = $response->getHeader();
|
||||
$header->setBodyId('pmd_body');
|
||||
|
||||
@ -117,9 +117,9 @@ foreach ($tables as $each_table) {
|
||||
$data_checked = $is_checked;
|
||||
}
|
||||
$table_html = htmlspecialchars($each_table['Name']);
|
||||
$multi_values .= '<tr>';
|
||||
$multi_values .= '<tr class="marked">';
|
||||
$multi_values .= '<td><input type="checkbox" name="table_select[]"'
|
||||
. ' value="' . $table_html . '"' . $is_checked . ' /></td>';
|
||||
. ' value="' . $table_html . '"' . $is_checked . ' class="checkall"/></td>';
|
||||
$multi_values .= '<td class="export_table_name">'
|
||||
. str_replace(' ', ' ', $table_html) . '</td>';
|
||||
$multi_values .= '<td class="export_structure">'
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\config\PageSettings;
|
||||
|
||||
require_once 'libraries/common.inc.php';
|
||||
@ -14,7 +15,7 @@ require_once 'libraries/config/page_settings.forms.php';
|
||||
|
||||
PageSettings::showGroup('Import');
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('import.js');
|
||||
@ -37,7 +38,7 @@ list(
|
||||
) = PMA\libraries\Util::getDbInfo($db, isset($sub_part) ? $sub_part : '');
|
||||
|
||||
require 'libraries/display_import.lib.php';
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->addHTML(
|
||||
PMA_getImportDisplay(
|
||||
'database', $db, $table, $max_upload_size
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\plugins\export\ExportSql;
|
||||
|
||||
/**
|
||||
* requirements
|
||||
*/
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/mysql_charsets.inc.php';
|
||||
require_once 'libraries/display_create_table.lib.php';
|
||||
|
||||
/**
|
||||
@ -27,7 +27,7 @@ require_once 'libraries/check_user_privileges.lib.php';
|
||||
require_once 'libraries/operations.lib.php';
|
||||
|
||||
// add a javascript file for jQuery functions to handle Ajax actions
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('db_operations.js');
|
||||
@ -37,7 +37,7 @@ $sql_query = '';
|
||||
/**
|
||||
* Rename/move or copy database
|
||||
*/
|
||||
if (mb_strlen($GLOBALS['db'])
|
||||
if (strlen($GLOBALS['db']) > 0
|
||||
&& (! empty($_REQUEST['db_rename']) || ! empty($_REQUEST['db_copy']))
|
||||
) {
|
||||
if (! empty($_REQUEST['db_rename'])) {
|
||||
@ -46,9 +46,7 @@ if (mb_strlen($GLOBALS['db'])
|
||||
$move = false;
|
||||
}
|
||||
|
||||
if (! isset($_REQUEST['newname'])
|
||||
|| ! mb_strlen($_REQUEST['newname'])
|
||||
) {
|
||||
if (! isset($_REQUEST['newname']) || strlen($_REQUEST['newname']) === 0) {
|
||||
$message = PMA\libraries\Message::error(__('The database name is empty!'));
|
||||
} else {
|
||||
$_error = false;
|
||||
@ -177,8 +175,7 @@ if (mb_strlen($GLOBALS['db'])
|
||||
* Database has been successfully renamed/moved. If in an Ajax request,
|
||||
* generate the output with {@link PMA\libraries\Response} and exit
|
||||
*/
|
||||
if ($GLOBALS['is_ajax_request'] == true) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
if ($response->isAjax()) {
|
||||
$response->setRequestStatus($message->isSuccess());
|
||||
$response->addJSON('message', $message);
|
||||
$response->addJSON('newname', $_REQUEST['newname']);
|
||||
@ -230,7 +227,7 @@ if (isset($message)) {
|
||||
unset($message);
|
||||
}
|
||||
|
||||
$_REQUEST['db_collation'] = PMA_getDbCollation($GLOBALS['db']);
|
||||
$_REQUEST['db_collation'] = $GLOBALS['dbi']->getDbCollation($GLOBALS['db']);
|
||||
$is_information_schema = $GLOBALS['dbi']->isSystemSchema($GLOBALS['db']);
|
||||
|
||||
$response->addHTML('<div id="boxContainer" data-box-width="300">');
|
||||
@ -283,12 +280,8 @@ if (!$is_information_schema) {
|
||||
'%sFind out why%s.'
|
||||
)
|
||||
);
|
||||
$message->addParam(
|
||||
'<a href="'
|
||||
. './chk_rel.php' . $url_query . '">',
|
||||
false
|
||||
);
|
||||
$message->addParam('</a>', false);
|
||||
$message->addParamHtml('<a href="./chk_rel.php' . $url_query . '">');
|
||||
$message->addParamHtml('</a>');
|
||||
/* Show error if user has configured something, notice elsewhere */
|
||||
if (!empty($cfg['Servers'][$server]['pmadb'])) {
|
||||
$message->isError(true);
|
||||
|
||||
@ -6,15 +6,16 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\SavedSearches;
|
||||
use PMA\libraries\URL;
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
* requirements
|
||||
*/
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/bookmark.lib.php';
|
||||
require_once 'libraries/sql.lib.php';
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
|
||||
// Gets the relation settings
|
||||
$cfgRelation = PMA_getRelationsParam();
|
||||
@ -131,7 +132,7 @@ unset($message_to_display);
|
||||
// create new qbe search instance
|
||||
$db_qbe = new PMA\libraries\DbQbe($GLOBALS['db'], $savedSearchList, $savedSearch);
|
||||
|
||||
$url = 'db_designer.php' . PMA_URL_getCommon(
|
||||
$url = 'db_designer.php' . URL::getCommon(
|
||||
array_merge(
|
||||
$url_params,
|
||||
array('query' => 1)
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
* Include required files
|
||||
*/
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/mysql_charsets.inc.php';
|
||||
|
||||
/**
|
||||
* Include all other files
|
||||
|
||||
@ -13,9 +13,10 @@
|
||||
*/
|
||||
require_once 'libraries/common.inc.php';
|
||||
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\DbSearch;
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('db_search.js');
|
||||
@ -38,7 +39,7 @@ $url_params['goto'] = 'db_search.php';
|
||||
$db_search = new DbSearch($GLOBALS['db']);
|
||||
|
||||
// Display top links if we are not in an Ajax request
|
||||
if ($GLOBALS['is_ajax_request'] != true) {
|
||||
if (! $response->isAjax()) {
|
||||
list(
|
||||
$tables,
|
||||
$num_tables,
|
||||
@ -55,19 +56,18 @@ if ($GLOBALS['is_ajax_request'] != true) {
|
||||
// Main search form has been submitted, get results
|
||||
if (isset($_REQUEST['submit_search'])) {
|
||||
$response->addHTML($db_search->getSearchResults());
|
||||
} else {
|
||||
$response->addHTML('<div id="searchresults"></div>');
|
||||
}
|
||||
|
||||
// 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'])) {
|
||||
if ($response->isAjax() && empty($_REQUEST['ajax_page_request'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Display the search form
|
||||
$response->addHTML($db_search->getSelectionForm());
|
||||
$response->addHTML('<div id="searchresults"></div>');
|
||||
$response->addHTML(
|
||||
'<div id="togglesearchresultsdiv"><a id="togglesearchresultlink"></a></div>'
|
||||
. '<br class="clearfloat" />'
|
||||
);
|
||||
$response->addHTML($db_search->getSelectionForm());
|
||||
$response->addHTML('<br class="clearfloat" />');
|
||||
$response->addHTML($db_search->getResultDivs());
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\config\PageSettings;
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -19,7 +20,7 @@ PageSettings::showGroup('Sql_queries');
|
||||
/**
|
||||
* Runs common work
|
||||
*/
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('makegrid.js');
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
use PMA\libraries\Response;
|
||||
require_once 'libraries/common.inc.php';
|
||||
|
||||
if ($GLOBALS['cfg']['EnableAutocompleteForTablesAndColumns']) {
|
||||
@ -22,5 +23,5 @@ if ($GLOBALS['cfg']['EnableAutocompleteForTablesAndColumns']) {
|
||||
} else {
|
||||
$sql_autocomplete = true;
|
||||
}
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->addJSON("tables", json_encode($sql_autocomplete));
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
|
||||
/**
|
||||
* Loading common files. Used to check for authorization, localization and to
|
||||
@ -14,7 +15,7 @@ require_once 'libraries/common.inc.php';
|
||||
|
||||
$query = !empty($_POST['sql']) ? $_POST['sql'] : '';
|
||||
|
||||
$query = SqlParser\Utils\Formatter::format($query);
|
||||
$query = PhpMyAdmin\SqlParser\Utils\Formatter::format($query);
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->addJSON("sql", $query);
|
||||
|
||||
@ -16,7 +16,9 @@ require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/db_common.inc.php';
|
||||
|
||||
$container = libraries\di\Container::getDefaultContainer();
|
||||
$container->factory('PMA\libraries\controllers\database\DatabaseStructureController');
|
||||
$container->factory(
|
||||
'PMA\libraries\controllers\database\DatabaseStructureController'
|
||||
);
|
||||
$container->alias(
|
||||
'DatabaseStructureController',
|
||||
'PMA\libraries\controllers\database\DatabaseStructureController'
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\Tracker;
|
||||
|
||||
/**
|
||||
@ -16,7 +17,7 @@ require_once './libraries/tracking.lib.php';
|
||||
require_once 'libraries/display_create_table.lib.php';
|
||||
|
||||
//Get some js files needed for Ajax requests
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$header = $response->getHeader();
|
||||
$scripts = $header->getScripts();
|
||||
$scripts->addFile('jquery/jquery.tablesorter.js');
|
||||
|
||||
@ -52,21 +52,21 @@ class ConfigOption(ObjectDescription):
|
||||
# Generic index entries
|
||||
indexentry = self.indextemplate % (name,)
|
||||
self.indexnode['entries'].append((indextype, indexentry,
|
||||
targetname, targetname))
|
||||
targetname, targetname, None))
|
||||
self.indexnode['entries'].append((indextype, name,
|
||||
targetname, targetname))
|
||||
targetname, targetname, None))
|
||||
|
||||
# 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))
|
||||
targetname, targetname, None))
|
||||
self.indexnode['entries'].append((indextype, indexname,
|
||||
targetname, targetname))
|
||||
targetname, targetname, None))
|
||||
else:
|
||||
indexname = ', '.join(targetparts)
|
||||
self.indexnode['entries'].append((indextype, indexname,
|
||||
targetname, targetname))
|
||||
targetname, targetname, None))
|
||||
|
||||
self.env.domaindata['config']['objects'][self.objtype, name] = \
|
||||
self.env.docname, targetname
|
||||
@ -84,8 +84,8 @@ class ConfigSectionXRefRole(XRefRole):
|
||||
tgtid = 'index-%s' % env.new_serialno('index')
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = [
|
||||
('single', varname, tgtid, varname),
|
||||
('single', 'configuration section; %s' % varname, tgtid, varname)
|
||||
('single', varname, tgtid, varname, None),
|
||||
('single', 'configuration section; %s' % varname, tgtid, varname, None)
|
||||
]
|
||||
targetnode = nodes.target('', '', ids=[tgtid])
|
||||
document.note_explicit_target(targetnode)
|
||||
@ -118,7 +118,7 @@ class ConfigSection(ObjectDescription):
|
||||
indextype = 'single'
|
||||
indexentry = self.indextemplate % (name,)
|
||||
self.indexnode['entries'].append((indextype, indexentry,
|
||||
targetname, targetname))
|
||||
targetname, targetname, None))
|
||||
self.env.domaindata['config']['objects'][self.objtype, name] = \
|
||||
self.env.docname, targetname
|
||||
|
||||
@ -135,8 +135,8 @@ class ConfigOptionXRefRole(XRefRole):
|
||||
tgtid = 'index-%s' % env.new_serialno('index')
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = [
|
||||
('single', varname, tgtid, varname),
|
||||
('single', 'configuration option; %s' % varname, tgtid, varname)
|
||||
('single', varname, tgtid, varname, None),
|
||||
('single', 'configuration option; %s' % varname, tgtid, varname, None)
|
||||
]
|
||||
targetnode = nodes.target('', '', ids=[tgtid])
|
||||
document.note_explicit_target(targetnode)
|
||||
@ -165,9 +165,12 @@ class ConfigFileDomain(Domain):
|
||||
}
|
||||
|
||||
def clear_doc(self, docname):
|
||||
toremove = []
|
||||
for key, (fn, _) in self.data['objects'].items():
|
||||
if fn == docname:
|
||||
del self.data['objects'][key]
|
||||
toremove.append(key)
|
||||
for key in toremove:
|
||||
del self.data['objects'][key]
|
||||
|
||||
def resolve_xref(self, env, fromdocname, builder,
|
||||
typ, target, node, contnode):
|
||||
@ -185,4 +188,3 @@ class ConfigFileDomain(Domain):
|
||||
|
||||
def setup(app):
|
||||
app.add_domain(ConfigFileDomain)
|
||||
|
||||
|
||||
78
doc/bookmarks.rst
Normal file
@ -0,0 +1,78 @@
|
||||
.. _bookmarks:
|
||||
|
||||
Bookmarks
|
||||
=========
|
||||
|
||||
.. note::
|
||||
|
||||
You need to have configured the :ref:`linked-tables` for using bookmarks
|
||||
feature.
|
||||
|
||||
Storing bookmarks
|
||||
-----------------
|
||||
|
||||
Any query you have executed can be stored as a bookmark on the page
|
||||
where the results are displayed. You will find a button labeled
|
||||
:guilabel:`Bookmark this query` just at the end of the page. As soon as you have
|
||||
stored a bookmark, it is related to the database you run the query on.
|
||||
You can now access a bookmark dropdown on each page, the query box
|
||||
appears on for that database.
|
||||
|
||||
Variables inside bookmarks
|
||||
--------------------------
|
||||
|
||||
You can also have, inside the query, placeholders for variables.
|
||||
This is done by inserting into the query SQL comments between ``/*`` and
|
||||
``*/``. Inside the comments, the special strings ``[VARIABLE{variable-number}]`` is used.
|
||||
Be aware that the whole query minus the SQL comments must be
|
||||
valid by itself, otherwise you won't be able to store it as a bookmark.
|
||||
|
||||
When you execute the bookmark, everything typed into the *Variables*
|
||||
input boxes on the query box page will replace the strings ``/*[VARIABLE{variable-number}]*/`` in
|
||||
your stored query.
|
||||
|
||||
Also remember, that everything else inside the ``/*[VARIABLE{variable-number}]*/`` string for
|
||||
your query will remain the way it is, but will be stripped of the ``/**/``
|
||||
chars. So you can use:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
/*, [VARIABLE1] AS myname */
|
||||
|
||||
which will be expanded to
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
, VARIABLE1 as myname
|
||||
|
||||
in your query, where VARIABLE1 is the string you entered in the Variable 1 input box.
|
||||
|
||||
A more complex example. Say you have stored
|
||||
this query:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE1]%' */
|
||||
|
||||
Say, you now enter "phpMyAdmin" as the variable for the stored query, the full
|
||||
query will be:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
|
||||
|
||||
**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces
|
||||
inserted there will be later also inserted as spaces in your query and may lead
|
||||
to unexpected results especially when using the variable expansion inside of a
|
||||
"LIKE ''" expression.
|
||||
|
||||
Browsing table using bookmark
|
||||
-----------------------------
|
||||
|
||||
When bookmark is named same as table, it will be used as query when browsing
|
||||
this table.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`faqbookmark`,
|
||||
:ref:`faq6_22`
|
||||
143
doc/charts.rst
Normal file
@ -0,0 +1,143 @@
|
||||
.. _charts:
|
||||
|
||||
Charts
|
||||
======
|
||||
|
||||
.. versionadded:: 3.4.0
|
||||
|
||||
Since phpMyAdmin version 3.4.0, you can easily generate charts from a SQL query
|
||||
by clicking the "Display chart" link in the "Query results operations" area.
|
||||
|
||||
.. image:: images/query_result_operations.png
|
||||
|
||||
A window layer "Display chart" is shown in which you can customize the chart with the following options.
|
||||
|
||||
- Chart type: Allows you choose the type of the chart. Supported types are bar charts, column charts, line charts, spline charts, area charts, pie charts and timeline charts (only the chart types applicable for current series selection are offered).
|
||||
- X-axis: Allows to choose the field for the main axis.
|
||||
- Series: Allows to choose series for the chart. You can choose multiple series.
|
||||
- Title: Allows specifying a title for the chart which is displayed above the chart.
|
||||
- X-axis and Y-axis labels: Allows specifying labels for axes.
|
||||
- Start row and number of rows: Allows generating charts only for a specified number of rows of the results set.
|
||||
|
||||
.. image:: images/chart.png
|
||||
|
||||
Chart implementation
|
||||
--------------------
|
||||
|
||||
Charts in phpMyAdmin are drawn using `jqPlot <http://www.jqplot.com/>`_ jQuery library.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Pie chart
|
||||
+++++++++
|
||||
|
||||
Query results for a simple pie chart can be generated with:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT 'Food' AS 'expense',
|
||||
1250 AS 'amount' UNION
|
||||
SELECT 'Accommodation', 500 UNION
|
||||
SELECT 'Travel', 720 UNION
|
||||
SELECT 'Misc', 220
|
||||
|
||||
And the result of this query is:
|
||||
|
||||
+---------------+--------+
|
||||
| expense | anount |
|
||||
+===============+========+
|
||||
| Food | 1250 |
|
||||
+---------------+--------+
|
||||
| Accommodation | 500 |
|
||||
+---------------+--------+
|
||||
| Travel | 720 |
|
||||
+---------------+--------+
|
||||
| Misc | 220 |
|
||||
+---------------+--------+
|
||||
|
||||
Choosing expense as the X-axis and amount in series:
|
||||
|
||||
.. image:: images/pie_chart.png
|
||||
|
||||
Bar and column chart
|
||||
++++++++++++++++++++
|
||||
|
||||
Both bar charts and column chats support stacking. Upon selecting one of these types a checkbox is displayed to select stacking.
|
||||
|
||||
Query results for a simple bar or column chart can be generated with:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT
|
||||
'ACADEMY DINOSAUR' AS 'title',
|
||||
0.99 AS 'rental_rate',
|
||||
20.99 AS 'replacement_cost' UNION
|
||||
SELECT 'ACE GOLDFINGER', 4.99, 12.99 UNION
|
||||
SELECT 'ADAPTATION HOLES', 2.99, 18.99 UNION
|
||||
SELECT 'AFFAIR PREJUDICE', 2.99, 26.99 UNION
|
||||
SELECT 'AFRICAN EGG', 2.99, 22.99
|
||||
|
||||
And the result of this query is:
|
||||
|
||||
+------------------+--------------+-------------------+
|
||||
| title | rental_rate | replacement_cost |
|
||||
+==================+==============+===================+
|
||||
| ACADEMY DINOSAUR | 0.99 | 20.99 |
|
||||
+------------------+--------------+-------------------+
|
||||
| ACE GOLDFINGER | 4.99 | 12.99 |
|
||||
+------------------+--------------+-------------------+
|
||||
| ADAPTATION HOLES | 2.99 | 18.99 |
|
||||
+------------------+--------------+-------------------+
|
||||
| AFFAIR PREJUDICE | 2.99 | 26.99 |
|
||||
+------------------+--------------+-------------------+
|
||||
| AFRICAN EGG | 2.99 | 22.99 |
|
||||
+------------------+--------------+-------------------+
|
||||
|
||||
Choosing title as the X-axis and rental_rate and replacement_cost as series:
|
||||
|
||||
.. image:: images/column_chart.png
|
||||
|
||||
Scatter chart
|
||||
+++++++++++++
|
||||
|
||||
Scatter charts are useful in identifying the movement of one or more variable(s) compared to another variable.
|
||||
|
||||
Using the same data set from bar and column charts section and choosing replacement_cost as the X-axis and rental_rate in series:
|
||||
|
||||
.. image:: images/scatter_chart.png
|
||||
|
||||
Line, spline and timeline charts
|
||||
++++++++++++++++++++++++++++++++
|
||||
|
||||
These charts can be used to illustrate trends in underlying data. Spline charts draw smooth lines while timeline charts draw X-axis taking the distances between the dates/time into consideration.
|
||||
|
||||
Query results for a simple line, spline or timeline chart can be generated with:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT
|
||||
DATE('2006-01-08') AS 'date',
|
||||
2056 AS 'revenue',
|
||||
1378 AS 'cost' UNION
|
||||
SELECT DATE('2006-01-09'), 1898, 2301 UNION
|
||||
SELECT DATE('2006-01-15'), 1560, 600 UNION
|
||||
SELECT DATE('2006-01-17'), 3457, 1565
|
||||
|
||||
And the result of this query is:
|
||||
|
||||
+------------+---------+------+
|
||||
| date | revenue | cost |
|
||||
+============+=========+======+
|
||||
| 2016-01-08 | 2056 | 1378 |
|
||||
+------------+---------+------+
|
||||
| 2006-01-09 | 1898 | 2301 |
|
||||
+------------+---------+------+
|
||||
| 2006-01-15 | 1560 | 600 |
|
||||
+------------+---------+------+
|
||||
| 2006-01-17 | 3457 | 1565 |
|
||||
+------------+---------+------+
|
||||
|
||||
.. image:: images/line_chart.png
|
||||
.. image:: images/spline_chart.png
|
||||
.. image:: images/timeline_chart.png
|
||||
@ -44,14 +44,14 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'phpMyAdmin'
|
||||
copyright = u'2012 - 2016, The phpMyAdmin devel team'
|
||||
copyright = u'2012 - 2017, 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 = '4.6.6'
|
||||
version = '4.7.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version
|
||||
|
||||
@ -302,3 +302,8 @@ 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
|
||||
|
||||
484
doc/config.rst
@ -5,10 +5,15 @@
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Almost all configurable data is placed in :file:`config.inc.php`. If this file
|
||||
does not exist, please refer to the :ref:`setup` section to create one. This
|
||||
file only needs to contain the parameters you want to change from their
|
||||
corresponding default value in :file:`libraries/config.default.php`.
|
||||
All configurable data is placed in :file:`config.inc.php` in phpMyAdmin's
|
||||
toplevel directory. If this file does not exist, please refer to the
|
||||
:ref:`setup` section to create one. This file only needs to contain the
|
||||
parameters you want to change from their corresponding default value in
|
||||
:file:`libraries/config.default.php` (this file is not inteded for changes).
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`config-examples` for examples of configurations
|
||||
|
||||
If a directive is missing from your file, you can just add another line with
|
||||
the file. This file is for over-writing the defaults; if you wish to use the
|
||||
@ -48,13 +53,12 @@ Basic settings
|
||||
Sets here the complete :term:`URL` (with full path) to your phpMyAdmin
|
||||
installation's directory. E.g.
|
||||
``https://www.example.net/path_to_your_phpMyAdmin_directory/``. Note also
|
||||
that the :term:`URL` on most of web servers are case–sensitive. Don’t
|
||||
forget the trailing slash at the end.
|
||||
that the :term:`URL` on most of web servers are case sensitive (even on
|
||||
Windows). Don’t forget the trailing slash at the end.
|
||||
|
||||
Starting with version 2.3.0, it is advisable to try leaving this blank. In
|
||||
most cases phpMyAdmin automatically detects the proper setting. Users of
|
||||
port forwarding will need to set :config:option:`$cfg['PmaAbsoluteUri']`
|
||||
(`more info <https://sourceforge.net/p/phpmyadmin/support-requests/795/>`_).
|
||||
port forwarding or complex reverse proxy setup might need to set this.
|
||||
|
||||
A good test is to browse a table, edit a row and save it. There should be
|
||||
an error message if phpMyAdmin is having trouble auto–detecting the correct
|
||||
@ -104,6 +108,10 @@ Basic settings
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. deprecated:: 4.7.0
|
||||
|
||||
This setting was removed as the warning has been removed as well.
|
||||
|
||||
A warning is displayed on the main page if there is a difference
|
||||
between the MySQL library and server version.
|
||||
|
||||
@ -208,13 +216,22 @@ Server connection settings
|
||||
|
||||
* hostname, e.g., ``'localhost'`` or ``'mydb.example.org'``
|
||||
* IP address, e.g., ``'127.0.0.1'`` or ``'192.168.10.1'``
|
||||
* IPv6 address, e.g. ``2001:cdba:0000:0000:0000:0000:3257:9652``
|
||||
* dot - ``'.'``, i.e., use named pipes on windows systems
|
||||
* empty - ``''``, disables this server
|
||||
|
||||
.. note::
|
||||
|
||||
phpMyAdmin supports connecting to MySQL servers reachable via IPv6 only.
|
||||
To connect to an IPv6 MySQL server, enter its IPv6 address in this field.
|
||||
The hostname ``localhost`` is handled specially by MySQL and it uses
|
||||
the socket based connection protocol. To use TCP/IP networking, use an
|
||||
IP address or hostname such as ``127.0.0.1`` or ``db.example.com``. You
|
||||
can configure the path to the socket with
|
||||
:config:option:`$cfg['Servers'][$i]['socket']`.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['port']`,
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/connecting.html>
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['port']
|
||||
|
||||
@ -231,6 +248,11 @@ Server connection settings
|
||||
different from the default port, use ``127.0.0.1`` or the real hostname
|
||||
in :config:option:`$cfg['Servers'][$i]['host']`.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['host']`,
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/connecting.html>
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['socket']
|
||||
|
||||
:type: string
|
||||
@ -241,19 +263,38 @@ Server connection settings
|
||||
:command:`mysql` command–line client, issue the ``status`` command. Among the
|
||||
resulting information displayed will be the socket used.
|
||||
|
||||
.. note::
|
||||
|
||||
This takes effect only if :config:option:`$cfg['Servers'][$i]['host']` is set
|
||||
to ``localhost``.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['host']`,
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/connecting.html>
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
Whether to enable SSL for the connection between phpMyAdmin and the MySQL server.
|
||||
Whether to enable SSL for the connection between phpMyAdmin and the MySQL
|
||||
server to secure the connection.
|
||||
|
||||
When using the ``'mysql'`` extension,
|
||||
none of the remaining ``'ssl...'`` configuration options apply.
|
||||
|
||||
We strongly recommend the ``'mysqli'`` extension when using this option.
|
||||
|
||||
.. seealso:: :ref:`example-google-ssl`
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_key']
|
||||
|
||||
@ -268,7 +309,15 @@ Server connection settings
|
||||
|
||||
$cfg['Servers'][$i]['ssl_key'] = '/etc/mysql/server-key.pem';
|
||||
|
||||
.. seealso:: :ref:`example-google-ssl`
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_cert']
|
||||
|
||||
@ -277,7 +326,15 @@ Server connection settings
|
||||
|
||||
Path to the cert file when using SSL for connecting to the MySQL server.
|
||||
|
||||
.. seealso:: :ref:`example-google-ssl`
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_ca']
|
||||
|
||||
@ -286,7 +343,15 @@ Server connection settings
|
||||
|
||||
Path to the CA file when using SSL for connecting to the MySQL server.
|
||||
|
||||
.. seealso:: :ref:`example-google-ssl`
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_ca_path']
|
||||
|
||||
@ -295,6 +360,16 @@ Server connection settings
|
||||
|
||||
Directory containing trusted SSL CA certificates in PEM format.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_ciphers']
|
||||
|
||||
:type: string
|
||||
@ -302,6 +377,16 @@ Server connection settings
|
||||
|
||||
List of allowable ciphers for SSL connections to the MySQL server.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['ssl_verify']
|
||||
|
||||
:type: boolean
|
||||
@ -319,18 +404,39 @@ Server connection settings
|
||||
Since PHP 5.6.0 it also verifies whether server name matches CN of it's
|
||||
certificate. There is currently no way to disable just this check without
|
||||
disabling complete SSL verification.
|
||||
|
||||
.. warning::
|
||||
|
||||
Disabling the certificate verification defeats purpose of using SSL.
|
||||
This will make the connection vulnerable to man in the middle attacks.
|
||||
|
||||
.. note::
|
||||
|
||||
This flag only works with PHP 5.6.16 or later.
|
||||
|
||||
.. seealso:: :ref:`example-google-ssl`
|
||||
.. seealso::
|
||||
|
||||
:ref:`example-google-ssl`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['connect_type']
|
||||
|
||||
:type: string
|
||||
:default: ``'tcp'``
|
||||
|
||||
.. deprecated:: 4.7.0
|
||||
|
||||
This setting is no longer used as of 4.7.0, since MySQL decides the
|
||||
connection type based on host, so it could lead to unexpected results.
|
||||
Please set :config:option:`$cfg['Servers'][$i]['host']` accordingly
|
||||
instead.
|
||||
|
||||
What type connection to use with the MySQL server. Your options are
|
||||
``'socket'`` and ``'tcp'``. It defaults to tcp as that is nearly guaranteed
|
||||
to be available on all MySQL servers, while sockets are not supported on
|
||||
@ -354,6 +460,10 @@ Server connection settings
|
||||
Permits to use an alternate host to hold the configuration storage
|
||||
data.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['control_*']`
|
||||
|
||||
.. _controlport:
|
||||
.. config:option:: $cfg['Servers'][$i]['controlport']
|
||||
|
||||
@ -363,6 +473,10 @@ Server connection settings
|
||||
Permits to use an alternate port to connect to the host that
|
||||
holds the configuration storage.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['control_*']`
|
||||
|
||||
.. _controluser:
|
||||
.. config:option:: $cfg['Servers'][$i]['controluser']
|
||||
|
||||
@ -374,13 +488,59 @@ Server connection settings
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
This special account is used for 2 distinct purposes: to make possible all
|
||||
relational features (see :config:option:`$cfg['Servers'][$i]['pmadb']`).
|
||||
This special account is used to access :ref:`linked-tables`.
|
||||
You don't need it in single user case, but if phpMyAdmin is shared it
|
||||
is recommended to give access to :ref:`linked-tables` only to this user
|
||||
and configure phpMyAdmin to use it. All users will then be able to use
|
||||
the features without need to have direct access to :ref:`linked-tables`.
|
||||
|
||||
.. versionchanged:: 2.2.5
|
||||
those were called ``stduser`` and ``stdpass``
|
||||
|
||||
.. seealso:: :ref:`setup`, :ref:`authentication_modes`, :ref:`linked-tables`
|
||||
.. seealso::
|
||||
|
||||
:ref:`setup`,
|
||||
:ref:`authentication_modes`,
|
||||
:ref:`linked-tables`,
|
||||
:config:option:`$cfg['Servers'][$i]['pmadb']`,
|
||||
:config:option:`$cfg['Servers'][$i]['controlhost']`,
|
||||
:config:option:`$cfg['Servers'][$i]['controlport']`,
|
||||
:config:option:`$cfg['Servers'][$i]['control_*']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['control_*']
|
||||
|
||||
:type: mixed
|
||||
|
||||
.. versionadded:: 4.7.0
|
||||
|
||||
You can change any MySQL connection setting for control link (used to
|
||||
access :ref:`linked-tables`) using configuration prefixed with ``control_``.
|
||||
|
||||
This can be used to change any aspect of the control connection, which by
|
||||
default uses same parameters as the user one.
|
||||
|
||||
For example you can configure SSL for the control connection:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
// Enable SSL
|
||||
$cfg['Servers'][$i]['control_ssl'] = true;
|
||||
// Client secret key
|
||||
$cfg['Servers'][$i]['control_ssl_key'] = '../client-key.pem';
|
||||
// Client certificate
|
||||
$cfg['Servers'][$i]['control_ssl_cert'] = '../client-cert.pem';
|
||||
// Server certification authority
|
||||
$cfg['Servers'][$i]['control_ssl_ca'] = '../server-ca.pem';
|
||||
|
||||
.. seealso::
|
||||
|
||||
:config:option:`$cfg['Servers'][$i]['ssl']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca_path']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ciphers']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['auth_type']
|
||||
|
||||
@ -390,13 +550,13 @@ Server connection settings
|
||||
Whether config or cookie or :term:`HTTP` or signon authentication should be
|
||||
used for this server.
|
||||
|
||||
* 'config' authentication (``$auth_type = 'config'``) is the plain old
|
||||
* 'config' authentication (``$auth_type = 'config'``) is the plain old
|
||||
way: username and password are stored in :file:`config.inc.php`.
|
||||
* 'cookie' authentication mode (``$auth_type = 'cookie'``) allows you to
|
||||
* 'cookie' authentication mode (``$auth_type = 'cookie'``) allows you to
|
||||
log in as any valid MySQL user with the help of cookies.
|
||||
* 'http' authentication allows you to log in as any
|
||||
valid MySQL user via HTTP-Auth.
|
||||
* 'signon' authentication mode (``$auth_type = 'signon'``) allows you to
|
||||
* 'signon' authentication mode (``$auth_type = 'signon'``) allows you to
|
||||
log in from prepared PHP session data or using supplied PHP script.
|
||||
|
||||
.. seealso:: :ref:`authentication_modes`
|
||||
@ -436,6 +596,10 @@ Server connection settings
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. deprecated:: 4.7.0
|
||||
|
||||
This setting was removed as it can produce unexpected results.
|
||||
|
||||
Allow attempt to log in without password when a login with password
|
||||
fails. This can be used together with http authentication, when
|
||||
authentication is done some other way and phpMyAdmin gets user name
|
||||
@ -494,7 +658,7 @@ Server connection settings
|
||||
|
||||
More information on regular expressions can be found in the `PCRE
|
||||
pattern syntax
|
||||
<https://php.net/manual/en/reference.pcre.pattern.syntax.php>`_ portion
|
||||
<https://secure.php.net/manual/en/reference.pcre.pattern.syntax.php>`_ portion
|
||||
of the PHP reference manual.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['verbose']
|
||||
@ -508,6 +672,15 @@ Server connection settings
|
||||
show only certain databases on your system, for example. For HTTP
|
||||
auth, all non-US-ASCII characters will be stripped.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['extension']
|
||||
|
||||
:type: string
|
||||
:default: ``'mysqli'``
|
||||
|
||||
The PHP MySQL extension to use (``mysql`` or ``mysqli``).
|
||||
|
||||
It is recommended to use ``mysqli`` in all installations.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['pmadb']
|
||||
|
||||
:type: string
|
||||
@ -611,6 +784,12 @@ Server connection settings
|
||||
:type: string or false
|
||||
:default: ``''``
|
||||
|
||||
The designer feature can save your page layout; by pressing the "Save page" or "Save page as"
|
||||
button in the expanding designer menu, you can customize the layout and have it loaded the next
|
||||
time you use the designer. That layout is stored in this table. Furthermore, this table is also
|
||||
required for using the PDF relation export feature, see
|
||||
:config:option:`$cfg['Servers'][$i]['pdf\_pages']` for additional details.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['pdf_pages']
|
||||
|
||||
:type: string or false
|
||||
@ -673,7 +852,7 @@ Server connection settings
|
||||
``pma__column_info``)
|
||||
* to update your PRE-2.5.0 Column\_comments table use this: and
|
||||
remember that the Variable in :file:`config.inc.php` has been renamed from
|
||||
:config:option:`$cfg['Servers'][$i]['column\_comments']` to
|
||||
:samp:`$cfg['Servers'][$i]['column\_comments']` to
|
||||
:config:option:`$cfg['Servers'][$i]['column\_info']`
|
||||
|
||||
.. code-block:: mysql
|
||||
@ -1153,8 +1332,12 @@ Server connection settings
|
||||
|
||||
Disable using ``INFORMATION_SCHEMA`` to retrieve information (use
|
||||
``SHOW`` commands instead), because of speed issues when many
|
||||
databases are present. Currently used in some parts of the code, more
|
||||
to come.
|
||||
databases are present.
|
||||
|
||||
.. note::
|
||||
|
||||
Enabling this option might give you big performance boost on older
|
||||
MySQL servers.
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['SignonScript']
|
||||
|
||||
@ -1185,6 +1368,23 @@ Server connection settings
|
||||
|
||||
.. seealso:: :ref:`auth_signon`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['SignonCookieParams']
|
||||
|
||||
:type: array
|
||||
:default: ``array()``
|
||||
|
||||
.. versionadded:: 4.7.0
|
||||
|
||||
An associative array of session cookie parameters of other authentication system.
|
||||
It is not needed if the other system doesn't use session_set_cookie_params().
|
||||
Keys should include 'lifetime', 'path', 'domain', 'secure' or 'httponly'.
|
||||
Valid values are mentioned in `session_get_cookie_params <https://php.net/manual/en/
|
||||
function.session-get-cookie-params.php>`_, they should be set to same values as the
|
||||
other application uses. Takes effect only if
|
||||
:config:option:`$cfg['Servers'][$i]['SignonScript']` is not configured.
|
||||
|
||||
.. seealso:: :ref:`auth_signon`
|
||||
|
||||
.. config:option:: $cfg['Servers'][$i]['SignonURL']
|
||||
|
||||
:type: string
|
||||
@ -1208,6 +1408,13 @@ Server connection settings
|
||||
Generic settings
|
||||
----------------
|
||||
|
||||
.. config:option:: $cfg['DisableShortcutKeys']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
You can disable phpMyAdmin shortcut keys by setting :config:option:`$cfg['DisableShortcutKeys']` to false.
|
||||
|
||||
.. config:option:: $cfg['ServerDefault']
|
||||
|
||||
:type: integer
|
||||
@ -1301,14 +1508,14 @@ Generic settings
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
Whether `persistent connections <https://php.net/manual/en/features
|
||||
Whether `persistent connections <https://secure.php.net/manual/en/features
|
||||
.persistent-connections.php>`_ should be used or not. Works with
|
||||
following extensions:
|
||||
|
||||
* mysql (`mysql\_pconnect <https://php.net/manual/en/function.mysql-
|
||||
* mysql (`mysql\_pconnect <https://secure.php.net/manual/en/function.mysql-
|
||||
pconnect.php>`_),
|
||||
* mysqli (requires PHP 5.3.0 or newer, `more information
|
||||
<https://php.net/manual/en/mysqli.persistconns.php>`_).
|
||||
<https://secure.php.net/manual/en/mysqli.persistconns.php>`_).
|
||||
|
||||
.. config:option:: $cfg['ForceSSL']
|
||||
|
||||
@ -1345,7 +1552,7 @@ Generic settings
|
||||
:default: ``''``
|
||||
|
||||
Path for storing session data (`session\_save\_path PHP parameter
|
||||
<https://php.net/session_save_path>`_).
|
||||
<https://secure.php.net/session_save_path>`_).
|
||||
|
||||
.. config:option:: $cfg['MemoryLimit']
|
||||
|
||||
@ -1497,7 +1704,7 @@ Cookie authentication options
|
||||
|
||||
Define how long a login cookie is valid. Please note that php
|
||||
configuration option `session.gc\_maxlifetime
|
||||
<https://php.net/manual/en/session.configuration.php#ini.session.gc-
|
||||
<https://secure.php.net/manual/en/session.configuration.php#ini.session.gc-
|
||||
maxlifetime>`_ might limit session validity and if the session is lost,
|
||||
the login cookie is also invalidated. So it is a good idea to set
|
||||
``session.gc_maxlifetime`` at least to the same value of
|
||||
@ -1855,20 +2062,8 @@ Main panel
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
.. config:option:: $cfg['ShowChgPassword']
|
||||
|
||||
:type: boolean
|
||||
:default: true
|
||||
|
||||
.. config:option:: $cfg['ShowCreateDb']
|
||||
|
||||
:type: boolean
|
||||
:default: true
|
||||
|
||||
Defines whether to display the :guilabel:`PHP information` and
|
||||
:guilabel:`Change password` links and form for creating database or not at
|
||||
the starting main (right) frame. This setting does not check MySQL commands
|
||||
entered directly.
|
||||
Defines whether to display the :guilabel:`PHP information` or not at
|
||||
the starting main (right) frame.
|
||||
|
||||
Please note that to block the usage of ``phpinfo()`` in scripts, you have to
|
||||
put this in your :file:`php.ini`:
|
||||
@ -1885,11 +2080,29 @@ Main panel
|
||||
This might also make easier some remote attacks on your installations,
|
||||
so enable this only when needed.
|
||||
|
||||
Also note that enabling the :guilabel:`Change password` link has no effect
|
||||
.. config:option:: $cfg['ShowChgPassword']
|
||||
|
||||
:type: boolean
|
||||
:default: true
|
||||
|
||||
Defines whether to display the :guilabel:`Change password` link or not at
|
||||
the starting main (right) frame. This setting does not check MySQL commands
|
||||
entered directly.
|
||||
|
||||
Please note that enabling the :guilabel:`Change password` link has no effect
|
||||
with config authentication mode: because of the hard coded password value
|
||||
in the configuration file, end users can't be allowed to change their
|
||||
passwords.
|
||||
|
||||
.. config:option:: $cfg['ShowCreateDb']
|
||||
|
||||
:type: boolean
|
||||
:default: true
|
||||
|
||||
Defines whether to display the form for creating database or not at the
|
||||
starting main (right) frame. This setting does not check MySQL commands
|
||||
entered directly.
|
||||
|
||||
.. config:option:: $cfg['ShowGitRevision']
|
||||
|
||||
:type: boolean
|
||||
@ -1999,6 +2212,9 @@ Browse mode
|
||||
descending order for columns of type TIME, DATE, DATETIME and
|
||||
TIMESTAMP, ascending order else- by default.
|
||||
|
||||
.. versionchanged:: 3.4.0
|
||||
Since phpMyAdmin 3.4.0 the default value is ``'SMART'``.
|
||||
|
||||
.. config:option:: $cfg['GridEditing']
|
||||
|
||||
:type: string
|
||||
@ -2124,6 +2340,13 @@ Export and import settings
|
||||
items are similar to texts seen on export page, so you can easily
|
||||
identify what they mean.
|
||||
|
||||
.. config:option:: $cfg['Export']['format']
|
||||
|
||||
:type: string
|
||||
:default: ``'sql'``
|
||||
|
||||
Default export format.
|
||||
|
||||
.. config:option:: $cfg['Export']['method']
|
||||
|
||||
:type: string
|
||||
@ -2137,7 +2360,40 @@ Export and import settings
|
||||
* ``custom-no-form`` same as ``custom`` but does not display the option
|
||||
of using quick export
|
||||
|
||||
.. config:option:: $cfg['Export']['charset']
|
||||
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
Defines charset for generated export. By default no charset conversion is
|
||||
done assuming UTF-8.
|
||||
|
||||
.. config:option:: $cfg['Export']['file_template_table']
|
||||
|
||||
:type: string
|
||||
:default: ``'@TABLE@'``
|
||||
|
||||
Default filename template for table exports.
|
||||
|
||||
.. seealso:: :ref:`faq6_27`
|
||||
|
||||
.. config:option:: $cfg['Export']['file_template_database']
|
||||
|
||||
:type: string
|
||||
:default: ``'@DATABASE@'``
|
||||
|
||||
Default filename template for database exports.
|
||||
|
||||
.. seealso:: :ref:`faq6_27`
|
||||
|
||||
.. config:option:: $cfg['Export']['file_template_server']
|
||||
|
||||
:type: string
|
||||
:default: ``'@SERVER@'``
|
||||
|
||||
Default filename template for server exports.
|
||||
|
||||
.. seealso:: :ref:`faq6_27`
|
||||
|
||||
.. config:option:: $cfg['Import']
|
||||
|
||||
@ -2148,6 +2404,13 @@ Export and import settings
|
||||
items are similar to texts seen on import page, so you can easily
|
||||
identify what they mean.
|
||||
|
||||
.. config:option:: $cfg['Import']['charset']
|
||||
|
||||
:type: string
|
||||
:default: ``''``
|
||||
|
||||
Defines charset for import. By default no charset conversion is done
|
||||
assuming UTF-8.
|
||||
|
||||
Tabs display settings
|
||||
---------------------
|
||||
@ -2280,7 +2543,7 @@ Languages
|
||||
recode)
|
||||
* iconv - use iconv or libiconv functions
|
||||
* recode - use recode\_string function
|
||||
* mb - use mbstring extension
|
||||
* mb - use :term:`mbstring` extension
|
||||
* none - disable encoding conversion
|
||||
|
||||
Enabled charset conversion activates a pull-down menu in the Export
|
||||
@ -2464,7 +2727,7 @@ Design customization
|
||||
:default: false
|
||||
|
||||
Defines whether to show row links (Edit, Copy, Delete) and checkboxes
|
||||
for multiple row operations even when the selection does not have a unique key.
|
||||
for multiple row operations even when the selection does not have a :term:`unique key`.
|
||||
Using row actions in the absence of a unique key may result in different/more
|
||||
rows being affected since there is no guaranteed way to select the exact row(s).
|
||||
|
||||
@ -2480,7 +2743,7 @@ Design customization
|
||||
:type: string
|
||||
:default: ``'NONE'``
|
||||
|
||||
This defines the default sort order for the tables, having a primary key,
|
||||
This defines the default sort order for the tables, having a :term:`primary key`,
|
||||
when there is no sort order defines externally.
|
||||
Acceptable values : ['NONE', 'ASC', 'DESC']
|
||||
|
||||
@ -2788,6 +3051,8 @@ Various display setting
|
||||
``SELECT COUNT`` will be used, otherwise the approximate count will be
|
||||
used.
|
||||
|
||||
.. seealso:: :ref:`faq3_11`
|
||||
|
||||
.. config:option:: $cfg['MaxExactCountViews']
|
||||
|
||||
:type: integer
|
||||
@ -2861,14 +3126,6 @@ Page titles
|
||||
Theme manager settings
|
||||
----------------------
|
||||
|
||||
.. config:option:: $cfg['ThemePath']
|
||||
|
||||
:type: string
|
||||
:default: ``'./themes'``
|
||||
|
||||
If theme manager is active, use this as the path of the subdirectory
|
||||
containing all the themes.
|
||||
|
||||
.. config:option:: $cfg['ThemeManager']
|
||||
|
||||
:type: boolean
|
||||
@ -2881,7 +3138,7 @@ Theme manager settings
|
||||
:type: string
|
||||
:default: ``'pmahomme'``
|
||||
|
||||
The default theme (a subdirectory under :config:option:`$cfg['ThemePath']`).
|
||||
The default theme (a subdirectory under :file:`./themes/`).
|
||||
|
||||
.. config:option:: $cfg['ThemePerServer']
|
||||
|
||||
@ -2941,6 +3198,14 @@ Developer
|
||||
Enable logging queries and execution times to be
|
||||
displayed in the console's Debug SQL tab.
|
||||
|
||||
.. config:option:: $cfg['DBG']['sqllog']
|
||||
|
||||
:type: boolean
|
||||
:default: false
|
||||
|
||||
Enable logging of queries and execution times to the syslog.
|
||||
Requires :config:option:`$cfg['DBG']['sql']` to be enabled.
|
||||
|
||||
.. config:option:: $cfg['DBG']['demo']
|
||||
|
||||
:type: boolean
|
||||
@ -2949,11 +3214,103 @@ Developer
|
||||
Enable to let server present itself as demo server.
|
||||
This is used for `phpMyAdmin demo server <https://www.phpmyadmin.net/try/>`_.
|
||||
|
||||
.. _config-examples:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
See following configuration snippets for usual setups of phpMyAdmin.
|
||||
See following configuration snippets for typical setups of phpMyAdmin.
|
||||
|
||||
Basic example
|
||||
+++++++++++++
|
||||
|
||||
Example configuration file, which can be copied to :file:`config.inc.php` to
|
||||
get some core configuration layout; it is distributed with phpMyAdmin as
|
||||
:file:`config.sample.inc.php`. Please note that it does not contain all
|
||||
configuration options, only the most frequently used ones.
|
||||
|
||||
.. literalinclude:: ../config.sample.inc.php
|
||||
:language: php
|
||||
|
||||
.. warning::
|
||||
|
||||
Don't use the controluser 'pma' if it does not yet exist and don't use 'pmapass'
|
||||
as password.
|
||||
|
||||
|
||||
.. _example-signon:
|
||||
|
||||
Example for signon authentication
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
This example uses :file:`examples/signon.php` to demonstrate usage of :ref:`auth_signon`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$i = 0;
|
||||
$i++;
|
||||
$cfg['Servers'][$i]['extension'] = 'mysqli';
|
||||
$cfg['Servers'][$i]['auth_type'] = 'signon';
|
||||
$cfg['Servers'][$i]['SignonSession'] = 'SignonSession';
|
||||
$cfg['Servers'][$i]['SignonURL'] = 'examples/signon.php';
|
||||
?>`
|
||||
|
||||
Example for IP address limited autologin
|
||||
++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
If you want to automatically login when accessing phpMyAdmin locally while asking
|
||||
for a password when accessing remotely, you can achieve it using following snippet:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
if ($_SERVER["REMOTE_ADDR"] == "127.0.0.1") {
|
||||
$cfg['Servers'][$i]['auth_type'] = 'config';
|
||||
$cfg['Servers'][$i]['user'] = 'root';
|
||||
$cfg['Servers'][$i]['password'] = 'yourpassword';
|
||||
} else {
|
||||
$cfg['Servers'][$i]['auth_type'] = 'cookie';
|
||||
}
|
||||
|
||||
.. note::
|
||||
|
||||
Filtering based on IP addresses isn't reliable over the internet, use it
|
||||
only for local address.
|
||||
|
||||
Example for using multiple MySQL servers
|
||||
++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
You can configure any number of servers using :config:option:`$cfg['Servers']`,
|
||||
following example shows two of them:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cfg['blowfish_secret']='multiServerExample70518';
|
||||
//any string of your choice
|
||||
$i = 0;
|
||||
|
||||
$i++; // server 1 :
|
||||
$cfg['Servers'][$i]['auth_type'] = 'cookie';
|
||||
$cfg['Servers'][$i]['verbose'] = 'no1';
|
||||
$cfg['Servers'][$i]['host'] = 'localhost';
|
||||
$cfg['Servers'][$i]['extension'] = 'mysqli';
|
||||
// more options for #1 ...
|
||||
|
||||
$i++; // server 2 :
|
||||
$cfg['Servers'][$i]['auth_type'] = 'cookie';
|
||||
$cfg['Servers'][$i]['verbose'] = 'no2';
|
||||
$cfg['Servers'][$i]['host'] = 'remote.host.addr';//or ip:'10.9.8.1'
|
||||
// this server must allow remote clients, e.g., host 10.9.8.%
|
||||
// not only in mysql.host but also in the startup configuration
|
||||
$cfg['Servers'][$i]['extension'] = 'mysqli';
|
||||
// more options for #2 ...
|
||||
|
||||
// end of server sections
|
||||
$cfg['ServerDefault'] = 0; // to choose the server on startup
|
||||
|
||||
// further general options ...
|
||||
?>
|
||||
|
||||
.. _example-google-ssl:
|
||||
|
||||
@ -2963,7 +3320,9 @@ Google Cloud SQL with SSL
|
||||
To connect to Google Could SQL, you currently need to disable certificate
|
||||
verification. This is caused by the certficate being issued for CN matching
|
||||
your instance name, but you connect to an IP address and PHP tries to match
|
||||
these two. With verfication you end up with error message like::
|
||||
these two. With verfication you end up with error message like:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Peer certificate CN=`api-project-851612429544:pmatest' did not match expected CN=`8.8.8.8'
|
||||
|
||||
@ -2978,7 +3337,7 @@ server certificates and tell phpMyAdmin to use them:
|
||||
.. code-block:: php
|
||||
|
||||
// IP address of your instance
|
||||
$cfg['Servers'][2]['host'] = '8.8.8.8';
|
||||
$cfg['Servers'][$i]['host'] = '8.8.8.8';
|
||||
// Use SSL for connection
|
||||
$cfg['Servers'][$i]['ssl'] = true;
|
||||
// Client secret key
|
||||
@ -2996,4 +3355,5 @@ server certificates and tell phpMyAdmin to use them:
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_key']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_cert']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_ca']`,
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`
|
||||
:config:option:`$cfg['Servers'][$i]['ssl_verify']`,
|
||||
<https://bugs.php.net/bug.php?id=72048>
|
||||
|
||||
@ -6,7 +6,7 @@ Copyright
|
||||
.. code-block:: none
|
||||
|
||||
Copyright (C) 1998-2000 Tobias Ratschiller <tobias_at_ratschiller.com>
|
||||
Copyright (C) 2001-2014 Marc Delisle <marc_at_infomarc.info>
|
||||
Copyright (C) 2001-2017 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>
|
||||
@ -38,12 +38,5 @@ jQuery's license, which is where we got the files under js/jquery/ is
|
||||
(MIT|GPL), a copy of each license is available in this repository (GPL
|
||||
is available as LICENSE, MIT as js/jquery/MIT-LICENSE.txt).
|
||||
|
||||
TCPDF which is located under libraries/tcpdf is released under GPL
|
||||
version 3 and the license is available as libraries/tcpdf/LICENSE.TXT.
|
||||
|
||||
DejaVu fonts which are located under libraries/tcpdf/fonts/ and their
|
||||
license is documented in
|
||||
libraries/tcpdf/fonts/dejavu-fonts-ttf-2.33/LICENSE.
|
||||
|
||||
PHP-gettext which is located under libraries/php-gettext/ is released
|
||||
under GPL version 2 license which is available in the LICENSE file.
|
||||
The download kit additionally includes several composer libraries. See their
|
||||
licensing information in the vendor/ directory.
|
||||
|
||||
@ -183,7 +183,7 @@ Credits, in chronological order
|
||||
* :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 <https://acko.net/blog/ufpdf-unicode-utf-8-extension-for-fpdf/>) and
|
||||
Nicola Asuni for the "TCPDF" library (see <https://www.tcpdf.org/>).
|
||||
Nicola Asuni for the "TCPDF" library (see <https://tcpdf.org/>).
|
||||
|
||||
* Olof Edlund <olof.edlund\_at\_upright.se>
|
||||
|
||||
@ -563,7 +563,7 @@ Following people have contributed to translation of phpMyAdmin:
|
||||
|
||||
* Finnish
|
||||
|
||||
* Juha <jremes\_at\_outlook.com>
|
||||
* Juha Remes <jremes\_at\_outlook.com>
|
||||
* Lari Oesch <lari\_at\_oesch.me>
|
||||
|
||||
|
||||
|
||||
412
doc/faq.rst
@ -68,7 +68,7 @@ and :file:`index.php`.
|
||||
|
||||
.. _faq1_7:
|
||||
|
||||
1.7 How can I GZip a dump or a CSV export? It does not seem to work.
|
||||
1.7 How can I gzip a dump or a CSV export? It does not seem to work.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
This feature is based on the ``gzencode()``
|
||||
@ -115,8 +115,8 @@ It seems to clear up many problems between Internet Explorer and SSL.
|
||||
|
||||
.. _faq1_11:
|
||||
|
||||
1.11 I get an 'open\_basedir restriction' while uploading a file from the query box.
|
||||
------------------------------------------------------------------------------------
|
||||
1.11 I get an 'open\_basedir restriction' while uploading a file from the import tab.
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
Since version 2.2.4, phpMyAdmin supports servers with open\_basedir
|
||||
restrictions. However you need to create temporary directory and configure it
|
||||
@ -128,9 +128,15 @@ and after execution of your :term:`SQL` commands, removed.
|
||||
1.12 I have lost my MySQL root password, what can I do?
|
||||
-------------------------------------------------------
|
||||
|
||||
phpMyAdmin does authenticate against MySQL server you're using, so to recover
|
||||
from phpMyAdmin password loss, you need to recover at MySQL level.
|
||||
|
||||
The MySQL manual explains how to `reset the permissions
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/resetting-permissions.html>`_.
|
||||
|
||||
If you are using MySQL server installed by your hosting provider, please
|
||||
contact their support to recover the password for you.
|
||||
|
||||
.. _faq1_13:
|
||||
|
||||
1.13 (withdrawn).
|
||||
@ -159,14 +165,13 @@ Starting with version 2.7.0, the import engine has been re–written and
|
||||
these problems should not occur. If possible, upgrade your phpMyAdmin
|
||||
to the latest version to take advantage of the new import features.
|
||||
|
||||
The first things to check (or ask your host provider to check) are the
|
||||
values of ``upload_max_filesize``, ``memory_limit`` and
|
||||
``post_max_size`` in the :file:`php.ini` configuration file. All of these
|
||||
three settings limit the maximum size of data that can be submitted
|
||||
and handled by PHP. One user also said that ``post_max_size`` and
|
||||
``memory_limit`` need to be larger than ``upload_max_filesize``.
|
||||
There exist several workarounds if your upload is too big or your
|
||||
hosting provider is unwilling to change the settings:
|
||||
The first things to check (or ask your host provider to check) are the values
|
||||
of ``max_execution_time``, ``upload_max_filesize``, ``memory_limit`` and
|
||||
``post_max_size`` in the :file:`php.ini` configuration file. All of these three
|
||||
settings limit the maximum size of data that can be submitted and handled by
|
||||
PHP. Please note that ``post_max_size`` needs to be larger than
|
||||
``upload_max_filesize``. There exist several workarounds if your upload is too
|
||||
big or your hosting provider is unwilling to change the settings:
|
||||
|
||||
* Look at the :config:option:`$cfg['UploadDir']` feature. This allows one to upload a file to the server
|
||||
via scp, ftp, or your favorite file transfer method. PhpMyAdmin is
|
||||
@ -207,7 +212,7 @@ your server - as mentioned in :ref:`faq1_17`. This problem is
|
||||
generally caused by using MySQL version 4.1 or newer. MySQL changed
|
||||
the authentication hash and your PHP is trying to use the old method.
|
||||
The proper solution is to use the `mysqli extension
|
||||
<https://www.php.net/mysqli>`_ with the proper client library to match
|
||||
<https://secure.php.net/mysqli>`_ with the proper client library to match
|
||||
your MySQL installation. More
|
||||
information (and several workarounds) are located in the `MySQL
|
||||
Documentation <https://dev.mysql.com/doc/refman/5.7/en/old-client.html>`_.
|
||||
@ -242,6 +247,41 @@ or something similar.
|
||||
There are currently two interfaces PHP provides as MySQL extensions - ``mysql``
|
||||
and ``mysqli``. The ``mysqli`` is tried first, because it's the best one.
|
||||
|
||||
This problem can be also caused by wrong paths in the :file:`php.ini` or using
|
||||
wrong :file:`php.ini`.
|
||||
|
||||
Make sure that the extension files do exist in the folder which the
|
||||
``extension_dir`` points to and that the corresponding lines in your
|
||||
:file:`php.ini` are not commented out (you can use ``phpinfo()`` to check
|
||||
current setup):
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[PHP]
|
||||
|
||||
; Directory in which the loadable extensions (modules) reside.
|
||||
extension_dir = "C:/Apache2/modules/php/ext"
|
||||
|
||||
The :file:`php.ini` can be loaded from several locations (especially on
|
||||
Windows), so please check you're updating the correct one. If using Apache, you
|
||||
can tell it to use specific path for this file using ``PHPIniDir`` directive:
|
||||
|
||||
.. code-block:: apache
|
||||
|
||||
LoadFile "C:/php/php5ts.dll"
|
||||
LoadModule php5_module "C:/php/php5apache2_2.dll"
|
||||
<IfModule php5_module>
|
||||
PHPIniDir "C:/PHP"
|
||||
<Location>
|
||||
AddType text/html .php
|
||||
AddHandler application/x-httpd-php .php
|
||||
</Location>
|
||||
</IfModule>
|
||||
|
||||
In some rare cases this problem can be also caused by other extensions loaded
|
||||
in PHP which prevent MySQL extensions to be loaded. If anything else fails, you
|
||||
can try commenting out extensions for other databses from :file:`php.ini`.
|
||||
|
||||
.. _faq1_21:
|
||||
|
||||
1.21 I am running the CGI version of PHP under Unix, and I cannot log in using cookie auth.
|
||||
@ -272,6 +312,12 @@ directory and add the following line to the group [mysqld]:
|
||||
|
||||
set-variable = lower_case_table_names=0
|
||||
|
||||
.. note::
|
||||
|
||||
Forcing this variable to 0 with --lower-case-table-names=0 on a
|
||||
case-insensitive filesystem and access MyISAM tablenames using different
|
||||
lettercases, index corruption may result.
|
||||
|
||||
Next, save the file and restart the MySQL service. You can always
|
||||
check the value of this directive using the query
|
||||
|
||||
@ -279,6 +325,8 @@ check the value of this directive using the query
|
||||
|
||||
SHOW VARIABLES LIKE 'lower_case_table_names';
|
||||
|
||||
.. seealso:: `Identifier Case Sensitivity in the MySQL Reference Manual <https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html>`_
|
||||
|
||||
.. _faq1_24:
|
||||
|
||||
1.24 (withdrawn).
|
||||
@ -330,7 +378,7 @@ This can happen due to a MySQL bug when having database / table names
|
||||
with upper case characters although ``lower_case_table_names`` is
|
||||
set to 1. To fix this, turn off this directive, convert all database
|
||||
and table names to lower case and turn it on again. Alternatively,
|
||||
there's a bug-fix available starting with MySQL 3.23.56 /
|
||||
there's a bug-fix available starting with MySQL 3.23.56 /
|
||||
4.0.11-gamma.
|
||||
|
||||
.. _faq1_29:
|
||||
@ -378,12 +426,16 @@ MMCache but upgrading MMCache to version 2.3.21 solves the problem.
|
||||
|
||||
.. _faq1_31:
|
||||
|
||||
1.31 Does phpMyAdmin support PHP 5?
|
||||
-----------------------------------
|
||||
1.31 Which PHP versions does phpMyAdmin support?
|
||||
------------------------------------------------
|
||||
|
||||
Yes.
|
||||
Since release 4.5, phpMyAdmin supports only PHP 5.5 and newer. Since release
|
||||
4.1 phpMyAdmin supports only PHP 5.3 and newer. For PHP 5.2 you can use 4.0.x
|
||||
releases.
|
||||
|
||||
Since release 4.5, phpMyAdmin supports only PHP 5.5 and newer. Since release 4.1 phpMyAdmin supports only PHP 5.3 and newer. For PHP 5.2 you can use 4.0.x releases.
|
||||
PHP 7 is supported since phpMyAdmin 4.6, PHP 7.1 is supported since 4.6.5.
|
||||
|
||||
phpMyAdmin also works fine with HHVM.
|
||||
|
||||
.. _faq1_32:
|
||||
|
||||
@ -415,12 +467,12 @@ Yes. This procedure was tested with phpMyAdmin 2.6.1, PHP 4.3.9 in
|
||||
------------------------------------------------------
|
||||
|
||||
Yes. Out of the box, you can use :term:`URL` like
|
||||
https://example.com/phpMyAdmin/index.php?server=X&db=database&table=table&target=script.
|
||||
``http://server/phpMyAdmin/index.php?server=X&db=database&table=table&target=script``.
|
||||
For ``server`` you use the server number
|
||||
which refers to the order of the server paragraph in
|
||||
:file:`config.inc.php`. Table and script parts are optional. If you want
|
||||
https://example.com/phpMyAdmin/database[/table][/script] :term:`URL`, you need to do some configuration. Following
|
||||
lines apply only for `Apache <https://httpd.apache.org/>`_ web server.
|
||||
``http://server/phpMyAdmin/database[/table][/script]`` :term:`URL`, you need to do some configuration. Following
|
||||
lines apply only for `Apache <https://httpd.apache.org>`_ web server.
|
||||
First make sure, that you have enabled some features within global
|
||||
configuration. You need ``Options SymLinksIfOwnerMatch`` and ``AllowOverride
|
||||
FileInfo`` enabled for directory where phpMyAdmin is installed and you
|
||||
@ -477,7 +529,7 @@ extension which works fine in this case.
|
||||
|
||||
Yes but the default configuration values of Suhosin are known to cause
|
||||
problems with some operations, for example editing a table with many
|
||||
columns and no primary key or with textual primary key.
|
||||
columns and no :term:`primary key` or with textual :term:`primary key`.
|
||||
|
||||
Suhosin configuration might lead to malfunction in some cases and it
|
||||
can not be fully avoided as phpMyAdmin is kind of application which
|
||||
@ -537,10 +589,14 @@ You can also disable the warning using the :config:option:`$cfg['SuhosinDisableW
|
||||
1.39 When I try to connect via https, I can log in, but then my connection is redirected back to http. What can cause this behavior?
|
||||
------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Be sure that you have enabled ``SSLOptions`` and ``StdEnvVars`` in
|
||||
your Apache configuration.
|
||||
This is caused by the fact that PHP scripts have no knowledge that the site is
|
||||
using https. Depending on used webserver, you should configure it to let PHP
|
||||
know about URL and scheme used to access it.
|
||||
|
||||
.. seealso:: <http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#ssloptions>
|
||||
For example in Apache ensure that you have enabled ``SSLOptions`` and
|
||||
``StdEnvVars`` in the configuration.
|
||||
|
||||
.. seealso:: <https://httpd.apache.org/docs/2.4/mod/mod_ssl.html>
|
||||
|
||||
.. _faq1_40:
|
||||
|
||||
@ -558,7 +614,7 @@ the set-cookie headers. Example from the Apache 2.2 documentation:
|
||||
ProxyPassReverseCookieDomain backend.example.com public.example.com
|
||||
ProxyPassReverseCookiePath / /mirror/foo/
|
||||
|
||||
Note: if the backend url looks like https://example.com/~user/phpmyadmin, the
|
||||
Note: if the backend url looks like ``http://server/~user/phpmyadmin``, the
|
||||
tilde (~) must be url encoded as %7E in the ProxyPassReverse\* lines.
|
||||
This is not specific to phpmyadmin, it's just the behavior of Apache.
|
||||
|
||||
@ -626,7 +682,7 @@ Some users have requested to be able to reduce the size of the phpMyAdmin instal
|
||||
This is not recommended and could lead to confusion over missing features, but can be done.
|
||||
A list of files and corresponding functionality which degrade gracefully when removed include:
|
||||
|
||||
* :file:`./libraries/tcpdf` folder (exporting to PDF)
|
||||
* :file:`./vendor/tecnickcom/tcpdf` folder (exporting to PDF)
|
||||
* :file:`./locale/` folder, or unused subfolders (interface translations)
|
||||
* Any unused themes in :file:`./themes/`
|
||||
* :file:`./js/jquery/src/` (included for licensing reasons)
|
||||
@ -635,6 +691,7 @@ A list of files and corresponding functionality which degrade gracefully when re
|
||||
* :file:`./setup/` (setup script)
|
||||
* :file:`./examples/`
|
||||
* :file:`./sql/` (SQL scripts to configure advanced functionality)
|
||||
* :file:`./js/openlayers/` (GIS visualization)
|
||||
|
||||
.. _faqconfig:
|
||||
|
||||
@ -650,7 +707,7 @@ Edit your :file:`config.inc.php` file and ensure there is nothing (I.E. no
|
||||
blank lines, no spaces, no characters...) neither before the ``<?php`` tag at
|
||||
the beginning, neither after the ``?>`` tag at the end. We also got a report
|
||||
from a user under :term:`IIS`, that used a zipped distribution kit: the file
|
||||
:file:`libraries/Config.class.php` contained an end-of-line character (hex 0A)
|
||||
:file:`libraries/Config.php` contained an end-of-line character (hex 0A)
|
||||
at the end; removing this character cleared his errors.
|
||||
|
||||
.. _faq2_2:
|
||||
@ -668,7 +725,22 @@ support into PHP.
|
||||
2.3 The error message "Warning: MySQL Connection Failed: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111) ..." is displayed. What can I do?
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
For RedHat users, Harald Legner suggests this on the mailing list:
|
||||
The error message can also be: :guilabel:`Error #2002 - The server is not
|
||||
responding (or the local MySQL server's socket is not correctly configured)`.
|
||||
|
||||
First, you need to determine what socket is being used by MySQL. To do this,
|
||||
connect to your server and go to the MySQL bin directory. In this directory
|
||||
there should be a file named *mysqladmin*. Type ``./mysqladmin variables``, and
|
||||
this should give you a bunch of info about your MySQL server, including the
|
||||
socket (*/tmp/mysql.sock*, for example). You can also ask your ISP for the
|
||||
connection info or, if you're hosting your own, connect from the 'mysql'
|
||||
command-line client and type 'status' to get the connection type and socket or
|
||||
port number.
|
||||
|
||||
Then, you need to tell PHP to use this socket. You can do this for all PHP in
|
||||
the :file:`php.ini` or for phpMyAdmin only in the :file:`config.inc.php`. For
|
||||
example: :config:option:`$cfg['Servers'][$i]['socket']` Please also make sure
|
||||
that the permissions of this file allow to be readable by your webserver.
|
||||
|
||||
On my RedHat-Box the socket of MySQL is */var/lib/mysql/mysql.sock*.
|
||||
In your :file:`php.ini` you will find a line
|
||||
@ -685,24 +757,8 @@ change it to
|
||||
|
||||
Then restart apache and it will work.
|
||||
|
||||
Here is a fix suggested by Brad Ummer:
|
||||
|
||||
* First, you need to determine what socket is being used by MySQL. To do
|
||||
this, telnet to your server and go to the MySQL bin directory. In this
|
||||
directory there should be a file named *mysqladmin*. Type
|
||||
``./mysqladmin variables``, and this should give you a bunch of info
|
||||
about your MySQL server, including the socket (*/tmp/mysql.sock*, for
|
||||
example).
|
||||
* Then, you need to tell PHP to use this socket. To do this in
|
||||
phpMyAdmin, you need to complete the socket information in the
|
||||
:file:`config.inc.php`. For example:
|
||||
:config:option:`$cfg['Servers'][$i]['socket']` Please also make sure that
|
||||
the permissions of this file allow to be readable by your webserver (i.e.
|
||||
'0755').
|
||||
|
||||
Have also a look at the `corresponding section of the MySQL
|
||||
documentation <https://dev.mysql.com/doc/en/can-not-connect-to-
|
||||
server.html>`_.
|
||||
documentation <https://dev.mysql.com/doc/refman/5.7/en/can-not-connect-to-server.html>`_.
|
||||
|
||||
.. _faq2_4:
|
||||
|
||||
@ -745,20 +801,18 @@ doesn't work in this configuration with port forwarding. If you enter
|
||||
2.7 Using and creating themes
|
||||
-----------------------------
|
||||
|
||||
Themes are configured with :config:option:`$cfg['ThemePath']`,
|
||||
:config:option:`$cfg['ThemeManager']` and :config:option:`$cfg['ThemeDefault']`.
|
||||
Under :config:option:`$cfg['ThemePath']`, you should not delete the
|
||||
directory ``pmahomme`` or its underlying structure, because this is the
|
||||
system theme used by phpMyAdmin. ``pmahomme`` contains all images and
|
||||
styles, for backwards compatibility and for all themes that would not
|
||||
include images or css-files. If :config:option:`$cfg['ThemeManager']`
|
||||
is enabled, you can select your favorite theme on the main page. Your selected
|
||||
theme will be stored in a cookie.
|
||||
Themes are configured with :config:option:`$cfg['ThemeManager']` and
|
||||
:config:option:`$cfg['ThemeDefault']`. Under :file:`./themes/`, you should not
|
||||
delete the directory ``pmahomme`` or its underlying structure, because this is
|
||||
the system theme used by phpMyAdmin. ``pmahomme`` contains all images and
|
||||
styles, for backwards compatibility and for all themes that would not include
|
||||
images or css-files. If :config:option:`$cfg['ThemeManager']` is enabled, you
|
||||
can select your favorite theme on the main page. Your selected theme will be
|
||||
stored in a cookie.
|
||||
|
||||
To create a theme:
|
||||
|
||||
* make a new subdirectory (for example "your\_theme\_name") under :config:option:`$cfg['ThemePath']` (by
|
||||
default ``themes``)
|
||||
* make a new subdirectory (for example "your\_theme\_name") under :file:`./themes/`.
|
||||
* copy the files and directories from ``pmahomme`` to "your\_theme\_name"
|
||||
* edit the css-files in "your\_theme\_name/css"
|
||||
* put your new images in "your\_theme\_name/img"
|
||||
@ -798,11 +852,11 @@ Here are a few points to check:
|
||||
Dorninger for the hint).
|
||||
* In the :file:`php.ini` directive ``arg_separator.input``, a value of ";"
|
||||
will cause this error. Replace it with "&;".
|
||||
* If you are using `Hardened-PHP <http://www.hardened-php.net/>`_, you
|
||||
might want to increase `request limits <http://www.hardened-
|
||||
php.net/hphp/troubleshooting.html>`_.
|
||||
* If you are using `Suhosin <https://suhosin.org/stories/index.html>`_, you
|
||||
might want to increase `request limits <https://suhosin.org/stories/faq.html>`_.
|
||||
* The directory specified in the :file:`php.ini` directive
|
||||
``session.save_path`` does not exist or is read-only.
|
||||
``session.save_path`` does not exist or is read-only (this can be caused
|
||||
by `bug in the PHP installer <https://bugs.php.net/bug.php?id=39842>`_).
|
||||
|
||||
.. _faq2_9:
|
||||
|
||||
@ -810,7 +864,7 @@ Here are a few points to check:
|
||||
---------------------------------
|
||||
|
||||
To be able to see a progress bar during your uploads, your server must
|
||||
have the `APC <https://php.net/manual/en/book.apc.php>`_ extension, the
|
||||
have the `APC <https://secure.php.net/manual/en/book.apc.php>`_ extension, the
|
||||
`uploadprogress <https://pecl.php.net/package/uploadprogress>`_ one, or
|
||||
you must be running PHP 5.4.0 or higher. Moreover, the JSON extension
|
||||
has to be enabled in your PHP.
|
||||
@ -845,9 +899,9 @@ again.
|
||||
----------------------------------------------------------------------------------------------------
|
||||
|
||||
Compressed dumps are built in memory and because of this are limited
|
||||
to php's memory limit. For GZip/BZip2 exports this can be overcome
|
||||
to php's memory limit. For gzip/bzip2 exports this can be overcome
|
||||
since 2.5.4 using :config:option:`$cfg['CompressOnFly']` (enabled by default).
|
||||
Zip exports can not be handled this way, so if you need Zip files for larger
|
||||
zip exports can not be handled this way, so if you need zip files for larger
|
||||
dump, you have to use another way.
|
||||
|
||||
.. _faq3_3:
|
||||
@ -903,10 +957,10 @@ TableSeparator or disabling that feature.
|
||||
3.7 I have table with many (100+) columns and when I try to browse table I get series of errors like "Warning: unable to parse url". How can this be fixed?
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Your table neither have a primary key nor an unique one, so we must
|
||||
Your table neither have a :term:`primary key` nor an :term:`unique key`, so we must
|
||||
use a long expression to identify this row. This causes problems to
|
||||
parse\_url function. The workaround is to create a primary or unique
|
||||
key.
|
||||
parse\_url function. The workaround is to create a :term:`primary key`
|
||||
or :term:`unique key`.
|
||||
|
||||
.. _faq3_8:
|
||||
|
||||
@ -931,19 +985,19 @@ official phpMyAdmin-homepage.
|
||||
|
||||
When MySQL is running in ANSI-compatibility mode, there are some major
|
||||
differences in how :term:`SQL` is structured (see
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_ansi>). Most important of all, the
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html>). Most important of all, the
|
||||
quote-character (") is interpreted as an identifier quote character and not as
|
||||
a string quote character, which makes many internal phpMyAdmin operations into
|
||||
invalid :term:`SQL` statements. There is no
|
||||
workaround to this behaviour. News to this item will be posted in `Bug report
|
||||
#1013 <https://sourceforge.net/p/phpmyadmin/bugs/1013/>`_.
|
||||
workaround to this behaviour. News to this item will be posted in `issue
|
||||
#7383 <https://github.com/phpmyadmin/phpmyadmin/issues/7383>`_.
|
||||
|
||||
.. _faq3_10:
|
||||
|
||||
3.10 Homonyms and no primary key: When the results of a SELECT display more that one column with the same value (for example ``SELECT lastname from employees where firstname like 'A%'`` and two "Smith" values are displayed), if I click Edit I cannot be sure that I am editing the intended row.
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Please make sure that your table has a primary key, so that phpMyAdmin
|
||||
Please make sure that your table has a :term:`primary key`, so that phpMyAdmin
|
||||
can use it for the Edit and Delete links.
|
||||
|
||||
.. _faq3_11:
|
||||
@ -959,6 +1013,8 @@ However, one can easily replace the approximate row count with exact count by
|
||||
simply clicking on the approximate count. This can also be done for all tables
|
||||
at once by clicking on the rows sum displayed at the bottom.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['MaxExactCount']`
|
||||
|
||||
.. _faq3_12:
|
||||
|
||||
3.12 (withdrawn).
|
||||
@ -1026,6 +1082,20 @@ accordingly. This is done for the sake of efficiency.
|
||||
At some point, the character set used to store bookmark content has changed.
|
||||
It's better to recreate your bookmark from the newer phpMyAdmin version.
|
||||
|
||||
.. _faq3_21:
|
||||
|
||||
3.21 I am unable to log in with a username containing unicode characters such as á.
|
||||
-----------------------------------------------------------------------------------
|
||||
|
||||
This can happen if MySQL server is not configured to use utf-8 as default
|
||||
charset. This is a limitation of how PHP and the MySQL server interact; there
|
||||
is no way for PHP to set the charset before authenticating.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`phpMyAdmin issue 12232 <https://github.com/phpmyadmin/phpmyadmin/issues/12232>`_,
|
||||
`MySQL documentation note <https://secure.php.net/manual/en/mysqli.real-connect.php#refsect1-mysqli.real-connect-notes>`_
|
||||
|
||||
.. _faqmultiuser:
|
||||
|
||||
ISPs, multi-user installations
|
||||
@ -1176,12 +1246,12 @@ Xitami server.
|
||||
5.3 I have problems dumping tables with Konqueror (phpMyAdmin 2.2.2).
|
||||
---------------------------------------------------------------------
|
||||
|
||||
With Konqueror 2.1.1: plain dumps, zip and GZip dumps work ok, except
|
||||
With Konqueror 2.1.1: plain dumps, zip and gzip dumps work ok, except
|
||||
that the proposed file name for the dump is always 'tbl\_dump.php'.
|
||||
Bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps
|
||||
The bzip2 dumps don't seem to work. With Konqueror 2.2.1: plain dumps
|
||||
work; zip dumps are placed into the user's temporary directory, so
|
||||
they must be moved before closing Konqueror, or else they disappear.
|
||||
GZip dumps give an error message. Testing needs to be done for
|
||||
gzip dumps give an error message. Testing needs to be done for
|
||||
Konqueror 2.2.2.
|
||||
|
||||
.. _faq5_4:
|
||||
@ -1194,21 +1264,14 @@ till version 6.
|
||||
|
||||
.. _faq5_5:
|
||||
|
||||
5.5 In Internet Explorer 5.0, I get JavaScript errors when browsing my rows.
|
||||
5.5 (withdrawn).
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Upgrade to at least Internet Explorer 5.5 SP2.
|
||||
|
||||
.. _faq5_6:
|
||||
|
||||
5.6 In Internet Explorer 5.0, 5.5 or 6.0, I get an error (like "Page not found") when trying to modify a row in a table with many columns, or with a text column.
|
||||
5.6 (withdrawn).
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Your table neither have a primary key nor an unique one, so we must use a long
|
||||
:term:`URL` to identify this row. There is a limit on the length of the
|
||||
:term:`URL` in those browsers, and this not happen in Netscape, for example.
|
||||
The workaround is to create a primary or unique key, or use another browser.
|
||||
|
||||
.. _faq5_7:
|
||||
|
||||
5.7 I refresh (reload) my browser, and come back to the welcome page.
|
||||
@ -1235,13 +1298,9 @@ This is a Mozilla bug (see bug #26882 at `BugZilla
|
||||
|
||||
.. _faq5_10:
|
||||
|
||||
5.10 With Netscape 4.75 I get empty rows between each row of data in a CSV exported file.
|
||||
5.10 (withdrawn).
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
This is a known Netscape 4.75 bug: it adds some line feeds when
|
||||
exporting data in octet-stream mode. Since we can't detect the
|
||||
specific Netscape version, we cannot workaround this bug.
|
||||
|
||||
.. _faq5_11:
|
||||
|
||||
5.11 Extended-ASCII characters like German umlauts are displayed wrong.
|
||||
@ -1262,26 +1321,19 @@ Netscape and Mozilla do not have this problem.
|
||||
|
||||
.. _faq5_13:
|
||||
|
||||
5.13 With Internet Explorer 5.5 or 6, and HTTP authentication type, I cannot manage two servers: I log in to the first one, then the other one, but if I switch back to the first, I have to log in on each operation.
|
||||
5.13 (withdrawn)
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
This is a bug in Internet Explorer, other browsers do not behave this
|
||||
way.
|
||||
|
||||
.. _faq5_14:
|
||||
|
||||
5.14 Using Opera6, I can manage to get to the authentication, but nothing happens after that, only a blank screen.
|
||||
5.14 (withdrawn)
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Please upgrade to Opera7 at least.
|
||||
|
||||
.. _faq5_15:
|
||||
|
||||
5.15 I have display problems with Safari.
|
||||
5.15 (withdrawn)
|
||||
-----------------------------------------
|
||||
|
||||
Please upgrade to at least version 1.2.3.
|
||||
|
||||
.. _faq5_16:
|
||||
|
||||
5.16 With Internet Explorer, I get "Access is denied" Javascript errors. Or I cannot make phpMyAdmin work under Windows.
|
||||
@ -1308,14 +1360,9 @@ installed in their Firefox is causing the problem.
|
||||
|
||||
.. _faq5_18:
|
||||
|
||||
5.18 With Konqueror 4.2.x an invalid ``LIMIT`` clause is generated when I browse a table.
|
||||
5.18 (withdrawn)
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
This happens only when both of these conditions are met: using the
|
||||
``http`` authentication mode and ``register_globals`` being set to
|
||||
``On`` on the server. It seems to be a browser-specific problem;
|
||||
meanwhile use the ``cookie`` authentication mode.
|
||||
|
||||
.. _faq5_19:
|
||||
|
||||
5.19 I get JavaScript errors in my browser.
|
||||
@ -1325,6 +1372,55 @@ Issues have been reported with some combinations of browser
|
||||
extensions. To troubleshoot, disable all extensions then clear your
|
||||
browser cache to see if the problem goes away.
|
||||
|
||||
.. _faq5_20:
|
||||
|
||||
5.20 I get errors about violating Content Security Policy.
|
||||
----------------------------------------------------------
|
||||
|
||||
If you see errors like:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Refused to apply inline style because it violates the following Content Security Policy directive
|
||||
|
||||
This is usually caused by some software, which wrongly rewrites
|
||||
:mailheader:`Content Security Policy` headers. Usually this is caused by
|
||||
antivirus proxy or browser addons which are causing such errors.
|
||||
|
||||
If you see these errors, try disabling the HTTP proxy in antivirus or disable
|
||||
the :mailheader:`Content Security Policy` rewriting in it. If that doesn't
|
||||
help, try disabling browser extensions.
|
||||
|
||||
Alternatively it can be also server configuration issue (if the webserver is
|
||||
configured to emit :mailheader:`Content Security Policy` headers, they can
|
||||
override the ones from phpMyAdmin).
|
||||
|
||||
Programs known to cause these kind of errors:
|
||||
|
||||
* Kaspersky Internet Security
|
||||
|
||||
.. _faq5_21:
|
||||
|
||||
5.21 I get errors about potentially unsafe operation when browsing table or executing SQL query.
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
If you see errors like:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
A potentially unsafe operation has been detected in your request to this site.
|
||||
|
||||
This is usually caused by web application firewall doing requests filtering. It
|
||||
tries to prevent SQL injection, however phpMyAdmin is tool designed to execute
|
||||
SQL queries, thus it makes it unusable.
|
||||
|
||||
Please whitelist phpMyAdmin scripts from the web application firewall settings
|
||||
or disable it completely for phpMyAdmin path.
|
||||
|
||||
Programs known to cause these kind of errors:
|
||||
|
||||
* Wordfence Web Application Firewall
|
||||
|
||||
.. _faqusing:
|
||||
|
||||
Using phpMyAdmin
|
||||
@ -1509,13 +1605,17 @@ schema layout. Which tables will go on which pages?
|
||||
Browsers on other operating systems, and other browsers on Windows, do
|
||||
not have this problem.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`relations`
|
||||
|
||||
.. _faq6_9:
|
||||
|
||||
6.9 phpMyAdmin is changing the type of one of my columns!
|
||||
---------------------------------------------------------
|
||||
|
||||
No, it's MySQL that is doing `silent column type changing
|
||||
<https://dev.mysql.com/doc/en/silent-column-changes.html>`_.
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/silent-column-changes.html>`_.
|
||||
|
||||
.. _underscore:
|
||||
|
||||
@ -1543,7 +1643,7 @@ It means "average".
|
||||
**Structure:**
|
||||
|
||||
* "Add DROP TABLE" will add a line telling MySQL to `drop the table
|
||||
<https://dev.mysql.com/doc/mysql/en/drop-table.html>`_, if it already
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/drop-table.html>`_, if it already
|
||||
exists during the import. It does NOT drop the table after your
|
||||
export, it only affects the import file.
|
||||
* "If Not Exists" will only create the table if it doesn't exist.
|
||||
@ -1564,10 +1664,10 @@ It means "average".
|
||||
* "Extended inserts" provides a shorter dump file by using only once the
|
||||
INSERT verb and the table name.
|
||||
* "Delayed inserts" are best explained in the `MySQL manual - INSERT DELAYED Syntax
|
||||
<https://dev.mysql.com/doc/mysql/en/insert-delayed.html>`_.
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/insert-delayed.html>`_.
|
||||
* "Ignore inserts" treats errors as a warning instead. Again, more info
|
||||
is provided in the `MySQL manual - INSERT Syntax
|
||||
<https://dev.mysql.com/doc/mysql/en/insert.html>`_, but basically with
|
||||
<https://dev.mysql.com/doc/refman/5.7/en/insert.html>`_, but basically with
|
||||
this selected, invalid values are adjusted and inserted rather than
|
||||
causing the entire statement to fail.
|
||||
|
||||
@ -1608,10 +1708,10 @@ etc.).
|
||||
|
||||
.. _faq6_17:
|
||||
|
||||
6.17 Transformations: I can't enter my own mimetype! WTF is this feature then useful for?
|
||||
-----------------------------------------------------------------------------------------
|
||||
6.17 Transformations: I can't enter my own mimetype! What is this feature then useful for?
|
||||
------------------------------------------------------------------------------------------
|
||||
|
||||
Slow down :). Defining mimetypes is of no use, if you can't put
|
||||
Defining mimetypes is of no use if you can't put
|
||||
transformations on them. Otherwise you could just put a comment on the
|
||||
column. Because entering your own mimetype will cause serious syntax
|
||||
checking issues and validation, this introduces a high-risk false-
|
||||
@ -1626,57 +1726,10 @@ mimetypes by heart so he/she can enter it at will?
|
||||
6.18 Bookmarks: Where can I store bookmarks? Why can't I see any bookmarks below the query box? What are these variables for?
|
||||
-----------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Any query you have executed can be stored as a bookmark on the page
|
||||
where the results are displayed. You will find a button labeled
|
||||
'Bookmark this query' just at the end of the page. As soon as you have
|
||||
stored a bookmark, it is related to the database you run the query on.
|
||||
You can now access a bookmark dropdown on each page, the query box
|
||||
appears on for that database.
|
||||
You need to have configured the :ref:`linked-tables` for using bookmarks
|
||||
feature. Once you have done that, you can use bookmarks in the :guilabel:`SQL` tab.
|
||||
|
||||
You can also have, inside the query, placeholders for variables.
|
||||
This is done by inserting into the query SQL comments between ``/*`` and
|
||||
``*/``. Inside the comments, the special strings ``[VARIABLE{variable-number}]`` is used.
|
||||
Be aware that the whole query minus the SQL comments must be
|
||||
valid by itself, otherwise you won't be able to store it as a bookmark.
|
||||
|
||||
When you execute the bookmark, everything typed into the *Variables*
|
||||
input boxes on the query box page will replace the strings ``/*[VARIABLE{variable-number}]*/`` in
|
||||
your stored query.
|
||||
|
||||
Also remember, that everything else inside the ``/*[VARIABLE{variable-number}]*/`` string for
|
||||
your query will remain the way it is, but will be stripped of the ``/**/``
|
||||
chars. So you can use:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
/*, [VARIABLE1] AS myname */
|
||||
|
||||
which will be expanded to
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
, VARIABLE1 as myname
|
||||
|
||||
in your query, where VARIABLE1 is the string you entered in the Variable 1 input box.
|
||||
|
||||
A more complex example. Say you have stored
|
||||
this query:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT Name, Address FROM addresses WHERE 1 /* AND Name LIKE '%[VARIABLE1]%' */
|
||||
|
||||
Say, you now enter "phpMyAdmin" as the variable for the stored query, the full
|
||||
query will be:
|
||||
|
||||
.. code-block:: mysql
|
||||
|
||||
SELECT Name, Address FROM addresses WHERE 1 AND Name LIKE '%phpMyAdmin%'
|
||||
|
||||
**NOTE THE ABSENCE OF SPACES** inside the ``/**/`` construct. Any spaces
|
||||
inserted there will be later also inserted as spaces in your query and may lead
|
||||
to unexpected results especially when using the variable expansion inside of a
|
||||
"LIKE ''" expression.
|
||||
.. seealso:: :ref:`bookmarks`
|
||||
|
||||
.. _faq6_19:
|
||||
|
||||
@ -1706,7 +1759,7 @@ DATABASES, LOCK TABLES. Those privileges also enable users to see all the
|
||||
database names. So if your users do not need those privileges, you can remove
|
||||
them and their databases list will shorten.
|
||||
|
||||
.. seealso:: <https://bugs.mysql.com/179>
|
||||
.. seealso:: <https://bugs.mysql.com/bug.php?id=179>
|
||||
|
||||
.. _faq6_21:
|
||||
|
||||
@ -1733,6 +1786,8 @@ limit of 100, see :config:option:`$cfg['ForeignKeyMaxLimit']`.
|
||||
Yes. If a bookmark has the same label as a table name and it's not a
|
||||
public bookmark, it will be executed.
|
||||
|
||||
.. seealso:: :ref:`bookmarks`
|
||||
|
||||
.. _faq6_23:
|
||||
|
||||
6.23 Export: I heard phpMyAdmin can export Microsoft Excel files?
|
||||
@ -1773,7 +1828,7 @@ in Browse mode or on the Structure page.
|
||||
-----------------------------------
|
||||
|
||||
In all places where phpMyAdmin accepts format strings, you can use
|
||||
``@VARIABLE@`` expansion and `strftime <https://php.net/strftime>`_
|
||||
``@VARIABLE@`` expansion and `strftime <https://secure.php.net/strftime>`_
|
||||
format strings. The expanded variables depend on a context (for
|
||||
example, if you haven't chosen a table, you can not get the table
|
||||
name), but the following variables can be used:
|
||||
@ -1829,8 +1884,7 @@ other.
|
||||
Not every table can be put to the chart. Only tables with one, two or
|
||||
three columns can be visualised as a chart. Moreover the table must be
|
||||
in a special format for chart script to understand it. Currently
|
||||
supported formats can be found in the `wiki <https://wiki.phpmyadmin.ne
|
||||
t/pma/Charts#Data_formats_for_query_results_chart>`_.
|
||||
supported formats can be found in :ref:`charts`.
|
||||
|
||||
.. _faq6_30:
|
||||
|
||||
@ -1849,7 +1903,7 @@ methods:
|
||||
Configure upload directory with :config:option:`$cfg['UploadDir']`, upload both .shp and .dbf files with
|
||||
the same filename and chose the .shp file from the import page.
|
||||
|
||||
Create a Zip archive with .shp and .dbf files and import it. For this
|
||||
Create a zip archive with .shp and .dbf files and import it. For this
|
||||
to work, you need to set :config:option:`$cfg['TempDir']` to a place where the web server user can
|
||||
write (for example ``'./tmp'``).
|
||||
|
||||
@ -1966,7 +2020,7 @@ Note: The Range search feature will work only `Numeric` and `Date` data type col
|
||||
|
||||
.. _faq6_36:
|
||||
|
||||
6.36 What is Central columns and How can I use this feature?
|
||||
6.36 What is Central columns and how can I use this feature?
|
||||
------------------------------------------------------------
|
||||
|
||||
As the name suggests, the Central columns feature enables to maintain a central list of
|
||||
@ -2018,8 +2072,8 @@ Third Normal Form.
|
||||
`ownerEmail` varchar(64) NOT NULL,
|
||||
);
|
||||
|
||||
The above table is not in First normal Form as no primary key exists. Primary key
|
||||
is supposed to be (`petName`,`ownerLastName`,`ownerFirstName`) . If the primary key
|
||||
The above table is not in First normal Form as no :term:`primary key` exists. Primary key
|
||||
is supposed to be (`petName`,`ownerLastName`,`ownerFirstName`) . If the :term:`primary key`
|
||||
is chosen as suggested the resultant table won't be in Second as well as Third Normal
|
||||
form as the following dependencies exists.
|
||||
|
||||
@ -2046,7 +2100,7 @@ involve a manual verification at one point.
|
||||
|
||||
* Ensure that you have exclusive access to the table to rearrange
|
||||
|
||||
* On your primary key column (i.e. id), remove the AUTO_INCREMENT setting
|
||||
* On your :term:`primary key` column (i.e. id), remove the AUTO_INCREMENT setting
|
||||
|
||||
* Delete your primary key in Structure > indexes
|
||||
|
||||
@ -2113,7 +2167,7 @@ Values entered in these field will be substituted in the query before being exec
|
||||
If you get errors like *#1031 - Table storage engine for 'table_name' doesn't have this option*
|
||||
while importing the dumps exported from pre-5.7.7 MySQL servers into new MySQL server versions 5.7.7+,
|
||||
it might be because ROW_FORMAT=FIXED is not supported with InnoDB tables. Moreover, the value of
|
||||
`innodb_strict_mode <http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_strict_mode>`_ would define if this would be reported as a warning or as an error.
|
||||
`innodb_strict_mode <https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_strict_mode>`_ would define if this would be reported as a warning or as an error.
|
||||
|
||||
Since MySQL version 5.7.9, the default value for `innodb_strict_mode` is `ON` and thus would generate
|
||||
an error when such a CREATE TABLE or ALTER TABLE statement is encountered.
|
||||
@ -2141,6 +2195,8 @@ phpMyAdmin project
|
||||
---------------------------------------------------
|
||||
|
||||
Our issues tracker is located at <https://github.com/phpmyadmin/phpmyadmin/issues>.
|
||||
For security issues, please refer to the instructions at <https://www.phpmyadmin.net/security> to email
|
||||
the developers directly.
|
||||
|
||||
.. _faq7_2:
|
||||
|
||||
@ -2211,6 +2267,22 @@ attempts.
|
||||
|
||||
This is a server configuration problem. Never enable ``display_errors`` on a production site.
|
||||
|
||||
.. _faq8_4:
|
||||
|
||||
8.4 CSV files exported from phpMyAdmin could allow a formula injection attack.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
It is possible to generate a :term:`CSV` file that, when imported to a spreadsheet program such as Microsoft Excel,
|
||||
could potentially allow the execution of arbitrary commands.
|
||||
|
||||
The CSV files generated by phpMyAdmin could potentially contain text that would be interpreted by a spreadsheet program as
|
||||
a formula, but we do not believe escaping those fields is the proper behavior. There is no means to properly escape and
|
||||
differentiate between a desired text output and a formula that should be escaped, and CSV is a text format where function
|
||||
definitions should not be interpreted anyway. We have discussed this at length and feel it is the responsibility of the
|
||||
spreadsheet program to properly parse and sanitize such data on input instead.
|
||||
|
||||
Google also has a `similar view <https://sites.google.com/site/bughunteruniversity/nonvuln/csv-excel-formula-injection>`_.
|
||||
|
||||
.. _faqsynchronization:
|
||||
|
||||
Synchronization
|
||||
|
||||
153
doc/glossary.rst
@ -10,7 +10,7 @@ From Wikipedia, the free encyclopedia
|
||||
.htaccess
|
||||
the default name of Apache's directory-level configuration file.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/.htaccess>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/.htaccess>
|
||||
|
||||
ACL
|
||||
Access Contol List
|
||||
@ -18,7 +18,7 @@ From Wikipedia, the free encyclopedia
|
||||
Blowfish
|
||||
a keyed, symmetric block cipher, designed in 1993 by Bruce Schneier.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Blowfish_(cipher)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Blowfish_(cipher)>
|
||||
|
||||
Browser
|
||||
a software application that enables a user to display and interact with text, images, and other information typically located on a web page at a website on the World Wide Web.
|
||||
@ -28,39 +28,39 @@ From Wikipedia, the free encyclopedia
|
||||
bzip2
|
||||
a free software/open source data compression algorithm and program developed by Julian Seward.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Bzip2>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Bzip2>
|
||||
|
||||
CGI
|
||||
Common Gateway Interface is an important World Wide Web technology that
|
||||
enables a client web browser to request data from a program executed on
|
||||
the Web server.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/CGI>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/CGI>
|
||||
|
||||
Changelog
|
||||
a log or record of changes made to a project.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Changelog>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Changelog>
|
||||
|
||||
Client
|
||||
a computer system that accesses a (remote) service on another computer by some kind of network.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Client_(computing)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Client_(computing)>
|
||||
|
||||
column
|
||||
a set of data values of a particular simple type, one for each row of the table.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Column_(database)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Column_(database)>
|
||||
|
||||
Cookie
|
||||
a packet of information sent by a server to a World Wide Web browser and then sent back by the browser each time it accesses that server.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/HTTP_cookie>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/HTTP_cookie>
|
||||
|
||||
CSV
|
||||
Comma- separated values
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Comma-separated_values>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Comma-separated_values>
|
||||
|
||||
DB
|
||||
look at :term:`database`
|
||||
@ -68,7 +68,7 @@ From Wikipedia, the free encyclopedia
|
||||
database
|
||||
an organized collection of data.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Database>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Database>
|
||||
|
||||
Engine
|
||||
look at :term:`storage engines`
|
||||
@ -76,25 +76,25 @@ From Wikipedia, the free encyclopedia
|
||||
extension
|
||||
a PHP module that extends PHP with additional functionality.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/extension>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Software_extension>
|
||||
|
||||
FAQ
|
||||
Frequently Asked Questions is a list of commonly asked question and there
|
||||
answers.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/FAQ>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/FAQ>
|
||||
|
||||
Field
|
||||
one part of divided data/columns.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Field_(computer_science)>
|
||||
.. seealso:: <https://en.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:: <https://www.wikipedia.org/wiki/Foreign_key>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Foreign_key>
|
||||
|
||||
FPDF
|
||||
the free :term:`PDF` library
|
||||
@ -104,7 +104,7 @@ From Wikipedia, the free encyclopedia
|
||||
GD
|
||||
Graphics Library by Thomas Boutell and others for dynamically manipulating images.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/GD_Graphics_Library>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/GD_Graphics_Library>
|
||||
|
||||
GD2
|
||||
look at :term:`gd`
|
||||
@ -112,28 +112,28 @@ From Wikipedia, the free encyclopedia
|
||||
gzip
|
||||
gzip is short for GNU zip, a GNU free software file compression program.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Gzip>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Gzip>
|
||||
|
||||
host
|
||||
any machine connected to a computer network, a node that has a hostname.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Host>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Host>
|
||||
|
||||
hostname
|
||||
the unique name by which a network attached device is known on a network.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Hostname>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Hostname>
|
||||
|
||||
HTTP
|
||||
HyperText Transfer Protocol is the primary method used to transfer or
|
||||
convey information on the World Wide Web.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/HyperText_Transfer_Protocol>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/HyperText_Transfer_Protocol>
|
||||
|
||||
https
|
||||
a :term:`HTTP`-connection with additional security measures.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Https:_URI_scheme>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Https:_URI_scheme>
|
||||
|
||||
IEC
|
||||
International Electrotechnical Commission
|
||||
@ -142,42 +142,42 @@ From Wikipedia, the free encyclopedia
|
||||
Internet Information Services is a set of Internet-based services for
|
||||
servers using Microsoft Windows.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Internet_Information_Services>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Information_Services>
|
||||
|
||||
Index
|
||||
a feature that allows quick access to the rows in a table.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Index_(database)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Index_(database)>
|
||||
|
||||
IP
|
||||
Internet Protocol is a data-oriented protocol used by source and
|
||||
destination hosts for communicating data across a packet-switched
|
||||
internetwork.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Internet_Protocol>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Internet_Protocol>
|
||||
|
||||
IP Address
|
||||
a unique number that devices use in order to identify and communicate with each other on a network utilizing the Internet Protocol standard.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/IP_Address>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/IP_Address>
|
||||
|
||||
IPv6
|
||||
IPv6 (Internet Protocol version 6) is the latest revision of the
|
||||
Internet Protocol (:term:`IP`), designed to deal with the
|
||||
long-anticipated problem of its precedessor IPv4 running out of addresses.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/IPv6>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/IPv6>
|
||||
|
||||
ISAPI
|
||||
Internet Server Application Programming Interface is the API of Internet Information Services (IIS).
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/ISAPI>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/ISAPI>
|
||||
|
||||
ISP
|
||||
Internet service provider is a business or organization that offers users
|
||||
access to the Internet and related services.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/ISP>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/ISP>
|
||||
|
||||
ISO
|
||||
International Standards Organisation
|
||||
@ -185,7 +185,7 @@ From Wikipedia, the free encyclopedia
|
||||
JPEG
|
||||
a most commonly used standard method of lossy compression for photographic images.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/JPEG>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/JPEG>
|
||||
|
||||
JPG
|
||||
look at :term:`jpeg`
|
||||
@ -196,38 +196,45 @@ From Wikipedia, the free encyclopedia
|
||||
LATEX
|
||||
a document preparation system for the TEX typesetting program.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/LaTeX>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/LaTeX>
|
||||
|
||||
Mac
|
||||
Apple Macintosh is line of personal computers is designed, developed, manufactured, and marketed by Apple Computer.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Mac>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Mac>
|
||||
|
||||
Mac OS X
|
||||
the operating system which is included with all currently shipping Apple Macintosh computers in the consumer and professional markets.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Mac_OS_X>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Mac_OS_X>
|
||||
|
||||
mbstring
|
||||
The PHP `mbstring` functions provide support for languages represented by multi-byte character sets, most notably UTF-8.
|
||||
|
||||
If you have troubles installing this extension, please follow :ref:`faqmysql`, it provides useful hints.
|
||||
|
||||
.. seealso:: <https://secure.php.net/manual/en/book.mbstring.php>
|
||||
|
||||
MCrypt
|
||||
a cryptographic library.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/MCrypt>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/MCrypt>
|
||||
|
||||
mcrypt
|
||||
the MCrypt PHP extension.
|
||||
|
||||
.. seealso:: <https://php.net/mcrypt>
|
||||
.. seealso:: <https://secure.php.net/mcrypt>
|
||||
|
||||
MIME
|
||||
Multipurpose Internet Mail Extensions is
|
||||
an Internet Standard for the format of e-mail.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/MIME>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/MIME>
|
||||
|
||||
module
|
||||
some sort of extension for the Apache Webserver.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/module>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Apache_HTTP_Server>
|
||||
|
||||
mod_proxy_fcgi
|
||||
an Apache module implmenting a Fast CGI interface; PHP can be run as a CGI module, FastCGI, or
|
||||
@ -236,34 +243,34 @@ From Wikipedia, the free encyclopedia
|
||||
MySQL
|
||||
a multithreaded, multi-user, SQL (Structured Query Language) Database Management System (DBMS).
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/MySQL>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/MySQL>
|
||||
|
||||
mysqli
|
||||
the improved MySQL client PHP extension.
|
||||
|
||||
.. seealso:: <https://php.net/mysqli>
|
||||
.. seealso:: <https://secure.php.net/manual/en/book.mysqli.php>
|
||||
|
||||
mysql
|
||||
the MySQL client PHP extension.
|
||||
|
||||
.. seealso:: <https://php.net/mysql>
|
||||
.. seealso:: <https://secure.php.net/manual/en/book.mysql.php>
|
||||
|
||||
OpenDocument
|
||||
open standard for office documents.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/OpenDocument>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/OpenDocument>
|
||||
|
||||
OS X
|
||||
look at :term:`Mac OS X`.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/OS_X>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/OS_X>
|
||||
|
||||
PDF
|
||||
Portable Document Format is a file format developed by Adobe Systems for
|
||||
representing two dimensional documents in a device independent and
|
||||
resolution independent format.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Portable_Document_Format>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Portable_Document_Format>
|
||||
|
||||
PEAR
|
||||
the PHP Extension and Application Repository.
|
||||
@ -274,7 +281,7 @@ From Wikipedia, the free encyclopedia
|
||||
Perl Compatible Regular Expressions is the perl-compatible regular
|
||||
expression functions for PHP
|
||||
|
||||
.. seealso:: <https://php.net/pcre>
|
||||
.. seealso:: <https://secure.php.net/pcre>
|
||||
|
||||
PHP
|
||||
short for "PHP: Hypertext Preprocessor", is an open-source, reflective
|
||||
@ -282,19 +289,36 @@ From Wikipedia, the free encyclopedia
|
||||
and dynamic web content, and more recently, a broader range of software
|
||||
applications.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/PHP>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/PHP>
|
||||
|
||||
port
|
||||
a connection through which data is sent and received.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Port_(computing)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Port_(computing)>
|
||||
|
||||
primary key
|
||||
A primary key is an index over one or more fields in a table with
|
||||
unique values for each single row in this table. Every table should have
|
||||
a primary key for easier accessing/identifying data in this table. There
|
||||
can only be one primary key per table and it is named always **PRIMARY**.
|
||||
In fact a primary key is just an :term:`unique key` with the name
|
||||
**PRIMARY**. If no primary key is defined MySQL will use first *unique
|
||||
key* as primary key if there is one.
|
||||
|
||||
You can create the primary key when creating the table (in phpMyAdmin
|
||||
just check the primary key radio buttons for each field you wish to be
|
||||
part of the primary key).
|
||||
|
||||
You can also add a primary key to an existing table with `ALTER` `TABLE`
|
||||
or `CREATE` `INDEX` (in phpMyAdmin you can just click on 'add index' on
|
||||
the table structure page below the listed fields).
|
||||
|
||||
RFC
|
||||
Request for Comments (RFC) documents are a series of memoranda
|
||||
encompassing new research, innovations, and methodologies applicable to
|
||||
Internet technologies.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Request_for_Comments>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Request_for_Comments>
|
||||
|
||||
RFC 1952
|
||||
GZIP file format specification version 4.3
|
||||
@ -304,17 +328,23 @@ From Wikipedia, the free encyclopedia
|
||||
Row (record, tuple)
|
||||
represents a single, implicitly structured data item in a table.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Row_(database)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Row_(database)>
|
||||
|
||||
Server
|
||||
a computer system that provides services to other computing systems over a network.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Server_(computing)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Server_(computing)>
|
||||
|
||||
Storage Engines
|
||||
handlers for different table types
|
||||
MySQL can use several different formats for storing data on disk, these
|
||||
are called storage engines or table types. phpMyAdmin allows a user to
|
||||
change their storage engine for a particular table through the operations
|
||||
tab.
|
||||
|
||||
.. seealso:: <https://dev.mysql.com/doc/en/storage-engines.html>
|
||||
Common table types are InnoDB and MyISAM, though many others exist and
|
||||
may be desirable in some situations.
|
||||
|
||||
.. seealso:: <https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html>
|
||||
|
||||
socket
|
||||
a form of inter-process communication.
|
||||
@ -325,7 +355,7 @@ From Wikipedia, the free encyclopedia
|
||||
Secure Sockets Layer is a cryptographic protocol which provides secure
|
||||
communication on the Internet.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Secure_Sockets_Layer>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Secure_Sockets_Layer>
|
||||
|
||||
Stored procedure
|
||||
a subroutine available to applications accessing a relational database system
|
||||
@ -335,7 +365,7 @@ From Wikipedia, the free encyclopedia
|
||||
SQL
|
||||
Structured Query Language
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/SQL>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/SQL>
|
||||
|
||||
table
|
||||
a set of data elements (cells) that is organized, defined and stored as
|
||||
@ -343,18 +373,18 @@ From Wikipedia, the free encyclopedia
|
||||
identified by a label or key or by it?s position in relation to other
|
||||
items.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Table_(database)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Table_(database)>
|
||||
|
||||
tar
|
||||
a type of archive file format: the Tape ARchive format.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Tar_(file_format)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Tar_(file_format)>
|
||||
|
||||
TCP
|
||||
Transmission Control Protocol is one of the core protocols of the
|
||||
Internet protocol suite.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/TCP>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/TCP>
|
||||
|
||||
TCPDF
|
||||
Rewrite of :term:`UFPDF` with various improvements.
|
||||
@ -366,6 +396,11 @@ From Wikipedia, the free encyclopedia
|
||||
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Database_trigger>
|
||||
|
||||
unique key
|
||||
An unique key is an index over one or more fields in a table which has a
|
||||
unique value for each row. The first unique key will be treated as
|
||||
:term:`primary key` if there is no *primary key* defined.
|
||||
|
||||
UFPDF
|
||||
Unicode/UTF-8 extension for :term:`FPDF`
|
||||
|
||||
@ -376,28 +411,28 @@ From Wikipedia, the free encyclopedia
|
||||
standardized format, that is used for referring to resources, such as
|
||||
documents and images on the Internet, by their location.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/URL>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/URL>
|
||||
|
||||
Webserver
|
||||
A computer (program) that is responsible for accepting HTTP requests from clients and serving them Web pages.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Webserver>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Webserver>
|
||||
|
||||
XML
|
||||
Extensible Markup Language is a W3C-recommended general- purpose markup
|
||||
language for creating special-purpose markup languages, capable of
|
||||
describing many different kinds of data.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/XML>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/XML>
|
||||
|
||||
ZIP
|
||||
a popular data compression and archival format.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/ZIP_(file_format)>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/ZIP_(file_format)>
|
||||
|
||||
zlib
|
||||
an open-source, cross- platform data compression library by Jean-loup Gailly and Mark Adler.
|
||||
|
||||
.. seealso:: <https://www.wikipedia.org/wiki/Zlib>
|
||||
.. seealso:: <https://en.wikipedia.org/wiki/Zlib>
|
||||
|
||||
|
||||
|
||||
BIN
doc/images/bar_chart.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
doc/images/chart.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
doc/images/column_chart.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/images/display_chart.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
doc/images/line_chart.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
doc/images/pie_chart.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/images/pma-relations-category.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
doc/images/pma-relations-links.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
doc/images/pma-relations-relation-link.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
doc/images/pma-relations-relation-name.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/pma-relations-relation-view-link.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
doc/images/query_result_operations.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
doc/images/scatter_chart.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
doc/images/spline_chart.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
doc/images/timeline_chart.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@ -1,11 +1,77 @@
|
||||
Import and export
|
||||
=================
|
||||
|
||||
In addition to the standard Import and Export tab, you can also import an SQL file directly by dragging and dropping
|
||||
it from your local file manager to the phpMyAdmin interface in your web browser.
|
||||
Import
|
||||
++++++
|
||||
|
||||
Open Document Spreadsheet
|
||||
-------------------------
|
||||
To import data, go to the "Import" tab in phpMyAdmin. To import data into a
|
||||
specific database or table, open the database or table before going to the
|
||||
"Import" tab.
|
||||
|
||||
In addition to the standard Import and Export tab, you can also import an SQL
|
||||
file directly by dragging and dropping it from your local file manager to the
|
||||
phpMyAdmin interface in your web browser.
|
||||
|
||||
If you are having troubles importing big files, please consult :ref:`faq1_16`.
|
||||
|
||||
You can import using following methods:
|
||||
|
||||
Form based upload
|
||||
|
||||
Can be used with any supported format, also (b|g)zipped files, e.g., mydump.sql.gz .
|
||||
|
||||
Form based SQL Query
|
||||
|
||||
Can be used with valid SQL dumps.
|
||||
|
||||
Using upload directory
|
||||
|
||||
You can specify an upload directory on your web server where phpMyAdmin is installed, after uploading your file into this directory you can select this file in the import dialog of phpMyAdmin, see :config:option:`$cfg['UploadDir']`.
|
||||
|
||||
|
||||
phpMyAdmin can import from several various commonly used formats.
|
||||
|
||||
CSV
|
||||
---
|
||||
|
||||
Comma separated values format which is often used by spreadsheets or various other programs for export/import.
|
||||
|
||||
.. note::
|
||||
|
||||
When importing data into a table from a CSV file where the table has an
|
||||
'auto_increment' field, make the 'auto_increment' value for each record in
|
||||
the CSV field to be '0' (zero). This allows the 'auto_increment' field to
|
||||
populate correctly.
|
||||
|
||||
It is now possible to import a CSV file at the server or database level.
|
||||
Instead of having to create a table to import the CSV file into, a best-fit
|
||||
structure will be determined for you and the data imported into it, instead.
|
||||
All other features, requirements, and limitations are as before.
|
||||
|
||||
CSV using LOAD DATA
|
||||
-------------------
|
||||
|
||||
Similar to CSV, only using the internal MySQL parser and not the phpMyAdmin one.
|
||||
|
||||
ESRI Shape File
|
||||
---------------
|
||||
|
||||
The ESRI shapefile or simply a shapefile is a popular geospatial vector data
|
||||
format for geographic information systems software. It is developed and
|
||||
regulated by Esri as a (mostly) open specification for data interoperability
|
||||
among Esri and other software products.
|
||||
|
||||
MediaWiki
|
||||
---------
|
||||
|
||||
MediaWiki files, which can be exported by phpMyAdmin (version 4.0 or later),
|
||||
can now also be imported. This is the format used by Wikipedia to display
|
||||
tables.
|
||||
|
||||
Open Document Spreadsheet (ODS)
|
||||
-------------------------------
|
||||
|
||||
OpenDocument workbooks containing one or more spreadsheets can now be directly imported.
|
||||
|
||||
When importing an ODS speadsheet, the spreadsheet must be named in a specific way in order to make the
|
||||
import as simple as possible.
|
||||
@ -25,3 +91,267 @@ accomplished by inserting a new row at the top of your spreadsheet). When on the
|
||||
checkbox for "The first line of the file contains the table column names;" this way your newly imported
|
||||
data will go to the proper columns.
|
||||
|
||||
.. note::
|
||||
|
||||
Formulas and calculations will NOT be evaluated, rather, their value from
|
||||
the most recent save will be loaded. Please ensure that all values in the
|
||||
spreadsheet are as needed before importing it.
|
||||
|
||||
SQL
|
||||
---
|
||||
|
||||
SQL can be used to make any manipulation on data, it is also useful for restoring backed up data.
|
||||
|
||||
XML
|
||||
---
|
||||
|
||||
XML files exported by phpMyAdmin (version 3.3.0 or later) can now be imported.
|
||||
Structures (databases, tables, views, triggers, etc.) and/or data will be
|
||||
created depending on the contents of the file.
|
||||
|
||||
The supported xml schemas are not yet documented in this wiki.
|
||||
|
||||
|
||||
Export
|
||||
++++++
|
||||
|
||||
phpMyAdmin can export into text files (even compressed) on your local disk (or
|
||||
a special the webserver :config:option:`$cfg['SaveDir']` folder) in various
|
||||
commonly used formats:
|
||||
|
||||
CodeGen
|
||||
-------
|
||||
|
||||
`NHibernate <https://en.wikipedia.org/wiki/NHibernate>`_ file format. Planned
|
||||
versions: Java, Hibernate, PHP PDO, JSON, etc. So the preliminary name is
|
||||
codegen.
|
||||
|
||||
CSV
|
||||
---
|
||||
|
||||
Comma separated values format which is often used by spreadsheets or various
|
||||
other programs for export/import.
|
||||
|
||||
CSV for Microsoft Excel
|
||||
-----------------------
|
||||
|
||||
This is just preconfigured version of CSV export which can be imported into
|
||||
most English versions of Microsoft Excel. Some localised versions (like
|
||||
"Danish") are expecting ";" instead of "," as field separator.
|
||||
|
||||
Microsoft Word 2000
|
||||
-------------------
|
||||
|
||||
If you're using Microsoft Word 2000 or newer (or compatible such as
|
||||
OpenOffice.org), you can use this export.
|
||||
|
||||
JSON
|
||||
----
|
||||
|
||||
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It
|
||||
is easy for humans to read and write and it is easy for machines to parse and
|
||||
generate.
|
||||
|
||||
.. versionchanged:: 4.7.0
|
||||
|
||||
The generated JSON structure has been changed in phpMyAdmin 4.7.0 to
|
||||
produce valid JSON data.
|
||||
|
||||
The generated JSON is list of objects with following attributes:
|
||||
|
||||
.. js:data:: type
|
||||
|
||||
Type of given object, can be one of:
|
||||
|
||||
``header``
|
||||
Export header containing comment and phpMyAdmin version.
|
||||
``database``
|
||||
Start of a database marker, containing name of database.
|
||||
``table``
|
||||
Table data export.
|
||||
|
||||
.. js:data:: version
|
||||
|
||||
Used in ``header`` :js:data:`type` and indicates phpMyAdmin version.
|
||||
|
||||
.. js:data:: comment
|
||||
|
||||
Optional textual comment.
|
||||
|
||||
.. js:data:: name
|
||||
|
||||
Object name - either table or database based on :js:data:`type`.
|
||||
|
||||
.. js:data:: database
|
||||
|
||||
Database name for ``table`` :js:data:`type`.
|
||||
|
||||
.. js:data:: data
|
||||
|
||||
Table content for ``table`` :js:data:`type`.
|
||||
|
||||
Sample output:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
[
|
||||
{
|
||||
"comment": "Export to JSON plugin for PHPMyAdmin",
|
||||
"type": "header",
|
||||
"version": "4.7.0-dev"
|
||||
},
|
||||
{
|
||||
"name": "cars",
|
||||
"type": "database"
|
||||
},
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"car_id": "1",
|
||||
"description": "Green Chrysler 300",
|
||||
"make_id": "5",
|
||||
"mileage": "113688",
|
||||
"price": "13545.00",
|
||||
"transmission": "automatic",
|
||||
"yearmade": "2007"
|
||||
}
|
||||
],
|
||||
"database": "cars",
|
||||
"name": "cars",
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"make": "Chrysler",
|
||||
"make_id": "5"
|
||||
}
|
||||
],
|
||||
"database": "cars",
|
||||
"name": "makes",
|
||||
"type": "table"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
LaTeX
|
||||
-----
|
||||
|
||||
If you want to embed table data or structure in LaTeX, this is right choice for you.
|
||||
|
||||
LaTeX is a typesetting system that is very suitable for producing scientific
|
||||
and mathematical documents of high typographical quality. It is also suitable
|
||||
for producing all sorts of other documents, from simple letters to complete
|
||||
books. LaTeX uses TeX as its formatting engine. Learn more about TeX and
|
||||
LaTeX on `the Comprehensive TeX Archive Network <https://www.ctan.org/>`_
|
||||
also see the `short description od TeX <https://www.ctan.org/tex/>`_.
|
||||
|
||||
The output needs to be embedded into a LaTeX document before it can be
|
||||
rendered, for example in following document:
|
||||
|
||||
.. code-block:: latex
|
||||
|
||||
|
||||
\documentclass{article}
|
||||
\title{phpMyAdmin SQL output}
|
||||
\author{}
|
||||
\usepackage{longtable,lscape}
|
||||
\date{}
|
||||
\setlength{\parindent}{0pt}
|
||||
\usepackage[left=2cm,top=2cm,right=2cm,nohead,nofoot]{geometry}
|
||||
\pdfpagewidth 210mm
|
||||
\pdfpageheight 297mm
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
% insert phpMyAdmin LaTeX Dump here
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
MediaWiki
|
||||
---------
|
||||
|
||||
Both tables and databases can be exported in the MediaWiki format, which is
|
||||
used by Wikipedia to display tables. It can export structure, data or both,
|
||||
including table names or headers.
|
||||
|
||||
OpenDocument Spreadsheet
|
||||
------------------------
|
||||
|
||||
Open standard for spreadsheet data, which is being widely adopted. Many recent
|
||||
spreadsheet programs, such as LibreOffice, OpenOffice or Google Docs can handle
|
||||
this format. Additionally, some versions of Microsoft Excel can be adapted to
|
||||
use the OpenDocument Formats through helpers like
|
||||
<http://odf-converter.sourceforge.net/>.
|
||||
|
||||
OpenDocument Text
|
||||
-----------------
|
||||
|
||||
New standard for text data which is being widely addopted. Most recent word
|
||||
processors (such as OpenOffice.org, AbiWord or KWord) can handle this.
|
||||
|
||||
PDF
|
||||
---
|
||||
|
||||
For presentation purposes, non editable PDF might be best choice for you.
|
||||
|
||||
PHP Array
|
||||
---------
|
||||
|
||||
You can generate a php file which will declare a multidimensional array with
|
||||
the contents of the selected table or database.
|
||||
|
||||
SQL
|
||||
---
|
||||
|
||||
Export in SQL can be used to restore your database, thus it is useful for
|
||||
backing up.
|
||||
|
||||
The option 'Maximal length of created query' seems to be undocumented. But
|
||||
experiments has shown that it splits large extended INSERTS so each one is no
|
||||
bigger than the given number of bytes (or characters?). Thus when importing the
|
||||
file, for large tables you avoid the error "Got a packet bigger than
|
||||
'max_allowed_packet' bytes".
|
||||
|
||||
.. seealso::
|
||||
|
||||
https://dev.mysql.com/doc/refman/5.7/en/packet-too-large.html
|
||||
|
||||
Data Options
|
||||
~~~~~~~~~~~~
|
||||
|
||||
**Complete inserts** adds the column names to the SQL dump. This parameter
|
||||
improves the readability and reliability of the dump. Adding the column names
|
||||
increases the size of the dump, but when combined with Extended inserts it's
|
||||
negligible.
|
||||
|
||||
**Extended inserts** combines multiple rows of data into a single INSERT query.
|
||||
This will significantly decrease filesize for large SQL dumps, increases the
|
||||
INSERT speed when imported, and is generally recommended.
|
||||
|
||||
.. seealso::
|
||||
|
||||
http://www.scriptalicious.com/blog/2009/04/complete-inserts-or-extended-inserts-in-phpmyadmin/
|
||||
|
||||
Texy!
|
||||
-----
|
||||
|
||||
`Texy! <https://texy.info/>`_ markup format. You can see example on `Texy! demo
|
||||
<https://texy.info/en/try/4q5we>`_.
|
||||
|
||||
XML
|
||||
---
|
||||
|
||||
Easily parsable export for use with custom scripts.
|
||||
|
||||
.. versionchanged:: 3.3.0
|
||||
|
||||
The XML schema used has changed as of version 3.3.0
|
||||
|
||||
YAML
|
||||
----
|
||||
|
||||
YAML is a data serialization format which is both human readable and
|
||||
computationally powerful ( <http://www.yaml.org> ).
|
||||
|
||||
|
||||
@ -48,6 +48,21 @@ Currently phpMyAdmin can:
|
||||
<https://www.phpmyadmin.net/translations/>`_
|
||||
|
||||
|
||||
Shortcut keys
|
||||
-------------
|
||||
|
||||
Currently phpMyAdmin supports following shortcuts:
|
||||
|
||||
* k - Toggle console
|
||||
* h - Go to home page
|
||||
* s - Open settings
|
||||
* d + s - Go to database structure (Provided you are in database related page)
|
||||
* d + f - Search database (Provided you are in database related page)
|
||||
* t + s - Go to table structure (Provided you are in table related page)
|
||||
* t + f - Search table (Provided you are in table related page)
|
||||
* backspace - Takes you to older page.
|
||||
|
||||
|
||||
A word about users
|
||||
------------------
|
||||
|
||||
|
||||
@ -13,6 +13,21 @@ book and other officially endorsed `books at the phpMyAdmin site`_.
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
Third party tutorials and articles are listed on our `wiki page`_.
|
||||
Third party tutorials and articles which you might find interesting:
|
||||
|
||||
.. _wiki page: https://wiki.phpmyadmin.net/pma/Articles
|
||||
Česky (Czech)
|
||||
+++++++++++++
|
||||
|
||||
- `Seriál o phpMyAdminovi <https://cihar.com/publications/linuxsoft/>`_
|
||||
|
||||
English
|
||||
+++++++
|
||||
|
||||
- `Having fun with phpMyAdmin's MIME-transformations & PDF-features <http://garv.in/tops/texte/mimetutorial>`_
|
||||
- `Learning SQL Using phpMyAdmin (old tutorial) <http://www.php-editors.com/articles/sql_phpmyadmin.php>`_
|
||||
- `Install and configure phpMyAdmin on IIS <http://www.iis-aid.com/articles/how_to_guides/install_and_configure_phpmyadmin_iis>`_
|
||||
|
||||
Русский (Russian)
|
||||
+++++++++++++++++
|
||||
|
||||
* `Russian server about phpMyAdmin <http://php-myadmin.ru/>`_
|
||||
|
||||
85
doc/relations.rst
Normal file
@ -0,0 +1,85 @@
|
||||
.. _relations:
|
||||
|
||||
Relations
|
||||
=========
|
||||
|
||||
phpMyAdmin allows relationships (similar to foreign keys) using MySQL-native
|
||||
(InnoDB) methods when available and falling back on special phpMyAdmin-only
|
||||
features when needed. There are two ways of editing these relations, with the
|
||||
*relation view* and the drag-and-drop *designer* -- both of which are explained
|
||||
on this page.
|
||||
|
||||
.. note::
|
||||
|
||||
You need to have configured the :ref:`linked-tables` for using phpMyAdmin
|
||||
only relations.
|
||||
|
||||
Technical info
|
||||
--------------
|
||||
|
||||
Currently the only MySQL table type that natively supports relationships is
|
||||
InnoDB. When using an InnoDB table, phpMyAdmin will create real InnoDB
|
||||
relations which will be enforced by MySQL no matter which application accesses
|
||||
the database. In the case of any other table type, phpMyAdmin enforces the
|
||||
relations internally and those relations are not applied to any other
|
||||
application.
|
||||
|
||||
Relation view
|
||||
-------------
|
||||
|
||||
In order to get it working, you first have to properly create the
|
||||
[[pmadb|pmadb]]. Once that is setup, select a table's "Structure" page. Below
|
||||
the table definition, a link called "Relation view" is shown. If you click that
|
||||
link, a page will be shown that offers you to create a link to another table
|
||||
for any (most) fields. Only PRIMARY KEYS are shown there, so if the field you
|
||||
are referring to is not shown, you most likely are doing something wrong. The
|
||||
drop-down at the bottom is the field which will be used as the name for a
|
||||
record.
|
||||
|
||||
Relation view example
|
||||
+++++++++++++++++++++
|
||||
|
||||
.. image:: images/pma-relations-relation-view-link.png
|
||||
|
||||
.. image:: images/pma-relations-relation-link.png
|
||||
|
||||
Let's say you have categories and links and one category can contain several links. Your table structure would be something like this:
|
||||
|
||||
- `category.category_id` (must be unique)
|
||||
- `category.name`
|
||||
- `link.link_id`
|
||||
- `link.category_id`
|
||||
- `link.uri`.
|
||||
|
||||
Open the relation view (below the table structure) page for the `link` table and for `category_id` field, you select `category.category_id` as master record.
|
||||
|
||||
If you now browse the link table, the `category_id` field will be a clickable hyperlink to the proper category record. But all you see is just the `category_id`, not the name of the category.
|
||||
|
||||
.. image:: images/pma-relations-relation-name.png
|
||||
|
||||
To fix this, open the relation view of the `category` table and in the drop down at the bottom, select "name". If you now browse the link table again and hover the mouse over the `category_id` hyperlink, the value from the related category will be shown as tooltip.
|
||||
|
||||
.. image:: images/pma-relations-links.png
|
||||
|
||||
|
||||
Designer
|
||||
--------
|
||||
|
||||
The Designer feature is a graphical way of creating, editing, and displaying
|
||||
phpMyAdmin relations. These relations are compatible with those created in
|
||||
phpMyAdmin's relation view.
|
||||
|
||||
To use this feature, you need a properly configured :ref:`linked-tables` and
|
||||
must have the :config:option:`$cfg['Servers'][$i]['table_coords']` configured.
|
||||
|
||||
To use the designer, select a database's structure page, then look for the
|
||||
:guilabel:`Designer` tab.
|
||||
|
||||
To export the view into PDF, you have to create PDF pages first. The Designer
|
||||
creates the layout, how the tables shall be displayed. To finally export the
|
||||
view, you have to create this with a PDF page and select your layout, which you
|
||||
have created with the designer.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`faqpdf`
|
||||
@ -13,7 +13,7 @@ PHP
|
||||
---
|
||||
|
||||
* You need PHP 5.5.0 or newer, with ``session`` support, the Standard PHP Library
|
||||
(SPL) extension, JSON support, and the ``mbstring`` extension.
|
||||
(SPL) extension, JSON support, and the ``mbstring`` extension (see :term:`mbstring`).
|
||||
|
||||
* To support uploading of ZIP files, you need the PHP ``zip`` extension.
|
||||
|
||||
@ -21,19 +21,19 @@ PHP
|
||||
("image/jpeg: inline") with their original aspect ratio.
|
||||
|
||||
* When using the cookie authentication (the default), the `openssl
|
||||
<https://www.php.net/openssl>`_ extension is strongly suggested.
|
||||
<https://secure.php.net/openssl>`_ extension is strongly suggested.
|
||||
|
||||
* To support upload progress bars, see :ref:`faq2_9`.
|
||||
|
||||
* To support XML and Open Document Spreadsheet importing, you need the
|
||||
`libxml <https://www.php.net/libxml>`_ extension.
|
||||
`libxml <https://secure.php.net/libxml>`_ extension.
|
||||
|
||||
* To support reCAPTCHA on the login page, you need the
|
||||
`openssl <https://www.php.net/openssl>`_ extension.
|
||||
`openssl <https://secure.php.net/openssl>`_ extension.
|
||||
|
||||
* To support displaying phpMyAdmin's latest version, you need to enable
|
||||
``allow_url_open`` in your :file:`php.ini` or to have the
|
||||
`curl <https://www.php.net/curl>`_ extension.
|
||||
`curl <https://secure.php.net/curl>`_ extension.
|
||||
|
||||
.. seealso:: :ref:`faq1_31`, :ref:`authentication_modes`
|
||||
|
||||
|
||||
314
doc/setup.rst
@ -23,13 +23,23 @@ phpMyAdmin is included in most Linux distributions. It is recommended to use
|
||||
distribution packages when possible - they usually provide integration to your
|
||||
distribution and you will automatically get security updates from your distribution.
|
||||
|
||||
.. _debian-package:
|
||||
|
||||
Debian
|
||||
------
|
||||
|
||||
Debian's package repositories include a phpMyAdmin package, but be aware that
|
||||
the configuration file is maintained in ``/etc/phpmyadmin`` and may differ in
|
||||
some ways from the official phpMyAdmin documentation.
|
||||
some ways from the official phpMyAdmin documentation. Specifically it does:
|
||||
|
||||
* Configuration of web server (works for Apache and lighttpd).
|
||||
* Creating of :ref:`linked-tables` using dbconfig-common.
|
||||
* Securing setup script, see :ref:`debian-setup`.
|
||||
|
||||
.. seealso::
|
||||
|
||||
More information can be found in `README.Debian <https://anonscm.debian.org/cgit/collab-maint/phpmyadmin.git/tree/debian/README.Debian>`_
|
||||
(it is installed as :file:`/usr/share/doc/phmyadmin/README.Debian` with the package).
|
||||
|
||||
OpenSUSE
|
||||
--------
|
||||
@ -42,7 +52,12 @@ Ubuntu
|
||||
|
||||
Ubuntu ships phpMyAdmin package, however if you want to use recent version, you
|
||||
can use packages from
|
||||
`PPA for Michal Čihař <https://launchpad.net/~nijel/+archive/phpmyadmin>`_.
|
||||
`phpMyAdmin PPA <https://launchpad.net/~nijel/+archive/ubuntu/phpmyadmin>`_.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The packages are same as in :ref:`debian-package` please check the documentation
|
||||
there for more details.
|
||||
|
||||
Gentoo
|
||||
------
|
||||
@ -86,13 +101,37 @@ which include phpMyAdmin together with a database and web server such as
|
||||
|
||||
You can find more of such options at `Wikipedia <https://en.wikipedia.org/wiki/List_of_AMP_packages>`_.
|
||||
|
||||
Installing from Git
|
||||
+++++++++++++++++++
|
||||
|
||||
You can clone current phpMyAdmin source from
|
||||
``https://github.com/phpmyadmin/phpmyadmin.git``:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
git clone https://github.com/phpmyadmin/phpmyadmin.git
|
||||
|
||||
Additionally you need to install dependencies using `Composer tool`_:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
composer update
|
||||
|
||||
If you do not intend to develop, you can skip installation of developer tools
|
||||
by invoking:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
composer update --no-dev
|
||||
|
||||
|
||||
.. _composer:
|
||||
|
||||
Installing using Composer
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
You can install phpMyAdmin using `Composer <https://getcomposer.org/>`_,
|
||||
however it's currently not available in the default
|
||||
`Packagist <https://packagist.org/>`_ repository due to its technical
|
||||
You can install phpMyAdmin using `Composer tool`_, however it's currently not
|
||||
available in the default `Packagist`_ repository due to its technical
|
||||
limitations.
|
||||
|
||||
The installation is possible by adding our own repository
|
||||
@ -107,7 +146,7 @@ The installation is possible by adding our own repository
|
||||
Installing using Docker
|
||||
+++++++++++++++++++++++
|
||||
|
||||
phpMyAdmin comes with a Docker image, which you can easily deploy. You can
|
||||
phpMyAdmin comes with a `Docker image`_, which you can easily deploy. You can
|
||||
download it using:
|
||||
|
||||
.. code-block:: sh
|
||||
@ -115,22 +154,49 @@ download it using:
|
||||
docker pull phpmyadmin/phpmyadmin
|
||||
|
||||
The phpMyAdmin server will be executed on port 80. It supports several ways of
|
||||
configuring the link to the database server, which you can manage using
|
||||
environment variables:
|
||||
configuring the link to the database server, either by Docker's link feature
|
||||
by linking your database container to ``db`` for phpMyAdmin (by specifying
|
||||
``--link your_db_host:db``) or by environment variables (in this case it's up
|
||||
to you to setup networking in Docker to allow phpMyAdmin container to access
|
||||
the database container over network).
|
||||
|
||||
.. _docker-vars:
|
||||
|
||||
Docker environment variables
|
||||
----------------------------
|
||||
|
||||
You can configure several phpMyAdmin features using environment variables:
|
||||
|
||||
.. envvar:: PMA_ARBITRARY
|
||||
|
||||
Allows you to enter database server hostname on login form (see
|
||||
:config:option:`$cfg['AllowArbitraryServer']`).
|
||||
Allows you to enter database server hostname on login form.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['AllowArbitraryServer']`
|
||||
|
||||
.. envvar:: PMA_HOST
|
||||
|
||||
Host name or IP address of the database server to use.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['Servers'][$i]['host']`
|
||||
|
||||
.. envvar:: PMA_HOSTS
|
||||
|
||||
Comma separated host names or IP addresses of the database servers to use.
|
||||
|
||||
.. note:: Used only if :envvar:`PMA_HOST` is empty.
|
||||
|
||||
.. envvar:: PMA_VERBOSE
|
||||
|
||||
Verbose name the database server.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['Servers'][$i]['verbose']`
|
||||
|
||||
.. envvar:: PMA_VERBOSES
|
||||
|
||||
Comma separated verbose name the database servers.
|
||||
|
||||
.. note:: Used only if :envvar:`PMA_VERBOSE` is empty.
|
||||
|
||||
.. envvar:: PMA_USER
|
||||
|
||||
User name to use for :ref:`auth_config`.
|
||||
@ -148,6 +214,8 @@ environment variables:
|
||||
The fully-qualified path (``https://pma.example.net/``) where the reverse
|
||||
proxy makes phpMyAdmin available.
|
||||
|
||||
.. seealso:: :config:option:`$cfg['PmaAbsoluteUri']`
|
||||
|
||||
By default, :ref:`cookie` is used, but if :envvar:`PMA_USER` and
|
||||
:envvar:`PMA_PASSWORD` are set, it is switched to :ref:`auth_config`.
|
||||
|
||||
@ -155,16 +223,33 @@ By default, :ref:`cookie` is used, but if :envvar:`PMA_USER` and
|
||||
|
||||
The credentials you need to login are stored in the MySQL server, in case
|
||||
of Docker image there are various ways to set it (for example
|
||||
:envvar:`MYSQL_ROOT_PASSWORD` when starting MySQL container). Please check
|
||||
:samp:`MYSQL_ROOT_PASSWORD` when starting MySQL container). Please check
|
||||
documentation for `MariaDB container <https://hub.docker.com/r/_/mariadb/>`_
|
||||
or `MySQL container <https://hub.docker.com/r/_/mysql/>`_.
|
||||
|
||||
.. _docker-custom:
|
||||
|
||||
Customizing configuration
|
||||
-------------------------
|
||||
|
||||
Additionally configuration can be tweaked by :file:`/etc/phpmyadmin/config.user.inc.php`. If
|
||||
this file exists, it will be loaded after configuration generated from above
|
||||
environment variables, so you can override any configuration variable. This
|
||||
configuraiton can be added as a volume when invoking docker using
|
||||
`-v /some/local/directory/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php` parameters.
|
||||
|
||||
Note that the supplied configuration file is applied after :ref:`docker-vars`,
|
||||
but you can override any of the values.
|
||||
|
||||
For example to change default behaviour of CSV export you can use following
|
||||
configuration file:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$cfg['Export']['csv_columns'] = true;
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
See :ref:`config` for detailed description of configuration options.
|
||||
@ -227,6 +312,80 @@ arbitrary server - allowing you to specify MySQL/MariaDB server on login page.
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
Customizing configuration file using docker-compose
|
||||
---------------------------------------------------
|
||||
|
||||
You can use external file to customize phpMyAdmin configuration and pass it
|
||||
using volumes directive:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin/phpmyadmin
|
||||
container_name: phpmyadmin
|
||||
environment:
|
||||
- PMA_ARBITRARY=1
|
||||
restart: always
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
- /sessions
|
||||
- ~/docker/phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php
|
||||
|
||||
.. seealso:: :ref:`docker-custom`
|
||||
|
||||
Running behind haproxy in a subdirectory
|
||||
----------------------------------------
|
||||
|
||||
When you want to expose phpMyAdmin running in a Docker container in a
|
||||
subdirectory, you need to rewrite the request path in the server proxying the
|
||||
requests. For example using haproxy it can be done as:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
frontend http
|
||||
bind *:80
|
||||
option forwardfor
|
||||
option http-server-close
|
||||
|
||||
### NETWORK restriction
|
||||
acl LOCALNET src 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12
|
||||
|
||||
# /phpmyadmin
|
||||
acl phpmyadmin path_dir /phpmyadmin
|
||||
use_backend phpmyadmin if phpmyadmin LOCALNET
|
||||
|
||||
backend phpmyadmin
|
||||
mode http
|
||||
|
||||
reqirep ^(GET|POST|HEAD)\ /phpmyadmin/(.*) \1\ /\2
|
||||
|
||||
# phpMyAdmin container IP
|
||||
server localhost 172.30.21.21:80
|
||||
|
||||
You then should specify :envvar:`PMA_ABSOLUTE_URI` in the docker-compose
|
||||
configuration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
phpmyadmin:
|
||||
restart: always
|
||||
image: phpmyadmin/phpmyadmin
|
||||
container_name: phpmyadmin
|
||||
hostname: phpmyadmin
|
||||
domainname: example.com
|
||||
ports:
|
||||
- 8000:80
|
||||
environment:
|
||||
- PMA_HOSTS=172.26.36.7,172.26.36.8,172.26.36.9,172.26.36.10
|
||||
- PMA_VERBOSES=production-db1,production-db2,dev-db1,dev-db2
|
||||
- PMA_USER=root
|
||||
- PMA_PASSWORD=
|
||||
- PMA_ABSOLUTE_URI=http://example.com/phpmyadmin/
|
||||
|
||||
.. _quick_install:
|
||||
|
||||
Quick Install
|
||||
@ -278,6 +437,8 @@ simple configuration may look like this:
|
||||
$i=0;
|
||||
$i++;
|
||||
$cfg['Servers'][$i]['auth_type'] = 'cookie';
|
||||
// if you insist on "root" having no password:
|
||||
// $cfg['Servers'][$i]['AllowNoPassword'] = true; `
|
||||
?>
|
||||
|
||||
Or, if you prefer to not be prompted every time you log in:
|
||||
@ -294,6 +455,11 @@ Or, if you prefer to not be prompted every time you log in:
|
||||
$cfg['Servers'][$i]['auth_type'] = 'config';
|
||||
?>
|
||||
|
||||
.. warning::
|
||||
|
||||
Storing passwords in the configuration is insecure as anybody can then
|
||||
manipulate with your database.
|
||||
|
||||
For a full explanation of possible configuration values, see the
|
||||
:ref:`config` of this document.
|
||||
|
||||
@ -324,21 +490,38 @@ options which the setup script does not provide.
|
||||
recommended, for example with HTTP–AUTH in a :term:`.htaccess` file or switch to using
|
||||
``auth_type`` cookie or http. See the :ref:`faqmultiuser`
|
||||
for additional information, especially :ref:`faq4_4`.
|
||||
#. Open the `main phpMyAdmin directory <index.php>`_ in your browser.
|
||||
#. Open the main phpMyAdmin directory in your browser.
|
||||
phpMyAdmin should now display a welcome screen and your databases, or
|
||||
a login dialog if using :term:`HTTP` or
|
||||
cookie authentication mode.
|
||||
#. You should deny access to the ``./libraries`` and ``./setup/lib``
|
||||
subfolders in your webserver configuration.
|
||||
Such configuration prevents from possible
|
||||
path exposure and cross side scripting vulnerabilities that might
|
||||
happen to be found in that code. For the Apache webserver, this is
|
||||
often accomplished with a :term:`.htaccess` file in those directories.
|
||||
#. It is generally a good idea to protect a public phpMyAdmin installation
|
||||
against access by robots as they usually can not do anything good
|
||||
there. You can do this using ``robots.txt`` file in root of your
|
||||
webserver or limit access by web server configuration, see
|
||||
:ref:`faq1_42`.
|
||||
|
||||
.. _debian-setup:
|
||||
|
||||
Setup script on Debian, Ubuntu and derivatives
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Debian and Ubuntu have changed way how setup is enabled and disabled, in a way
|
||||
that single command has to be executed for either of these.
|
||||
|
||||
To allow editing configuration invoke:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
/usr/sbin/pma-configure
|
||||
|
||||
To block editing configuration invoke:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
/usr/sbin/pma-secure
|
||||
|
||||
Setup script on openSUSE
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Some openSUSE releases do not include setup script in the package. In case you
|
||||
want to generate configuration on these you can either download original
|
||||
package from <https://www.phpmyadmin.net/> or use setup script on our demo
|
||||
server: <https://demo.phpmyadmin.net/STABLE/setup/>.
|
||||
|
||||
|
||||
.. _verify:
|
||||
@ -374,9 +557,10 @@ Some additional downloads (for example themes) might be signed by Michal Čihař
|
||||
|
||||
and you can get more identification information from <https://keybase.io/nijel>.
|
||||
|
||||
You should verify that the signature matches
|
||||
the archive you have downloaded. This way you can be sure that you are using
|
||||
the same code that was released.
|
||||
You should verify that the signature matches the archive you have downloaded.
|
||||
This way you can be sure that you are using the same code that was released.
|
||||
You should also verify the date of the signature to make sure that you
|
||||
downloaded the latest version.
|
||||
|
||||
Each archive is accompanied with ``.asc`` files which contains the PGP signature
|
||||
for it. Once you have both of them in the same folder, you can verify the signature:
|
||||
@ -462,8 +646,13 @@ clear error regardless of the fact that the key is trusted or not:
|
||||
phpMyAdmin configuration storage
|
||||
++++++++++++++++++++++++++++++++
|
||||
|
||||
For a whole set of additional features (bookmarks, comments, :term:`SQL`-history,
|
||||
tracking mechanism, :term:`PDF`-generation, column contents transformation,
|
||||
.. versionchanged:: 3.4.0
|
||||
|
||||
Prior to phpMyAdmin 3.4.0 this was called Linked Tables Infrastructure, but
|
||||
the name was changed due to extended scope of the storage.
|
||||
|
||||
For a whole set of additional features (:ref:`bookmarks`, comments, :term:`SQL`-history,
|
||||
tracking mechanism, :term:`PDF`-generation, :ref:`transformations`, :ref:`relations`
|
||||
etc.) you need to create a set of special tables. Those tables can be located
|
||||
in your own database, or in a central database for a multi-user installation
|
||||
(this database would then be accessed by the controluser, so no other user
|
||||
@ -507,6 +696,8 @@ If you already had this infrastructure and:
|
||||
:file:`sql/upgrade_tables_mysql_4_1_2+.sql`.
|
||||
* upgraded to phpMyAdmin 4.3.0 or newer from 2.5.0 or newer (<= 4.2.x),
|
||||
please use :file:`sql/upgrade_column_info_4_3_0+.sql`.
|
||||
* upgraded to phpMyAdmin 4.7.0 or newer from 4.3.0 or newer,
|
||||
please use :file:`sql/upgrade_tables_4_7_0+.sql`.
|
||||
|
||||
and then create new tables by importing :file:`sql/create_tables.sql`.
|
||||
|
||||
@ -543,7 +734,6 @@ Upgrading from an older version
|
||||
This way you will not leave old no longer working code in the directory,
|
||||
which can have severe security implications or can cause various breakages.
|
||||
|
||||
|
||||
Simply copy :file:`config.inc.php` from your previous installation into
|
||||
the newly unpacked one. Configuration files from old versions may
|
||||
require some tweaking as some options have been changed or removed.
|
||||
@ -555,6 +745,15 @@ You should **not** copy :file:`libraries/config.default.php` over
|
||||
:file:`config.inc.php` because the default configuration file is version-
|
||||
specific.
|
||||
|
||||
The complete upgrade can be performed in few simple steps:
|
||||
|
||||
1. Download the latest phpMyAdmin version from <https://www.phpmyadmin.net/downloads/>.
|
||||
2. Rename existing phpMyAdmin folder (for example to ``phpmyadmin-old``).
|
||||
3. Unpack freshly donwloaded phpMyAdmin to desired location (for example ``phpmyadmin``).
|
||||
4. Copy :file:`config.inc.php`` from old location (``phpmyadmin-old``) to new one (``phpmyadmin``).
|
||||
5. Test that everything works properly.
|
||||
6. Remove backup of previous version (``phpmyadmin-old``).
|
||||
|
||||
If you have upgraded your MySQL server from a version previous to 4.1.2 to
|
||||
version 5.x or newer and if you use the phpMyAdmin configuration storage, you
|
||||
should run the :term:`SQL` script found in
|
||||
@ -607,8 +806,18 @@ What the user may now do is controlled entirely by the MySQL user management
|
||||
system. With HTTP or cookie authentication mode, you don't need to fill the
|
||||
user/password fields inside the :config:option:`$cfg['Servers']`.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`faq1_32`,
|
||||
:ref:`faq1_35`,
|
||||
:ref:`faq4_1`,
|
||||
:ref:`faq4_2`,
|
||||
:ref:`faq4_3`
|
||||
|
||||
.. index:: pair: HTTP; Authentication mode
|
||||
|
||||
.. _auth_http:
|
||||
|
||||
HTTP authentication mode
|
||||
------------------------
|
||||
|
||||
@ -629,6 +838,13 @@ HTTP authentication mode
|
||||
* See also :ref:`faq4_4` about not using the :term:`.htaccess` mechanism along with
|
||||
':term:`HTTP`' authentication mode.
|
||||
|
||||
.. note::
|
||||
|
||||
There is no way to do proper logout in HTTP authentication, most browsers
|
||||
will remember credentials until there is no different successful
|
||||
authentication. Because of this this method has limitation that you can not
|
||||
login with same user after logout.
|
||||
|
||||
.. index:: pair: Cookie; Authentication mode
|
||||
|
||||
.. _cookie:
|
||||
@ -639,12 +855,12 @@ Cookie authentication mode
|
||||
* Username and password are stored in cookies during the session and password
|
||||
is deleted when it ends.
|
||||
* With this mode, the user can truly log out of phpMyAdmin and log
|
||||
back in with the same username.
|
||||
back in with the same username (this is not possible with :ref:`auth_http`).
|
||||
* If you want to allow users to enter any hostname to connect (rather than only
|
||||
servers that are configured in :file:`config.inc.php`),
|
||||
see the :config:option:`$cfg['AllowArbitraryServer']` directive.
|
||||
* As mentioned in the :ref:`require` section, having the ``mcrypt`` extension will
|
||||
speed up access considerably, but is not required.
|
||||
* As mentioned in the :ref:`require` section, having the ``openssl`` extension
|
||||
will speed up access considerably, but is not required.
|
||||
|
||||
.. index:: pair: Signon; Authentication mode
|
||||
|
||||
@ -657,7 +873,8 @@ Signon authentication mode
|
||||
application to authenticate to phpMyAdmin to implement single signon
|
||||
solution.
|
||||
* The other application has to store login information into session
|
||||
data (see :config:option:`$cfg['Servers'][$i]['SignonSession']`) or you
|
||||
data (see :config:option:`$cfg['Servers'][$i]['SignonSession']` and
|
||||
:config:option:`$cfg['Servers'][$i]['SignonCookieParams']`) or you
|
||||
need to implement script to return the credentials (see
|
||||
:config:option:`$cfg['Servers'][$i]['SignonScript']`).
|
||||
* When no credentials are available, the user is being redirected to
|
||||
@ -687,8 +904,10 @@ in :file:`examples/signon-script.php`:
|
||||
.. seealso::
|
||||
:config:option:`$cfg['Servers'][$i]['auth_type']`,
|
||||
:config:option:`$cfg['Servers'][$i]['SignonSession']`,
|
||||
:config:option:`$cfg['Servers'][$i]['SignonCookieParams']`,
|
||||
:config:option:`$cfg['Servers'][$i]['SignonScript']`,
|
||||
:config:option:`$cfg['Servers'][$i]['SignonURL']`
|
||||
:config:option:`$cfg['Servers'][$i]['SignonURL']`,
|
||||
:ref:`example-signon`
|
||||
|
||||
|
||||
.. index:: pair: Config; Authentication mode
|
||||
@ -716,22 +935,37 @@ Config authentication mode
|
||||
of which are beyond the scope of this manual but easily searchable
|
||||
with Google).
|
||||
|
||||
|
||||
Securing your phpMyAdmin installation
|
||||
+++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The phpMyAdmin team tries hard to make the application secure, however there
|
||||
are always ways to make your installation more secure:
|
||||
|
||||
* Follow our `Security announcements <https://www.phpmyadmin.net/security/>`_ and upgrade
|
||||
phpMyAdmin whenever new vulnerability is published.
|
||||
* Serve phpMyAdmin on HTTPS only. Preferably, you should use HSTS as well, so that
|
||||
you're protected from protocol downgrade attacks.
|
||||
* Ensure your PHP setup follows recommendations for production sites, for example
|
||||
`display_errors <https://secure.php.net/manual/en/errorfunc.configuration.php#ini.display-errors>`_
|
||||
should be disabled.
|
||||
* Remove the ``test`` directory from phpMyAdmin, unless you are developing and need test suite.
|
||||
* Remove the ``setup`` directory from phpMyAdmin, you will probably not
|
||||
use it after the initial setup.
|
||||
* Properly choose an authentication method - :ref:`cookie`
|
||||
is probably the best choice for shared hosting.
|
||||
* Deny access to auxiliary files in :file:`./libraries/` or
|
||||
:file:`./templates/` subfolders in your webserver configuration.
|
||||
Such configuration prevents from possible path exposure and cross side
|
||||
scripting vulnerabilities that might happen to be found in that code. For the
|
||||
Apache webserver, this is often accomplished with a :term:`.htaccess` file in
|
||||
those directories.
|
||||
* It is generally a good idea to protect a public phpMyAdmin installation
|
||||
against access by robots as they usually can not do anything good there. You
|
||||
can do this using ``robots.txt`` file in root of your webserver or limit
|
||||
access by web server configuration, see :ref:`faq1_42`.
|
||||
* In case you don't want all MySQL users to be able to access
|
||||
phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them.
|
||||
phpMyAdmin, you can use :config:option:`$cfg['Servers'][$i]['AllowDeny']['rules']` to limit them
|
||||
or :config:option:`$cfg['Servers'][$i]['AllowRoot']` to deny root user access.
|
||||
* Consider hiding phpMyAdmin behind an authentication proxy, so that
|
||||
users need to authenticate prior to providing MySQL credentials
|
||||
to phpMyAdmin. You can achieve this by configuring your web server to request
|
||||
@ -754,6 +988,9 @@ are always ways to make your installation more secure:
|
||||
* If you are afraid of automated attacks, enabling Captcha by
|
||||
:config:option:`$cfg['CaptchaLoginPublicKey']` and
|
||||
:config:option:`$cfg['CaptchaLoginPrivateKey']` might be an option.
|
||||
* Failed login attemps are logged to syslog (if available). This can allow using a tool such as
|
||||
fail2ban to block brute-force attempts. Note that the log file used by syslog is not the same
|
||||
as the Apache error or access log files.
|
||||
|
||||
Known issues
|
||||
++++++++++++
|
||||
@ -772,3 +1009,8 @@ Trouble logging back in after logging out using 'http' authentication
|
||||
|
||||
When using the 'http' ``auth_type``, it can be impossible to log back in (when the logout comes
|
||||
manually or after a period of inactivity). `Issue 11898 <https://github.com/phpmyadmin/phpmyadmin/issues/11898>`_.
|
||||
|
||||
|
||||
.. _Composer tool: https://getcomposer.org/
|
||||
.. _Packagist: https://packagist.org/
|
||||
.. _Docker image: https://hub.docker.com/r/phpmyadmin/phpmyadmin/
|
||||
|
||||
@ -3,6 +3,11 @@
|
||||
Transformations
|
||||
===============
|
||||
|
||||
.. note::
|
||||
|
||||
You need to have configured the :ref:`linked-tables` for using transformations
|
||||
feature.
|
||||
|
||||
.. _transformationsintro:
|
||||
|
||||
Introduction
|
||||
@ -29,7 +34,7 @@ options, you can consult your *<www.your-host.com>/<your-install-
|
||||
dir>/transformation\_overview.php* installation.
|
||||
|
||||
For a tutorial on how to effectively use transformations, see our
|
||||
`Link section <https://www.phpmyadmin.net/home_page/docs.php>`_ on the
|
||||
`Link section <https://www.phpmyadmin.net/docs/>`_ on the
|
||||
official phpMyAdmin homepage.
|
||||
|
||||
.. _transformationshowto:
|
||||
@ -128,9 +133,9 @@ The applyTransformation() method always gets passed three variables:
|
||||
function as an array.
|
||||
#. **$meta** - Contains an object with information about your column. The
|
||||
data is drawn from the output of the `mysql\_fetch\_field()
|
||||
<https://www.php.net/mysql_fetch_field>`_ function. This means, all
|
||||
<https://secure.php.net/mysql_fetch_field>`_ function. This means, all
|
||||
object properties described on the `manual page
|
||||
<https://www.php.net/mysql_fetch_field>`_ are available in this
|
||||
<https://secure.php.net/mysql_fetch_field>`_ are available in this
|
||||
variable and can be used to transform a column accordingly to
|
||||
unsigned/zerofill/not\_null/... properties. The $meta->mimetype
|
||||
variable contains the original MIME-type of the column (i.e.
|
||||
|
||||
@ -5,6 +5,9 @@ User Guide
|
||||
:maxdepth: 2
|
||||
|
||||
transformations
|
||||
bookmarks
|
||||
privileges
|
||||
other
|
||||
relations
|
||||
charts
|
||||
import_export
|
||||
other
|
||||
|
||||
@ -27,9 +27,6 @@ Currently known list of external libraries:
|
||||
js/jquery
|
||||
jQuery js framework and various jQuery based libraries.
|
||||
|
||||
libraries/php-gettext
|
||||
php-gettext library
|
||||
libraries/tcpdf
|
||||
tcpdf library, stripped down of not needed files
|
||||
libraries/phpseclib
|
||||
portions of phpseclib library
|
||||
vendor/
|
||||
The download kit includes various Composer packages as
|
||||
dependencies.
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/error_report.lib.php';
|
||||
require_once 'libraries/user_preferences.lib.php';
|
||||
@ -15,7 +16,7 @@ if (!isset($_REQUEST['exception_type'])
|
||||
die('Oops, something went wrong!!');
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
|
||||
if (isset($_REQUEST['send_error_report'])
|
||||
&& ($_REQUEST['send_error_report'] == true
|
||||
@ -35,7 +36,6 @@ if (isset($_REQUEST['send_error_report'])
|
||||
) {
|
||||
$_SESSION['error_subm_count'] = 0;
|
||||
$_SESSION['prev_errors'] = '';
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->addJSON('_stopErrorReportLoop', '1');
|
||||
} else {
|
||||
$_SESSION['prev_error_subm_time'] = time();
|
||||
|
||||
@ -22,7 +22,6 @@ foreach ($hosts as $host) {
|
||||
$cfg['Servers'][$i]['host'] = $host;
|
||||
$cfg['Servers'][$i]['port'] = '';
|
||||
$cfg['Servers'][$i]['socket'] = '';
|
||||
$cfg['Servers'][$i]['connect_type'] = 'tcp';
|
||||
$cfg['Servers'][$i]['compress'] = false;
|
||||
$cfg['Servers'][$i]['controluser'] = 'pma';
|
||||
$cfg['Servers'][$i]['controlpass'] = 'pmapass';
|
||||
|
||||
@ -89,7 +89,7 @@ $base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];
|
||||
|
||||
$realm = $base . '/';
|
||||
$returnTo = $base . dirname($_SERVER['PHP_SELF']);
|
||||
if ($returnTo[mb_strlen($returnTo) - 1] != '/') {
|
||||
if ($returnTo[strlen($returnTo) - 1] != '/') {
|
||||
$returnTo .= '/';
|
||||
}
|
||||
$returnTo .= 'openid.php';
|
||||
|
||||
984
export.php
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* "Echo" service to allow force downloading of exported charts (png or svg)
|
||||
* and server status monitor settings
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
require_once 'libraries/common.inc.php';
|
||||
|
||||
if (isset($_REQUEST['monitorconfig'])) {
|
||||
/* For monitor chart config export */
|
||||
PMA_downloadHeader('monitor.cfg', 'application/json; charset=UTF-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
echo urldecode($_REQUEST['monitorconfig']);
|
||||
|
||||
} else if (isset($_REQUEST['import'])) {
|
||||
/* For monitor chart config import */
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
if (!file_exists($_FILES['file']['tmp_name'])) {
|
||||
exit();
|
||||
}
|
||||
echo file_get_contents($_FILES['file']['tmp_name']);
|
||||
}
|
||||
@ -5,8 +5,10 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\gis\GISFactory;
|
||||
use PMA\libraries\gis\GISVisualization;
|
||||
use PMA\libraries\URL;
|
||||
|
||||
/**
|
||||
* Escapes special characters if the variable is set.
|
||||
@ -100,7 +102,7 @@ if (isset($_REQUEST['generate']) && $_REQUEST['generate'] == true) {
|
||||
'visualization' => $visualization,
|
||||
'openLayers' => $open_layers,
|
||||
);
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response = Response::getInstance();
|
||||
$response->addJSON($extra_data);
|
||||
exit;
|
||||
}
|
||||
@ -127,7 +129,7 @@ if (isset($_REQUEST['input_name'])) {
|
||||
echo '<input type="hidden" name="input_name" value="'
|
||||
, htmlspecialchars($_REQUEST['input_name']) , '" />';
|
||||
}
|
||||
echo PMA_URL_getHiddenInputs();
|
||||
echo URL::getHiddenInputs();
|
||||
|
||||
echo '<!-- Visualization section -->';
|
||||
echo '<div id="placeholder" style="width:450px;height:300px;'
|
||||
@ -426,5 +428,5 @@ echo '</div>';
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
|
||||
PMA\libraries\Response::getInstance()->addJSON('gis_editor', ob_get_contents());
|
||||
Response::getInstance()->addJSON('gis_editor', ob_get_contents());
|
||||
ob_end_clean();
|
||||
|
||||
250
import.php
@ -5,7 +5,12 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\Encoding;
|
||||
use PMA\libraries\plugins\ImportPlugin;
|
||||
use PMA\libraries\File;
|
||||
use PMA\libraries\URL;
|
||||
use PMA\libraries\Bookmark;
|
||||
|
||||
/* Enable LOAD DATA LOCAL INFILE for LDI plugin */
|
||||
if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
|
||||
@ -17,7 +22,6 @@ if (isset($_POST['format']) && $_POST['format'] == 'ldi') {
|
||||
*/
|
||||
require_once 'libraries/common.inc.php';
|
||||
require_once 'libraries/sql.lib.php';
|
||||
require_once 'libraries/bookmark.lib.php';
|
||||
//require_once 'libraries/display_import_functions.lib.php';
|
||||
|
||||
if (isset($_REQUEST['show_as_php'])) {
|
||||
@ -33,9 +37,10 @@ if (isset($_REQUEST['simulate_dml'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$response = Response::getInstance();
|
||||
|
||||
// If it's a refresh console bookmarks request
|
||||
if (isset($_REQUEST['console_bookmark_refresh'])) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->addJSON(
|
||||
'console_message_bookmark', PMA\libraries\Console::getBookmarkContent()
|
||||
);
|
||||
@ -43,11 +48,10 @@ if (isset($_REQUEST['console_bookmark_refresh'])) {
|
||||
}
|
||||
// If it's a console bookmark add request
|
||||
if (isset($_REQUEST['console_bookmark_add'])) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
if (isset($_REQUEST['label']) && isset($_REQUEST['db'])
|
||||
&& isset($_REQUEST['bookmark_query']) && isset($_REQUEST['shared'])
|
||||
) {
|
||||
$cfgBookmark = PMA_Bookmark_getParams();
|
||||
$cfgBookmark = Bookmark::getParams();
|
||||
$bookmarkFields = array(
|
||||
'bkm_database' => $_REQUEST['db'],
|
||||
'bkm_user' => $cfgBookmark['user'],
|
||||
@ -55,7 +59,8 @@ if (isset($_REQUEST['console_bookmark_add'])) {
|
||||
'bkm_label' => $_REQUEST['label']
|
||||
);
|
||||
$isShared = ($_REQUEST['shared'] == 'true' ? true : false);
|
||||
if (PMA_Bookmark_save($bookmarkFields, $isShared)) {
|
||||
$bookmark = Bookmark::createBookmark($bookmarkFields, $isShared);
|
||||
if ($bookmark !== false && $bookmark->save()) {
|
||||
$response->addJSON('message', __('Succeeded'));
|
||||
$response->addJSON('data', $bookmarkFields);
|
||||
$response->addJSON('isShared', $isShared);
|
||||
@ -86,7 +91,6 @@ $post_params = array(
|
||||
'local_import_file'
|
||||
);
|
||||
|
||||
// TODO: adapt full list of allowed parameters, as in export.php
|
||||
foreach ($post_params as $one_post_param) {
|
||||
if (isset($_POST[$one_post_param])) {
|
||||
$GLOBALS[$one_post_param] = $_POST[$one_post_param];
|
||||
@ -113,7 +117,8 @@ if (! empty($sql_query)) {
|
||||
// apply values for parameters
|
||||
if (! empty($_REQUEST['parameterized'])
|
||||
&& ! empty($_REQUEST['parameters'])
|
||||
&& is_array($_REQUEST['parameters'])) {
|
||||
&& is_array($_REQUEST['parameters'])
|
||||
) {
|
||||
$parameters = $_REQUEST['parameters'];
|
||||
foreach ($parameters as $parameter => $replacement) {
|
||||
$quoted = preg_quote($parameter, '/');
|
||||
@ -199,7 +204,6 @@ if ($_POST == array() && $_GET == array()) {
|
||||
$_SESSION['Import_message']['message'] = $message->getDisplay();
|
||||
$_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto'];
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus(false);
|
||||
$response->addJSON('message', $message);
|
||||
|
||||
@ -208,7 +212,6 @@ if ($_POST == array() && $_GET == array()) {
|
||||
|
||||
// Add console message id to response output
|
||||
if (isset($_POST['console_message_id'])) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->addJSON('console_message_id', $_POST['console_message_id']);
|
||||
}
|
||||
|
||||
@ -250,7 +253,7 @@ $format = PMA_securePath($format);
|
||||
|
||||
// Create error and goto url
|
||||
if ($import_type == 'table') {
|
||||
$err_url = 'tbl_import.php' . PMA_URL_getCommon(
|
||||
$err_url = 'tbl_import.php' . URL::getCommon(
|
||||
array(
|
||||
'db' => $db, 'table' => $table
|
||||
)
|
||||
@ -258,29 +261,29 @@ if ($import_type == 'table') {
|
||||
$_SESSION['Import_message']['go_back_url'] = $err_url;
|
||||
$goto = 'tbl_import.php';
|
||||
} elseif ($import_type == 'database') {
|
||||
$err_url = 'db_import.php' . PMA_URL_getCommon(array('db' => $db));
|
||||
$err_url = 'db_import.php' . URL::getCommon(array('db' => $db));
|
||||
$_SESSION['Import_message']['go_back_url'] = $err_url;
|
||||
$goto = 'db_import.php';
|
||||
} elseif ($import_type == 'server') {
|
||||
$err_url = 'server_import.php' . PMA_URL_getCommon();
|
||||
$err_url = 'server_import.php' . URL::getCommon();
|
||||
$_SESSION['Import_message']['go_back_url'] = $err_url;
|
||||
$goto = 'server_import.php';
|
||||
} else {
|
||||
if (empty($goto) || !preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) {
|
||||
if (mb_strlen($table) && mb_strlen($db)) {
|
||||
if (strlen($table) > 0 && strlen($db) > 0) {
|
||||
$goto = 'tbl_structure.php';
|
||||
} elseif (mb_strlen($db)) {
|
||||
} elseif (strlen($db) > 0) {
|
||||
$goto = 'db_structure.php';
|
||||
} else {
|
||||
$goto = 'server_sql.php';
|
||||
}
|
||||
}
|
||||
if (mb_strlen($table) && mb_strlen($db)) {
|
||||
$common = PMA_URL_getCommon(array('db' => $db, 'table' => $table));
|
||||
} elseif (mb_strlen($db)) {
|
||||
$common = PMA_URL_getCommon(array('db' => $db));
|
||||
if (strlen($table) > 0 && strlen($db) > 0) {
|
||||
$common = URL::getCommon(array('db' => $db, 'table' => $table));
|
||||
} elseif (strlen($db) > 0) {
|
||||
$common = URL::getCommon(array('db' => $db));
|
||||
} else {
|
||||
$common = PMA_URL_getCommon();
|
||||
$common = URL::getCommon();
|
||||
}
|
||||
$err_url = $goto . $common
|
||||
. (preg_match('@^tbl_[a-z]*\.php$@', $goto)
|
||||
@ -295,7 +298,7 @@ if (basename($_SERVER['SCRIPT_NAME']) === 'import.php') {
|
||||
}
|
||||
|
||||
|
||||
if (mb_strlen($db)) {
|
||||
if (strlen($db) > 0) {
|
||||
$GLOBALS['dbi']->selectDb($db);
|
||||
}
|
||||
|
||||
@ -327,23 +330,27 @@ $run_query = true;
|
||||
$charset_conversion = false;
|
||||
$reset_charset = false;
|
||||
$bookmark_created = false;
|
||||
$result = false;
|
||||
$msg = 'Sorry an unexpected error happened!';
|
||||
|
||||
// Bookmark Support: get a query back from bookmark if required
|
||||
if (! empty($_REQUEST['id_bookmark'])) {
|
||||
$id_bookmark = (int)$_REQUEST['id_bookmark'];
|
||||
include_once 'libraries/bookmark.lib.php';
|
||||
switch ($_REQUEST['action_bookmark']) {
|
||||
case 0: // bookmarked query that have to be run
|
||||
$import_text = PMA_Bookmark_get(
|
||||
$bookmark = Bookmark::get(
|
||||
$db,
|
||||
$id_bookmark,
|
||||
'id',
|
||||
isset($_REQUEST['action_bookmark_all'])
|
||||
);
|
||||
|
||||
if (! empty($_REQUEST['bookmark_variable'])) {
|
||||
$import_text = PMA_Bookmark_applyVariables(
|
||||
$import_text
|
||||
$import_text = $bookmark->applyVariables(
|
||||
$_REQUEST['bookmark_variable']
|
||||
);
|
||||
} else {
|
||||
$import_text = $bookmark->getQuery();
|
||||
}
|
||||
|
||||
// refresh navigation and main panels
|
||||
@ -365,10 +372,10 @@ if (! empty($_REQUEST['id_bookmark'])) {
|
||||
}
|
||||
break;
|
||||
case 1: // bookmarked query that have to be displayed
|
||||
$import_text = PMA_Bookmark_get($db, $id_bookmark);
|
||||
if ($GLOBALS['is_ajax_request'] == true) {
|
||||
$bookmark = Bookmark::get($db, $id_bookmark);
|
||||
$import_text = $bookmark->getQuery();
|
||||
if ($response->isAjax()) {
|
||||
$message = PMA\libraries\Message::success(__('Showing bookmark'));
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus($message->isSuccess());
|
||||
$response->addJSON('message', $message);
|
||||
$response->addJSON('sql_query', $import_text);
|
||||
@ -379,22 +386,24 @@ if (! empty($_REQUEST['id_bookmark'])) {
|
||||
}
|
||||
break;
|
||||
case 2: // bookmarked query that have to be deleted
|
||||
$import_text = PMA_Bookmark_get($db, $id_bookmark);
|
||||
PMA_Bookmark_delete($id_bookmark);
|
||||
if ($GLOBALS['is_ajax_request'] == true) {
|
||||
$message = PMA\libraries\Message::success(
|
||||
__('The bookmark has been deleted.')
|
||||
);
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus($message->isSuccess());
|
||||
$response->addJSON('message', $message);
|
||||
$response->addJSON('action_bookmark', $_REQUEST['action_bookmark']);
|
||||
$response->addJSON('id_bookmark', $id_bookmark);
|
||||
exit;
|
||||
} else {
|
||||
$run_query = false;
|
||||
$error = true; // this is kind of hack to skip processing the query
|
||||
$bookmark = Bookmark::get($db, $id_bookmark);
|
||||
if (! empty($bookmark)) {
|
||||
$bookmark->delete();
|
||||
if ($response->isAjax()) {
|
||||
$message = PMA\libraries\Message::success(
|
||||
__('The bookmark has been deleted.')
|
||||
);
|
||||
$response->setRequestStatus($message->isSuccess());
|
||||
$response->addJSON('message', $message);
|
||||
$response->addJSON('action_bookmark', $_REQUEST['action_bookmark']);
|
||||
$response->addJSON('id_bookmark', $id_bookmark);
|
||||
exit;
|
||||
} else {
|
||||
$run_query = false;
|
||||
$error = true; // this is kind of hack to skip processing the query
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} // end bookmarks reading
|
||||
@ -459,132 +468,18 @@ if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) {
|
||||
// Do we have file to import?
|
||||
|
||||
if ($import_file != 'none' && ! $error) {
|
||||
// work around open_basedir and other limitations
|
||||
$open_basedir = @ini_get('open_basedir');
|
||||
|
||||
// If we are on a server with open_basedir, we must move the file
|
||||
// before opening it.
|
||||
|
||||
if (! empty($open_basedir)) {
|
||||
$tmp_subdir = ini_get('upload_tmp_dir');
|
||||
if (empty($tmp_subdir)) {
|
||||
$tmp_subdir = sys_get_temp_dir();
|
||||
}
|
||||
$tmp_subdir = rtrim($tmp_subdir, DIRECTORY_SEPARATOR);
|
||||
if (@is_writable($tmp_subdir)) {
|
||||
$import_file_new = $tmp_subdir . DIRECTORY_SEPARATOR
|
||||
. basename($import_file) . uniqid();
|
||||
if (move_uploaded_file($import_file, $import_file_new)) {
|
||||
$import_file = $import_file_new;
|
||||
$file_to_unlink = $import_file_new;
|
||||
}
|
||||
|
||||
$size = filesize($import_file);
|
||||
} else {
|
||||
|
||||
// If the php.ini is misconfigured (eg. there is no /tmp access defined
|
||||
// with open_basedir), $tmp_subdir won't be writable and the user gets
|
||||
// a 'File could not be read!' error (at PMA_detectCompression), which
|
||||
// is not too meaningful. Show a meaningful error message to the user
|
||||
// instead.
|
||||
|
||||
$message = PMA\libraries\Message::error(
|
||||
__(
|
||||
'Uploaded file cannot be moved, because the server has ' .
|
||||
'open_basedir enabled without access to the %s directory ' .
|
||||
'(for temporary files).'
|
||||
)
|
||||
);
|
||||
$message->addParam($tmp_subdir);
|
||||
PMA_stopImport($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle file compression
|
||||
* @todo duplicate code exists in File.php
|
||||
*/
|
||||
$compression = PMA_detectCompression($import_file);
|
||||
if ($compression === false) {
|
||||
$message = PMA\libraries\Message::error(__('File could not be read!'));
|
||||
PMA_stopImport($message); //Contains an 'exit'
|
||||
$import_handle = new File($import_file);
|
||||
$import_handle->checkUploadedFile();
|
||||
if ($import_handle->isError()) {
|
||||
PMA_stopImport($import_handle->getError());
|
||||
}
|
||||
|
||||
switch ($compression) {
|
||||
case 'application/bzip2':
|
||||
if ($cfg['BZipDump'] && @function_exists('bzopen')) {
|
||||
$import_handle = @bzopen($import_file, 'r');
|
||||
} else {
|
||||
$message = PMA\libraries\Message::error(
|
||||
__(
|
||||
'You attempted to load file with unsupported compression ' .
|
||||
'(%s). Either support for it is not implemented or disabled ' .
|
||||
'by your configuration.'
|
||||
)
|
||||
);
|
||||
$message->addParam($compression);
|
||||
PMA_stopImport($message);
|
||||
}
|
||||
break;
|
||||
case 'application/gzip':
|
||||
if ($cfg['GZipDump'] && @function_exists('gzopen')) {
|
||||
$import_handle = @gzopen($import_file, 'r');
|
||||
} else {
|
||||
$message = PMA\libraries\Message::error(
|
||||
__(
|
||||
'You attempted to load file with unsupported compression ' .
|
||||
'(%s). Either support for it is not implemented or disabled ' .
|
||||
'by your configuration.'
|
||||
)
|
||||
);
|
||||
$message->addParam($compression);
|
||||
PMA_stopImport($message);
|
||||
}
|
||||
break;
|
||||
case 'application/zip':
|
||||
if ($cfg['ZipDump'] && @function_exists('zip_open')) {
|
||||
/**
|
||||
* Load interface for zip extension.
|
||||
*/
|
||||
include_once 'libraries/zip_extension.lib.php';
|
||||
$zipResult = PMA_getZipContents($import_file);
|
||||
if (! empty($zipResult['error'])) {
|
||||
$message = PMA\libraries\Message::rawError($zipResult['error']);
|
||||
PMA_stopImport($message);
|
||||
} else {
|
||||
$import_text = $zipResult['data'];
|
||||
}
|
||||
} else {
|
||||
$message = PMA\libraries\Message::error(
|
||||
__(
|
||||
'You attempted to load file with unsupported compression ' .
|
||||
'(%s). Either support for it is not implemented or disabled ' .
|
||||
'by your configuration.'
|
||||
)
|
||||
);
|
||||
$message->addParam($compression);
|
||||
PMA_stopImport($message);
|
||||
}
|
||||
break;
|
||||
case 'none':
|
||||
$import_handle = @fopen($import_file, 'r');
|
||||
break;
|
||||
default:
|
||||
$message = PMA\libraries\Message::error(
|
||||
__(
|
||||
'You attempted to load file with unsupported compression (%s). ' .
|
||||
'Either support for it is not implemented or disabled by your ' .
|
||||
'configuration.'
|
||||
)
|
||||
);
|
||||
$message->addParam($compression);
|
||||
PMA_stopImport($message);
|
||||
// the previous function exits
|
||||
}
|
||||
// use isset() because zip compression type does not use a handle
|
||||
if (! $error && isset($import_handle) && $import_handle === false) {
|
||||
$message = PMA\libraries\Message::error(__('File could not be read!'));
|
||||
PMA_stopImport($message);
|
||||
$import_handle->setDecompressContent(true);
|
||||
$import_handle->open();
|
||||
if ($import_handle->isError()) {
|
||||
PMA_stopImport($import_handle->getError());
|
||||
}
|
||||
} elseif (! $error) {
|
||||
if (! isset($import_text) || empty($import_text)) {
|
||||
@ -603,7 +498,7 @@ if ($import_file != 'none' && ! $error) {
|
||||
//$_SESSION['Import_message'] = $message->getDisplay();
|
||||
|
||||
// Convert the file's charset if necessary
|
||||
if ($GLOBALS['PMA_recoding_engine'] != PMA_CHARSET_NONE && isset($charset_of_file)) {
|
||||
if (Encoding::isSupported() && isset($charset_of_file)) {
|
||||
if ($charset_of_file != 'utf-8') {
|
||||
$charset_conversion = true;
|
||||
}
|
||||
@ -658,8 +553,8 @@ if (! $error) {
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($import_handle)) {
|
||||
fclose($import_handle);
|
||||
if (isset($import_handle)) {
|
||||
$import_handle->close();
|
||||
}
|
||||
|
||||
// Cleanup temporary file
|
||||
@ -703,14 +598,12 @@ if (! empty($id_bookmark) && $_REQUEST['action_bookmark'] == 2) {
|
||||
$message->addParam($executed_queries);
|
||||
|
||||
if ($import_notice) {
|
||||
$message->addString($import_notice);
|
||||
$message->addHtml($import_notice);
|
||||
}
|
||||
if (! empty($local_import_file)) {
|
||||
$message->addString('(' . htmlspecialchars($local_import_file) . ')');
|
||||
$message->addText('(' . $local_import_file . ')');
|
||||
} else {
|
||||
$message->addString(
|
||||
'(' . htmlspecialchars($_FILES['import_file']['name']) . ')'
|
||||
);
|
||||
$message->addText('(' . $_FILES['import_file']['name'] . ')');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -729,11 +622,11 @@ if ($timeout_passed) {
|
||||
. ' please %sresubmit the same file%s and import will resume.'
|
||||
)
|
||||
);
|
||||
$message->addParam('<a href="' . $importUrl . '">', false);
|
||||
$message->addParam('</a>', false);
|
||||
$message->addParamHtml('<a href="' . $importUrl . '">');
|
||||
$message->addParamHtml('</a>');
|
||||
|
||||
if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) {
|
||||
$message->addString(
|
||||
$message->addText(
|
||||
__(
|
||||
'However on last run no data has been parsed,'
|
||||
. ' this usually means phpMyAdmin won\'t be able to'
|
||||
@ -844,7 +737,7 @@ if ($go_sql) {
|
||||
// since only one bookmark has to be added for all the queries submitted through
|
||||
// the SQL tab
|
||||
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
|
||||
$cfgBookmark = PMA_Bookmark_getParams();
|
||||
$cfgBookmark = Bookmark::getParams();
|
||||
PMA_storeTheQueryAsBookmark(
|
||||
$db, $cfgBookmark['user'],
|
||||
$_REQUEST['sql_query'], $_POST['bkm_label'],
|
||||
@ -852,7 +745,6 @@ if ($go_sql) {
|
||||
);
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->addJSON('ajax_reload', $ajax_reload);
|
||||
$response->addHTML($html_output);
|
||||
exit();
|
||||
@ -860,7 +752,7 @@ if ($go_sql) {
|
||||
} else if ($result) {
|
||||
// Save a Bookmark with more than one queries (if Bookmark label given).
|
||||
if (! empty($_POST['bkm_label']) && ! empty($import_text)) {
|
||||
$cfgBookmark = PMA_Bookmark_getParams();
|
||||
$cfgBookmark = Bookmark::getParams();
|
||||
PMA_storeTheQueryAsBookmark(
|
||||
$db, $cfgBookmark['user'],
|
||||
$_REQUEST['sql_query'], $_POST['bkm_label'],
|
||||
@ -868,7 +760,6 @@ if ($go_sql) {
|
||||
);
|
||||
}
|
||||
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus(true);
|
||||
$response->addJSON('message', PMA\libraries\Message::success($msg));
|
||||
$response->addJSON(
|
||||
@ -876,7 +767,6 @@ if ($go_sql) {
|
||||
PMA\libraries\Util::getMessage($msg, $sql_query, 'success')
|
||||
);
|
||||
} else if ($result == false) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
$response->setRequestStatus(false);
|
||||
$response->addJSON('message', PMA\libraries\Message::error($msg));
|
||||
} else {
|
||||
|
||||
@ -24,9 +24,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')
|
||||
&& ini_get('session.upload_progress.enabled')
|
||||
) {
|
||||
if (ini_get('session.upload_progress.enabled')) {
|
||||
|
||||
$sessionupload = array();
|
||||
define('UPLOAD_PREFIX', ini_get('session.upload_progress.prefix'));
|
||||
@ -34,7 +32,7 @@ if (version_compare(PHP_VERSION, '5.4.0', '>=')
|
||||
session_start();
|
||||
foreach ($_SESSION as $key => $value) {
|
||||
// only copy session-prefixed data
|
||||
if (mb_substr($key, 0, mb_strlen(UPLOAD_PREFIX))
|
||||
if (substr($key, 0, strlen(UPLOAD_PREFIX))
|
||||
== UPLOAD_PREFIX) {
|
||||
$sessionupload[$key] = $value;
|
||||
}
|
||||
@ -69,7 +67,7 @@ if (defined('SESSIONUPLOAD')) {
|
||||
|
||||
// remove session upload data that are not set anymore
|
||||
foreach ($_SESSION as $key => $value) {
|
||||
if (mb_substr($key, 0, mb_strlen(UPLOAD_PREFIX))
|
||||
if (substr($key, 0, strlen(UPLOAD_PREFIX))
|
||||
== UPLOAD_PREFIX
|
||||
&& ! isset($sessionupload[$key])
|
||||
) {
|
||||
|
||||
91
index.php
@ -5,7 +5,13 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
use PMA\libraries\Response;
|
||||
use PMA\libraries\RecentFavoriteTable;
|
||||
use PMA\libraries\URL;
|
||||
use PMA\libraries\Sanitize;
|
||||
use PMA\libraries\Charsets;
|
||||
use PMA\libraries\ThemeManager;
|
||||
use PMA\libraries\LanguageManager;
|
||||
|
||||
/**
|
||||
* Gets some core libraries and displays a top message if required
|
||||
@ -74,11 +80,11 @@ if (! empty($_REQUEST['db'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$response = Response::getInstance();
|
||||
/**
|
||||
* Check if it is an ajax request to reload the recent tables list.
|
||||
*/
|
||||
if ($GLOBALS['is_ajax_request'] && ! empty($_REQUEST['recent_table'])) {
|
||||
$response = PMA\libraries\Response::getInstance();
|
||||
if ($response->isAjax() && ! empty($_REQUEST['recent_table'])) {
|
||||
$response->addJSON(
|
||||
'list',
|
||||
RecentFavoriteTable::getInstance('recent')->getHtmlList()
|
||||
@ -87,7 +93,7 @@ if ($GLOBALS['is_ajax_request'] && ! empty($_REQUEST['recent_table'])) {
|
||||
}
|
||||
|
||||
if ($GLOBALS['PMA_Config']->isGitRevision()) {
|
||||
if (isset($_REQUEST['git_revision']) && $GLOBALS['is_ajax_request'] == true) {
|
||||
if (isset($_REQUEST['git_revision']) && $response->isAjax()) {
|
||||
PMA_printGitRevision();
|
||||
exit;
|
||||
}
|
||||
@ -105,7 +111,7 @@ if (! empty($message)) {
|
||||
unset($message);
|
||||
}
|
||||
|
||||
$common_url_query = PMA_URL_getCommon();
|
||||
$common_url_query = URL::getCommon();
|
||||
$mysql_cur_user_and_host = '';
|
||||
|
||||
// when $server > 0, a server has been chosen so we can display
|
||||
@ -202,7 +208,7 @@ if ($server > 0 || count($cfg['Servers']) > 1
|
||||
} // end if
|
||||
echo ' <li id="li_select_mysql_collation" class="no_bullets" >';
|
||||
echo ' <form method="post" action="index.php">' , "\n"
|
||||
. PMA_URL_getHiddenInputs(null, null, 4, 'collation_connection')
|
||||
. URL::getHiddenInputs(null, null, 4, 'collation_connection')
|
||||
. ' <label for="select_collation_connection">' . "\n"
|
||||
. ' ' . PMA\libraries\Util::getImage('s_asci.png')
|
||||
. " " . __('Server connection collation') . "\n"
|
||||
@ -211,8 +217,7 @@ if ($server > 0 || count($cfg['Servers']) > 1
|
||||
. ': ' . "\n"
|
||||
. ' </label>' . "\n"
|
||||
|
||||
. PMA_generateCharsetDropdownBox(
|
||||
PMA_CSDROPDOWN_COLLATION,
|
||||
. Charsets::getCollationDropdownBox(
|
||||
'collation_connection',
|
||||
'select_collation_connection',
|
||||
$collation_connection,
|
||||
@ -231,11 +236,12 @@ echo '<h2>' , __('Appearance settings') , '</h2>';
|
||||
echo ' <ul>';
|
||||
|
||||
// Displays language selection combo
|
||||
if (empty($cfg['Lang'])) {
|
||||
$language_manager = LanguageManager::getInstance();
|
||||
if (empty($cfg['Lang']) && $language_manager->hasChoice()) {
|
||||
echo '<li id="li_select_lang" class="no_bullets">';
|
||||
include_once 'libraries/display_select_lang.lib.php';
|
||||
|
||||
echo PMA\libraries\Util::getImage('s_lang.png') , " "
|
||||
, PMA_getLanguageSelectorHtml();
|
||||
, $language_manager->getSelectorDisplay();
|
||||
echo '</li>';
|
||||
}
|
||||
|
||||
@ -244,7 +250,7 @@ if (empty($cfg['Lang'])) {
|
||||
if ($GLOBALS['cfg']['ThemeManager']) {
|
||||
echo '<li id="li_select_theme" class="no_bullets">';
|
||||
echo PMA\libraries\Util::getImage('s_theme.png') , " "
|
||||
, $_SESSION['PMA_Theme_Manager']->getHtmlSelectBox();
|
||||
, ThemeManager::getInstance()->getHtmlSelectBox();
|
||||
echo '</li>';
|
||||
}
|
||||
echo '<li id="li_select_fontsize">';
|
||||
@ -309,9 +315,10 @@ if ($server > 0 && $GLOBALS['cfg']['ShowServerInfo']) {
|
||||
echo ' <li id="li_select_mysql_charset">';
|
||||
echo ' ' , __('Server charset:') , ' '
|
||||
. ' <span lang="en" dir="ltr">';
|
||||
echo ' ' , $mysql_charsets_descriptions[$mysql_charset_map['utf-8']];
|
||||
echo ' (' , $mysql_charset_map['utf-8'] , ')'
|
||||
. ' </span>'
|
||||
$unicode = Charsets::$mysql_charset_map['utf-8'];
|
||||
$charsets = Charsets::getMySQLCharsetsDescriptions();
|
||||
echo ' ' , $charsets[$unicode], ' (' . $unicode, ')';
|
||||
echo ' </span>'
|
||||
. ' </li>'
|
||||
. ' </ul>'
|
||||
. ' </div>';
|
||||
@ -419,14 +426,14 @@ PMA_printListItem(
|
||||
PMA_printListItem(
|
||||
__('List of changes'),
|
||||
'li_pma_changes',
|
||||
'changelog.php' . PMA_URL_getCommon(),
|
||||
'changelog.php' . URL::getCommon(),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
PMA_printListItem(
|
||||
__('License'),
|
||||
'li_pma_license',
|
||||
'license.php' . PMA_URL_getCommon(),
|
||||
'license.php' . URL::getCommon(),
|
||||
null,
|
||||
'_blank'
|
||||
);
|
||||
@ -474,7 +481,7 @@ if ($cfg['LoginCookieValidityDisableWarning'] == false) {
|
||||
if ($gc_time < $GLOBALS['cfg']['LoginCookieValidity'] ) {
|
||||
trigger_error(
|
||||
__(
|
||||
'Your PHP parameter [a@https://php.net/manual/en/session.' .
|
||||
'Your PHP parameter [a@https://secure.php.net/manual/en/session.' .
|
||||
'configuration.php#ini.session.gc-maxlifetime@_blank]session.' .
|
||||
'gc_maxlifetime[/a] is lower than cookie validity configured ' .
|
||||
'in phpMyAdmin, because of this, your login might expire sooner ' .
|
||||
@ -557,12 +564,8 @@ if ($server > 0) {
|
||||
);
|
||||
}
|
||||
$msg = PMA\libraries\Message::notice($msg_text);
|
||||
$msg->addParam(
|
||||
'<a href="./chk_rel.php'
|
||||
. $common_url_query . '">',
|
||||
false
|
||||
);
|
||||
$msg->addParam('</a>', false);
|
||||
$msg->addParamHtml('<a href="./chk_rel.php' . $common_url_query . '">');
|
||||
$msg->addParamHtml('</a>');
|
||||
/* Show error if user has configured something, notice elsewhere */
|
||||
if (!empty($cfg['Servers'][$server]['pmadb'])) {
|
||||
$msg->isError(true);
|
||||
@ -571,48 +574,6 @@ if ($server > 0) {
|
||||
} // end if
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning about different MySQL library and server version
|
||||
* (a difference on the third digit does not count).
|
||||
* If someday there is a constant that we can check about mysqlnd,
|
||||
* we can use it instead of strpos().
|
||||
* If no default server is set, $GLOBALS['dbi'] is not defined yet.
|
||||
* We also do not warn if MariaDB is detected, as it has its own version
|
||||
* numbering.
|
||||
*/
|
||||
if (isset($GLOBALS['dbi'])
|
||||
&& $cfg['ServerLibraryDifference_DisableWarning'] == false
|
||||
) {
|
||||
$_client_info = $GLOBALS['dbi']->getClientInfo();
|
||||
if ($server > 0
|
||||
&& mb_strpos($_client_info, 'mysqlnd') === false
|
||||
&& mb_strpos(PMA_MYSQL_STR_VERSION, 'MariaDB') === false
|
||||
&& substr(PMA_MYSQL_CLIENT_API, 0, 3) != substr(
|
||||
PMA_MYSQL_INT_VERSION, 0, 3
|
||||
)
|
||||
) {
|
||||
trigger_error(
|
||||
PMA_sanitize(
|
||||
sprintf(
|
||||
__(
|
||||
'Your PHP MySQL library version %s differs from your ' .
|
||||
'MySQL server version %s. This may cause unpredictable ' .
|
||||
'behavior.'
|
||||
),
|
||||
$_client_info,
|
||||
substr(
|
||||
PMA_MYSQL_STR_VERSION,
|
||||
0,
|
||||
strpos(PMA_MYSQL_STR_VERSION . '-', '-')
|
||||
)
|
||||
)
|
||||
),
|
||||
E_USER_NOTICE
|
||||
);
|
||||
}
|
||||
unset($_client_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning about Suhosin only if its simulation mode is not enabled
|
||||
*/
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
/* vim: set expandtab sw=4 ts=4 sts=4: */
|
||||
/**
|
||||
* phpMyAdmin's BigInts library
|
||||
*/
|
||||
|
||||
/**
|
||||
* @var BigInts object to handle big integers (in string)
|
||||
* as JS can handle upto 53 bits of precision only.
|
||||
*/
|
||||
var BigInts = {
|
||||
|
||||
/**
|
||||
* Compares two integer strings
|
||||
*
|
||||
* @param int1 the string representation of 1st integer
|
||||
* @param int2 the string representation of 2nd integer
|
||||
*
|
||||
* @return int 0 if equal, < 0 if int1 < int2, else > 0
|
||||
*/
|
||||
compare: function(int1, int2) {
|
||||
// trim integers
|
||||
int1 = int1.trim();
|
||||
int2 = int2.trim();
|
||||
// length of integer strings
|
||||
var len1 = int1.length;
|
||||
var len2 = int2.length;
|
||||
// integer is -ve or not
|
||||
var isNeg1 = (int1[0] === '-');
|
||||
var isNeg2 = (int2[0] === '-');
|
||||
// Sign of int1 != int2 then no actual comparison
|
||||
// is needed we can return result directly
|
||||
if (isNeg1 !== isNeg2) {
|
||||
return (isNeg1 === true ? -1 : 1);
|
||||
}
|
||||
// replace - sign with 0
|
||||
int1[0] = isNeg1 ? '0' : int1[0];
|
||||
int2[0] = isNeg2 ? '0' : int2[0];
|
||||
// pad integers with 0 to make them
|
||||
// equal length
|
||||
int1 = BigInts.lpad(int1, len2);
|
||||
int2 = BigInts.lpad(int2, len1);
|
||||
// Now they are good to compare as strings
|
||||
if (int1 !== int2) {
|
||||
return (int1 < int2 ? -1 : 1);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds leading zeros to a integer given a total length
|
||||
*
|
||||
* @param int the string representation of the integer
|
||||
* @param total the total length required
|
||||
*
|
||||
* @return int the integer of length given with added leading
|
||||
* zeros if necessary
|
||||
*/
|
||||
lpad: function(int, total){
|
||||
var len = int.length;
|
||||
var pad = '';
|
||||
while(len < total) {
|
||||
pad += '0';
|
||||
len++;
|
||||
}
|
||||
return (pad + int);
|
||||
}
|
||||
};
|
||||
@ -1,4 +1,4 @@
|
||||
Copyright (C) 2015 by Marijn Haverbeke <marijnh@gmail.com> and others
|
||||
Copyright (C) 2016 by Marijn Haverbeke <marijnh@gmail.com> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
2
js/codemirror/addon/hint/show-hint.css
vendored
@ -25,8 +25,6 @@
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
max-width: 19em;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
|
||||
147
js/codemirror/addon/hint/show-hint.js
vendored
@ -25,8 +25,18 @@
|
||||
};
|
||||
|
||||
CodeMirror.defineExtension("showHint", function(options) {
|
||||
// We want a single cursor position.
|
||||
if (this.listSelections().length > 1 || this.somethingSelected()) return;
|
||||
options = parseOptions(this, this.getCursor("start"), options);
|
||||
var selections = this.listSelections()
|
||||
if (selections.length > 1) return;
|
||||
// By default, don't allow completion when something is selected.
|
||||
// A hint function can have a `supportsSelection` property to
|
||||
// indicate that it can handle selections.
|
||||
if (this.somethingSelected()) {
|
||||
if (!options.hint.supportsSelection) return;
|
||||
// Don't try with cross-line selections
|
||||
for (var i = 0; i < selections.length; i++)
|
||||
if (selections[i].head.line != selections[i].anchor.line) return;
|
||||
}
|
||||
|
||||
if (this.state.completionActive) this.state.completionActive.close();
|
||||
var completion = this.state.completionActive = new Completion(this, options);
|
||||
@ -38,12 +48,12 @@
|
||||
|
||||
function Completion(cm, options) {
|
||||
this.cm = cm;
|
||||
this.options = this.buildOptions(options);
|
||||
this.options = options;
|
||||
this.widget = null;
|
||||
this.debounce = 0;
|
||||
this.tick = 0;
|
||||
this.startPos = this.cm.getCursor();
|
||||
this.startLen = this.cm.getLine(this.startPos.line).length;
|
||||
this.startPos = this.cm.getCursor("start");
|
||||
this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;
|
||||
|
||||
var self = this;
|
||||
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
|
||||
@ -98,23 +108,22 @@
|
||||
},
|
||||
|
||||
update: function(first) {
|
||||
if (this.tick == null) return;
|
||||
if (this.data) CodeMirror.signal(this.data, "update");
|
||||
if (!this.options.hint.async) {
|
||||
this.finishUpdate(this.options.hint(this.cm, this.options), first);
|
||||
} else {
|
||||
var myTick = ++this.tick, self = this;
|
||||
this.options.hint(this.cm, function(data) {
|
||||
if (self.tick == myTick) self.finishUpdate(data, first);
|
||||
}, this.options);
|
||||
}
|
||||
if (this.tick == null) return
|
||||
var self = this, myTick = ++this.tick
|
||||
fetchHints(this.options.hint, this.cm, this.options, function(data) {
|
||||
if (self.tick == myTick) self.finishUpdate(data, first)
|
||||
})
|
||||
},
|
||||
|
||||
finishUpdate: function(data, first) {
|
||||
this.data = data;
|
||||
if (this.data) CodeMirror.signal(this.data, "update");
|
||||
|
||||
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
|
||||
if (this.widget) this.widget.close();
|
||||
|
||||
if (data && this.data && isNewCompletion(this.data, data)) return;
|
||||
this.data = data;
|
||||
|
||||
if (data && data.list.length) {
|
||||
if (picked && data.list.length == 1) {
|
||||
this.pick(data, 0);
|
||||
@ -123,20 +132,26 @@
|
||||
CodeMirror.signal(data, "shown");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
buildOptions: function(options) {
|
||||
var editor = this.cm.options.hintOptions;
|
||||
var out = {};
|
||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
||||
if (editor) for (var prop in editor)
|
||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
||||
if (options) for (var prop in options)
|
||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
function isNewCompletion(old, nw) {
|
||||
var moved = CodeMirror.cmpPos(nw.from, old.from)
|
||||
return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
|
||||
}
|
||||
|
||||
function parseOptions(cm, pos, options) {
|
||||
var editor = cm.options.hintOptions;
|
||||
var out = {};
|
||||
for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
|
||||
if (editor) for (var prop in editor)
|
||||
if (editor[prop] !== undefined) out[prop] = editor[prop];
|
||||
if (options) for (var prop in options)
|
||||
if (options[prop] !== undefined) out[prop] = options[prop];
|
||||
if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
|
||||
return out;
|
||||
}
|
||||
|
||||
function getText(completion) {
|
||||
if (typeof completion == "string") return completion;
|
||||
else return completion.text;
|
||||
@ -214,6 +229,9 @@
|
||||
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
||||
(completion.options.container || document.body).appendChild(hints);
|
||||
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
|
||||
var scrolls = hints.scrollHeight > hints.clientHeight + 1
|
||||
var startScroll = cm.getScrollInfo();
|
||||
|
||||
if (overlapY > 0) {
|
||||
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
|
||||
if (curTop - height > 0) { // Fits above cursor
|
||||
@ -238,6 +256,8 @@
|
||||
}
|
||||
hints.style.left = (left = pos.left - overlapX) + "px";
|
||||
}
|
||||
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
|
||||
node.style.paddingRight = cm.display.nativeBarWidth + "px"
|
||||
|
||||
cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
|
||||
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
|
||||
@ -255,7 +275,6 @@
|
||||
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
|
||||
}
|
||||
|
||||
var startScroll = cm.getScrollInfo();
|
||||
cm.on("scroll", this.onScroll = function() {
|
||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
|
||||
var newTop = top + startScroll.top - curScroll.top;
|
||||
@ -335,34 +354,70 @@
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", function(cm, options) {
|
||||
var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
|
||||
if (helpers.length) {
|
||||
for (var i = 0; i < helpers.length; i++) {
|
||||
var cur = helpers[i](cm, options);
|
||||
if (cur && cur.list.length) return cur;
|
||||
}
|
||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
||||
if (words) return CodeMirror.hint.fromList(cm, {words: words});
|
||||
} else if (CodeMirror.hint.anyword) {
|
||||
return CodeMirror.hint.anyword(cm, options);
|
||||
function applicableHelpers(cm, helpers) {
|
||||
if (!cm.somethingSelected()) return helpers
|
||||
var result = []
|
||||
for (var i = 0; i < helpers.length; i++)
|
||||
if (helpers[i].supportsSelection) result.push(helpers[i])
|
||||
return result
|
||||
}
|
||||
|
||||
function fetchHints(hint, cm, options, callback) {
|
||||
if (hint.async) {
|
||||
hint(cm, callback, options)
|
||||
} else {
|
||||
var result = hint(cm, options)
|
||||
if (result && result.then) result.then(callback)
|
||||
else callback(result)
|
||||
}
|
||||
}
|
||||
|
||||
function resolveAutoHints(cm, pos) {
|
||||
var helpers = cm.getHelpers(pos, "hint"), words
|
||||
if (helpers.length) {
|
||||
var resolved = function(cm, callback, options) {
|
||||
var app = applicableHelpers(cm, helpers);
|
||||
function run(i) {
|
||||
if (i == app.length) return callback(null)
|
||||
fetchHints(app[i], cm, options, function(result) {
|
||||
if (result && result.list.length > 0) callback(result)
|
||||
else run(i + 1)
|
||||
})
|
||||
}
|
||||
run(0)
|
||||
}
|
||||
resolved.async = true
|
||||
resolved.supportsSelection = true
|
||||
return resolved
|
||||
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
|
||||
return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
|
||||
} else if (CodeMirror.hint.anyword) {
|
||||
return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
|
||||
} else {
|
||||
return function() {}
|
||||
}
|
||||
}
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", {
|
||||
resolve: resolveAutoHints
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
|
||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
||||
var to = CodeMirror.Pos(cur.line, token.end);
|
||||
if (token.string && /\w/.test(token.string[token.string.length - 1])) {
|
||||
var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
|
||||
} else {
|
||||
var term = "", from = to;
|
||||
}
|
||||
var found = [];
|
||||
for (var i = 0; i < options.words.length; i++) {
|
||||
var word = options.words[i];
|
||||
if (word.slice(0, token.string.length) == token.string)
|
||||
if (word.slice(0, term.length) == term)
|
||||
found.push(word);
|
||||
}
|
||||
|
||||
if (found.length) return {
|
||||
list: found,
|
||||
from: CodeMirror.Pos(cur.line, token.start),
|
||||
to: CodeMirror.Pos(cur.line, token.end)
|
||||
};
|
||||
if (found.length) return {list: found, from: from, to: to};
|
||||
});
|
||||
|
||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
||||
@ -373,7 +428,7 @@
|
||||
alignWithWord: true,
|
||||
closeCharacters: /[\s()\[\]{};:>,]/,
|
||||
closeOnUnfocus: true,
|
||||
completeOnSingleClick: false,
|
||||
completeOnSingleClick: true,
|
||||
container: null,
|
||||
customKeys: null,
|
||||
extraKeys: null
|
||||
|
||||
83
js/codemirror/addon/hint/sql-hint.js
vendored
@ -18,7 +18,9 @@
|
||||
QUERY_DIV: ";",
|
||||
ALIAS_KEYWORD: "AS"
|
||||
};
|
||||
var Pos = CodeMirror.Pos;
|
||||
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
|
||||
|
||||
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
|
||||
|
||||
function getKeywords(editor) {
|
||||
var mode = editor.doc.modeOption;
|
||||
@ -30,10 +32,28 @@
|
||||
return typeof item == "string" ? item : item.text;
|
||||
}
|
||||
|
||||
function getItem(list, item) {
|
||||
if (!list.slice) return list[item];
|
||||
for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)
|
||||
return list[i];
|
||||
function wrapTable(name, value) {
|
||||
if (isArray(value)) value = {columns: value}
|
||||
if (!value.text) value.text = name
|
||||
return value
|
||||
}
|
||||
|
||||
function parseTables(input) {
|
||||
var result = {}
|
||||
if (isArray(input)) {
|
||||
for (var i = input.length - 1; i >= 0; i--) {
|
||||
var item = input[i]
|
||||
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
||||
}
|
||||
} else if (input) {
|
||||
for (var name in input)
|
||||
result[name.toUpperCase()] = wrapTable(name, input[name])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getTable(name) {
|
||||
return tables[name.toUpperCase()]
|
||||
}
|
||||
|
||||
function shallowClone(object) {
|
||||
@ -50,11 +70,18 @@
|
||||
}
|
||||
|
||||
function addMatches(result, search, wordlist, formatter) {
|
||||
for (var word in wordlist) {
|
||||
if (!wordlist.hasOwnProperty(word)) continue;
|
||||
if (wordlist.slice) word = wordlist[word];
|
||||
|
||||
if (match(search, word)) result.push(formatter(word));
|
||||
if (isArray(wordlist)) {
|
||||
for (var i = 0; i < wordlist.length; i++)
|
||||
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
|
||||
} else {
|
||||
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
|
||||
var val = wordlist[word]
|
||||
if (!val || val === true)
|
||||
val = word
|
||||
else
|
||||
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
|
||||
if (match(search, val)) result.push(formatter(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +105,7 @@
|
||||
}
|
||||
|
||||
function nameCompletion(cur, token, result, editor) {
|
||||
// Try to complete table, colunm names and return start position of completion
|
||||
// Try to complete table, column names and return start position of completion
|
||||
var useBacktick = false;
|
||||
var nameParts = [];
|
||||
var start = token.start;
|
||||
@ -115,13 +142,13 @@
|
||||
var alias = false;
|
||||
var aliasTable = table;
|
||||
// Check if table is available. If not, find table by Alias
|
||||
if (!getItem(tables, table)) {
|
||||
if (!getTable(table)) {
|
||||
var oldTable = table;
|
||||
table = findTableByAlias(table, editor);
|
||||
if (table !== oldTable) alias = true;
|
||||
}
|
||||
|
||||
var columns = getItem(tables, table);
|
||||
var columns = getTable(table);
|
||||
if (columns && columns.columns)
|
||||
columns = columns.columns;
|
||||
|
||||
@ -151,15 +178,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function convertCurToNumber(cur) {
|
||||
// max characters of a line is 999,999.
|
||||
return cur.line + cur.ch / Math.pow(10, 6);
|
||||
}
|
||||
|
||||
function convertNumberToCur(num) {
|
||||
return Pos(Math.floor(num), +num.toString().split('.').pop());
|
||||
}
|
||||
|
||||
function findTableByAlias(alias, editor) {
|
||||
var doc = editor.doc;
|
||||
var fullQuery = doc.getValue();
|
||||
@ -182,15 +200,14 @@
|
||||
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
|
||||
|
||||
//find valid range
|
||||
var prevItem = 0;
|
||||
var current = convertCurToNumber(editor.getCursor());
|
||||
for (var i=0; i< separator.length; i++) {
|
||||
var _v = convertCurToNumber(separator[i]);
|
||||
if (current > prevItem && current <= _v) {
|
||||
validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) };
|
||||
var prevItem = null;
|
||||
var current = editor.getCursor()
|
||||
for (var i = 0; i < separator.length; i++) {
|
||||
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
||||
validRange = {start: prevItem, end: separator[i]};
|
||||
break;
|
||||
}
|
||||
prevItem = _v;
|
||||
prevItem = separator[i];
|
||||
}
|
||||
|
||||
var query = doc.getRange(validRange.start, validRange.end, false);
|
||||
@ -199,7 +216,7 @@
|
||||
var lineText = query[i];
|
||||
eachWord(lineText, function(word) {
|
||||
var wordUpperCase = word.toUpperCase();
|
||||
if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))
|
||||
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
|
||||
table = previousWord;
|
||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||
previousWord = word;
|
||||
@ -210,11 +227,11 @@
|
||||
}
|
||||
|
||||
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||
tables = (options && options.tables) || {};
|
||||
tables = parseTables(options && options.tables)
|
||||
var defaultTableName = options && options.defaultTable;
|
||||
var disableKeywords = options && options.disableKeywords;
|
||||
defaultTable = defaultTableName && getItem(tables, defaultTableName);
|
||||
keywords = keywords || getKeywords(editor);
|
||||
defaultTable = defaultTableName && getTable(defaultTableName);
|
||||
keywords = getKeywords(editor);
|
||||
|
||||
if (defaultTableName && !defaultTable)
|
||||
defaultTable = findTableByAlias(defaultTableName, editor);
|
||||
|
||||
10
js/codemirror/addon/lint/lint.css
vendored
@ -4,10 +4,11 @@
|
||||
}
|
||||
|
||||
.CodeMirror-lint-tooltip {
|
||||
background-color: infobackground;
|
||||
background-color: #ffd;
|
||||
border: 1px solid black;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
color: infotext;
|
||||
color: black;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
overflow: hidden;
|
||||
padding: 2px 5px;
|
||||
@ -24,11 +25,6 @@
|
||||
-ms-transition: opacity .4s;
|
||||
}
|
||||
|
||||
.CodeMirror-lint-tooltip code {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
|
||||
background-position: left bottom;
|
||||
background-repeat: repeat-x;
|
||||
|
||||
54
js/codemirror/addon/lint/lint.js
vendored
@ -1,5 +1,6 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
@ -60,6 +61,7 @@
|
||||
this.timeout = null;
|
||||
this.hasGutter = hasGutter;
|
||||
this.onMouseOver = function(e) { onMouseOver(cm, e); };
|
||||
this.waitingFor = 0
|
||||
}
|
||||
|
||||
function parseOptions(_cm, options) {
|
||||
@ -111,21 +113,35 @@
|
||||
var tip = document.createElement("div");
|
||||
tip.className = "CodeMirror-lint-message-" + severity;
|
||||
tip.appendChild(document.createTextNode(ann.message));
|
||||
// Unescaping only the <code> tag.
|
||||
tip.innerHTML = tip.innerHTML.replace("<code>", "<code>")
|
||||
.replace("</code>", "</code>");
|
||||
return tip;
|
||||
}
|
||||
|
||||
function lintAsync(cm, getAnnotations, passOptions) {
|
||||
var state = cm.state.lint
|
||||
var id = ++state.waitingFor
|
||||
function abort() {
|
||||
id = -1
|
||||
cm.off("change", abort)
|
||||
}
|
||||
cm.on("change", abort)
|
||||
getAnnotations(cm.getValue(), function(annotations, arg2) {
|
||||
cm.off("change", abort)
|
||||
if (state.waitingFor != id) return
|
||||
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
|
||||
updateLinting(cm, annotations)
|
||||
}, passOptions, cm);
|
||||
}
|
||||
|
||||
function startLinting(cm) {
|
||||
var state = cm.state.lint, options = state.options;
|
||||
var passOptions = options.options || options; // Support deprecated passing of `options` property in options
|
||||
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
|
||||
if (!getAnnotations) return;
|
||||
if (options.async || getAnnotations.async)
|
||||
getAnnotations(cm.getValue(), updateLinting, passOptions, cm);
|
||||
else
|
||||
if (options.async || getAnnotations.async) {
|
||||
lintAsync(cm, getAnnotations, passOptions)
|
||||
} else {
|
||||
updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
|
||||
}
|
||||
}
|
||||
|
||||
function updateLinting(cm, annotationsNotSorted) {
|
||||
@ -170,9 +186,14 @@
|
||||
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
|
||||
}
|
||||
|
||||
function popupSpanTooltip(ann, e) {
|
||||
function popupTooltips(annotations, e) {
|
||||
var target = e.target || e.srcElement;
|
||||
showTooltipFor(e, annotationTooltip(ann), target);
|
||||
var tooltip = document.createDocumentFragment();
|
||||
for (var i = 0; i < annotations.length; i++) {
|
||||
var ann = annotations[i];
|
||||
tooltip.appendChild(annotationTooltip(ann));
|
||||
}
|
||||
showTooltipFor(e, tooltip, target);
|
||||
}
|
||||
|
||||
function onMouseOver(cm, e) {
|
||||
@ -180,16 +201,20 @@
|
||||
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
|
||||
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
|
||||
var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
|
||||
|
||||
var annotations = [];
|
||||
for (var i = 0; i < spans.length; ++i) {
|
||||
var ann = spans[i].__annotation;
|
||||
if (ann) return popupSpanTooltip(ann, e);
|
||||
if (ann) annotations.push(ann);
|
||||
}
|
||||
if (annotations.length) popupTooltips(annotations, e);
|
||||
}
|
||||
|
||||
CodeMirror.defineOption("lint", false, function(cm, val, old) {
|
||||
if (old && old != CodeMirror.Init) {
|
||||
clearMarks(cm);
|
||||
cm.off("change", onChange);
|
||||
if (cm.state.lint.options.lintOnChange !== false)
|
||||
cm.off("change", onChange);
|
||||
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
|
||||
clearTimeout(cm.state.lint.timeout);
|
||||
delete cm.state.lint;
|
||||
@ -199,11 +224,16 @@
|
||||
var gutters = cm.getOption("gutters"), hasLintGutter = false;
|
||||
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
|
||||
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
|
||||
cm.on("change", onChange);
|
||||
if (state.options.tooltips != false)
|
||||
if (state.options.lintOnChange !== false)
|
||||
cm.on("change", onChange);
|
||||
if (state.options.tooltips != false && state.options.tooltips != "gutter")
|
||||
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
|
||||
|
||||
startLinting(cm);
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.defineExtension("performLint", function() {
|
||||
if (this.state.lint) startLinting(this);
|
||||
});
|
||||
});
|
||||
|
||||
2
js/codemirror/addon/runmode/runmode.js
vendored
@ -16,7 +16,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
|
||||
var ie = /MSIE \d/.test(navigator.userAgent);
|
||||
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
|
||||
|
||||
if (callback.nodeType == 1) {
|
||||
if (callback.appendChild) {
|
||||
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
|
||||
var node = callback, col = 0;
|
||||
node.innerHTML = "";
|
||||
|
||||
72
js/codemirror/lib/codemirror.css
vendored
@ -41,19 +41,21 @@
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@ -63,30 +65,37 @@
|
||||
-webkit-animation: blink 1.06s steps(1) infinite;
|
||||
-moz-animation: blink 1.06s steps(1) infinite;
|
||||
animation: blink 1.06s steps(1) infinite;
|
||||
background-color: #7e7;
|
||||
}
|
||||
@-moz-keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% { background: #7e7; }
|
||||
50% { background: none; }
|
||||
100% { background: #7e7; }
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
div.CodeMirror-overwrite div.CodeMirror-cursor {}
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: -20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@ -162,7 +171,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actuall scrolling happens, thus preventing shaking and
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
@ -188,21 +197,26 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -30px;
|
||||
/* Hack to make IE7 behave */
|
||||
*zoom:1;
|
||||
*display:inline;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
height: 100%;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
@ -235,6 +249,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
@ -277,19 +293,22 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
.CodeMirror div.CodeMirror-cursor {
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
@ -297,17 +316,14 @@ div.CodeMirror-cursors {
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror ::selection { background: #d7d4f0; }
|
||||
.CodeMirror ::-moz-selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
|
||||
.CodeMirror span { *vertical-align: text-bottom; }
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
|
||||
16929
js/codemirror/lib/codemirror.js
vendored
227
js/codemirror/mode/javascript/javascript.js
vendored
@ -1,8 +1,6 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
// TODO actually recognize syntax of TypeScript constructs
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
@ -13,6 +11,11 @@
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
function expressionAllowed(stream, state, backUp) {
|
||||
return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
|
||||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var statementIndent = parserConfig.statementIndent;
|
||||
@ -30,14 +33,15 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
var jsKeywords = {
|
||||
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
|
||||
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C,
|
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
||||
"function": kw("function"), "catch": kw("catch"),
|
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
|
||||
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
|
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
|
||||
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
|
||||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
|
||||
"await": C, "async": kw("async")
|
||||
};
|
||||
|
||||
// Extend the 'normal' keywords with the TypeScript language extensions
|
||||
@ -45,18 +49,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var type = {type: "variable", style: "variable-3"};
|
||||
var tsKeywords = {
|
||||
// object-like things
|
||||
"interface": kw("interface"),
|
||||
"extends": kw("extends"),
|
||||
"constructor": kw("constructor"),
|
||||
"interface": kw("class"),
|
||||
"implements": C,
|
||||
"namespace": C,
|
||||
"module": kw("module"),
|
||||
"enum": kw("module"),
|
||||
"type": kw("type"),
|
||||
|
||||
// scope modifiers
|
||||
"public": kw("public"),
|
||||
"private": kw("private"),
|
||||
"protected": kw("protected"),
|
||||
"static": kw("static"),
|
||||
"public": kw("modifier"),
|
||||
"private": kw("modifier"),
|
||||
"protected": kw("modifier"),
|
||||
"abstract": kw("modifier"),
|
||||
|
||||
// operators
|
||||
"as": operator,
|
||||
|
||||
// types
|
||||
"string": type, "number": type, "bool": type, "any": type
|
||||
"string": type, "number": type, "boolean": type, "any": type
|
||||
};
|
||||
|
||||
for (var attr in tsKeywords) {
|
||||
@ -105,6 +115,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
} else if (ch == "0" && stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
} else if (ch == "0" && stream.eat(/o/i)) {
|
||||
stream.eatWhile(/[0-7]/i);
|
||||
return ret("number", "number");
|
||||
} else if (ch == "0" && stream.eat(/b/i)) {
|
||||
stream.eatWhile(/[01]/i);
|
||||
return ret("number", "number");
|
||||
} else if (/\d/.test(ch)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
@ -115,8 +131,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
} else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
||||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
|
||||
} else if (expressionAllowed(stream, state, 1)) {
|
||||
readRegexp(stream);
|
||||
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
|
||||
return ret("regexp", "string-2");
|
||||
@ -131,7 +146,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
} else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
if (ch != ">" || !state.lexical || state.lexical.type != ">")
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", "operator", stream.current());
|
||||
} else if (wordRE.test(ch)) {
|
||||
stream.eatWhile(wordRE);
|
||||
@ -194,13 +210,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var arrow = stream.string.indexOf("=>", stream.start);
|
||||
if (arrow < 0) return;
|
||||
|
||||
if (isTS) { // Try to skip TypeScript return type declarations after the arguments
|
||||
var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
|
||||
if (m) arrow = m.index
|
||||
}
|
||||
|
||||
var depth = 0, sawSomething = false;
|
||||
for (var pos = arrow - 1; pos >= 0; --pos) {
|
||||
var ch = stream.string.charAt(pos);
|
||||
var bracket = brackets.indexOf(ch);
|
||||
if (bracket >= 0 && bracket < 3) {
|
||||
if (!depth) { ++pos; break; }
|
||||
if (--depth == 0) break;
|
||||
if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
|
||||
} else if (bracket >= 3 && bracket < 6) {
|
||||
++depth;
|
||||
} else if (wordRE.test(ch)) {
|
||||
@ -275,8 +296,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
return false;
|
||||
}
|
||||
var state = cx.state;
|
||||
cx.marked = "def";
|
||||
if (state.context) {
|
||||
cx.marked = "def";
|
||||
if (inList(state.localVars)) return;
|
||||
state.localVars = {name: varname, next: state.localVars};
|
||||
} else {
|
||||
@ -329,28 +350,30 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
function statement(type, value) {
|
||||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "if") {
|
||||
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
|
||||
cx.state.cc.pop()();
|
||||
return cont(pushlex("form"), expression, statement, poplex, maybeelse);
|
||||
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
|
||||
}
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
if (type == "case") return cont(expression, expect(":"));
|
||||
if (type == "default") return cont(expect(":"));
|
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
||||
statement, poplex, popcontext);
|
||||
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
|
||||
if (type == "class") return cont(pushlex("form"), className, poplex);
|
||||
if (type == "export") return cont(pushlex("form"), afterExport, poplex);
|
||||
if (type == "import") return cont(pushlex("form"), afterImport, poplex);
|
||||
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
|
||||
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
|
||||
if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
|
||||
if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";"));
|
||||
if (type == "async") return cont(statement)
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
@ -359,6 +382,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
function expressionNoComma(type) {
|
||||
return expressionInner(type, true);
|
||||
}
|
||||
function parenExpr(type) {
|
||||
if (type != "(") return pass()
|
||||
return cont(pushlex(")"), expression, expect(")"), poplex)
|
||||
}
|
||||
function expressionInner(type, noComma) {
|
||||
if (cx.state.fatArrowAt == cx.stream.start) {
|
||||
var body = noComma ? arrowBodyNoComma : arrowBody;
|
||||
@ -369,12 +396,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
|
||||
if (type == "function") return cont(functiondef, maybeop);
|
||||
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
|
||||
if (type == "class") return cont(pushlex("form"), classExpression, poplex);
|
||||
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
|
||||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
|
||||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
|
||||
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
|
||||
if (type == "quasi") { return pass(quasi, maybeop); }
|
||||
if (type == "quasi") return pass(quasi, maybeop);
|
||||
if (type == "new") return cont(maybeTarget(noComma));
|
||||
return cont();
|
||||
}
|
||||
function maybeexpression(type) {
|
||||
@ -425,6 +454,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
findFatArrow(cx.stream, cx.state);
|
||||
return pass(type == "{" ? statement : expressionNoComma);
|
||||
}
|
||||
function maybeTarget(noComma) {
|
||||
return function(type) {
|
||||
if (type == ".") return cont(noComma ? targetNoComma : target);
|
||||
else return pass(noComma ? expressionNoComma : expression);
|
||||
};
|
||||
}
|
||||
function target(_, value) {
|
||||
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
|
||||
}
|
||||
function targetNoComma(_, value) {
|
||||
if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
|
||||
}
|
||||
function maybelabel(type) {
|
||||
if (type == ":") return cont(poplex, statement);
|
||||
return pass(maybeoperatorComma, expect(";"), poplex);
|
||||
@ -433,7 +474,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (type == "variable") {cx.marked = "property"; return cont();}
|
||||
}
|
||||
function objprop(type, value) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
if (type == "async") {
|
||||
cx.marked = "property";
|
||||
return cont(objprop);
|
||||
} else if (type == "variable" || cx.style == "keyword") {
|
||||
cx.marked = "property";
|
||||
if (value == "get" || value == "set") return cont(getterSetter);
|
||||
return cont(afterprop);
|
||||
@ -442,8 +486,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
return cont(afterprop);
|
||||
} else if (type == "jsonld-keyword") {
|
||||
return cont(afterprop);
|
||||
} else if (type == "modifier") {
|
||||
return cont(objprop)
|
||||
} else if (type == "[") {
|
||||
return cont(expression, expect("]"), afterprop);
|
||||
} else if (type == "spread") {
|
||||
return cont(expression);
|
||||
} else if (type == ":") {
|
||||
return pass(afterprop)
|
||||
}
|
||||
}
|
||||
function getterSetter(type) {
|
||||
@ -456,17 +506,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (type == "(") return pass(functiondef);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
function proceed(type, value) {
|
||||
if (type == ",") {
|
||||
var lex = cx.state.lexical;
|
||||
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
|
||||
return cont(what, proceed);
|
||||
return cont(function(type, value) {
|
||||
if (type == end || value == end) return pass()
|
||||
return pass(what)
|
||||
}, proceed);
|
||||
}
|
||||
if (type == end) return cont();
|
||||
if (type == end || value == end) return cont();
|
||||
return cont(expect(end));
|
||||
}
|
||||
return function(type) {
|
||||
if (type == end) return cont();
|
||||
return function(type, value) {
|
||||
if (type == end || value == end) return cont();
|
||||
return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
@ -479,20 +532,45 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function maybetype(type) {
|
||||
if (isTS && type == ":") return cont(typedef);
|
||||
function maybetype(type, value) {
|
||||
if (isTS) {
|
||||
if (type == ":") return cont(typeexpr);
|
||||
if (value == "?") return cont(maybetype);
|
||||
}
|
||||
}
|
||||
function maybedefault(_, value) {
|
||||
if (value == "=") return cont(expressionNoComma);
|
||||
function typeexpr(type) {
|
||||
if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);}
|
||||
if (type == "string" || type == "number" || type == "atom") return cont(afterType);
|
||||
if (type == "{") return cont(commasep(typeprop, "}"))
|
||||
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType)
|
||||
}
|
||||
function typedef(type) {
|
||||
if (type == "variable") {cx.marked = "variable-3"; return cont();}
|
||||
function maybeReturnType(type) {
|
||||
if (type == "=>") return cont(typeexpr)
|
||||
}
|
||||
function typeprop(type) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
cx.marked = "property"
|
||||
return cont(typeprop)
|
||||
} else if (type == ":") {
|
||||
return cont(typeexpr)
|
||||
}
|
||||
}
|
||||
function typearg(type) {
|
||||
if (type == "variable") return cont(typearg)
|
||||
else if (type == ":") return cont(typeexpr)
|
||||
}
|
||||
function afterType(type, value) {
|
||||
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
|
||||
if (value == "|" || type == ".") return cont(typeexpr)
|
||||
if (type == "[") return cont(expect("]"), afterType)
|
||||
}
|
||||
function vardef() {
|
||||
return pass(pattern, maybetype, maybeAssign, vardefCont);
|
||||
}
|
||||
function pattern(type, value) {
|
||||
if (type == "modifier") return cont(pattern)
|
||||
if (type == "variable") { register(value); return cont(); }
|
||||
if (type == "spread") return cont(pattern);
|
||||
if (type == "[") return contCommasep(pattern, "]");
|
||||
if (type == "{") return contCommasep(proppattern, "}");
|
||||
}
|
||||
@ -502,6 +580,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
return cont(maybeAssign);
|
||||
}
|
||||
if (type == "variable") cx.marked = "property";
|
||||
if (type == "spread") return cont(pattern);
|
||||
if (type == "}") return pass();
|
||||
return cont(expect(":"), pattern, maybeAssign);
|
||||
}
|
||||
function maybeAssign(_type, value) {
|
||||
@ -537,28 +617,34 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
function functiondef(type, value) {
|
||||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext);
|
||||
}
|
||||
function funarg(type) {
|
||||
if (type == "spread") return cont(funarg);
|
||||
return pass(pattern, maybetype, maybedefault);
|
||||
return pass(pattern, maybetype, maybeAssign);
|
||||
}
|
||||
function classExpression(type, value) {
|
||||
// Class expressions may have an optional name.
|
||||
if (type == "variable") return className(type, value);
|
||||
return classNameAfter(type, value);
|
||||
}
|
||||
function className(type, value) {
|
||||
if (type == "variable") {register(value); return cont(classNameAfter);}
|
||||
}
|
||||
function classNameAfter(type, value) {
|
||||
if (value == "extends") return cont(expression, classNameAfter);
|
||||
if (value == "extends" || value == "implements") return cont(isTS ? typeexpr : expression, classNameAfter);
|
||||
if (type == "{") return cont(pushlex("}"), classBody, poplex);
|
||||
}
|
||||
function classBody(type, value) {
|
||||
if (type == "variable" || cx.style == "keyword") {
|
||||
if (value == "static") {
|
||||
if ((value == "static" || value == "get" || value == "set" ||
|
||||
(isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) &&
|
||||
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) {
|
||||
cx.marked = "keyword";
|
||||
return cont(classBody);
|
||||
}
|
||||
cx.marked = "property";
|
||||
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
|
||||
return cont(functiondef, classBody);
|
||||
return cont(isTS ? classfield : functiondef, classBody);
|
||||
}
|
||||
if (value == "*") {
|
||||
cx.marked = "keyword";
|
||||
@ -567,23 +653,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (type == ";") return cont(classBody);
|
||||
if (type == "}") return cont();
|
||||
}
|
||||
function classGetterSetter(type) {
|
||||
if (type != "variable") return pass();
|
||||
cx.marked = "property";
|
||||
return cont();
|
||||
function classfield(type, value) {
|
||||
if (value == "?") return cont(classfield)
|
||||
if (type == ":") return cont(typeexpr, maybeAssign)
|
||||
return pass(functiondef)
|
||||
}
|
||||
function afterModule(type, value) {
|
||||
if (type == "string") return cont(statement);
|
||||
if (type == "variable") { register(value); return cont(maybeFrom); }
|
||||
}
|
||||
function afterExport(_type, value) {
|
||||
function afterExport(type, value) {
|
||||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
|
||||
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
|
||||
if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
|
||||
return pass(statement);
|
||||
}
|
||||
function exportField(type, value) {
|
||||
if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
|
||||
if (type == "variable") return pass(expressionNoComma, exportField);
|
||||
}
|
||||
function afterImport(type) {
|
||||
if (type == "string") return cont();
|
||||
return pass(importSpec, maybeFrom);
|
||||
return pass(importSpec, maybeMoreImports, maybeFrom);
|
||||
}
|
||||
function importSpec(type, value) {
|
||||
if (type == "{") return contCommasep(importSpec, "}");
|
||||
@ -591,6 +678,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (value == "*") cx.marked = "keyword";
|
||||
return cont(maybeAs);
|
||||
}
|
||||
function maybeMoreImports(type) {
|
||||
if (type == ",") return cont(importSpec, maybeMoreImports)
|
||||
}
|
||||
function maybeAs(_type, value) {
|
||||
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
|
||||
}
|
||||
@ -599,17 +689,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
}
|
||||
function arrayLiteral(type) {
|
||||
if (type == "]") return cont();
|
||||
return pass(expressionNoComma, maybeArrayComprehension);
|
||||
}
|
||||
function maybeArrayComprehension(type) {
|
||||
if (type == "for") return pass(comprehension, expect("]"));
|
||||
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
|
||||
return pass(commasep(expressionNoComma, "]"));
|
||||
}
|
||||
function comprehension(type) {
|
||||
if (type == "for") return cont(forspec, comprehension);
|
||||
if (type == "if") return cont(expression, comprehension);
|
||||
}
|
||||
|
||||
function isContinuedStatement(state, textAfter) {
|
||||
return state.lastType == "operator" || state.lastType == "," ||
|
||||
@ -628,7 +709,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
indented: basecolumn || 0
|
||||
};
|
||||
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
|
||||
state.globalVars = parserConfig.globalVars;
|
||||
@ -652,14 +733,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize == tokenComment) return CodeMirror.Pass;
|
||||
if (state.tokenize != tokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
|
||||
// Kludge to prevent 'maybelse' from blocking lexical scope pops
|
||||
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
|
||||
var c = state.cc[i];
|
||||
if (c == poplex) lexical = lexical.prev;
|
||||
else if (c != maybeelse) break;
|
||||
}
|
||||
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
|
||||
while ((lexical.type == "stat" || lexical.type == "form") &&
|
||||
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
|
||||
(top == maybeoperatorComma || top == maybeoperatorNoComma) &&
|
||||
!/^[,\.=+\-*:?[\(]/.test(textAfter))))
|
||||
lexical = lexical.prev;
|
||||
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
|
||||
lexical = lexical.prev;
|
||||
var type = lexical.type, closing = firstChar == type;
|
||||
@ -684,7 +769,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
|
||||
helperType: jsonMode ? "json" : "javascript",
|
||||
jsonldMode: jsonldMode,
|
||||
jsonMode: jsonMode
|
||||
jsonMode: jsonMode,
|
||||
|
||||
expressionAllowed: expressionAllowed,
|
||||
skipExpression: function(state) {
|
||||
var top = state.cc[state.cc.length - 1]
|
||||
if (top == expression || top == expressionNoComma) state.cc.pop()
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
44
js/codemirror/mode/sql/sql.js
vendored
150
js/codemirror/mode/xml/xml.js
vendored
@ -11,54 +11,56 @@
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
|
||||
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
|
||||
if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
|
||||
var htmlConfig = {
|
||||
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
|
||||
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
|
||||
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
|
||||
'track': true, 'wbr': true, 'menuitem': true},
|
||||
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
|
||||
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
|
||||
'th': true, 'tr': true},
|
||||
contextGrabbers: {
|
||||
'dd': {'dd': true, 'dt': true},
|
||||
'dt': {'dd': true, 'dt': true},
|
||||
'li': {'li': true},
|
||||
'option': {'option': true, 'optgroup': true},
|
||||
'optgroup': {'optgroup': true},
|
||||
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
|
||||
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
|
||||
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
|
||||
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
|
||||
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
|
||||
'rp': {'rp': true, 'rt': true},
|
||||
'rt': {'rp': true, 'rt': true},
|
||||
'tbody': {'tbody': true, 'tfoot': true},
|
||||
'td': {'td': true, 'th': true},
|
||||
'tfoot': {'tbody': true},
|
||||
'th': {'td': true, 'th': true},
|
||||
'thead': {'tbody': true, 'tfoot': true},
|
||||
'tr': {'tr': true}
|
||||
},
|
||||
doNotIndent: {"pre": true},
|
||||
allowUnquoted: true,
|
||||
allowMissing: true,
|
||||
caseFold: true
|
||||
}
|
||||
|
||||
var Kludges = parserConfig.htmlMode ? {
|
||||
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
|
||||
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
|
||||
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
|
||||
'track': true, 'wbr': true, 'menuitem': true},
|
||||
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
|
||||
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
|
||||
'th': true, 'tr': true},
|
||||
contextGrabbers: {
|
||||
'dd': {'dd': true, 'dt': true},
|
||||
'dt': {'dd': true, 'dt': true},
|
||||
'li': {'li': true},
|
||||
'option': {'option': true, 'optgroup': true},
|
||||
'optgroup': {'optgroup': true},
|
||||
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
|
||||
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
|
||||
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
|
||||
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
|
||||
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
|
||||
'rp': {'rp': true, 'rt': true},
|
||||
'rt': {'rp': true, 'rt': true},
|
||||
'tbody': {'tbody': true, 'tfoot': true},
|
||||
'td': {'td': true, 'th': true},
|
||||
'tfoot': {'tbody': true},
|
||||
'th': {'td': true, 'th': true},
|
||||
'thead': {'tbody': true, 'tfoot': true},
|
||||
'tr': {'tr': true}
|
||||
},
|
||||
doNotIndent: {"pre": true},
|
||||
allowUnquoted: true,
|
||||
allowMissing: true,
|
||||
caseFold: true
|
||||
} : {
|
||||
autoSelfClosers: {},
|
||||
implicitlyClosed: {},
|
||||
contextGrabbers: {},
|
||||
doNotIndent: {},
|
||||
allowUnquoted: false,
|
||||
allowMissing: false,
|
||||
caseFold: false
|
||||
};
|
||||
var alignCDATA = parserConfig.alignCDATA;
|
||||
var xmlConfig = {
|
||||
autoSelfClosers: {},
|
||||
implicitlyClosed: {},
|
||||
contextGrabbers: {},
|
||||
doNotIndent: {},
|
||||
allowUnquoted: false,
|
||||
allowMissing: false,
|
||||
caseFold: false
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("xml", function(editorConf, config_) {
|
||||
var indentUnit = editorConf.indentUnit
|
||||
var config = {}
|
||||
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
|
||||
for (var prop in defaults) config[prop] = defaults[prop]
|
||||
for (var prop in config_) config[prop] = config_[prop]
|
||||
|
||||
// Return variables for tokenizers
|
||||
var type, setStyle;
|
||||
@ -109,6 +111,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
inText.isInText = true;
|
||||
|
||||
function inTag(stream, state) {
|
||||
var ch = stream.next();
|
||||
@ -187,7 +190,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
this.tagName = tagName;
|
||||
this.indent = state.indented;
|
||||
this.startOfLine = startOfLine;
|
||||
if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
|
||||
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
|
||||
this.noIndent = true;
|
||||
}
|
||||
function popContext(state) {
|
||||
@ -200,8 +203,8 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
return;
|
||||
}
|
||||
parentTagName = state.context.tagName;
|
||||
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
|
||||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
|
||||
return;
|
||||
}
|
||||
popContext(state);
|
||||
@ -232,9 +235,9 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
if (type == "word") {
|
||||
var tagName = stream.current();
|
||||
if (state.context && state.context.tagName != tagName &&
|
||||
Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
|
||||
config.implicitlyClosed.hasOwnProperty(state.context.tagName))
|
||||
popContext(state);
|
||||
if (state.context && state.context.tagName == tagName) {
|
||||
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
|
||||
setStyle = "tag";
|
||||
return closeState;
|
||||
} else {
|
||||
@ -268,7 +271,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
var tagName = state.tagName, tagStart = state.tagStart;
|
||||
state.tagName = state.tagStart = null;
|
||||
if (type == "selfcloseTag" ||
|
||||
Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
|
||||
config.autoSelfClosers.hasOwnProperty(tagName)) {
|
||||
maybePopContext(state, tagName);
|
||||
} else {
|
||||
maybePopContext(state, tagName);
|
||||
@ -281,12 +284,12 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
}
|
||||
function attrEqState(type, stream, state) {
|
||||
if (type == "equals") return attrValueState;
|
||||
if (!Kludges.allowMissing) setStyle = "error";
|
||||
if (!config.allowMissing) setStyle = "error";
|
||||
return attrState(type, stream, state);
|
||||
}
|
||||
function attrValueState(type, stream, state) {
|
||||
if (type == "string") return attrContinuedState;
|
||||
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
|
||||
if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
|
||||
setStyle = "error";
|
||||
return attrState(type, stream, state);
|
||||
}
|
||||
@ -296,12 +299,14 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {tokenize: inText,
|
||||
state: baseState,
|
||||
indented: 0,
|
||||
tagName: null, tagStart: null,
|
||||
context: null};
|
||||
startState: function(baseIndent) {
|
||||
var state = {tokenize: inText,
|
||||
state: baseState,
|
||||
indented: baseIndent || 0,
|
||||
tagName: null, tagStart: null,
|
||||
context: null}
|
||||
if (baseIndent != null) state.baseIndent = baseIndent
|
||||
return state
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
@ -334,19 +339,19 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
|
||||
// Indent the starts of attribute names.
|
||||
if (state.tagName) {
|
||||
if (multilineTagIndentPastTag)
|
||||
if (config.multilineTagIndentPastTag !== false)
|
||||
return state.tagStart + state.tagName.length + 2;
|
||||
else
|
||||
return state.tagStart + indentUnit * multilineTagIndentFactor;
|
||||
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
|
||||
}
|
||||
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
||||
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
|
||||
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
|
||||
if (tagAfter && tagAfter[1]) { // Closing tag spotted
|
||||
while (context) {
|
||||
if (context.tagName == tagAfter[2]) {
|
||||
context = context.prev;
|
||||
break;
|
||||
} else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
|
||||
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
|
||||
context = context.prev;
|
||||
} else {
|
||||
break;
|
||||
@ -354,25 +359,30 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
|
||||
}
|
||||
} else if (tagAfter) { // Opening tag spotted
|
||||
while (context) {
|
||||
var grabbers = Kludges.contextGrabbers[context.tagName];
|
||||
var grabbers = config.contextGrabbers[context.tagName];
|
||||
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
|
||||
context = context.prev;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (context && !context.startOfLine)
|
||||
while (context && context.prev && !context.startOfLine)
|
||||
context = context.prev;
|
||||
if (context) return context.indent + indentUnit;
|
||||
else return 0;
|
||||
else return state.baseIndent || 0;
|
||||
},
|
||||
|
||||
electricInput: /<\/[\s\w:]+>$/,
|
||||
blockCommentStart: "<!--",
|
||||
blockCommentEnd: "-->",
|
||||
|
||||
configuration: parserConfig.htmlMode ? "html" : "xml",
|
||||
helperType: parserConfig.htmlMode ? "html" : "xml"
|
||||
configuration: config.htmlMode ? "html" : "xml",
|
||||
helperType: config.htmlMode ? "html" : "xml",
|
||||
|
||||
skipAttribute: function(state) {
|
||||
if (state.state == attrValueState)
|
||||
state.state = attrState
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@ -84,9 +84,15 @@ var PMA_commonParams = (function () {
|
||||
* @return string
|
||||
*/
|
||||
getUrlQuery: function () {
|
||||
var common = this.get('common_query');
|
||||
var separator = '?';
|
||||
if (common.length > 0) {
|
||||
separator = '&';
|
||||
}
|
||||
return PMA_sprintf(
|
||||
'%s&server=%s&db=%s&table=%s',
|
||||
'%s%sserver=%s&db=%s&table=%s',
|
||||
this.get('common_query'),
|
||||
separator,
|
||||
encodeURIComponent(this.get('server')),
|
||||
encodeURIComponent(this.get('db')),
|
||||
encodeURIComponent(this.get('table'))
|
||||
|
||||
22
js/config.js
@ -585,10 +585,10 @@ function setTab(tab_id)
|
||||
{
|
||||
$('ul.tabs').each(function() {
|
||||
var $this = $(this);
|
||||
if (!$this.find('li a[href=#' + tab_id + ']').length) {
|
||||
if (!$this.find('li a[href="#' + tab_id + '"]').length) {
|
||||
return;
|
||||
}
|
||||
$this.find('li').removeClass('active').find('a[href=#' + tab_id + ']').parent().addClass('active');
|
||||
$this.find('li').removeClass('active').find('a[href="#' + tab_id + '"]').parent().addClass('active');
|
||||
$this.parent().find('div.tabs_contents fieldset').hide().filter('#' + tab_id).show();
|
||||
var hashValue = 'tab_' + tab_id;
|
||||
location.hash = hashValue;
|
||||
@ -798,8 +798,8 @@ function savePrefsToLocalStorage(form)
|
||||
type: 'POST',
|
||||
data: {
|
||||
ajax_request: true,
|
||||
server: $form.find('input[name=server]').val(),
|
||||
token: $form.find('input[name=token]').val(),
|
||||
server: PMA_commonParams.get('server'),
|
||||
token: PMA_commonParams.get('token'),
|
||||
submit_get_json: true
|
||||
},
|
||||
success: function (data) {
|
||||
@ -838,7 +838,7 @@ function updatePrefsDate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares message which informs that localStorage preferences are available and can be imported
|
||||
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
|
||||
*/
|
||||
function offerPrefsAutoimport()
|
||||
{
|
||||
@ -853,7 +853,17 @@ function offerPrefsAutoimport()
|
||||
if ($a.attr('href') == '#no') {
|
||||
$cnt.remove();
|
||||
$.post('index.php', {
|
||||
token: $cnt.find('input[name=token]').val(),
|
||||
token: PMA_commonParams.get('token'),
|
||||
server: PMA_commonParams.get('server'),
|
||||
prefs_autoload: 'hide'
|
||||
}, null, 'html');
|
||||
return;
|
||||
} else if ($a.attr('href') == '#delete') {
|
||||
$cnt.remove();
|
||||
localStorage.clear();
|
||||
$.post('index.php', {
|
||||
token: PMA_commonParams.get('token'),
|
||||
server: PMA_commonParams.get('server'),
|
||||
prefs_autoload: 'hide'
|
||||
}, null, 'html');
|
||||
return;
|
||||
|
||||
@ -127,12 +127,6 @@ var PMA_console = {
|
||||
PMA_consoleDebug.initialize();
|
||||
|
||||
PMA_console.$consoleToolbar.children('.console_switch').click(PMA_console.toggle);
|
||||
$(document).keydown(function(event) {
|
||||
// Ctrl + Alt + C
|
||||
if (event.ctrlKey && event.altKey && event.keyCode === 67) {
|
||||
PMA_console.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
$('#pma_console').find('.toolbar').children().mousedown(function(event) {
|
||||
event.preventDefault();
|
||||
@ -196,9 +190,10 @@ var PMA_console = {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var data = $.parseJSON(xhr.responseText);
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
PMA_console.ajaxCallback(data);
|
||||
} catch (e) {
|
||||
console.trace();
|
||||
console.log("Invalid JSON!" + e.message);
|
||||
if (AJAX.xhr && AJAX.xhr.status === 0 && AJAX.xhr.statusText !== 'abort') {
|
||||
PMA_ajaxShowMessage($('<div />',{'class':'error','html':PMA_messages.strRequestFailed+' ( '+escapeHtml(AJAX.xhr.statusText)+' )'}));
|
||||
@ -255,7 +250,7 @@ var PMA_console = {
|
||||
if (options && options.profiling === true) {
|
||||
PMA_console.$requestForm.append('<input name="profiling" value="on">');
|
||||
}
|
||||
if (! confirmQuery(PMA_console.$requestForm[0], PMA_console.$requestForm.children('textarea')[0])) {
|
||||
if (! confirmQuery(PMA_console.$requestForm[0], PMA_console.$requestForm.children('textarea')[0].value)) {
|
||||
return;
|
||||
}
|
||||
PMA_console.$requestForm.children('[name=console_message_id]')
|
||||
|
||||
@ -132,7 +132,6 @@ AJAX.registerOnload('db_central_columns.js', function () {
|
||||
$('#tableslistcontainer').find('.checkall').show();
|
||||
});
|
||||
$('.edit_save_form').click(function(event) {
|
||||
//alert(1);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var rownum = $(this).data('rownum');
|
||||
@ -142,14 +141,14 @@ AJAX.registerOnload('db_central_columns.js', function () {
|
||||
.attr('name', $(this).attr('name'));
|
||||
}
|
||||
});
|
||||
|
||||
if($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
|
||||
$('#f_' + rownum + ' .default_type').attr('name','col_default_sel');
|
||||
} else {
|
||||
$('#f_' + rownum + ' .default_value').attr('name','col_default_val');
|
||||
}
|
||||
// alert(rownum);
|
||||
|
||||
var datastring = $('#f_' + rownum + ' :input').serialize();
|
||||
//console.log(datastring);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "db_central_columns.php",
|
||||
|
||||
@ -41,7 +41,7 @@ AJAX.registerOnload('db_operations.js', function () {
|
||||
var new_db_name = $('#new_db_name').val();
|
||||
|
||||
if (new_db_name == old_db_name) {
|
||||
PMA_ajaxShowMessage(PMA_messages.strDropDatabaseStrongWarning);
|
||||
PMA_ajaxShowMessage(PMA_messages.strDatabaseRenameToSameName, false, "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -133,11 +133,16 @@ AJAX.registerOnload('db_operations.js', function () {
|
||||
var question = PMA_messages.strDropDatabaseStrongWarning + ' ';
|
||||
question += PMA_sprintf(
|
||||
PMA_messages.strDoYouReally,
|
||||
'DROP DATABASE ' + escapeHtml(PMA_commonParams.get('db'))
|
||||
'DROP DATABASE `' + escapeHtml(PMA_commonParams.get('db') + '`')
|
||||
);
|
||||
var params = {
|
||||
'is_js_confirmed': '1',
|
||||
'ajax_request': true,
|
||||
'token': PMA_commonParams.get('token')
|
||||
};
|
||||
$(this).PMA_confirm(question, $(this).attr('href'), function (url) {
|
||||
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
|
||||
$.post(url, {'is_js_confirmed': '1', 'ajax_request': true}, function (data) {
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success) {
|
||||
//Database deleted successfully, refresh both the frames
|
||||
PMA_reloadNavigation();
|
||||
|
||||
@ -129,7 +129,8 @@ AJAX.registerOnload('db_search.js', function () {
|
||||
var params = {
|
||||
'ajax_request': true,
|
||||
'is_js_confirmed': true,
|
||||
'sql_query' : browse_sql
|
||||
'sql_query' : browse_sql,
|
||||
'token' : PMA_commonParams.get('token')
|
||||
};
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success) {
|
||||
@ -171,7 +172,8 @@ AJAX.registerOnload('db_search.js', function () {
|
||||
var params = {
|
||||
'ajax_request': true,
|
||||
'is_js_confirmed': true,
|
||||
'sql_query': $(this).data('delete-sql')
|
||||
'sql_query': $(this).data('delete-sql'),
|
||||
'token' : PMA_commonParams.get('token')
|
||||
};
|
||||
var url = $(this).attr('href');
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ AJAX.registerTeardown('db_structure.js', function () {
|
||||
$('a.real_row_count').off('click');
|
||||
$('a.row_count_sum').off('click');
|
||||
$('select[name=submit_mult]').unbind('change');
|
||||
$("#filterText").unbind('keyup');
|
||||
});
|
||||
|
||||
/**
|
||||
@ -210,6 +211,26 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Filtering tables on table listing of particular database
|
||||
*
|
||||
*/
|
||||
$("#filterText").keyup(function() {
|
||||
var filterInput = $(this).val().toUpperCase();
|
||||
var structureTable = $('#structureTable')[0];
|
||||
$('#structureTable tbody tr').each(function() {
|
||||
var tr = $(this);
|
||||
var a = tr.find('a')[0];
|
||||
if (a) {
|
||||
if (a.text.trim().toUpperCase().indexOf(filterInput) > -1) {
|
||||
tr[0].style.display = "";
|
||||
} else {
|
||||
tr[0].style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Event handler on select of "Make consistent with central list"
|
||||
*/
|
||||
@ -217,9 +238,11 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
if ($(this).val() === 'make_consistent_with_central_list') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
jqConfirm(PMA_messages.makeConsistentMessage, function(){
|
||||
$('#tablesForm').submit();
|
||||
});
|
||||
jqConfirm(
|
||||
PMA_messages.makeConsistentMessage, function(){
|
||||
$('#tablesForm').submit();
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
else if ($(this).val() === 'copy_tbl' || $(this).val() === 'add_prefix_tbl' || $(this).val() === 'replace_prefix_tbl' || $(this).val() === 'copy_tbl_change_prefix') {
|
||||
@ -295,7 +318,7 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
* @var question String containing the question to be asked for confirmation
|
||||
*/
|
||||
var question = PMA_messages.strTruncateTableStrongWarning + ' ' +
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'TRUNCATE ' + escapeHtml(curr_table_name)) +
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'TRUNCATE `' + escapeHtml(curr_table_name) + '`') +
|
||||
getForeignKeyCheckboxLoader();
|
||||
|
||||
$this_anchor.PMA_confirm(question, $this_anchor.attr('href'), function (url) {
|
||||
@ -303,6 +326,7 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
|
||||
|
||||
var params = getJSConfirmCommonParam(this);
|
||||
params.token = PMA_commonParams.get('token');
|
||||
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
@ -354,10 +378,10 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
var question;
|
||||
if (! is_view) {
|
||||
question = PMA_messages.strDropTableStrongWarning + ' ' +
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP TABLE ' + escapeHtml(curr_table_name));
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP TABLE `' + escapeHtml(curr_table_name) + '`');
|
||||
} else {
|
||||
question =
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP VIEW ' + escapeHtml(curr_table_name));
|
||||
PMA_sprintf(PMA_messages.strDoYouReally, 'DROP VIEW `' + escapeHtml(curr_table_name) + '`');
|
||||
}
|
||||
question += getForeignKeyCheckboxLoader();
|
||||
|
||||
@ -366,11 +390,11 @@ AJAX.registerOnload('db_structure.js', function () {
|
||||
var $msg = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
|
||||
|
||||
var params = getJSConfirmCommonParam(this);
|
||||
params.token = PMA_commonParams.get('token');
|
||||
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxShowMessage(data.message);
|
||||
toggleRowColors($curr_row.next());
|
||||
$curr_row.hide("medium").remove();
|
||||
PMA_adjustTotals();
|
||||
PMA_reloadNavigation();
|
||||
|
||||
@ -83,7 +83,12 @@ AJAX.registerOnload('db_tracking.js', function () {
|
||||
$anchor.PMA_confirm(question, $anchor.attr('href'), function (url) {
|
||||
PMA_ajaxShowMessage(PMA_messages.strDeletingTrackingData);
|
||||
AJAX.source = $anchor;
|
||||
$.post(url, {'ajax_page_request': true, 'ajax_request': true}, AJAX.responseHandler);
|
||||
var params = {
|
||||
'ajax_page_request': true,
|
||||
'ajax_request': true,
|
||||
'token': PMA_commonParams.get('token')
|
||||
};
|
||||
$.post(url, params, AJAX.responseHandler);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -64,6 +64,7 @@ var ErrorReport = {
|
||||
$('#error_report_dialog').remove();
|
||||
}
|
||||
var $div = $('<div id="error_report_dialog"></div>');
|
||||
$div.css('z-index', '1000');
|
||||
|
||||
var button_options = {};
|
||||
|
||||
@ -303,8 +304,8 @@ var ErrorReport = {
|
||||
|
||||
};
|
||||
|
||||
TraceKit.report.subscribe(ErrorReport.error_handler);
|
||||
ErrorReport.set_up_error_reporting();
|
||||
$(function () {
|
||||
AJAX.registerOnload('error_report.js', function(){
|
||||
TraceKit.report.subscribe(ErrorReport.error_handler);
|
||||
ErrorReport.set_up_error_reporting();
|
||||
ErrorReport.wrap_global_functions();
|
||||
});
|
||||
|
||||
@ -126,7 +126,7 @@ function loadTemplate(id)
|
||||
$.post('tbl_export.php', params, function (response) {
|
||||
if (response.success === true) {
|
||||
var $form = $('form[name="dump"]');
|
||||
var options = $.parseJSON(response.data);
|
||||
var options = JSON.parse(response.data);
|
||||
$.each(options, function (key, value) {
|
||||
var $element = $form.find('[name="' + key + '"]');
|
||||
if ($element.length) {
|
||||
@ -522,10 +522,13 @@ function check_table_selected(row) {
|
||||
|
||||
if (data && structure) {
|
||||
table_select.prop({checked: true, indeterminate: false});
|
||||
$row.addClass('marked');
|
||||
} else if (data || structure) {
|
||||
table_select.prop({checked: true, indeterminate: true});
|
||||
$row.removeClass('marked');
|
||||
} else {
|
||||
table_select.prop({checked: false, indeterminate: false});
|
||||
$row.removeClass('marked');
|
||||
}
|
||||
}
|
||||
|
||||
@ -535,8 +538,10 @@ function toggle_table_select(row) {
|
||||
|
||||
if (table_selected) {
|
||||
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true);
|
||||
$row.addClass('marked');
|
||||
} else {
|
||||
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false);
|
||||
$row.removeClass('marked');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
208
js/functions.js
@ -471,8 +471,13 @@ function suggestPassword(passwd_form)
|
||||
passwd.value += pwchars.charAt(Math.abs(randomWords[i]) % pwchars.length);
|
||||
}
|
||||
|
||||
passwd_form.text_pma_pw.value = passwd.value;
|
||||
passwd_form.text_pma_pw2.value = passwd.value;
|
||||
$jquery_passwd_form = $(passwd_form);
|
||||
|
||||
passwd_form.elements['pma_pw'].value = passwd.value;
|
||||
passwd_form.elements['pma_pw2'].value = passwd.value;
|
||||
meter_obj = $jquery_passwd_form.find('meter[name="pw_meter"]').first();
|
||||
meter_obj_label = $jquery_passwd_form.find('span[name="pw_strength"]').first();
|
||||
checkPasswordStrength(passwd.value, meter_obj, meter_obj_label);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -516,10 +521,16 @@ function PMA_current_version(data)
|
||||
var current = parseVersionString($('span.version').text());
|
||||
var latest = parseVersionString(data.version);
|
||||
var url = 'https://web.phpmyadmin.net/files/' + escapeHtml(encodeURIComponent(data.version)) + '/';
|
||||
var version_information_message = '<span class="latest">' +
|
||||
PMA_messages.strLatestAvailable +
|
||||
' <a href="' + url + '" class="disableAjax">' + escapeHtml(data.version) + '</a>' +
|
||||
'</span>';
|
||||
var version_information_message = document.createElement('span');
|
||||
version_information_message.className = 'latest';
|
||||
var version_information_message_link = document.createElement('a');
|
||||
version_information_message_link.href = url;
|
||||
version_information_message_link.className = 'disableAjax';
|
||||
version_information_message_link_text = document.createTextNode(data.version);
|
||||
version_information_message_link.appendChild(version_information_message_link_text);
|
||||
var prefix_message = document.createTextNode(PMA_messages.strLatestAvailable + ' ');
|
||||
version_information_message.appendChild(prefix_message);
|
||||
version_information_message.appendChild(version_information_message_link);
|
||||
if (latest > current) {
|
||||
var message = PMA_sprintf(
|
||||
PMA_messages.strNewerVersion,
|
||||
@ -532,14 +543,26 @@ function PMA_current_version(data)
|
||||
htmlClass = 'error';
|
||||
}
|
||||
$('#newer_version_notice').remove();
|
||||
$('#maincontainer').after('<div id="newer_version_notice" class="' + htmlClass + '"><a href="' + url + '" class="disableAjax">' + message + '</a></div>');
|
||||
var maincontainer_div = document.createElement('div');
|
||||
maincontainer_div.id = 'newer_version_notice';
|
||||
maincontainer_div.className = htmlClass;
|
||||
var maincontainer_div_link = document.createElement('a');
|
||||
maincontainer_div_link.href = url;
|
||||
maincontainer_div_link.className = 'disableAjax';
|
||||
maincontainer_div_link_text = document.createTextNode(message);
|
||||
maincontainer_div_link.appendChild(maincontainer_div_link_text);
|
||||
maincontainer_div.appendChild(maincontainer_div_link);
|
||||
$('#maincontainer').append($(maincontainer_div));
|
||||
}
|
||||
if (latest === current) {
|
||||
version_information_message = ' (' + PMA_messages.strUpToDate + ')';
|
||||
version_information_message = document.createTextNode(' (' + PMA_messages.strUpToDate + ')');
|
||||
}
|
||||
/* Remove extra whitespace */
|
||||
var version_info = $('#li_pma_version').contents().get(2);
|
||||
version_info.textContent = $.trim(version_info.textContent);
|
||||
var $liPmaVersion = $('#li_pma_version');
|
||||
$liPmaVersion.find('span.latest').remove();
|
||||
$liPmaVersion.append(version_information_message);
|
||||
$liPmaVersion.append($(version_information_message));
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,7 +672,7 @@ function confirmLink(theLink, theSqlQuery)
|
||||
* This function is called by the 'checkSqlQuery()' js function.
|
||||
*
|
||||
* @param theForm1 object the form
|
||||
* @param sqlQuery1 object the sql query textarea
|
||||
* @param sqlQuery1 string the sql query string
|
||||
*
|
||||
* @return boolean whether to run the query or not
|
||||
*
|
||||
@ -674,15 +697,15 @@ function confirmQuery(theForm1, sqlQuery1)
|
||||
var do_confirm_re_2 = new RegExp('^\\s*DELETE\\s+FROM\\s', 'i');
|
||||
var do_confirm_re_3 = new RegExp('^\\s*TRUNCATE\\s', 'i');
|
||||
|
||||
if (do_confirm_re_0.test(sqlQuery1.value) ||
|
||||
do_confirm_re_1.test(sqlQuery1.value) ||
|
||||
do_confirm_re_2.test(sqlQuery1.value) ||
|
||||
do_confirm_re_3.test(sqlQuery1.value)) {
|
||||
if (do_confirm_re_0.test(sqlQuery1) ||
|
||||
do_confirm_re_1.test(sqlQuery1) ||
|
||||
do_confirm_re_2.test(sqlQuery1) ||
|
||||
do_confirm_re_3.test(sqlQuery1)) {
|
||||
var message;
|
||||
if (sqlQuery1.value.length > 100) {
|
||||
message = sqlQuery1.value.substr(0, 100) + '\n ...';
|
||||
if (sqlQuery1.length > 100) {
|
||||
message = sqlQuery1.substr(0, 100) + '\n ...';
|
||||
} else {
|
||||
message = sqlQuery1.value;
|
||||
message = sqlQuery1;
|
||||
}
|
||||
var is_confirmed = confirm(PMA_sprintf(PMA_messages.strDoYouReally, message));
|
||||
// statement is confirmed -> update the
|
||||
@ -695,7 +718,6 @@ function confirmQuery(theForm1, sqlQuery1)
|
||||
// statement is rejected -> do not submit the form
|
||||
else {
|
||||
window.focus();
|
||||
sqlQuery1.focus();
|
||||
return false;
|
||||
} // end if (handle confirm box result)
|
||||
} // end if (display confirm box)
|
||||
@ -723,31 +745,30 @@ function checkSqlQuery(theForm)
|
||||
} else {
|
||||
sqlQuery = theForm.elements.sql_query.value;
|
||||
}
|
||||
var isEmpty = 1;
|
||||
var space_re = new RegExp('\\s+');
|
||||
if (typeof(theForm.elements.sql_file) != 'undefined' &&
|
||||
theForm.elements.sql_file.value.replace(space_re, '') !== '') {
|
||||
return true;
|
||||
}
|
||||
if (isEmpty && typeof(theForm.elements.id_bookmark) != 'undefined' &&
|
||||
if (typeof(theForm.elements.id_bookmark) != 'undefined' &&
|
||||
(theForm.elements.id_bookmark.value !== null || theForm.elements.id_bookmark.value !== '') &&
|
||||
theForm.elements.id_bookmark.selectedIndex !== 0) {
|
||||
return true;
|
||||
}
|
||||
var result = false;
|
||||
// Checks for "DROP/DELETE/ALTER" statements
|
||||
if (sqlQuery.replace(space_re, '') !== '') {
|
||||
return confirmQuery(theForm, sqlQuery);
|
||||
}
|
||||
theForm.reset();
|
||||
isEmpty = 1;
|
||||
|
||||
if (isEmpty) {
|
||||
result = confirmQuery(theForm, sqlQuery);
|
||||
} else {
|
||||
alert(PMA_messages.strFormEmpty);
|
||||
codemirror_editor.focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (codemirror_editor) {
|
||||
codemirror_editor.focus();
|
||||
} else if (codemirror_inline_editor) {
|
||||
codemirror_inline_editor.focus();
|
||||
}
|
||||
return result;
|
||||
} // end of the 'checkSqlQuery()' function
|
||||
|
||||
/**
|
||||
@ -895,17 +916,31 @@ AJAX.registerOnload('functions.js', function () {
|
||||
document.onkeypress = function() {
|
||||
_idleSecondsCounter = 0;
|
||||
};
|
||||
function guid() {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
|
||||
function SetIdleTime() {
|
||||
_idleSecondsCounter++;
|
||||
}
|
||||
function UpdateIdleTime() {
|
||||
var href = 'index.php';
|
||||
var guid = 'default';
|
||||
if (isStorageSupported('sessionStorage')) {
|
||||
guid = window.sessionStorage.guid;
|
||||
}
|
||||
var params = {
|
||||
'ajax_request' : true,
|
||||
'token' : PMA_commonParams.get('token'),
|
||||
'server' : PMA_commonParams.get('server'),
|
||||
'db' : PMA_commonParams.get('db'),
|
||||
'guid': guid,
|
||||
'access_time':_idleSecondsCounter
|
||||
};
|
||||
$.ajax({
|
||||
@ -914,28 +949,42 @@ AJAX.registerOnload('functions.js', function () {
|
||||
data: params,
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
var remaining = PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter;
|
||||
if (PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter < 0) {
|
||||
/* There is other active window, let's reset counter */
|
||||
_idleSecondsCounter = 0;
|
||||
}
|
||||
var remaining = Math.min(
|
||||
/* Remaining login validity */
|
||||
PMA_commonParams.get('LoginCookieValidity') - _idleSecondsCounter,
|
||||
/* Remaining time till session GC */
|
||||
PMA_commonParams.get('session_gc_maxlifetime')
|
||||
);
|
||||
var interval = 1000;
|
||||
if (remaining > 5) {
|
||||
// max value for setInterval() function
|
||||
var interval = Math.min(remaining * 1000, Math.pow(2, 31) - 1);
|
||||
updateTimeout = window.setTimeout(UpdateIdleTime, interval);
|
||||
} else if (remaining > 0) {
|
||||
// We're close to session expiry
|
||||
updateTimeout = window.setTimeout(UpdateIdleTime, 2000);
|
||||
interval = Math.min((remaining - 1) * 1000, Math.pow(2, 31) - 1);
|
||||
}
|
||||
updateTimeout = window.setTimeout(UpdateIdleTime, interval);
|
||||
} else { //timeout occurred
|
||||
if(isStorageSupported('sessionStorage')){
|
||||
clearInterval(IncInterval);
|
||||
if (isStorageSupported('sessionStorage')){
|
||||
window.sessionStorage.clear();
|
||||
}
|
||||
window.location.reload(true);
|
||||
clearInterval(IncInterval);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (PMA_commonParams.get('logged_in') && PMA_commonParams.get('auth_type') == 'cookie') {
|
||||
if (PMA_commonParams.get('logged_in')) {
|
||||
IncInterval = window.setInterval(SetIdleTime, 1000);
|
||||
var interval = (PMA_commonParams.get('LoginCookieValidity') - 5) * 1000;
|
||||
var session_timeout = Math.min(
|
||||
PMA_commonParams.get('LoginCookieValidity'),
|
||||
PMA_commonParams.get('session_gc_maxlifetime')
|
||||
);
|
||||
if (isStorageSupported('sessionStorage')) {
|
||||
window.sessionStorage.setItem('guid', guid());
|
||||
}
|
||||
var interval = (session_timeout - 5) * 1000;
|
||||
if (interval > Math.pow(2, 31) - 1) { // max value for setInterval() function
|
||||
interval = Math.pow(2, 31) - 1;
|
||||
}
|
||||
@ -974,7 +1023,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
last_click_checked = checked;
|
||||
|
||||
// remember the last clicked row
|
||||
last_clicked_row = last_click_checked ? $table.find('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr) : -1;
|
||||
last_clicked_row = last_click_checked ? $table.find('tr:not(.noclick)').index($tr) : -1;
|
||||
last_shift_clicked_row = -1;
|
||||
} else {
|
||||
// handle the shift click
|
||||
@ -990,7 +1039,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
start = last_shift_clicked_row;
|
||||
end = last_clicked_row;
|
||||
}
|
||||
$tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
|
||||
$tr.parent().find('tr:not(.noclick)')
|
||||
.slice(start, end + 1)
|
||||
.removeClass('marked')
|
||||
.find(':checkbox')
|
||||
@ -999,7 +1048,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
}
|
||||
|
||||
// handle new shift click
|
||||
var curr_row = $table.find('tr.odd:not(.noclick), tr.even:not(.noclick)').index($tr);
|
||||
var curr_row = $table.find('tr:not(.noclick)').index($tr);
|
||||
if (curr_row >= last_clicked_row) {
|
||||
start = last_clicked_row;
|
||||
end = curr_row;
|
||||
@ -1007,7 +1056,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
start = curr_row;
|
||||
end = last_clicked_row;
|
||||
}
|
||||
$tr.parent().find('tr.odd:not(.noclick), tr.even:not(.noclick)')
|
||||
$tr.parent().find('tr:not(.noclick)')
|
||||
.slice(start, end + 1)
|
||||
.addClass('marked')
|
||||
.find(':checkbox')
|
||||
@ -1034,7 +1083,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
* so that it works also for pages reached via AJAX)
|
||||
*/
|
||||
/*AJAX.registerOnload('functions.js', function () {
|
||||
$(document).on('hover', 'tr.odd, tr.even',function (event) {
|
||||
$(document).on('hover', 'tr',function (event) {
|
||||
var $tr = $(this);
|
||||
$tr.toggleClass('hover',event.type=='mouseover');
|
||||
$tr.children().toggleClass('hover',event.type=='mouseover');
|
||||
@ -1860,7 +1909,6 @@ AJAX.registerOnload('functions.js', function () {
|
||||
});
|
||||
|
||||
$(document).on('click', "input#sql_query_edit_save", function () {
|
||||
$(".success").hide();
|
||||
//hide already existing success message
|
||||
var sql_query;
|
||||
if (codemirror_inline_editor) {
|
||||
@ -1881,6 +1929,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
if (! checkSqlQuery($fake_form[0])) {
|
||||
return false;
|
||||
}
|
||||
$(".success").hide();
|
||||
$fake_form.appendTo($('body')).submit();
|
||||
});
|
||||
|
||||
@ -1946,7 +1995,7 @@ function codemirrorAutocompleteOnInputRead(instance) {
|
||||
data: params,
|
||||
success: function (data) {
|
||||
if (data.success) {
|
||||
var tables = $.parseJSON(data.tables);
|
||||
var tables = JSON.parse(data.tables);
|
||||
sql_autocomplete_default_table = PMA_commonParams.get('table');
|
||||
sql_autocomplete = [];
|
||||
for (var table in tables) {
|
||||
@ -2036,7 +2085,7 @@ function bindCodeMirrorToInlineEditor() {
|
||||
|
||||
function catchKeypressesFromSqlInlineEdit(event) {
|
||||
// ctrl-enter is 10 in chrome and ie, but 13 in ff
|
||||
if (event.ctrlKey && (event.keyCode == 13 || event.keyCode == 10)) {
|
||||
if ((event.ctrlKey || event.metaKey) && (event.keyCode == 13 || event.keyCode == 10)) {
|
||||
$("#sql_query_edit_save").trigger('click');
|
||||
}
|
||||
}
|
||||
@ -2214,11 +2263,17 @@ function PMA_updateCode($base, htmlValue, rawValue)
|
||||
* @param mixed timeout number of milliseconds for the message to be visible
|
||||
* optional, defaults to 5000. If set to 'false', the
|
||||
* notification will never disappear
|
||||
* @param string type string to dictate the type of message shown.
|
||||
* optional, defaults to normal notification.
|
||||
* If set to 'error', the notification will show message
|
||||
* with red background.
|
||||
* If set to 'success', the notification will show with
|
||||
* a green background.
|
||||
* @return jQuery object jQuery Element that holds the message div
|
||||
* this object can be passed to PMA_ajaxRemoveMessage()
|
||||
* to remove the notification
|
||||
*/
|
||||
function PMA_ajaxShowMessage(message, timeout)
|
||||
function PMA_ajaxShowMessage(message, timeout, type)
|
||||
{
|
||||
/**
|
||||
* @var self_closing Whether the notification will automatically disappear
|
||||
@ -2249,6 +2304,12 @@ function PMA_ajaxShowMessage(message, timeout)
|
||||
} else if (timeout === false) {
|
||||
self_closing = false;
|
||||
}
|
||||
// Determine type of message, add styling as required
|
||||
if (type === "error") {
|
||||
message = "<div class=\"error\">" + message + "</div>";
|
||||
} else if (type === "success") {
|
||||
message = "<div class=\"success\">" + message + "</div>";
|
||||
}
|
||||
// Create a parent element for the AJAX messages, if necessary
|
||||
if ($('#loading_parent').length === 0) {
|
||||
$('<div id="loading_parent"></div>')
|
||||
@ -2738,7 +2799,6 @@ jQuery.fn.PMA_confirm = function (question, url, callbackFn, openCallback) {
|
||||
|
||||
/**
|
||||
* jQuery function to sort a table's body after a new row has been appended to it.
|
||||
* Also fixes the even/odd classes of the table rows at the end.
|
||||
*
|
||||
* @param string text_selector string to select the sortKey's text
|
||||
*
|
||||
@ -2777,13 +2837,6 @@ jQuery.fn.PMA_sort_table = function (text_selector) {
|
||||
$(table_body).append(row);
|
||||
row.sortKey = null;
|
||||
});
|
||||
|
||||
//Re-check the classes of each row
|
||||
$(this).find('tr:odd')
|
||||
.removeClass('even').addClass('odd')
|
||||
.end()
|
||||
.find('tr:even')
|
||||
.removeClass('odd').addClass('even');
|
||||
});
|
||||
};
|
||||
|
||||
@ -2974,7 +3027,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
}
|
||||
});
|
||||
|
||||
$("input[value=AUTO_INCREMENT]").change(function(){
|
||||
$(document).on('change', "input[value=AUTO_INCREMENT]", function() {
|
||||
if (this.checked) {
|
||||
var col = /\d/.exec($(this).attr('name'));
|
||||
col = col[0];
|
||||
@ -3162,6 +3215,10 @@ AJAX.registerOnload('functions.js', function () {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data._scripts) {
|
||||
AJAX.scriptHandler.load(data._scripts);
|
||||
}
|
||||
|
||||
$('<div id="change_password_dialog"></div>')
|
||||
.dialog({
|
||||
title: PMA_messages.strChangePassword,
|
||||
@ -3178,7 +3235,6 @@ AJAX.registerOnload('functions.js', function () {
|
||||
.find("legend").remove().end()
|
||||
.find("table.noclick").unwrap().addClass("some-margin")
|
||||
.find("input#text_pma_pw").focus();
|
||||
displayPasswordGenerateButton();
|
||||
$('#fieldset_change_password_footer').hide();
|
||||
PMA_ajaxRemoveMessage($msgbox);
|
||||
$('#change_password_form').bind('submit', function (e) {
|
||||
@ -3508,7 +3564,7 @@ AJAX.registerOnload('functions.js', function () {
|
||||
url: href,
|
||||
data: params,
|
||||
success: function (data) {
|
||||
central_column_list[db + '_' + table] = $.parseJSON(data.message);
|
||||
central_column_list[db + '_' + table] = JSON.parse(data.message);
|
||||
},
|
||||
async:false
|
||||
});
|
||||
@ -4037,7 +4093,9 @@ var toggleButton = function ($obj) {
|
||||
removeClass = 'off';
|
||||
addClass = 'on';
|
||||
}
|
||||
$.post(url, {'ajax_request': true}, function (data) {
|
||||
|
||||
var params = {'ajax_request': true, 'token': PMA_commonParams.get('token')};
|
||||
$.post(url, params, function (data) {
|
||||
if (typeof data !== 'undefined' && data.success === true) {
|
||||
PMA_ajaxRemoveMessage($msg);
|
||||
$container
|
||||
@ -4164,6 +4222,8 @@ AJAX.registerOnload('functions.js', function () {
|
||||
favorite_tables: (isStorageSupported('localStorage') && typeof window.localStorage.favorite_tables !== 'undefined')
|
||||
? window.localStorage.favorite_tables
|
||||
: '',
|
||||
token: PMA_commonParams.get('token'),
|
||||
server: PMA_commonParams.get('server'),
|
||||
no_debug: true
|
||||
},
|
||||
success: function (data) {
|
||||
@ -4581,7 +4641,7 @@ function copyToClipboard()
|
||||
});
|
||||
|
||||
textArea.value += '\n';
|
||||
elementList = $('tbody .odd,tbody .even');
|
||||
elementList = $('tbody tr');
|
||||
elementList.each(function() {
|
||||
var childElementList = $(this).find('.data span');
|
||||
childElementList.each(function(){
|
||||
@ -4615,6 +4675,16 @@ AJAX.registerTeardown('functions.js', function () {
|
||||
|
||||
AJAX.registerOnload('functions.js', function () {
|
||||
$('input#print').click(printPage);
|
||||
$('.logout').click(function() {
|
||||
var form = $(
|
||||
'<form method="POST" action="' + $(this).attr('href') + '" class="disableAjax">' +
|
||||
'<input type="hidden" name="token" value="' + PMA_commonParams.get('token') + '"/>' +
|
||||
'</form>'
|
||||
);
|
||||
$('body').append(form);
|
||||
form.submit();
|
||||
return false;
|
||||
});
|
||||
/**
|
||||
* Ajaxification for the "Create View" action
|
||||
*/
|
||||
@ -4786,22 +4856,6 @@ $(document).on("change", "input.sub_checkall_box", function () {
|
||||
.parents("tr").toggleClass("marked", is_checked);
|
||||
});
|
||||
|
||||
/**
|
||||
* Toggles row colors of a set of 'tr' elements starting from a given element
|
||||
*
|
||||
* @param $start Starting element
|
||||
*/
|
||||
function toggleRowColors($start)
|
||||
{
|
||||
for (var $curr_row = $start; $curr_row.length > 0; $curr_row = $curr_row.next()) {
|
||||
if ($curr_row.hasClass('odd')) {
|
||||
$curr_row.removeClass('odd').addClass('even');
|
||||
} else if ($curr_row.hasClass('even')) {
|
||||
$curr_row.removeClass('even').addClass('odd');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a byte number to human-readable form
|
||||
*
|
||||
|
||||
@ -6,34 +6,34 @@
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
chdir('..');
|
||||
|
||||
// Send correct type:
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
if (!defined('TESTSUITE')) {
|
||||
chdir('..');
|
||||
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
define('PMA_PATH_TO_BASEDIR', '../');
|
||||
require_once './libraries/common.inc.php';
|
||||
// Send correct type:
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
define('PMA_PATH_TO_BASEDIR', '../');
|
||||
require_once './libraries/common.inc.php';
|
||||
}
|
||||
|
||||
$buffer = PMA\libraries\OutputBuffering::getInstance();
|
||||
$buffer->start();
|
||||
register_shutdown_function(
|
||||
function () {
|
||||
echo PMA\libraries\OutputBuffering::getInstance()->getContents();
|
||||
}
|
||||
);
|
||||
if (!defined('TESTSUITE')) {
|
||||
register_shutdown_function(
|
||||
function () {
|
||||
echo PMA\libraries\OutputBuffering::getInstance()->getContents();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Get the data for the sprites, if it's available
|
||||
if (is_readable($_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php')) {
|
||||
include $_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php';
|
||||
}
|
||||
$sprites = array();
|
||||
if (function_exists('PMA_sprites')) {
|
||||
$sprites = PMA_sprites();
|
||||
}
|
||||
$sprites = $_SESSION['PMA_Theme']->getSpriteData();
|
||||
|
||||
// We only need the keys from the array of sprites data,
|
||||
// since they contain the (partial) class names
|
||||
$keys = array();
|
||||
|
||||
@ -7,33 +7,37 @@
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
chdir('..');
|
||||
if (!defined('TESTSUITE')) {
|
||||
chdir('..');
|
||||
|
||||
// Close session early as we won't write anything there
|
||||
session_write_close();
|
||||
// Close session early as we won't write anything there
|
||||
session_write_close();
|
||||
|
||||
// Send correct type
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
// Enable browser cache for 1 hour
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
// Send correct type
|
||||
header('Content-Type: text/javascript; charset=UTF-8');
|
||||
// Enable browser cache for 1 hour
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
|
||||
|
||||
// When a token is not presented, even though whitelisted arrays are removed
|
||||
// in PMA_removeRequestVars(). This is a workaround for that.
|
||||
$_GET['scripts'] = json_encode($_GET['scripts']);
|
||||
// When a token is not presented, even though whitelisted arrays are removed
|
||||
// in PMA_removeRequestVars(). This is a workaround for that.
|
||||
$_GET['scripts'] = json_encode($_GET['scripts']);
|
||||
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
define('PMA_PATH_TO_BASEDIR', '../');
|
||||
require_once './libraries/common.inc.php';
|
||||
// Avoid loading the full common.inc.php because this would add many
|
||||
// non-js-compatible stuff like DOCTYPE
|
||||
define('PMA_MINIMUM_COMMON', true);
|
||||
define('PMA_PATH_TO_BASEDIR', '../');
|
||||
require_once './libraries/common.inc.php';
|
||||
}
|
||||
|
||||
$buffer = PMA\libraries\OutputBuffering::getInstance();
|
||||
$buffer->start();
|
||||
register_shutdown_function(
|
||||
function () {
|
||||
echo PMA\libraries\OutputBuffering::getInstance()->getContents();
|
||||
}
|
||||
);
|
||||
if (!defined('TESTSUITE')) {
|
||||
register_shutdown_function(
|
||||
function () {
|
||||
echo PMA\libraries\OutputBuffering::getInstance()->getContents();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$_GET['scripts'] = json_decode($_GET['scripts']);
|
||||
if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
|
||||
@ -43,7 +47,7 @@ if (! empty($_GET['scripts']) && is_array($_GET['scripts'])) {
|
||||
$script_name = 'js';
|
||||
|
||||
$path = explode("/", $script);
|
||||
foreach ($path as $index => $filename) {
|
||||
foreach ($path as $filename) {
|
||||
// Allow alphanumeric, "." and "-" chars only, no files starting
|
||||
// with .
|
||||
if (preg_match("@^[\w][\w\.-]+$@", $filename)) {
|
||||
|
||||