Compare commits

...

45 Commits
v4.10 ... v4.12

Author SHA1 Message Date
Peter Knut
4112aaf26f Release 4.12 2024-11-21 12:54:30 +01:00
Peter Knut
5fdc9dc427 Update docs 2024-11-21 09:59:57 +01:00
Peter Knut
cc646de4ca Remove funding config 2024-11-19 23:41:47 +01:00
Peter Knut
b6b379a8ce Improve arrays formatting in dump method 2024-11-19 23:11:36 +01:00
Peter Knut
f93db81c0e Update translations 2024-11-19 22:58:20 +01:00
Peter Knut
2cafcd7fc8 Handle the situation when no driver is found
This can happen if Adminer for MySQL with existing login is replaced by Adminer for PostgreSQL.
2024-11-19 22:58:20 +01:00
Peter Knut
53799ff6ab Update Spanish translations
Thanks to isaacpolaino (https://github.com/adminerevo/adminerevo/discussions/21#discussioncomment-11283326)
2024-11-19 22:00:12 +01:00
Peter Knut
638288cc04 Cleanup: Definition of custom PDO statement class 2024-11-19 22:00:12 +01:00
Peter Knut
99f4c22c72 MSSQL: Allow to set Encrypt and TrustServerCertificate with AdminerLoginSsl plugin (issue #5)
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax#use-trustservercertificate
2024-11-19 22:00:12 +01:00
Peter Knut
55e0c348b8 MSSQL, MongoDB: Connect to localhost with default port if server is not specified 2024-11-19 22:00:12 +01:00
Peter Knut
379003fc8d MongoDB: Fix parsing WHERE condition from SQL query
Thanks to herobank110 (https://github.com/vrana/adminer/pull/491)
2024-11-19 22:00:12 +01:00
Peter Knut
0933e4e67d MongoDB: Small cleanup 2024-11-19 22:00:12 +01:00
Peter Knut
ee26735ac6 Refactor drivers definition and compilation
- Rename 'server' driver to 'mysql'
- MySQL driver is no longer the required default
- Fix compiled SQLite single-driver Adminer
- Allow to compile only selected drivers
2024-11-19 22:00:11 +01:00
Peter Knut
214d7745a7 Compiler: Refactor languages compilation
- Allow to compile only selected languages
- Fix translations in plugins
2024-11-07 10:52:13 +01:00
Peter Knut
99b7c08e3a Compiler: Add new lines before selected keywords, not after 2024-11-05 22:16:39 +01:00
Peter Knut
b1ecb0649e Improve dumping methods if run from terminal 2024-11-05 15:56:57 +01:00
vukbgit
2430ad2702 MariaDB: Add support for UUID data type
- MariaDB >= 10.7
- UUID string data type
- uuid() function for UUID type on new/edit item form
2024-11-04 14:40:50 +01:00
Peter Knut
9eeeca6b0e Fix highlighting default submit button in indexes form 2024-11-03 22:31:45 +01:00
Peter Knut
d165cd9aec Change logo link to main page (login) 2024-11-03 22:31:45 +01:00
Peter Knut
a0a0d44c7c Update project URL and info 2024-11-03 22:31:45 +01:00
Peter Knut
316754af47 Enhance checking of new version
- Do not verify version on login page
- Do not show error from version checking
- Sync expiration of version cookie with file
- Clean up the code
2024-11-03 22:31:45 +01:00
Peter Knut
47f1f19970 Fix SQL query code direction if RTL language is used 2024-11-03 22:31:45 +01:00
Peter Knut
5c4dc82081 PostgreSQL: Fix layout of stored function parameters 2024-11-03 22:31:45 +01:00
Peter Knut
226d4ad54b MySQL: Print comments of stored procedures and functions 2024-11-03 22:31:45 +01:00
Peter Knut
85c0c8f003 Fix disappearing dragged row 2024-11-03 22:31:45 +01:00
Peter Knut
c815ea875b Fix compiling single language version 2024-11-03 22:31:45 +01:00
Peter Knut
872991fa14 Docs: Update migration section 2024-11-03 22:31:45 +01:00
Peter Knut
35411d8f4e Bump version to 4.12-dev 2024-11-03 22:31:45 +01:00
Peter Knut
81e337bed1 Release 4.11 2024-10-30 22:14:44 +01:00
Peter Knut
18ddbf1d60 MySQL: Fix highlighting current table in menu on macOS 2024-10-30 22:12:59 +01:00
Peter Knut
e4235d21e5 Clean up JS code 2024-10-30 21:16:39 +01:00
Peter Knut
10dfc54bf4 Show help popup after a short delay, refactoring 2024-10-30 21:16:39 +01:00
Peter Knut
af3c863be3 Fix drag-n-drop moving of function parameters 2024-10-30 21:16:39 +01:00
Peter Knut
6cd5495c1b PostgreSQL: Show list of schemas in database, unify lists of sequences and user types 2024-10-30 21:16:39 +01:00
Peter Knut
78ad8381ab Update CS and SK translations 2024-10-30 21:16:39 +01:00
Peter Knut
87fc82f88e Fix printing error message while validating server URL 2024-10-30 21:16:39 +01:00
Peter Knut
0519a0b985 Devel: Add modification time to CSS and JS links for easier development 2024-10-30 21:16:39 +01:00
Peter Knut
f61cf1ba0c Support drag-n-drop moving on touch screens 2024-10-30 21:16:39 +01:00
HyP3r
fc2e025603 MS SQL: Prefix Unicode strings with 'N' so they are treated correctly 2024-10-30 21:16:39 +01:00
Peter Knut
659e72b692 MariaDB: Fix several links to documentation pages 2024-10-30 21:16:39 +01:00
Peter Knut
123373ca82 Switch to custom JUSH library 2024-10-30 21:16:39 +01:00
Peter Knut
e99f2d90cf Update project information 2024-10-30 21:16:39 +01:00
Peter Knut
bdabc5aa13 Small CSS tuning 2024-10-30 21:16:39 +01:00
Peter Knut
92f3e0ca00 Reset the style of sortable row after dragging 2024-10-22 23:29:03 +02:00
Peter Knut
aa1266e4f2 Bump version to 4.10.1-dev 2024-10-22 23:29:03 +02:00
94 changed files with 1877 additions and 979 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1,2 +0,0 @@
patreon: jakubvrana
custom: ["https://sourceforge.net/p/adminer/donate/"]

View File

@@ -1,35 +1,95 @@
# Changelog Changelog
=========
## Adminer 4.10 (2024-10-22) Adminer 4.12 (2024-11-21)
-------------------------
### New features
- MySQL: Print comments of stored procedures and functions
- MariaDB: Add support for UUID data type (by vukbgit)
- MS SQL: Allow to set Encrypt and TrustServerCertificate with AdminerLoginSsl plugin (issue #5)
- MS SQL, MongoDB: Connect to localhost with default port if server is not specified
- Compiler: Allow to compile only selected drivers and languages
### Changes
- Change logo link to main page (login)
- Enhance checking of new version
- Update project URL and info
- Rename 'server' driver to 'mysql'
- Compiler: MySQL driver is no longer the required default
- Update Spanish translations (by isaacpolaino)
### Bugfixes
- PostgreSQL: Fix layout of stored function parameters
- MongoDB: Fix parsing WHERE condition from SQL query
- Fix SQL query code direction if RTL language is used
- Fix disappearing dragged row
- Fix highlighting default submit button in indexes form
- Compiler: Fix translations in plugins
- Compiler: Fix compiled SQLite single-driver Adminer
Adminer 4.11 (2024-10-30)
-------------------------
### New features
- PostgreSQL, MS SQL: Show list of schemas in database, unify lists of sequences and user types
### Changes
- Support drag-n-drop moving on touch screens
- Update project information in comments
- Update CS and SK translations
- Show help popup after a short delay
- Small CSS tuning
### Bugfixes
- Fix drag-n-drop moving of function parameters
- MariaDB: Fix several links to documentation pages
- MySQL: Fix highlighting current table in menu on macOS
- MS SQL: Prefix Unicode strings with 'N' so they are treated correctly
- Fix printing error message while validating server URL
Adminer 4.10 (2024-10-22)
-------------------------
### New features
### UI changes and improvements
- Add drag-n-drop moving of rows in table selection filter - Add drag-n-drop moving of rows in table selection filter
- Add drag-n-drop moving of rows in table editing - Add drag-n-drop moving of rows in table editing
- Add removal buttons to table selection filter - Add removal buttons to table selection filter (by Roy Orbitson)
- Enable regular expressions when searching data in all tables (by Roy Orbitson)
- Integrate tables-filter plugin into the base code - Integrate tables-filter plugin into the base code
- Full width design for database select box - Plugin to auto-include adminer.js when present (by Roy Orbitson)
- Add 'Home' to breadcrumb navigation
- Print username next to the logout button - Print username next to the logout button
- Show partitioning info in table structure page - Show partitioning info in table structure page
- Show second link for editing a table under the table view - Show second link for editing a table under the table view
### Changes
- Check new version against GitHub pages (by Adrian Jones)
- Add 'Home' to breadcrumb navigation
- Full width design for database select box
- Add table head to the list of indexes - Add table head to the list of indexes
- Hide edited value if selected function will not use it - Hide edited value if selected function will not use it
- Hide arrow buttons in number input fields - Hide arrow buttons in number input fields
- Do not display empty action links in main menu - Do not display empty action links in main menu
- Remove deprecated HTML table parameters - Remove deprecated HTML table parameters
- Remove option to hide default values - Remove option to hide default values
### Functional enhancements
- Enable regular expressions when searching data in all tables
- Elasticsearch: New condition operators as the combination of query type and match type - Elasticsearch: New condition operators as the combination of query type and match type
- Elasticsearch: Proper formatting of boolean values - Elasticsearch: Proper formatting of boolean values
- Plugin to auto-include adminer.js when present
- Check new version against GitHub pages
### Bugfixes ### Bugfixes
- Fix missing SQL statement if warnings are printed (regression from 4.9) - Fix missing SQL statement if warnings are printed (regression from 4.9)
## Adminer 4.9.4 (2024-10-09) Adminer 4.9.4 (2024-10-09)
--------------------------
- Fix the width of inline edit field - Fix the width of inline edit field
- Unify displaying of 'New item' action based on privileges - Unify displaying of 'New item' action based on privileges
- Better default value for object definition `(*.*)` while creating new database user - Better default value for object definition `(*.*)` while creating new database user
@@ -40,49 +100,57 @@
- Editor: Fix building links with array parameters - Editor: Fix building links with array parameters
- Clean up the code for PHP < 5.6 - Clean up the code for PHP < 5.6
## Adminer 4.9.3 (2024-10-02) Adminer 4.9.3 (2024-10-02)
--------------------------
- MySQL, PostgreSQL: Fix queries splitting and string constants - MySQL, PostgreSQL: Fix queries splitting and string constants
- MySQL: Fix where clause for `JSON` column - MySQL: Fix where clause for `JSON` column (by SeaEagle)
- MySQL: Fix editing user's proxy privilege, refactoring - MySQL: Fix editing user's proxy privilege, refactoring
- MariaDB: Fix comparing `CURRENT_TIMESTAMP` definition while altering a table - MariaDB: Fix comparing `CURRENT_TIMESTAMP` definition while altering a table
- PostgreSQL: Fix editing record that contains a field with `GENERATED ALWAYS` default value - PostgreSQL: Fix editing record that contains a field with `GENERATED ALWAYS` default value
- Fix using undefined Min_DB::info property - Fix using undefined Min_DB::info property
- Do not include unchanged `PARTITION BY` definition into `ALTER TABLE` query - Do not include unchanged `PARTITION BY` definition into `ALTER TABLE` query
- Do not limit unlimited memory while executing queries - Do not limit unlimited memory while executing queries (by Michael Graß)
- Fix number conversion warning while reading INI settings - Fix number conversion warning while reading INI settings
- Hide invalid edit form if table record is not found - Hide invalid edit form if table record is not found
- CSS: Fix background color of `<pre>` used as edit field - CSS: Fix background color of `<pre>` used as edit field
- CSS: Bigger font size for code blocks - CSS: Bigger font size for code blocks
## Adminer 4.9.2 (2024-09-18) Adminer 4.9.2 (2024-09-18)
--------------------------
- Fix textarea height for single-line inputs (used typically for SQLite text field) - Fix textarea height for single-line inputs (used typically for SQLite text field)
- Fix undefined property in error message if driver does not support error number (e.g. PostgreSQL) - Fix undefined property in error message if driver does not support error number (e.g. PostgreSQL)
- PostgreSQL: Fix search fields configuration (regression from 4.9) - PostgreSQL: Fix search fields configuration (regression from 4.9)
- PostgreSQL: Fix search condition for network address types, add macaddr8 type - PostgreSQL: Fix search condition for network address types, add macaddr8 type
- PostgreSQL: Fix exporting `CREATE TABLE` query with `GENERATED` default values - PostgreSQL: Fix exporting `CREATE TABLE` query with `GENERATED` default values
- PostgreSQL: Fix exporting `CREATE TABLE` query with sequence default value - PostgreSQL: Fix exporting `CREATE TABLE` query with sequence default value (by khoazero123)
- PostgreSQL: Allow to set connection's sslmode with AdminerLoginSsl plugin - PostgreSQL: Allow to set connection's sslmode with AdminerLoginSsl plugin
- MySQL: Do not show `empty` enum value in strict mode - MySQL: Do not show `empty` enum value in strict mode
- Editor: Fix searching in tables - Editor: Fix searching in tables
- Function to retrieve driver name that can be used in plugins - Add function to retrieve driver name that can be used in plugins (by Roy Orbison)
## Adminer 4.9.1 (2024-09-09) Adminer 4.9.1 (2024-09-09)
- Compatibility with PHP 8.3 --------------------------
- Compatibility with PHP 8.3 (by Sneda8)
- Fix compiling jush external files - Fix compiling jush external files
- Improved displaying of long table names in menu - Improved displaying of long table names in menu
- Replace deprecated `<acronym>` with `<abbr>` - Replace deprecated `<acronym>` with `<abbr>`
- Add support for translations in plugins - Add support for translations in plugins
- Add .editorconfig file - Add .editorconfig file
- MySQL: Add `unix_timestamp` to functions - MySQL: Add `unix_timestamp` to functions (by Michal Paulovic)
- PostgreSQL: Show only accessible databases - PostgreSQL: Show only accessible databases (by Thomas Daniels)
- PostgreSQL: Make data length calculation more accurate - PostgreSQL: Make data length calculation more accurate (by caltong)
- PostgreSQL: Fix documentation link for `SERIAL` type - PostgreSQL: Fix documentation link for `SERIAL` type
- PostgreSQL: Fix undefined properties on PHP 8 - PostgreSQL: Fix undefined properties on PHP 8
- Elasticsearch: Fix field selection - Elasticsearch: Fix field selection
- AdminerEditForeign: Refactor and fix the plugin - AdminerEditForeign: Refactor and fix the plugin
- AdminerLoginOtp: Autocomplete hints for OTP input field, code refactoring - AdminerLoginOtp: Autocomplete hints for OTP input field, code refactoring
## Adminer 4.9 (2024-08-19) Adminer 4.9 (2024-08-19)
------------------------
- Validate server input in login form - Validate server input in login form
- Validate connection to server in HTTP based drivers - Validate connection to server in HTTP based drivers
- Move dependencies from submodules to Composer - Move dependencies from submodules to Composer
@@ -91,13 +159,16 @@
- Add new Elasticsearch 7 driver - Add new Elasticsearch 7 driver
- Set saving to file as a default export option - Set saving to file as a default export option
- Improve URL and email detection - Improve URL and email detection
- Fix AdminerVersionNoverify plugin blocking other plugins to modify HTML head - Fix AdminerVersionNoverify plugin blocking other plugins to modify HTML head (by Roy Orbitson)
- Fix several bugs and security issues in AdminerFileUpload plugin - Fix several bugs and security issues in AdminerFileUpload plugin
- Skip dump of generated columns - Skip dump of generated columns (by Denitz)
- Fix uninitialized string offset (by Adrian Jones)
- Update composer.json - Update composer.json
- Add script for exporting compiled adminer variants - Add script for exporting compiled adminer variants
## Adminer 4.8.2 (2024-03-16) Adminer 4.8.2 (2024-03-16)
--------------------------
- Support multi-line table comments - Support multi-line table comments
- MySQL: Use `ST_SRID()` instead of `SRID()` for MySQL 8 (PR #418) - MySQL: Use `ST_SRID()` instead of `SRID()` for MySQL 8 (PR #418)
- PostgreSQL: Don't reset table comments (regression from 4.2.0) - PostgreSQL: Don't reset table comments (regression from 4.2.0)
@@ -105,7 +176,9 @@
- Update several translations: lv, bn, fr, it, nl, ru, cs, sk - Update several translations: lv, bn, fr, it, nl, ru, cs, sk
- Allow responsive styles on larger devices - Allow responsive styles on larger devices
## Adminer 4.8.1 (2021-05-14) Adminer 4.8.1 (2021-05-14)
--------------------------
- Internet Explorer or PDO in ## Adminer 4.7.8-4.8.0: Fix XSS in doc_link (bug #797) - Internet Explorer or PDO in ## Adminer 4.7.8-4.8.0: Fix XSS in doc_link (bug #797)
- Fix more PHP 8 warnings (bug #781) - Fix more PHP 8 warnings (bug #781)
- Avoid PHP warnings with PDO drivers (bug #786, regression from 4.7.8) - Avoid PHP warnings with PDO drivers (bug #786, regression from 4.7.8)
@@ -117,7 +190,9 @@
- PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug #785, regression from 4.7.9) - PostgreSQL < 10 PDO: Avoid displaying GENERATED ALWAYS BY IDENTITY everywhere (bug #785, regression from 4.7.9)
- SQLite: Fix displayed types (bug #784, regression from 4.8.0) - SQLite: Fix displayed types (bug #784, regression from 4.8.0)
## Adminer 4.8.0 (2021-02-10) Adminer 4.8.0 (2021-02-10)
--------------------------
- Support function default values in insert (bug #713) - Support function default values in insert (bug #713)
- Allow SQL pseudo-function in insert - Allow SQL pseudo-function in insert
- Skip date columns for non-date values in search anywhere - Skip date columns for non-date values in search anywhere
@@ -137,7 +212,9 @@
- MongoDB: Handle errors - MongoDB: Handle errors
- SimpleDB, Firebird, ClickHouse: Move to plugin - SimpleDB, Firebird, ClickHouse: Move to plugin
## Adminer 4.7.9 (2021-02-07) Adminer 4.7.9 (2021-02-07)
--------------------------
- Fix XSS in browsers which don't encode URL parameters (bug #775, regression from 4.7.0) - Fix XSS in browsers which don't encode URL parameters (bug #775, regression from 4.7.0)
- Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200 - Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200
- Don't syntax highlight during IME composition (bug #747) - Don't syntax highlight during IME composition (bug #747)
@@ -163,14 +240,20 @@
- Editor: Cast to string when searching (bug #325) - Editor: Cast to string when searching (bug #325)
- Editor: Avoid trailing dot in export filename - Editor: Avoid trailing dot in export filename
## Adminer 4.7.8 (2020-12-06) Adminer 4.7.8 (2020-12-06)
--------------------------
- Support PHP 8 - Support PHP 8
- Disallow connecting to privileged ports (bug #769) - Disallow connecting to privileged ports (bug #769)
## Adminer 4.7.7 (2020-05-11) Adminer 4.7.7 (2020-05-11)
--------------------------
- Fix open redirect if Adminer is accessible at //adminer.php%2F@ - Fix open redirect if Adminer is accessible at //adminer.php%2F@
## Adminer 4.7.6 (2020-01-31) Adminer 4.7.6 (2020-01-31)
--------------------------
- Speed up alter table form (regression from 4.4.0) - Speed up alter table form (regression from 4.4.0)
- Fix clicking on non-input fields in alter table (regression from 4.6.2) - Fix clicking on non-input fields in alter table (regression from 4.6.2)
- Display time of procedure execution - Display time of procedure execution
@@ -179,17 +262,23 @@
- PostgreSQL: Support exporting views - PostgreSQL: Support exporting views
- Editor: Fix focusing foreign key search in select - Editor: Fix focusing foreign key search in select
## Adminer 4.7.5 (2019-11-13) Adminer 4.7.5 (2019-11-13)
--------------------------
- Add id="" to cells with failed inline edit (bug #708) - Add id="" to cells with failed inline edit (bug #708)
- PostgreSQL: Fix getting default value in PostgreSQL 12 (bug #719) - PostgreSQL: Fix getting default value in PostgreSQL 12 (bug #719)
- PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug #706) - PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug #706)
- ClickHouse: SQL command - ClickHouse: SQL command
- Swedish translation - Swedish translation
## Adminer 4.7.4 (2019-10-22) Adminer 4.7.4 (2019-10-22)
--------------------------
- Fix XSS if Adminer is accessible at URL /data: - Fix XSS if Adminer is accessible at URL /data:
## Adminer 4.7.3 (2019-08-27) Adminer 4.7.3 (2019-08-27)
--------------------------
- Allow editing foreign keys pointing to tables in other database/schema (bug #694) - Allow editing foreign keys pointing to tables in other database/schema (bug #694)
- Fix blocking of concurrent instances in PHP >7.2 (bug #703) - Fix blocking of concurrent instances in PHP >7.2 (bug #703)
- MySQL: Speed up displaying tables in large databases (bug #700, regression from 4.7.2) - MySQL: Speed up displaying tables in large databases (bug #700, regression from 4.7.2)
@@ -202,7 +291,9 @@
- MS SQL: Support foreign keys to other DB - MS SQL: Support foreign keys to other DB
- MongoDB: Allow setting authSource from environment variable - MongoDB: Allow setting authSource from environment variable
## Adminer 4.7.2 (2019-07-18) Adminer 4.7.2 (2019-07-18)
--------------------------
- Do not attempt logging in without password (bug #676) - Do not attempt logging in without password (bug #676)
- Stretch footer over the whole table width (bug #624) - Stretch footer over the whole table width (bug #624)
- Allow overwriting tables when copying them - Allow overwriting tables when copying them
@@ -217,7 +308,9 @@
- MS SQL: Support comments - MS SQL: Support comments
- Elasticsearch: Fix setting number of rows - Elasticsearch: Fix setting number of rows
## Adminer 4.7.1 (2019-01-24) Adminer 4.7.1 (2019-01-24)
--------------------------
- Display the tables scrollbar (bug #647) - Display the tables scrollbar (bug #647)
- Remember visible columns in Create Table form (bug #493) - Remember visible columns in Create Table form (bug #493)
- Add autocomplete attributes to login form - Add autocomplete attributes to login form
@@ -225,7 +318,9 @@
- SQLite: Hide server field in login form - SQLite: Hide server field in login form
- Editor: Allow disabling boolean fields in PostgreSQL (bug #640) - Editor: Allow disabling boolean fields in PostgreSQL (bug #640)
## Adminer 4.7.0 (2018-11-24) Adminer 4.7.0 (2018-11-24)
--------------------------
- Simplify storing executed SQL queries to bookmarks - Simplify storing executed SQL queries to bookmarks
- Warn when using password with leading or trailing spaces - Warn when using password with leading or trailing spaces
- Hide import from server if importServerPath() returns an empty string - Hide import from server if importServerPath() returns an empty string
@@ -246,7 +341,9 @@
- ClickHouse: Connect, databases list, tables list, select, SQL command - ClickHouse: Connect, databases list, tables list, select, SQL command
- Georgian translation - Georgian translation
## Adminer 4.6.3 (2018-06-28) Adminer 4.6.3 (2018-06-28)
--------------------------
- Disallow using password-less databases - Disallow using password-less databases
- Copy triggers when copying table - Copy triggers when copying table
- Stop session before connecting - Stop session before connecting
@@ -264,7 +361,9 @@
- MS SQL: Support port with sqlsrv - MS SQL: Support port with sqlsrv
- Editor: Do not check boolean checkboxes with false in PostgreSQL (bug #607) - Editor: Do not check boolean checkboxes with false in PostgreSQL (bug #607)
## Adminer 4.6.2 (2018-02-20) Adminer 4.6.2 (2018-02-20)
--------------------------
- Semi-transparent border on table actions - Semi-transparent border on table actions
- Shorten JSON values in select (bug #594) - Shorten JSON values in select (bug #594)
- Speed up alter table form (regression from 4.4.0) - Speed up alter table form (regression from 4.4.0)
@@ -274,7 +373,9 @@
- PostgreSQL: Add IF EXISTS to DROP SEQUENCE in export (bug #595) - PostgreSQL: Add IF EXISTS to DROP SEQUENCE in export (bug #595)
- Editor: Fix displaying of true boolean values (regression from 4.5.0) - Editor: Fix displaying of true boolean values (regression from 4.5.0)
## Adminer 4.6.1 (2018-02-09) Adminer 4.6.1 (2018-02-09)
--------------------------
- Sticky position of table actions - Sticky position of table actions
- Speed up rendering of long tables (regression from 4.4.0) - Speed up rendering of long tables (regression from 4.4.0)
- Display notification about performing action after relogin - Display notification about performing action after relogin
@@ -291,7 +392,9 @@
- Customization: Support connecting to MySQL via SSL - Customization: Support connecting to MySQL via SSL
- Customization: Allow specifying server name displayed in breadcrumbs - Customization: Allow specifying server name displayed in breadcrumbs
## Adminer 4.6.0 (2018-02-05) Adminer 4.6.0 (2018-02-05)
--------------------------
- Fix counting selected rows after going back to select page - Fix counting selected rows after going back to select page
- PHP <5.3 compatibility even with Elasticsearch enabled - PHP <5.3 compatibility even with Elasticsearch enabled
- Fully support functions in default values - Fully support functions in default values
@@ -311,7 +414,9 @@
- SimpleDB: Document that allow_url_fopen is required - SimpleDB: Document that allow_url_fopen is required
- Malay translation - Malay translation
## Adminer 4.5.0 (2018-01-24) Adminer 4.5.0 (2018-01-24)
--------------------------
- Display name of the object in confirmation when dropping it - Display name of the object in confirmation when dropping it
- Display newlines in column comments (bug #573) - Display newlines in column comments (bug #573)
- Support current_timestamp() as default of time fields (bug #572) - Support current_timestamp() as default of time fields (bug #572)
@@ -335,7 +440,9 @@
- MongoDB: Support mongodb PHP extension - MongoDB: Support mongodb PHP extension
- Editor: Fix displaying of false values in PostgreSQL (bug #568) - Editor: Fix displaying of false values in PostgreSQL (bug #568)
## Adminer 4.4.0 (2018-01-17) Adminer 4.4.0 (2018-01-17)
--------------------------
- Add Content Security Policy - Add Content Security Policy
- Disallow scripts without nonce - Disallow scripts without nonce
- Rate limit password-less login attempts from the same IP address - Rate limit password-less login attempts from the same IP address
@@ -352,14 +459,18 @@
- Customization: Always send security headers - Customization: Always send security headers
- Hebrew translation - Hebrew translation
## Adminer 4.3.1 (2017-04-14) Adminer 4.3.1 (2017-04-14)
--------------------------
- Fix permanent login after logout (bug #539) - Fix permanent login after logout (bug #539)
- Fix SQL command autofocus (regression from 4.0.0) - Fix SQL command autofocus (regression from 4.0.0)
- PostgreSQL: Support JSON and JSONB data types - PostgreSQL: Support JSON and JSONB data types
- PostgreSQL: Fix index size computation in PostgreSQL < 9.0 (regression from 4.3.0) - PostgreSQL: Fix index size computation in PostgreSQL < 9.0 (regression from 4.3.0)
- PostgreSQL: Fix nullable fields in export - PostgreSQL: Fix nullable fields in export
## Adminer 4.3.0 (2017-03-15) Adminer 4.3.0 (2017-03-15)
--------------------------
- Make maxlength in edit fields a soft limit - Make maxlength in edit fields a soft limit
- Add accessibility labels - Add accessibility labels
- Add Cache-Control: immutable to static files - Add Cache-Control: immutable to static files
@@ -372,34 +483,46 @@
- MS SQL: Support pdo_dblib - MS SQL: Support pdo_dblib
- Elasticsearch: Support HTTPS by inputting https://server - Elasticsearch: Support HTTPS by inputting https://server
## Adminer 4.2.5 (2016-06-01) Adminer 4.2.5 (2016-06-01)
--------------------------
- Fix remote execution in SQLite query - Fix remote execution in SQLite query
- SQLite: Require credentials to use - SQLite: Require credentials to use
- PostgreSQL: Support KILL - PostgreSQL: Support KILL
## Adminer 4.2.4 (2016-02-06) Adminer 4.2.4 (2016-02-06)
--------------------------
- Fix remote execution in SQLite query - Fix remote execution in SQLite query
- MySQL: Support PHP 7 - MySQL: Support PHP 7
- Bosnian translation - Bosnian translation
- Finnish translation - Finnish translation
## Adminer 4.2.3 (2015-11-15) Adminer 4.2.3 (2015-11-15)
--------------------------
- Fix XSS in indexes (non-MySQL only) - Fix XSS in indexes (non-MySQL only)
- Support PHP 7 - Support PHP 7
- Greek translation - Greek translation
- Galician translation - Galician translation
- Bulgarian translation - Bulgarian translation
## Adminer 4.2.2 (2015-08-05) Adminer 4.2.2 (2015-08-05)
--------------------------
- Fix XSS in alter table (found by HP Fortify) - Fix XSS in alter table (found by HP Fortify)
## Adminer 4.2.1 (2015-03-10) Adminer 4.2.1 (2015-03-10)
--------------------------
- Send referrer header to the same domain - Send referrer header to the same domain
- MySQL: Fix usage of utf8mb4 if the client library doesn't support it - MySQL: Fix usage of utf8mb4 if the client library doesn't support it
- MySQL: Use utf8mb4 in export only if required - MySQL: Use utf8mb4 in export only if required
- SQLite: Use EXPLAIN QUERY PLAN in SQL query - SQLite: Use EXPLAIN QUERY PLAN in SQL query
## Adminer 4.2.0 (2015-02-07) Adminer 4.2.0 (2015-02-07)
--------------------------
- Fix XSS in login form (bug #436) - Fix XSS in login form (bug #436)
- Allow limiting number of displayed rows in SQL command - Allow limiting number of displayed rows in SQL command
- Fix reading routine column collations - Fix reading routine column collations
@@ -422,7 +545,9 @@
- Firebird: Alpha version - Firebird: Alpha version
- Danish translation - Danish translation
## Adminer 4.1.0 (2014-04-18) Adminer 4.1.0 (2014-04-18)
--------------------------
- Provide size of all databases in the overview - Provide size of all databases in the overview
- Prevent against brute force login attempts from the same IP address - Prevent against brute force login attempts from the same IP address
- Compute number of tables in the overview explicitly - Compute number of tables in the overview explicitly
@@ -442,18 +567,24 @@
- Translate numbers in ar, bn, fa - Translate numbers in ar, bn, fa
- Vietnamese translation - Vietnamese translation
## Adminer 4.0.3 (2014-02-01) Adminer 4.0.3 (2014-02-01)
--------------------------
- MongoDB: insert, truncate, indexes - MongoDB: insert, truncate, indexes
- SimpleDB, MongoDB: insert more fields at once - SimpleDB, MongoDB: insert more fields at once
- SQLite: Fix creating table and altering primary key, bug since ## Adminer 4.0.0 - SQLite: Fix creating table and altering primary key, bug since ## Adminer 4.0.0
- Don't store invalid credentials to session, bug since ## Adminer 4.0.0 - Don't store invalid credentials to session, bug since ## Adminer 4.0.0
- Norweigan translation - Norweigan translation
## Adminer 4.0.2 (2014-01-11) Adminer 4.0.2 (2014-01-11)
--------------------------
- Fix handling of long text in SQL textarea - Fix handling of long text in SQL textarea
- Support paste to SQL textarea in Opera - Support paste to SQL textarea in Opera
## Adminer 4.0.1 (2014-01-11) Adminer 4.0.1 (2014-01-11)
--------------------------
- Don't use type=number if a SQL function is used - Don't use type=number if a SQL function is used
- Disable highlighting in textareas with long texts - Disable highlighting in textareas with long texts
- Don't autofocus SQL textarea in Firefox - Don't autofocus SQL textarea in Firefox
@@ -463,7 +594,9 @@
- MongoDB: Count tables, display ObjectIds, sort, limit, offset, count rows - MongoDB: Count tables, display ObjectIds, sort, limit, offset, count rows
- Elasticsearch: Fix compiled version, create and drop DB, drop table - Elasticsearch: Fix compiled version, create and drop DB, drop table
## Adminer 4.0.0 (2014-01-08) Adminer 4.0.0 (2014-01-08)
--------------------------
- Driver for SimpleDB, MongoDB and Elasticsearch - Driver for SimpleDB, MongoDB and Elasticsearch
- Highlight SQL in textareas - Highlight SQL in textareas
- Save and continue edit by AJAX - Save and continue edit by AJAX
@@ -496,7 +629,9 @@
- Portugal Portuguese translation - Portugal Portuguese translation
- Thai translation - Thai translation
## Adminer 3.7.1 (2013-06-29) Adminer 3.7.1 (2013-06-29)
--------------------------
- Increase click target for checkboxes - Increase click target for checkboxes
- Use shadow for highlighting default button - Use shadow for highlighting default button
- Don't use LIMIT 1 if inline updating unique row - Don't use LIMIT 1 if inline updating unique row
@@ -514,7 +649,9 @@
- PostgreSQL: Handle timestamp types (bug #324) - PostgreSQL: Handle timestamp types (bug #324)
- Add Korean translation - Add Korean translation
## Adminer 3.7.0 (2013-05-19) Adminer 3.7.0 (2013-05-19)
--------------------------
- Allow more SQL files to be uploaded at the same time - Allow more SQL files to be uploaded at the same time
- Print run time next to executed queries - Print run time next to executed queries
- Don't drop original view and routine before creating the new one - Don't drop original view and routine before creating the new one
@@ -540,7 +677,9 @@
- SQLite: Export views - SQLite: Export views
- PostgreSQL: Fix swapped NULL and NOT NULL columns in PDO - PostgreSQL: Fix swapped NULL and NOT NULL columns in PDO
## Adminer 3.6.4 (2013-04-26) Adminer 3.6.4 (2013-04-26)
--------------------------
- Display pagination on a fixed position - Display pagination on a fixed position
- Increase default select limit to 50 - Increase default select limit to 50
- Display SQL edit form on Ctrl+click on the select query - Display SQL edit form on Ctrl+click on the select query
@@ -563,14 +702,18 @@
- MySQL: Link processlist documentation - MySQL: Link processlist documentation
- SQLite: Export indexes - SQLite: Export indexes
## Adminer 3.6.3 (2013-01-23) Adminer 3.6.3 (2013-01-23)
--------------------------
- Display error code in SQL query - Display error code in SQL query
- Allow specifying external links - Allow specifying external links
- Treat Meta key same as Ctrl - Treat Meta key same as Ctrl
- Fix XSS in displaying non-UTF-8 strings - Fix XSS in displaying non-UTF-8 strings
- Don't use type="number" for decimal numbers - Don't use type="number" for decimal numbers
## Adminer 3.6.2 (2012-12-21) Adminer 3.6.2 (2012-12-21)
--------------------------
- Edit values by Ctrl+click instead of double click - Edit values by Ctrl+click instead of double click
- Don't select row on double click - Don't select row on double click
- Support NULL in routine calls - Support NULL in routine calls
@@ -585,10 +728,14 @@
- PostgreSQL: Fix process list in version 9.2 - PostgreSQL: Fix process list in version 9.2
- MS SQL: Support databases starting with number - MS SQL: Support databases starting with number
## Adminer 3.6.1 (2012-09-17) Adminer 3.6.1 (2012-09-17)
--------------------------
- Fix compiled version on PHP with multibyte support - Fix compiled version on PHP with multibyte support
## Adminer 3.6.0 (2012-09-16) Adminer 3.6.0 (2012-09-16)
--------------------------
- Load more data in select - Load more data in select
- Edit strings with \n in textarea - Edit strings with \n in textarea
- Time out long running database list and select count - Time out long running database list and select count
@@ -602,11 +749,15 @@
- selectQueryBuild() method (customization) - selectQueryBuild() method (customization)
- Serbian translation - Serbian translation
## Adminer 3.5.1 (2012-08-10) Adminer 3.5.1 (2012-08-10)
--------------------------
- Support same name fields in CSV export - Support same name fields in CSV export
- Support Shift+click in export - Support Shift+click in export
## Adminer 3.5.0 (2012-08-05) Adminer 3.5.0 (2012-08-05)
--------------------------
- Links for column search in select - Links for column search in select
- Autohide column context menu in select - Autohide column context menu in select
- Autodisplay long table names in tables list - Autodisplay long table names in tables list
@@ -615,7 +766,9 @@
- SQLite: Better editing in tables without primary key - SQLite: Better editing in tables without primary key
- SQLite: Display number of rows in database overview - SQLite: Display number of rows in database overview
## Adminer 3.4.0 (2012-06-30) Adminer 3.4.0 (2012-06-30)
--------------------------
- Link to descending order - Link to descending order
- Shift+click on checkbox to select consecutive rows - Shift+click on checkbox to select consecutive rows
- Print current time next to executed SQL queries - Print current time next to executed SQL queries
@@ -637,7 +790,9 @@
- Ukrainian translation - Ukrainian translation
- Bengali translation - Bengali translation
## Adminer 3.3.4 (2012-03-07) Adminer 3.3.4 (2012-03-07)
--------------------------
- Foreign keys default actions (bug #188) - Foreign keys default actions (bug #188)
- SET DEFAULT foreign key action - SET DEFAULT foreign key action
- Fix minor parser bug in SQL command with webserver file - Fix minor parser bug in SQL command with webserver file
@@ -660,14 +815,18 @@
- Boolean search (Editor) - Boolean search (Editor)
- Persian translation - Persian translation
## Adminer 3.3.3 (2011-08-12) Adminer 3.3.3 (2011-08-12)
--------------------------
- Highlight checked rows - Highlight checked rows
- Titles of links in database overview and navigation - Titles of links in database overview and navigation
- Fix trigger export (SQLite) - Fix trigger export (SQLite)
- Default trigger statement (SQLite, PostgreSQL) - Default trigger statement (SQLite, PostgreSQL)
- Remove search by expression (PostgreSQL, MS SQL) - Remove search by expression (PostgreSQL, MS SQL)
## Adminer 3.3.2 (2011-08-08) Adminer 3.3.2 (2011-08-08)
--------------------------
- Display error with non-existent row in edit - Display error with non-existent row in edit
- Fix minor parser bug in SQL command with webserver file - Fix minor parser bug in SQL command with webserver file
- Fix SQL command Stop on error - Fix SQL command Stop on error
@@ -675,12 +834,16 @@
- Fast number of rows with big tables (PostgreSQL) - Fast number of rows with big tables (PostgreSQL)
- Sort databases and schemas (PostgreSQL) - Sort databases and schemas (PostgreSQL)
## Adminer 3.3.1 (2011-07-27) Adminer 3.3.1 (2011-07-27)
--------------------------
- Fix XSS introduced in Adminer 3.2.0 - Fix XSS introduced in Adminer 3.2.0
- Fix altering default values (PostgreSQL) - Fix altering default values (PostgreSQL)
- Process list (PostgreSQL) - Process list (PostgreSQL)
## Adminer 3.3.0 (2011-07-19) Adminer 3.3.0 (2011-07-19)
--------------------------
- Use Esc to disable in-place edit - Use Esc to disable in-place edit
- Shortcut for database privileges - Shortcut for database privileges
- Editable index names - Editable index names
@@ -706,10 +869,14 @@
- Easier sending of default headers (customization) - Easier sending of default headers (customization)
- Lithuanian and Romanian translation - Lithuanian and Romanian translation
## Adminer 3.2.2 (2011-03-28) Adminer 3.2.2 (2011-03-28)
--------------------------
- Fix AJAX history after reload - Fix AJAX history after reload
## Adminer 3.2.1 (2011-03-23) Adminer 3.2.1 (2011-03-23)
--------------------------
- Ability to save expression in edit - Ability to save expression in edit
- Respect default database collation (bug #119) - Respect default database collation (bug #119)
- Don't export triggers without table (bug #123) - Don't export triggers without table (bug #123)
@@ -730,7 +897,9 @@
- Allow own code in `<head>` (customization) - Allow own code in `<head>` (customization)
- Polish translation - Polish translation
## Adminer 3.2.0 (2011-02-24) Adminer 3.2.0 (2011-02-24)
--------------------------
- Get long texts and slow information by AJAX - Get long texts and slow information by AJAX
- Most links and forms by AJAX in browsers with support for history.pushState - Most links and forms by AJAX in browsers with support for history.pushState
- Copy tables - Copy tables
@@ -753,7 +922,9 @@
- Fix saving schema to cookie in Opera - Fix saving schema to cookie in Opera
- Portuguese, Slovenian and Turkish translation - Portuguese, Slovenian and Turkish translation
## Adminer 3.1.0 (2010-11-16) Adminer 3.1.0 (2010-11-16)
--------------------------
- TSV export and import - TSV export and import
- Customizable export - Customizable export
- Option to show only errors in SQL command - Option to show only errors in SQL command
@@ -770,7 +941,9 @@
- Arabic translation and RTL support - Arabic translation and RTL support
- Dual licensing: Apache or GPL - Dual licensing: Apache or GPL
## Adminer 3.0.1 (2010-10-18) Adminer 3.0.1 (2010-10-18)
--------------------------
- Send the form by Ctrl+Enter in all textareas - Send the form by Ctrl+Enter in all textareas
- Disable creating SQLite databases with extension other than db, sdb, sqlite - Disable creating SQLite databases with extension other than db, sdb, sqlite
- Ability to use Adminer in a frame through customization - Ability to use Adminer in a frame through customization
@@ -778,7 +951,9 @@
- MS SQL 2005 compatibility - MS SQL 2005 compatibility
- PostgreSQL: connect if the eponymous database does not exist - PostgreSQL: connect if the eponymous database does not exist
## Adminer 3.0.0 (2010-10-15) Adminer 3.0.0 (2010-10-15)
--------------------------
- Drivers for MS SQL, SQLite, PostgreSQL, Oracle - Drivers for MS SQL, SQLite, PostgreSQL, Oracle
- Allow concurrent logins on the same server - Allow concurrent logins on the same server
- Allow permanent login without customization - Allow permanent login without customization
@@ -804,18 +979,24 @@
- Defer table information in database overview to JavaScript (performance) - Defer table information in database overview to JavaScript (performance)
- Big tables optimizations (performance) - Big tables optimizations (performance)
## Adminer 2.3.2 (2010-04-21) Adminer 2.3.2 (2010-04-21)
--------------------------
- Fix COUNT(*) link - Fix COUNT(*) link
- Fix Save and continue edit - Fix Save and continue edit
## Adminer 2.3.1 (2010-04-06) Adminer 2.3.1 (2010-04-06)
--------------------------
- Add Drop button to Alter pages (regression from 2.0.0) - Add Drop button to Alter pages (regression from 2.0.0)
- Link COUNT(*) result to listing - Link COUNT(*) result to listing
- Newlines in select query edit - Newlines in select query edit
- Return to referrer after edit - Return to referrer after edit
- Respect session.auto_start (bug #42) - Respect session.auto_start (bug #42)
## Adminer 2.3.0 (2010-02-26) Adminer 2.3.0 (2010-02-26)
--------------------------
- Support for permanent login (customization required) - Support for permanent login (customization required)
- Search in all tables - Search in all tables
- Show status variables - Show status variables
@@ -827,14 +1008,18 @@
- Delete length when changing type in alter table - Delete length when changing type in alter table
- Ability to check table prefix in export - Ability to check table prefix in export
## Adminer 2.2.1 (2009-11-26) Adminer 2.2.1 (2009-11-26)
--------------------------
- Highlight current links - Highlight current links
- Improve concurrency - Improve concurrency
- Move number of tables to DB info (performance) - Move number of tables to DB info (performance)
- Search by foreign keys (Editor) - Search by foreign keys (Editor)
- Link new item in backward keys (Editor) - Link new item in backward keys (Editor)
## Adminer 2.2.0 (2009-10-20) Adminer 2.2.0 (2009-10-20)
--------------------------
- Database list - bulk drop, number of tables - Database list - bulk drop, number of tables
- Enlarge field for enum and set definition - Enlarge field for enum and set definition
- Display table links above table structure - Display table links above table structure
@@ -851,7 +1036,9 @@
- Move `<h1>` to $adminer->navigation (customization) - Move `<h1>` to $adminer->navigation (customization)
- Rename get_dbh to connection (customization) - Rename get_dbh to connection (customization)
## Adminer 2.1.0 (2009-09-12) Adminer 2.1.0 (2009-09-12)
--------------------------
- Edit default values directly in table creation - Edit default values directly in table creation
- Execute SQL file stored on server disk - Execute SQL file stored on server disk
- Display EXPLAIN in SQL query - Display EXPLAIN in SQL query
@@ -865,7 +1052,9 @@
- Speed up simple alter table - Speed up simple alter table
- Traditional Chinese translation - Traditional Chinese translation
## Adminer 2.0.0 (2009-08-06) Adminer 2.0.0 (2009-08-06)
--------------------------
- Editor: User friendly data editor - Editor: User friendly data editor
- Customization: Adminer class - Customization: Adminer class
- Create single column foreign key in table structure - Create single column foreign key in table structure
@@ -891,10 +1080,14 @@
- Fix CSV import - Fix CSV import
- Fix work with default values - Fix work with default values
## Adminer 1.11.1 (2009-07-03) Adminer 1.11.1 (2009-07-03)
--------------------------
- Fix problem with enabled Filter extension - Fix problem with enabled Filter extension
## Adminer 1.11.0 (2009-07-02) Adminer 1.11.0 (2009-07-02)
--------------------------
- Connection through socket by server :/path/to/socket - Connection through socket by server :/path/to/socket
- Simplify export - Simplify export
- Display execution time in SQL query - Display execution time in SQL query
@@ -915,12 +1108,16 @@
- Automatically add new fields in table creation - Automatically add new fields in table creation
- Use \n in SQL commands - Use \n in SQL commands
## phpMinAdmin 1.10.1 (2009-05-07) phpMinAdmin 1.10.1 (2009-05-07)
-------------------------------
- Highlight odd and hover rows - Highlight odd and hover rows
- Partition editing comfort (bug #12) - Partition editing comfort (bug #12)
- Allow full length in limited int - Allow full length in limited int
## phpMinAdmin 1.10.0 (2009-04-28) phpMinAdmin 1.10.0 (2009-04-28)
-------------------------------
- Partitioning (MySQL 5.1) - Partitioning (MySQL 5.1)
- CSV import - CSV import
- Plus and minus functions - Plus and minus functions
@@ -932,10 +1129,14 @@
- Size reduction by minification of variables and functions - Size reduction by minification of variables and functions
- Russian translation - Russian translation
## phpMinAdmin 1.9.1 (2008-10-27) phpMinAdmin 1.9.1 (2008-10-27)
------------------------------
- Update translations - Update translations
## phpMinAdmin 1.9.0 (2008-10-16) phpMinAdmin 1.9.0 (2008-10-16)
------------------------------
- List of tables and views with maintenance commands - List of tables and views with maintenance commands
- Clone rows - Clone rows
- Bulk edit and clone - Bulk edit and clone
@@ -951,7 +1152,9 @@
- Order by function result working also in older MySQL versions - Order by function result working also in older MySQL versions
- Tested on IIS - Tested on IIS
## phpMinAdmin 1.8.0 (2008-09-12) phpMinAdmin 1.8.0 (2008-09-12)
------------------------------
- Events (MySQL 5.1) - Events (MySQL 5.1)
- Access without login - accept ?username= - Access without login - accept ?username=
- Print SQL query in select, messages and warnings - Print SQL query in select, messages and warnings
@@ -960,7 +1163,9 @@
- Italian and Estonian translation - Italian and Estonian translation
- Order by COUNT(*) - Order by COUNT(*)
## phpMinAdmin 1.7.0 (2008-08-26) phpMinAdmin 1.7.0 (2008-08-26)
------------------------------
- Customizable export (select objects to export, SQL or CSV) - Customizable export (select objects to export, SQL or CSV)
- Ability to alter existing tables and drop old tables in export - Ability to alter existing tables and drop old tables in export
- Choose columns in select, aggregation - Choose columns in select, aggregation
@@ -974,10 +1179,14 @@
- Cache static files - Cache static files
- Faster checking of number of results - Faster checking of number of results
## phpMinAdmin 1.6.1 (2008-05-22) phpMinAdmin 1.6.1 (2008-05-22)
------------------------------
- Set session parameters only if not session.auto_start - Set session parameters only if not session.auto_start
## phpMinAdmin 1.6.0 (2008-05-16) phpMinAdmin 1.6.0 (2008-05-16)
------------------------------
- Order of columns in table - Order of columns in table
- Set max_allowed_packet in dump and use extended insert - Set max_allowed_packet in dump and use extended insert
- Spanish and German translations - Spanish and German translations
@@ -989,7 +1198,9 @@
- Last-Modified header for files - Last-Modified header for files
- Several bug fixes - Several bug fixes
## phpMinAdmin 1.5.0 (2008-01-09) phpMinAdmin 1.5.0 (2008-01-09)
------------------------------
- Mass delete - Mass delete
- Vertical privileges - Vertical privileges
- Specify connection port by colon in server - Specify connection port by colon in server
@@ -1000,14 +1211,18 @@
- Uncheck NULL by change - Uncheck NULL by change
- Mark shortened fields in select - Mark shortened fields in select
## phpMinAdmin 1.4.0 (2007-08-15) phpMinAdmin 1.4.0 (2007-08-15)
------------------------------
- Privileges - Privileges
- New design - New design
- Dutch translation - Dutch translation
- Use NULL for auto_increment (bug #1) - Use NULL for auto_increment (bug #1)
- Fix dropping procedure parameters - Fix dropping procedure parameters
## phpMinAdmin 1.3.2 (2007-08-06) phpMinAdmin 1.3.2 (2007-08-06)
------------------------------
- Next field by JavaScript in foreign keys - Next field by JavaScript in foreign keys
- Set time zone in dump - Set time zone in dump
- Refresh lang cookie - Refresh lang cookie
@@ -1015,12 +1230,16 @@
- Move vertical lines in schema properly - Move vertical lines in schema properly
- Fix maximum page in select - Fix maximum page in select
## phpMinAdmin 1.3.1 (2007-07-31) phpMinAdmin 1.3.1 (2007-07-31)
------------------------------
- Move references lines in schema - Move references lines in schema
- Fix dump - Fix dump
- Fix update links - Fix update links
## phpMinAdmin 1.3.0 (2007-07-27) phpMinAdmin 1.3.0 (2007-07-27)
------------------------------
- Breadcrumb navigation - Breadcrumb navigation
- Operator IN - Operator IN
- Timestamp default values - Timestamp default values
@@ -1030,13 +1249,17 @@
- More friendly user interface - More friendly user interface
- Slovak translation - Slovak translation
## phpMinAdmin 1.2.0 (2007-07-25) phpMinAdmin 1.2.0 (2007-07-25)
------------------------------
- Manipulate triggers - Manipulate triggers
- PDO Abstraction - PDO Abstraction
- Auto_increment value - Auto_increment value
- JavaScript for adding rows - JavaScript for adding rows
## phpMinAdmin 1.1.0 (2007-07-19) phpMinAdmin 1.1.0 (2007-07-19)
------------------------------
- Routines manipulation - Routines manipulation
- Views manipulation - Views manipulation
- Foreign keys manipulation - Foreign keys manipulation
@@ -1047,5 +1270,7 @@
- JavaScript for next rows in table edit - JavaScript for next rows in table edit
- Cache databases list - Cache databases list
## phpMinAdmin 1.0.0 (2007-07-11) phpMinAdmin 1.0.0 (2007-07-11)
------------------------------
- First official release - First official release

View File

@@ -1,4 +1,5 @@
# Licenses Licenses
========
You may use Adminer under the terms of either the Apache License Version 2.0 You may use Adminer under the terms of either the Apache License Version 2.0
or the GNU General Public License (GPL) version 2. or the GNU General Public License (GPL) version 2.

View File

@@ -1,4 +1,5 @@
# Adminer Adminer
=======
**Adminer** is a full-featured database management tool written in PHP. It consists of a single file ready to deploy to **Adminer** is a full-featured database management tool written in PHP. It consists of a single file ready to deploy to
the target server. As a companion, **Adminer Editor** offers data manipulation for end-users. the target server. As a companion, **Adminer Editor** offers data manipulation for end-users.
@@ -7,16 +8,23 @@ Supported database drivers:
- MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, MongoDB - MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, MongoDB
- With plugin: SimpleDB, Elasticsearch (beta), Firebird (alpha), ClickHouse (alpha) - With plugin: SimpleDB, Elasticsearch (beta), Firebird (alpha), ClickHouse (alpha)
## Requirements Requirements
------------
- PHP 5.6+ with enabled sessions. - PHP 5.6+ with enabled sessions.
## Migration from original Adminer Migration from original Adminer
-------------------------------
No action is needed for now. But please, read 👉 **[What to expect](#what-to-expect)** section before you decide to - Remove plugin AdminerTablesFilter (plugins/tables-filter.php).
switch to this project. - If you use complex custom theme, you will probably need to adjust a thing or two.
## Usage More information can be found in [Upgrade Guide](docs/upgrade.md).
Please, read also 👉 **[What to expect](#what-to-expect)** section before you decide to switch to this project.
Usage
-----
Download one for the latest [release files](https://github.com/pematon/adminer/releases), upload to the HTTP server Download one for the latest [release files](https://github.com/pematon/adminer/releases), upload to the HTTP server
with PHP and enjoy 😉 If you are not satisfied with any combination of the database driver and language, you can with PHP and enjoy 😉 If you are not satisfied with any combination of the database driver and language, you can
@@ -28,28 +36,31 @@ download the source code and compile your own Adminer:
```shell ```shell
# Adminer # Adminer
php compile.php <driver> <language> php compile.php <drivers> <languages>
# Editor # Editor
php compile.php editor <driver> <language> php compile.php editor <drivers> <languages>
``` ```
For example: For example:
```shell ```shell
php compile.php pgsql cs php compile.php pgsql cs
php compile.php mysql,pgsql en,de,cs,sk
``` ```
[Available drivers](https://github.com/pematon/adminer/tree/master/adminer/drivers), [Available drivers](https://github.com/pematon/adminer/tree/master/adminer/drivers),
[languages](https://github.com/pematon/adminer/tree/master/adminer/lang). [languages](https://github.com/pematon/adminer/tree/master/adminer/lang).
## Security Security
--------
Adminer does not allow connecting to databases without a password and it rate-limits the connection attempts to protect Adminer does not allow connecting to databases without a password and it rate-limits the connection attempts to protect
against brute-force attacks. Still, it is highly recommended to 🔒 **restrict access to Adminer** 🔒 by whitelisting IP against brute-force attacks. Still, it is highly recommended to 🔒 **restrict access to Adminer** 🔒 by whitelisting IP
addresses allowed to connect to it, by password-protecting the access in your web server or by enabling security plugins addresses allowed to connect to it, by password-protecting the access in your web server or by enabling security plugins
(e.g. to require an OTP). (e.g. to require an OTP).
## Plugins Plugins
-------
* Download plugins you want and place them into the `plugins` folder. * Download plugins you want and place them into the `plugins` folder.
* Create `index.php` file specifying which plugins do you want to use. * Create `index.php` file specifying which plugins do you want to use.
@@ -105,7 +116,9 @@ include "./adminer.php";
[Available plugins](https://github.com/pematon/adminer/tree/master/plugins). [Available plugins](https://github.com/pematon/adminer/tree/master/plugins).
## Main project files Main project files
------------------
- adminer/index.php - Run development version of Adminer. - adminer/index.php - Run development version of Adminer.
- editor/index.php - Run development version of Adminer Editor. - editor/index.php - Run development version of Adminer Editor.
- editor/example.php - Example customization. - editor/example.php - Example customization.
@@ -118,7 +131,8 @@ include "./adminer.php";
- lang.php - Update translations. - lang.php - Update translations.
- tests/katalon.html - Katalon Automation Recorder test suite. - tests/katalon.html - Katalon Automation Recorder test suite.
## Project history Project history
---------------
Adminer was originally developed by Jakub Vrana, and it can be still found on [official pages](https://www.adminer.org/). Adminer was originally developed by Jakub Vrana, and it can be still found on [official pages](https://www.adminer.org/).
Unfortunately, it is not maintained for several years. In the meantime, I (@peterpp) created for my company a set of Unfortunately, it is not maintained for several years. In the meantime, I (@peterpp) created for my company a set of
@@ -126,17 +140,20 @@ custom plugins, modern theme, fixed some bugs and practically rewrote the Elasti
and contributed to the [AdminerEvo](https://www.adminerevo.org/) project that looked promising. However, I finally and contributed to the [AdminerEvo](https://www.adminerevo.org/) project that looked promising. However, I finally
decided to continue working on this fork and fulfill my own vision. decided to continue working on this fork and fulfill my own vision.
## What to expect What to expect
--------------
Our top priority is fixing the security issues and reported bugs. But we really want to move forward and transform Our top priority is fixing the security issues and reported bugs. But we really want to move forward and transform
Adminer to a tool that will keep its simplicity, yet looks much better, is even easier to use and can be configured Adminer to a tool that will keep its simplicity, yet looks much better, is even easier to use and can be configured
without requirement of additional plugins. without requirement of additional plugins.
### Version 4.x ### Version 4.x
Original design and backward compatibility is kept. Many issues were fixed, and we introduced several functional and Original design and backward compatibility is kept. Many issues were fixed, and we introduced several functional and
UI improvements. UI improvements.
### Version 5 ### Version 5
Bridges will be burned 🔥🔥🔥. It's in development already, so you [can check](https://github.com/pematon/adminer/tree/version-5) Bridges will be burned 🔥🔥🔥. It's in development already, so you [can check](https://github.com/pematon/adminer/tree/version-5)
what's going on. Or you can become the early adopter and help us with testing 😉 what's going on. Or you can become the early adopter and help us with testing 😉

View File

@@ -1,4 +1,5 @@
# Reporting security issues Reporting security issues
=========================
To report a security issue, please [open a draft security advisory](https://github.com/pematon/adminer/security/advisories). To report a security issue, please [open a draft security advisory](https://github.com/pematon/adminer/security/advisories).
@@ -6,6 +7,7 @@ Security issues are handled with top priority. Once acknowledged, a fix should b
as soon as possible. Security advisories will be made public after a fix and new version have been released, as soon as possible. Security advisories will be made public after a fix and new version have been released,
or the advisory has been declined. or the advisory has been declined.
## Supported versions Supported versions
------------------
Only the last published version and the last development version (last commit) are supported. Only the last published version and the last development version (last commit) are supported.

View File

@@ -1,5 +1,6 @@
<?php <?php
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]);
$PROCEDURE = ($_GET["name"] ?: $_GET["call"]);
page_header(lang('Call') . ": " . h($PROCEDURE), $error); page_header(lang('Call') . ": " . h($PROCEDURE), $error);
$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE")); $routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
@@ -59,10 +60,9 @@ if (!$error && $_POST) {
} }
} }
} }
?>
<form action="" method="post"> echo "<form action='' method='post'>\n";
<?php
if ($in) { if ($in) {
echo "<table cellspacing='0' class='layout'>\n"; echo "<table cellspacing='0' class='layout'>\n";
foreach ($in as $key) { foreach ($in as $key) {
@@ -83,8 +83,28 @@ if ($in) {
} }
echo "</table>\n"; echo "</table>\n";
} }
?>
<p> echo "<p>",
<input type="submit" value="<?php echo lang('Call'); ?>"> "<input type='submit' value='", lang('Call'), "'>",
<input type="hidden" name="token" value="<?php echo $token; ?>"> "<input type='hidden' name='token' value='$token'>",
</form> "</p>\n",
"</form>\n";
$comment = $routine["comment"];
if ($comment !== null && $comment !== "") {
$comment = h(trim($routine["comment"], "\n"));
// Remove indenting of all lines (used in MySQL routines in 'sys' database).
if (preg_match('~^ +~', $comment, $matches)) {
preg_match_all("~^($matches[0]|$)~m", $comment, $linesWithIndent);
if (count($linesWithIndent[0]) == substr_count($comment, "\n")) {
$comment = preg_replace("~^($matches[0])~m", "", $comment);
}
}
// Format common headlines (used in MySQL routines in 'sys' database).
$comment = preg_replace('~(^|[^\n]\n)(Description|Parameters|Example)\n~', "$1\n<strong>$2</strong>\n", $comment);
echo "<pre class='comment'>$comment</pre>\n";
}

View File

@@ -182,8 +182,8 @@ foreach ($engines as $engine) {
<p> <p>
<?php if (support("columns") || $TABLE == "") { ?> <?php if (support("columns") || $TABLE == "") { ?>
<?php echo lang('Table name'); ?>: <input name="name" data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off"> <?php echo lang('Table name'); ?>: <input name="name" data-maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php if ($TABLE == "" && !$_POST) { echo script("focus(qs('#form')['name']);"); } ?> <?php if ($TABLE == "" && !$_POST) { echo script("focus(gid('form')['name']);"); } ?>
<?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . on_help("getTarget(event).value", 1) . script("qsl('select').onchange = helpClose;") : ""); ?> <?php echo ($engines ? "<select name='Engine'>" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" . help_script_command("value", true) : ""); ?>
<?php echo ($collations && !preg_match("~sqlite|mssql~", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?> <?php echo ($collations && !preg_match("~sqlite|mssql~", $jush) ? html_select("Collation", array("" => "(" . lang('collation') . ")") + $collations, $row["Collation"]) : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?> <?php } ?>
@@ -221,7 +221,7 @@ if (support("partitioning")) {
print_fieldset("partition", lang('Partition by'), $row["partition_by"]); print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
?> ?>
<p> <p>
<?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . script("qsl('select').onchange = partitionByChange;"); ?> <?php echo "<select name='partition_by'>" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>" . help_script_command("value.replace(/./, 'PARTITION BY \$&')", true) . script("qsl('select').onchange = partitionByChange;"); ?>
(<input name="partition" value="<?php echo h($row["partition"]); ?>">) (<input name="partition" value="<?php echo h($row["partition"]); ?>">)
<?php echo lang('Partitions'); ?>: <input type="number" name="partitions" class="size<?php echo ($partition_table || !$row["partition_by"] ? " hidden" : ""); ?>" value="<?php echo h($row["partitions"]); ?>"> <?php echo lang('Partitions'); ?>: <input type="number" name="partitions" class="size<?php echo ($partition_table || !$row["partition_by"] ? " hidden" : ""); ?>" value="<?php echo h($row["partitions"]); ?>">
<table cellspacing="0" id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>> <table cellspacing="0" id="partition-table"<?php echo ($partition_table ? "" : " class='hidden'"); ?>>

View File

@@ -66,7 +66,7 @@ echo ($_POST["add_x"] || strpos($name, "\n")
'mariadb' => "supported-character-sets-and-collations/", 'mariadb' => "supported-character-sets-and-collations/",
'mssql' => "ms187963.aspx", 'mssql' => "ms187963.aspx",
)) : ""); )) : "");
echo script("focus(qs('#name'));"); echo script("focus(gid('name'));");
?> ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php

View File

@@ -47,7 +47,28 @@ if ($tables_views && !$error && !$_POST["search"]) {
page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true); page_header(($_GET["ns"] == "" ? lang('Database') . ": " . h(DB) : lang('Schema') . ": " . h($_GET["ns"])), $error, true);
if ($adminer->homepage()) { if ($adminer->homepage()) {
if ($_GET["ns"] !== "") { if ($_GET["ns"] === "") {
echo "<h3 id='schemas'>" . lang('Schemas') . "</h3>\n";
$schemas = schemas();
if (!$schemas) {
echo "<p class='message'>" . lang('No schemas.') . "\n";
} else {
// TODO: Checkboxes for batch dropping of schemas.
echo "<div class='scrollable'>\n",
"<table class='nowrap'>\n",
'<thead><tr class="wrap">',
'<th>', lang('Schema'), "</th>",
'</tr></thead>';
foreach ($schemas as $name) {
echo "<tr", odd(), ">",
"<th><a href='", h(ME), "ns=" . urlencode($name), "' title='", lang('Show schema'), "'>" . h($name) . "</a></th>",
"</tr>";
}
echo '</table></div>';
}
} else {
echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n"; echo "<h3 id='tables-views'>" . lang('Tables and views') . "</h3>\n";
$tables_list = tables_list(); $tables_list = tables_list();
if (!$tables_list) { if (!$tables_list) {
@@ -73,7 +94,7 @@ if ($adminer->homepage()) {
echo "<table cellspacing='0' class='nowrap checkable'>\n"; echo "<table cellspacing='0' class='nowrap checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo '<thead><tr class="wrap">'; echo '<thead><tr class="wrap">';
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^(tables|views)\[/);", ""); echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("gid('check-all').onclick = partial(formCheck, /^(tables|views)\[/);", "");
echo '<th>' . lang('Table'); echo '<th>' . lang('Table');
echo '<td>' . lang('Engine') . doc_link(array('sql' => 'storage-engines.html')); echo '<td>' . lang('Engine') . doc_link(array('sql' => 'storage-engines.html'));
echo '<td>' . lang('Collation') . doc_link(array('sql' => 'charset-charsets.html', 'mariadb' => 'supported-character-sets-and-collations/')); echo '<td>' . lang('Collation') . doc_link(array('sql' => 'charset-charsets.html', 'mariadb' => 'supported-character-sets-and-collations/'));
@@ -126,17 +147,17 @@ if ($adminer->homepage()) {
echo "</div>\n"; echo "</div>\n";
if (!information_schema(DB)) { if (!information_schema(DB)) {
echo "<div class='footer'><div>\n"; echo "<div class='footer'><div>\n";
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . on_help("'VACUUM'"); $vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . help_script("VACUUM");
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help($jush == "sql" ? "'OPTIMIZE TABLE'" : "'VACUUM OPTIMIZE'"); $optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . help_script($jush == "sql" ? "OPTIMIZE TABLE" : "VACUUM OPTIMIZE");
echo "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>" echo "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>"
. ($jush == "sqlite" ? $vacuum . ($jush == "sqlite" ? $vacuum
: ($jush == "pgsql" ? $vacuum . $optimize : ($jush == "pgsql" ? $vacuum . $optimize
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") . $optimize : ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . help_script("ANALYZE TABLE") . $optimize
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'CHECK TABLE'") . "<input type='submit' name='check' value='" . lang('Check') . "'> " . help_script("CHECK TABLE")
. "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . on_help("'REPAIR TABLE'") . "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . help_script("REPAIR TABLE")
: ""))) : "")))
. "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . on_help($jush == "sqlite" ? "'DELETE'" : "'TRUNCATE" . ($jush == "pgsql" ? "'" : " TABLE'")) . confirm() . "<input type='submit' name='truncate' value='" . lang('Truncate') . "'> " . help_script($jush == "sqlite" ? "DELETE" : ("TRUNCATE" . ($jush == "pgsql" ? "" : " TABLE"))) . confirm()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . on_help("'DROP TABLE'") . confirm() . "\n"; . "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . help_script("DROP TABLE") . confirm() . "\n";
$databases = (support("scheme") ? $adminer->schemas() : $adminer->databases()); $databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
if (count($databases) != 1 && $jush != "sqlite") { if (count($databases) != 1 && $jush != "sqlite") {
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB)); $db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
@@ -161,37 +182,59 @@ if ($adminer->homepage()) {
if (support("routine")) { if (support("routine")) {
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n"; echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
$routines = routines(); $routines = routines();
if ($routines) { if ($routines) {
$commentsSupported = $routines[0]["ROUTINE_COMMENT"] !== null;
echo "<table>\n"; echo "<table>\n";
echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td></thead>\n"; echo '<thead><tr>',
'<th>', lang('Name'), '</th><td>', lang('Type'), '</td><td>', lang('Return type'), "</td>";
if ($commentsSupported) {
echo "<td>", lang('Comment'), "</td>";
}
echo "<td></td>",
"</tr></thead>\n";
odd(''); odd('');
foreach ($routines as $row) { foreach ($routines as $row) {
$name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"])); // not computed on the pages to be able to print the header first // not computed on the pages to be able to print the header first
echo '<tr' . odd() . '>'; $name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"]));
echo '<th><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . h($row["ROUTINE_NAME"]) . '</a>';
echo '<td>' . h($row["ROUTINE_TYPE"]); echo '<tr', odd(), '>',
echo '<td>' . h($row["DTD_IDENTIFIER"]); '<th><a href="', h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name), '">', h($row["ROUTINE_NAME"]), '</a></th>',
echo '<td><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . lang('Alter') . "</a>"; '<td>', h($row["ROUTINE_TYPE"]), '</td>',
'<td>', h($row["DTD_IDENTIFIER"]), '</td>';
if ($commentsSupported) {
echo '<td>', shorten_utf8(preg_replace('~\s{2,}~', " ", trim($row["ROUTINE_COMMENT"])), 50), '</td>';
}
echo '<td><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . lang('Alter') . "</a></td>";
} }
echo "</table>\n"; echo "</table>\n";
} }
echo '<p class="links">'
. (support("procedure") ? '<a href="' . h(ME) . 'procedure=">' . lang('Create procedure') . '</a>' : '') echo '<p class="links">',
. '<a href="' . h(ME) . 'function=">' . lang('Create function') . "</a>\n" (support("procedure") ? '<a href="' . h(ME) . 'procedure=">' . lang('Create procedure') . '</a>' : ''),
; '<a href="' . h(ME) . 'function=">' . lang('Create function') . "</a>\n";
} }
if (support("sequence")) { if (support("sequence")) {
echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n"; echo "<h3 id='sequences'>" . lang('Sequences') . "</h3>\n";
$sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name"); $sequences = get_vals("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = current_schema() ORDER BY sequence_name");
if ($sequences) { if ($sequences) {
echo "<table>\n"; echo "<table>\n",
echo "<thead><tr><th>" . lang('Name') . "</thead>\n"; "<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
odd(''); odd('');
foreach ($sequences as $val) { foreach ($sequences as $val) {
echo "<tr" . odd() . "><th><a href='" . h(ME) . "sequence=" . urlencode($val) . "'>" . h($val) . "</a>\n"; echo "<tr", odd(), ">",
"<th>", h($val), "</th>",
"<td><a href='", h(ME), "sequence=", urlencode($val), "'>", lang('Alter'), "</a></td>\n";
} }
echo "</table>\n"; echo "</table>\n";
} }
echo "<p class='links'><a href='" . h(ME) . "sequence='>" . lang('Create sequence') . "</a>\n"; echo "<p class='links'><a href='" . h(ME) . "sequence='>" . lang('Create sequence') . "</a>\n";
@@ -201,12 +244,16 @@ if ($adminer->homepage()) {
echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n"; echo "<h3 id='user-types'>" . lang('User types') . "</h3>\n";
$user_types = types(); $user_types = types();
if ($user_types) { if ($user_types) {
echo "<table>\n"; echo "<table>\n",
echo "<thead><tr><th>" . lang('Name') . "</thead>\n"; "<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
odd(''); odd('');
foreach ($user_types as $val) { foreach ($user_types as $val) {
echo "<tr" . odd() . "><th><a href='" . h(ME) . "type=" . urlencode($val) . "'>" . h($val) . "</a>\n"; echo "<tr", odd(), ">",
"<th>", h($val), "</th>",
"<td><a href='", h(ME), "type=", urlencode($val), "'>", lang('Alter'), "</a></td>\n";
} }
echo "</table>\n"; echo "</table>\n";
} }
echo "<p class='links'><a href='" . h(ME) . "type='>" . lang('Create type') . "</a>\n"; echo "<p class='links'><a href='" . h(ME) . "type='>" . lang('Create type') . "</a>\n";

View File

@@ -205,9 +205,6 @@ if (isset($_GET["mongo"])) {
return $connection->_db->selectCollection($_GET["select"])->count($where); return $connection->_db->selectCollection($_GET["select"])->count($where);
} }
$operators = array("=");
$operator_regexp = null;
} elseif (class_exists('MongoDB\Driver\Manager')) { } elseif (class_exists('MongoDB\Driver\Manager')) {
class Min_DB { class Min_DB {
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id; var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
@@ -216,15 +213,14 @@ if (isset($_GET["mongo"])) {
var $_db, $_db_name; var $_db, $_db_name;
function connect($uri, $options) { function connect($uri, $options) {
$class = 'MongoDB\Driver\Manager';
$this->_link = new $class($uri, $options); $this->_link = new MongoDB\Driver\Manager($uri, $options);
$this->executeCommand('admin', array('ping' => 1)); $this->executeCommand('admin', array('ping' => 1));
} }
function executeCommand($db, $command) { function executeCommand($db, $command) {
$class = 'MongoDB\Driver\Command';
try { try {
return $this->_link->executeCommand($db, new $class($command)); return $this->_link->executeCommand($db, new MongoDB\Driver\Command($command));
} catch (Exception $e) { } catch (Exception $e) {
$this->error = $e->getMessage(); $this->error = $e->getMessage();
return array(); return array();
@@ -341,9 +337,8 @@ if (isset($_GET["mongo"])) {
} }
$limit = min(200, max(1, (int) $limit)); $limit = min(200, max(1, (int) $limit));
$skip = $page * $limit; $skip = $page * $limit;
$class = 'MongoDB\Driver\Query';
try { try {
return new Min_Result($connection->_link->executeQuery("$connection->_db_name.$table", new $class($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort)))); return new Min_Result($connection->_link->executeQuery("$connection->_db_name.$table", new MongoDB\Driver\Query($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort))));
} catch (Exception $e) { } catch (Exception $e) {
$connection->error = $e->getMessage(); $connection->error = $e->getMessage();
return false; return false;
@@ -354,8 +349,7 @@ if (isset($_GET["mongo"])) {
global $connection; global $connection;
$db = $connection->_db_name; $db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere); $where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite'; $bulk = new MongoDB\Driver\BulkWrite(array());
$bulk = new $class(array());
if (isset($set['_id'])) { if (isset($set['_id'])) {
unset($set['_id']); unset($set['_id']);
} }
@@ -378,8 +372,7 @@ if (isset($_GET["mongo"])) {
global $connection; global $connection;
$db = $connection->_db_name; $db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere); $where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite'; $bulk = new MongoDB\Driver\BulkWrite(array());
$bulk = new $class(array());
$bulk->delete($where, array('limit' => $limit)); $bulk->delete($where, array('limit' => $limit));
return $connection->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount'); return $connection->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
} }
@@ -387,8 +380,7 @@ if (isset($_GET["mongo"])) {
function insert($table, $set) { function insert($table, $set) {
global $connection; global $connection;
$db = $connection->_db_name; $db = $connection->_db_name;
$class = 'MongoDB\Driver\BulkWrite'; $bulk = new MongoDB\Driver\BulkWrite(array());
$bulk = new $class(array());
if ($set['_id'] == '') { if ($set['_id'] == '') {
unset($set['_id']); unset($set['_id']);
} }
@@ -483,7 +475,11 @@ if (isset($_GET["mongo"])) {
} }
function sql_query_where_parser($queryWhere) { function sql_query_where_parser($queryWhere) {
$queryWhere = preg_replace('~^\sWHERE \(?\(?(.+?)\)?\)?$~', '\1', $queryWhere); $queryWhere = preg_replace('~^\s*WHERE\s*~', "", $queryWhere);
while ($queryWhere[0] == "(") {
$queryWhere = preg_replace('~^\((.*)\)$~', "$1", $queryWhere);
}
$wheres = explode(' AND ', $queryWhere); $wheres = explode(' AND ', $queryWhere);
$wheresOr = explode(') OR (', $queryWhere); $wheresOr = explode(') OR (', $queryWhere);
$where = array(); $where = array();
@@ -517,8 +513,7 @@ if (isset($_GET["mongo"])) {
$op = $match[1]; $op = $match[1];
} elseif (preg_match('~^\(date\)(.+)~', $op, $match)) { } elseif (preg_match('~^\(date\)(.+)~', $op, $match)) {
$dateTime = new DateTime($val); $dateTime = new DateTime($val);
$class = 'MongoDB\BSON\UTCDatetime'; $val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
$val = new $class($dateTime->getTimestamp() * 1000);
$op = $match[1]; $op = $match[1];
} }
switch ($op) { switch ($op) {
@@ -556,30 +551,6 @@ if (isset($_GET["mongo"])) {
} }
return $data; return $data;
} }
$operators = array(
"=",
"!=",
">",
"<",
">=",
"<=",
"regex",
"(f)=",
"(f)!=",
"(f)>",
"(f)<",
"(f)>=",
"(f)<=",
"(date)=",
"(date)!=",
"(date)>",
"(date)<",
"(date)>=",
"(date)<=",
);
$operator_regexp = 'regex';
} }
function table($idf) { function table($idf) {
@@ -629,6 +600,11 @@ if (isset($_GET["mongo"])) {
global $adminer; global $adminer;
$connection = new Min_DB; $connection = new Min_DB;
list($server, $username, $password) = $adminer->credentials(); list($server, $username, $password) = $adminer->credentials();
if ($server == "") {
$server = "localhost:27017";
}
$options = array(); $options = array();
if ($username . $password != "") { if ($username . $password != "") {
$options["username"] = $username; $options["username"] = $username;
@@ -736,7 +712,38 @@ if (isset($_GET["mongo"])) {
} }
function driver_config() { function driver_config() {
global $operators, $operator_regexp; if (class_exists('MongoDB')) {
$operators = ["="];
$operator_regexp = null;
} elseif (class_exists('MongoDB\Driver\Manager')) {
$operators = [
"=",
"!=",
">",
"<",
">=",
"<=",
"regex",
"(f)=",
"(f)!=",
"(f)>",
"(f)<",
"(f)>=",
"(f)<=",
"(date)=",
"(date)!=",
"(date)>",
"(date)<",
"(date)>=",
"(date)<=",
];
$operator_regexp = 'regex';
} else {
$operators = ["="];
$operator_regexp = null;
}
return array( return array(
'possible_drivers' => array("mongo", "mongodb"), 'possible_drivers' => array("mongo", "mongodb"),
'jush' => "mongo", 'jush' => "mongo",

View File

@@ -24,11 +24,26 @@ if (isset($_GET["mssql"])) {
function connect($server, $username, $password) { function connect($server, $username, $password) {
global $adminer; global $adminer;
$connection_info = [
"UID" => $username,
"PWD" => $password,
"CharacterSet" => "UTF-8",
];
$ssl = $adminer->connectSsl();
if (isset($ssl["Encrypt"])) {
$connection_info["Encrypt"] = $ssl["Encrypt"];
}
if (isset($ssl["TrustServerCertificate"])) {
$connection_info["TrustServerCertificate"] = $ssl["TrustServerCertificate"];
}
$db = $adminer->database(); $db = $adminer->database();
$connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8");
if ($db != "") { if ($db != "") {
$connection_info["Database"] = $db; $connection_info["Database"] = $db;
} }
$this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info); $this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
if ($this->_link) { if ($this->_link) {
$info = sqlsrv_server_info($this->_link); $info = sqlsrv_server_info($this->_link);
@@ -36,11 +51,13 @@ if (isset($_GET["mssql"])) {
} else { } else {
$this->_get_error(); $this->_get_error();
} }
return (bool) $this->_link; return (bool) $this->_link;
} }
function quote($string) { function quote($string) {
return "'" . str_replace("'", "''", $string) . "'"; $unicode = strlen($string) != strlen(utf8_decode($string));
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
} }
function select_db($database) { function select_db($database) {
@@ -163,7 +180,8 @@ if (isset($_GET["mssql"])) {
} }
function quote($string) { function quote($string) {
return "'" . str_replace("'", "''", $string) . "'"; $unicode = strlen($string) != strlen(utf8_decode($string));
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
} }
function select_db($database) { function select_db($database) {
@@ -301,6 +319,11 @@ if (isset($_GET["mssql"])) {
global $adminer; global $adminer;
$connection = new Min_DB; $connection = new Min_DB;
$credentials = $adminer->credentials(); $credentials = $adminer->credentials();
if ($credentials[0] == "") {
$credentials[0] = "localhost:1433";
}
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection; return $connection;
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
$drivers = array("server" => "MySQL") + $drivers; $drivers["mysql"] = "MySQL";
if (!defined("DRIVER")) { if (isset($_GET["mysql"])) {
define("DRIVER", "server"); // server - backwards compatibility define("DRIVER", "mysql");
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable // MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
if (extension_loaded("mysqli")) { if (extension_loaded("mysqli")) {
class Min_DB extends MySQLi { class Min_DB extends MySQLi {
@@ -371,16 +371,28 @@ if (!defined("DRIVER")) {
* @return mixed Min_DB or string for error * @return mixed Min_DB or string for error
*/ */
function connect() { function connect() {
global $adminer, $types, $structured_types; global $adminer, $types, $structured_types, $edit_functions;
$connection = new Min_DB; $connection = new Min_DB;
$credentials = $adminer->credentials(); $credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) { if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
$connection->set_charset(charset($connection)); $connection->set_charset(charset($connection));
$connection->query("SET sql_quote_show_create = 1, autocommit = 1"); $connection->query("SET sql_quote_show_create = 1, autocommit = 1");
if (min_version('5.7.8', 10.2, $connection)) {
if (min_version('5.7.8', '10.2', $connection)) {
$structured_types[lang('Strings')][] = "json"; $structured_types[lang('Strings')][] = "json";
$types["json"] = 4294967295; $types["json"] = 4294967295;
} }
// UUID data type for Mariadb >= 10.7
if (min_version('', '10.7', $connection)) {
$structured_types[lang('Strings')][] = "uuid";
$types["uuid"] = 128;
// insert/update function
$edit_functions[0]['uuid'] = 'uuid';
}
return $connection; return $connection;
} }
$return = $connection->error; $return = $connection->error;
@@ -500,11 +512,14 @@ if (!defined("DRIVER")) {
* @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name * @return array array($name => array("Name" => , "Engine" => , "Comment" => , "Oid" => , "Rows" => , "Collation" => , "Auto_increment" => , "Data_length" => , "Index_length" => , "Data_free" => )) or only inner array with $name
*/ */
function table_status($name = "", $fast = false) { function table_status($name = "", $fast = false) {
$return = array(); if ($fast && min_version(5)) {
foreach (get_rows($fast && min_version(5) $query = "SELECT TABLE_NAME AS Name, ENGINE AS Engine, CREATE_OPTIONS AS Create_options, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name");
? "SELECT TABLE_NAME AS Name, ENGINE AS Engine, CREATE_OPTIONS AS Create_options, TABLE_COMMENT AS Comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() " . ($name != "" ? "AND TABLE_NAME = " . q($name) : "ORDER BY Name") } else {
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "") $query = "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "");
) as $row) { }
$tables = [];
foreach (get_rows($query) as $row) {
if ($row["Engine"] == "InnoDB") { if ($row["Engine"] == "InnoDB") {
// ignore internal comment, unnecessary since MySQL 5.1.21 // ignore internal comment, unnecessary since MySQL 5.1.21
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]); $row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]);
@@ -513,11 +528,15 @@ if (!defined("DRIVER")) {
$row["Comment"] = ""; $row["Comment"] = "";
} }
if ($name != "") { if ($name != "") {
// MariaDB: Table name is returned as lowercase on macOS, so we fix it here.
$row["Name"] = $name;
return $row; return $row;
} }
$return[$row["Name"]] = $row;
$tables[$row["Name"]] = $row;
} }
return $return;
return $tables;
} }
/** Find out whether the identifier is view /** Find out whether the identifier is view
@@ -894,23 +913,30 @@ if (!defined("DRIVER")) {
); );
} }
/** Get information about stored routine /**
* @param string * Gets information about stored routine.
* @param string "FUNCTION" or "PROCEDURE" *
* @return array ("fields" => array("field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ), "returns" => , "definition" => , "language" => ) * @param string $name
*/ * @param string $type "FUNCTION" or "PROCEDURE"
*
* @return array ("fields" => array("field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ), "returns" => , "definition" => , "language" => )
*/
function routine($name, $type) { function routine($name, $type) {
global $connection, $enum_length, $inout, $types; global $connection, $enum_length, $inout, $types;
$aliases = array("bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar");
$info = get_rows("SELECT ROUTINE_BODY, ROUTINE_COMMENT FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB) . " AND ROUTINE_NAME = " . q($name))[0];
$aliases = ["bool", "boolean", "integer", "double precision", "real", "dec", "numeric", "fixed", "national char", "national varchar"];
$space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)"; $space = "(?:\\s|/\\*[\s\S]*?\\*/|(?:#|-- )[^\n]*\n?|--\r?\n)";
$type_pattern = "((" . implode("|", array_merge(array_keys($types), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum_length)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?"; $type_pattern = "((" . implode("|", array_merge(array_keys($types), $aliases)) . ")\\b(?:\\s*\\(((?:[^'\")]|$enum_length)++)\\))?\\s*(zerofill\\s*)?(unsigned(?:\\s+zerofill)?)?)(?:\\s*(?:CHARSET|CHARACTER\\s+SET)\\s*['\"]?([^'\"\\s,]+)['\"]?)?";
$pattern = "$space*(" . ($type == "FUNCTION" ? "" : $inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern"; $pattern = "$space*(" . ($type == "FUNCTION" ? "" : $inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2); $create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2);
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match); preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
$fields = array(); $fields = [];
preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER); preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER);
foreach ($matches as $param) { foreach ($matches as $param) {
$fields[] = array( $fields[] = [
"field" => str_replace("``", "`", $param[2]) . $param[3], "field" => str_replace("``", "`", $param[2]) . $param[3],
"type" => strtolower($param[5]), "type" => strtolower($param[5]),
"length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]), "length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]),
@@ -919,24 +945,29 @@ if (!defined("DRIVER")) {
"full_type" => $param[4], "full_type" => $param[4],
"inout" => strtoupper($param[1]), "inout" => strtoupper($param[1]),
"collation" => strtolower($param[9]), "collation" => strtolower($param[9]),
); ];
} }
if ($type != "FUNCTION") {
return array("fields" => $fields, "definition" => $match[11]); return $type == "FUNCTION" ? [
}
return array(
"fields" => $fields, "fields" => $fields,
"returns" => array("type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]), "returns" => ["type" => $match[12], "length" => $match[13], "unsigned" => $match[15], "collation" => $match[16]],
"definition" => $match[17], "definition" => $match[17],
"language" => "SQL", // available in information_schema.ROUTINES.PARAMETER_STYLE "language" => $info["ROUTINE_BODY"],
); "comment" => $info["ROUTINE_COMMENT"],
] : [
"fields" => $fields,
"returns" => null,
"definition" => $match[11],
"language" => $info["ROUTINE_BODY"],
"comment" => $info["ROUTINE_COMMENT"],
];
} }
/** Get list of routines /** Get list of routines
* @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => ) * @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => )
*/ */
function routines() { function routines() {
return get_rows("SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB)); return get_rows("SELECT ROUTINE_NAME AS SPECIFIC_NAME, ROUTINE_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, ROUTINE_COMMENT FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
} }
/** Get list of available routine languages /** Get list of available routine languages

View File

@@ -668,23 +668,29 @@ ORDER BY connamespace, conname") as $row) {
} }
function routine($name, $type) { function routine($name, $type) {
$rows = get_rows('SELECT routine_definition AS definition, LOWER(external_language) AS language, * $info = get_rows('SELECT routine_definition, external_language, type_udt_name
FROM information_schema.routines FROM information_schema.routines
WHERE routine_schema = current_schema() AND specific_name = ' . q($name)); WHERE routine_schema = current_schema() AND specific_name = ' . q($name))[0];
$return = $rows[0];
$return["returns"] = array("type" => $return["type_udt_name"]); $fields = get_rows('SELECT parameter_name AS field, data_type AS type, character_maximum_length AS length, parameter_mode AS inout
$return["fields"] = get_rows('SELECT parameter_name AS field, data_type AS type, character_maximum_length AS length, parameter_mode AS inout FROM information_schema.parameters
FROM information_schema.parameters WHERE specific_schema = current_schema() AND specific_name = ' . q($name) . '
WHERE specific_schema = current_schema() AND specific_name = ' . q($name) . ' ORDER BY ordinal_position');
ORDER BY ordinal_position');
return $return; return [
"fields" => $fields,
"returns" => ["type" => $info["type_udt_name"]],
"definition" => $info["routine_definition"],
"language" => strtolower($info["external_language"]),
"comment" => null, // Comments are not supported.
];
} }
function routines() { function routines() {
return get_rows('SELECT specific_name AS "SPECIFIC_NAME", routine_type AS "ROUTINE_TYPE", routine_name AS "ROUTINE_NAME", type_udt_name AS "DTD_IDENTIFIER" return get_rows('SELECT specific_name AS "SPECIFIC_NAME", routine_name AS "ROUTINE_NAME", routine_type AS "ROUTINE_TYPE", type_udt_name AS "DTD_IDENTIFIER", null AS ROUTINE_COMMENT
FROM information_schema.routines FROM information_schema.routines
WHERE routine_schema = current_schema() WHERE routine_schema = current_schema()
ORDER BY SPECIFIC_NAME'); ORDER BY SPECIFIC_NAME');
} }
function routine_languages() { function routine_languages() {

View File

@@ -182,8 +182,8 @@ $prefixes = array();
if (DB != "") { if (DB != "") {
$checked = ($TABLE != "" ? "" : " checked"); $checked = ($TABLE != "" ? "" : " checked");
echo "<thead><tr>"; echo "<thead><tr>";
echo "<th style='text-align: left;'><label class='block'><input type='checkbox' id='check-tables'$checked>" . lang('Tables') . "</label>" . script("qs('#check-tables').onclick = partial(formCheck, /^tables\\[/);", ""); echo "<th style='text-align: left;'><label class='block'><input type='checkbox' id='check-tables'$checked>" . lang('Tables') . "</label>" . script("gid('check-tables').onclick = partial(formCheck, /^tables\\[/);", "");
echo "<th style='text-align: right;'><label class='block'>" . lang('Data') . "<input type='checkbox' id='check-data'$checked></label>" . script("qs('#check-data').onclick = partial(formCheck, /^data\\[/);", ""); echo "<th style='text-align: right;'><label class='block'>" . lang('Data') . "<input type='checkbox' id='check-data'$checked></label>" . script("gid('check-data').onclick = partial(formCheck, /^data\\[/);", "");
echo "</thead>\n"; echo "</thead>\n";
$views = ""; $views = "";
@@ -208,7 +208,7 @@ if (DB != "") {
} else { } else {
echo "<thead><tr><th style='text-align: left;'>"; echo "<thead><tr><th style='text-align: left;'>";
echo "<label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . ">" . lang('Database') . "</label>"; echo "<label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . ">" . lang('Database') . "</label>";
echo script("qs('#check-databases').onclick = partial(formCheck, /^databases\\[/);", ""); echo script("gid('check-databases').onclick = partial(formCheck, /^databases\\[/);", "");
echo "</thead>\n"; echo "</thead>\n";
$databases = $adminer->databases(); $databases = $adminer->databases();
if ($databases) { if ($databases) {

View File

@@ -13,7 +13,7 @@ class Adminer {
* @return string HTML code * @return string HTML code
*/ */
function name() { function name() {
return "<a href='https://www.adminer.org/'" . target_blank() . " id='h1'>Adminer</a>"; return "<a id='h1' href='" . h(HOME_URL) . "'>Adminer</a>";
} }
/** Connection parameters /** Connection parameters
@@ -129,7 +129,7 @@ class Adminer {
echo "<table cellspacing='0' class='layout'>\n"; echo "<table cellspacing='0' class='layout'>\n";
echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);") . "\n"); echo $this->loginFormField('driver', '<tr><th>' . lang('System') . '<td>', html_select("auth[driver]", $drivers, DRIVER, "loginDriver(this);") . "\n");
echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n"); echo $this->loginFormField('server', '<tr><th>' . lang('Server') . '<td>', '<input name="auth[server]" value="' . h(SERVER) . '" title="hostname[:port]" placeholder="localhost" autocapitalize="off">' . "\n");
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(qs('#username')); qs('#username').form['auth[driver]'].onchange();")); echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(gid('username')); gid('username').form['auth[driver]'].onchange();"));
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n"); echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n");
echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n"); echo $this->loginFormField('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n");
echo "</table>\n"; echo "</table>\n";
@@ -424,8 +424,8 @@ class Adminer {
echo "<select name='columns[$i][fun]'>", echo "<select name='columns[$i][fun]'>",
optionlist([-1 => ""] + array_filter([lang('Functions') => $functions, lang('Aggregation') => $grouping]), $val["fun"]), optionlist([-1 => ""] + array_filter([lang('Functions') => $functions, lang('Aggregation') => $grouping]), $val["fun"]),
"</select>", "</select>",
on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1), help_script_command("value && value.replace(/ |\$/, '(') + ')'", true),
script("qsl('select').onchange = (event) => { helpClose();" . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""), script("qsl('select').onchange = (event) => { " . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""),
"($column)"; "($column)";
} else { } else {
echo $column; echo $column;
@@ -557,7 +557,7 @@ class Adminer {
json_row($key); json_row($key);
} }
echo ";\n"; echo ";\n";
echo "selectFieldChange.call(qs('#form')['select']);\n"; echo "selectFieldChange.call(gid('form')['select']);\n";
echo "</script>\n"; echo "</script>\n";
echo "</div></fieldset>\n"; echo "</div></fieldset>\n";
} }
@@ -1038,18 +1038,26 @@ class Adminer {
*/ */
function navigation($missing) { function navigation($missing) {
global $VERSION, $jush, $drivers, $connection; global $VERSION, $jush, $drivers, $connection;
?> ?>
<h1> <h1>
<?php echo $this->name(); ?> <?php echo $this->name(); ?>
<?php if ($missing != "auth"): ?>
<span class="version"> <?php if ($missing != "auth"): ?>
<?php echo $VERSION; ?> <span class="version">
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version"> <?php echo $VERSION; ?>
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?> <a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
</a> <?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
</span> </a>
</span>
<?php
if (!isset($_COOKIE["adminer_version"])) {
echo script("verifyVersion('" . js_escape(ME) . "', '" . get_token() . "');");
}
?>
<?php endif; ?> <?php endif; ?>
</h1> </h1>
<?php <?php
if ($missing == "auth") { if ($missing == "auth") {
$output = ""; $output = "";
@@ -1073,7 +1081,7 @@ class Adminer {
} }
} }
if ($output) { if ($output) {
echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});"); echo "<ul id='logins'>\n$output</ul>\n" . script("mixin(gid('logins'), {onmouseover: menuOver, onmouseout: menuOut});");
} }
} else { } else {
$tables = array(); $tables = array();
@@ -1156,7 +1164,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
if ($databases) { if ($databases) {
echo "<select id='database-select' name='db'>" . optionlist(["" => lang('Database')] + $databases, DB) . "</select>" echo "<select id='database-select' name='db'>" . optionlist(["" => lang('Database')] + $databases, DB) . "</select>"
. script("mixin(qs('#database-select'), {onmousedown: dbMouseDown, onchange: dbChange});"); . script("mixin(gid('database-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
} else { } else {
echo "<input id='database-select' name='db' value='" . h(DB) . "' autocapitalize='off'>\n"; echo "<input id='database-select' name='db' value='" . h(DB) . "' autocapitalize='off'>\n";
} }
@@ -1164,7 +1172,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
if (support("scheme") && $missing != "db" && DB != "" && $connection->select_db(DB)) { if (support("scheme") && $missing != "db" && DB != "" && $connection->select_db(DB)) {
echo "<br><select id='scheme-select' name='ns'>" . optionlist(["" => lang('Schema')] + $adminer->schemas(), $_GET["ns"]) . "</select>" echo "<br><select id='scheme-select' name='ns'>" . optionlist(["" => lang('Schema')] + $adminer->schemas(), $_GET["ns"]) . "</select>"
. script("mixin(qs('#scheme-select'), {onmousedown: dbMouseDown, onchange: dbChange});"); . script("mixin(gid('scheme-select'), {onmousedown: dbMouseDown, onchange: dbChange});");
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {
set_schema($_GET["ns"]); set_schema($_GET["ns"]);
@@ -1200,7 +1208,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
* @return null * @return null
*/ */
function tablesPrint($tables) { function tablesPrint($tables) {
echo "<ul id='tables'>" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});"); echo "<ul id='tables'>" . script("mixin(gid('tables'), {onmouseover: menuOver, onmouseout: menuOut});");
foreach ($tables as $table => $status) { foreach ($tables as $table => $status) {
$name = $this->tableName($status); $name = $this->tableName($status);

View File

@@ -71,7 +71,7 @@ if (!function_exists('is_server_host_valid')) {
*/ */
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) { function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) { if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
$this->error = lang('Invalid server or credentials.'); auth_error(lang('Invalid server or credentials.'));
return false; return false;
} }
@@ -147,7 +147,7 @@ if ($auth) {
set_session($key, null); set_session($key, null);
} }
unset_permanent(); unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.')); redirect(HOME_URL, lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.'));
} elseif ($permanent && !$_SESSION["pwds"]) { } elseif ($permanent && !$_SESSION["pwds"]) {
session_regenerate_id(); session_regenerate_id();
@@ -214,6 +214,12 @@ function auth_error($error) {
exit; exit;
} }
if (isset($_GET["username"]) && !DRIVER) {
page_header(lang('No driver'), lang('Database driver not found.'), false);
page_footer("auth");
exit;
}
if (isset($_GET["username"]) && !class_exists("Min_DB")) { if (isset($_GET["username"]) && !class_exists("Min_DB")) {
unset($_SESSION["pwds"][DRIVER]); unset($_SESSION["pwds"][DRIVER]);
unset_permanent(); unset_permanent();

View File

@@ -39,7 +39,7 @@ if ($_GET["script"] == "version") {
exit; exit;
} }
global $adminer, $connection, $driver, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $langs, $on_actions, $permanent, $structured_types, $has_token, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function global $adminer, $connection, $driver, $drivers, $edit_functions, $enum_length, $error, $functions, $grouping, $HTTPS, $inout, $jush, $LANG, $languages, $on_actions, $permanent, $structured_types, $has_token, $token, $translations, $types, $unsigned, $VERSION; // allows including Adminer inside a function
if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
$_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"]; $_SERVER["REQUEST_URI"] = $_SERVER["ORIG_PATH_INFO"];
@@ -73,39 +73,73 @@ if (function_exists("get_magic_quotes_runtime") && get_magic_quotes_runtime()) {
@ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated @ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated
@ini_set("precision", 15); // @ - can be disabled, 15 - internal PHP precision @ini_set("precision", 15); // @ - can be disabled, 15 - internal PHP precision
// Migration for backward compatibility. This will keep MySQL users logged in.
if (isset($_GET["username"])) {
// Old 'server' URL param.
if (isset($_GET["server"])) {
$_GET["mysql"] = $_GET["server"];
unset($_GET["server"]);
}
// No URL param for any driver.
$driver_params = array_filter(["mysql", "pgsql", "sqlite", "sqlite2", "oracle", "mssql", "mongo", "clickhouse", "elastic", "elastic5", "firebird", "simpledb"], function ($driver) {
return isset($_GET[$driver]);
});
if (!$driver_params) {
$_GET["mysql"] = "";
}
// Migrate session data.
if (isset($_SESSION["pwds"]["server"])) {
foreach (["pwds", "db", "dbs", "queries"] as $key) {
if (isset($_SESSION[$key]["server"])) {
$_SESSION[$key]["mysql"] = $_SESSION[$key]["server"];
unset($_SESSION[$key]["server"]);
}
}
}
}
include "../adminer/include/lang.inc.php"; include "../adminer/include/lang.inc.php";
include "../adminer/lang/$LANG.inc.php"; include "../adminer/lang/$LANG.inc.php";
include "../adminer/include/pdo.inc.php"; include "../adminer/include/pdo.inc.php";
include "../adminer/include/driver.inc.php"; include "../adminer/include/driver.inc.php";
include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/mysql.inc.php";
include "../adminer/drivers/pgsql.inc.php"; include "../adminer/drivers/pgsql.inc.php";
include "../adminer/drivers/sqlite.inc.php";
include "../adminer/drivers/oracle.inc.php"; include "../adminer/drivers/oracle.inc.php";
include "../adminer/drivers/mssql.inc.php"; include "../adminer/drivers/mssql.inc.php";
include "../adminer/drivers/mongo.inc.php"; include "../adminer/drivers/mongo.inc.php";
include "./include/adminer.inc.php"; include "./include/adminer.inc.php";
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer); $adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer());
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
$config = driver_config(); if (defined("DRIVER")) {
$possible_drivers = $config['possible_drivers']; $config = driver_config();
$jush = $config['jush']; $possible_drivers = $config['possible_drivers'];
$types = $config['types']; $jush = $config['jush'];
$structured_types = $config['structured_types']; $types = $config['types'];
$unsigned = $config['unsigned']; $structured_types = $config['structured_types'];
$operators = $config['operators']; $unsigned = $config['unsigned'];
$operator_like = $config['operator_like']; $operators = $config['operators'];
$operator_regexp = $config['operator_regexp']; $operator_like = $config['operator_like'];
$functions = $config['functions']; $operator_regexp = $config['operator_regexp'];
$grouping = $config['grouping']; $functions = $config['functions'];
$edit_functions = $config['edit_functions']; $grouping = $config['grouping'];
$edit_functions = $config['edit_functions'];
if ($adminer->operators === null) { if ($adminer->operators === null) {
$adminer->operators = $operators; $adminer->operators = $operators;
$adminer->operator_like = $operator_like; $adminer->operator_like = $operator_like;
$adminer->operator_regexp = $operator_regexp; $adminer->operator_regexp = $operator_regexp;
}
} else {
define("DRIVER", null);
} }
define("SERVER", $_GET[DRIVER]); // read from pgsql=localhost define("SERVER", DRIVER ? $_GET[DRIVER] : null); // read from pgsql=localhost
define("DB", $_GET["db"]); // for the sake of speed and size define("DB", $_GET["db"]); // for the sake of speed and size
define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?' define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
. (sid() ? SID . '&' : '') . (sid() ? SID . '&' : '')
@@ -113,6 +147,7 @@ define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '') . (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
. (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '') . (DB != "" ? 'db=' . urlencode(DB) . '&' . (isset($_GET["ns"]) ? "ns=" . urlencode($_GET["ns"]) . "&" : "") : '')
); );
define("HOME_URL", substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1) ?: ".");
include "../adminer/include/version.inc.php"; include "../adminer/include/version.inc.php";
include "../adminer/include/design.inc.php"; include "../adminer/include/design.inc.php";

View File

@@ -2,9 +2,22 @@
function dump($value) function dump($value)
{ {
echo "<pre>"; $cli = PHP_SAPI == 'cli';
var_export($value);
echo "</pre>\n"; if (!$cli) {
echo "<pre>";
}
$export = var_export($value, true);
$export = preg_replace('~=>\s+array\s*~', "=> array", $export);
$export = preg_replace('~\(\s+\)~', "()", $export);
echo $export;
if (!$cli) {
echo "</pre>";
}
echo "\n";
} }
function dumpe($value) function dumpe($value)

View File

@@ -18,10 +18,11 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
// Load Adminer version from file if cookie is missing. // Load Adminer version from file if cookie is missing.
$filename = get_temp_dir() . "/adminer.version"; $filename = get_temp_dir() . "/adminer.version";
if (!$_COOKIE["adminer_version"] && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds if (!$_COOKIE["adminer_version"] && file_exists($filename) && ($lifetime = filemtime($filename) + 86400 - time()) > 0) { // 86400 - 1 day in seconds
$data = unserialize(file_get_contents($filename)); $data = unserialize(file_get_contents($filename));
$_COOKIE["adminer_version"] = $data["version"]; $_COOKIE["adminer_version"] = $data["version"];
cookie("adminer_version", $data["version"], 24 * 3600); cookie("adminer_version", $data["version"], $lifetime); // Sync expiration with the file.
} }
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
@@ -29,9 +30,9 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="robots" content="noindex"> <meta name="robots" content="noindex">
<title><?php echo $title_page; ?></title> <title><?php echo $title_page; ?></title>
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css"> <link rel="stylesheet" type="text/css" href="../adminer/static/default.css?<?php echo filemtime("../adminer/static/default.css"); ?>">
<?php echo script_src("../adminer/static/functions.js"); ?> <?php echo script_src("../adminer/static/functions.js?" . filemtime("../adminer/static/functions.js")); ?>
<?php echo script_src("static/editing.js"); ?> <?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>
<?php if ($adminer->head()) { ?> <?php if ($adminer->head()) { ?>
<link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico"> <link rel="shortcut icon" type="image/x-icon" href="../adminer/static/favicon.ico">
<link rel="apple-touch-icon" href="../adminer/static/favicon.ico"> <link rel="apple-touch-icon" href="../adminer/static/favicon.ico">
@@ -42,27 +43,26 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
<body class="<?php echo lang('ltr'); ?> nojs"> <body class="<?php echo lang('ltr'); ?> nojs">
<script<?php echo nonce(); ?>> <script<?php echo nonce(); ?>>
document.body.onkeydown = bodyKeydown; const body = document.body;
document.body.onclick = bodyClick;
<?php if (!isset($_COOKIE["adminer_version"])): ?> body.onkeydown = bodyKeydown;
document.body.onload = function () { verifyVersion('<?php echo $VERSION; ?>', '<?php echo js_escape(ME); ?>', '<?php echo get_token(); ?>') }; body.onclick = bodyClick;
<?php endif; ?> body.classList.remove("nojs");
document.body.className = document.body.className.replace(/ nojs/, ' js'); body.classList.add("js");
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>'; var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>'; var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
</script> </script>
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div> <div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div>
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?> <?php echo script("initHelpPopup();"); ?>
<div id="content"> <div id="content">
<?php <?php
if ($breadcrumb !== null) { if ($breadcrumb !== null) {
echo '<p id="breadcrumb">'; echo '<p id="breadcrumb">';
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1); echo '<a href="' . h(HOME_URL) . '">' . lang('Home') . '</a> » ';
echo '<a href="' . h($link ?: ".") . '">' . lang('Home') . '</a> » ';
$server = ""; $server = "";
if ($breadcrumb === false) { if ($breadcrumb === false) {
@@ -188,19 +188,19 @@ function page_messages($error) {
/** /**
* Prints HTML footer. * Prints HTML footer.
* *
* @param $missing string "auth", "db", "ns" * @param ?string $missing "auth", "db", "ns"
*/ */
function page_footer($missing = "") function page_footer($missing = null)
{ {
global $adminer, $token; global $adminer, $token;
echo "</div>"; // #content echo "</div>"; // #content
echo "<div id='footer'>\n"; echo "<div id='footer'>\n";
switch_lang(); language_select();
if ($missing != "auth") { if ($missing != "auth") {
?> ?>
<div class="logout"> <div class="logout">
<form action="" method="post"> <form action="" method="post">

View File

@@ -297,7 +297,7 @@ function edit_fields(array $fields, array $collations, $type = "TABLE", $foreign
} }
?> ?>
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?></th> <th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?></th>
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("qs('#enum-edit').onblur = editingLengthBlur;"); ?></td> <td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;"></textarea><?php echo script("gid('enum-edit').onblur = editingLengthBlur;"); ?></td>
<td id="label-length"><?php echo lang('Length'); ?></td> <td id="label-length"><?php echo lang('Length'); ?></td>
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?></td> <td><?php echo lang('Options'); /* no label required, options have their own label */ ?></td>
<?php if ($type == "TABLE") { ?> <?php if ($type == "TABLE") { ?>
@@ -621,7 +621,7 @@ function doc_link(array $paths, $text = "<sup>?</sup>") {
]; ];
if (preg_match('~MariaDB~', $server_info)) { if (preg_match('~MariaDB~', $server_info)) {
$urls['sql'] = "https://mariadb.com/kb/en/library/"; $urls['sql'] = "https://mariadb.com/kb/en/";
$paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql'])); $paths['sql'] = (isset($paths['mariadb']) ? $paths['mariadb'] : str_replace(".html", "/", $paths['sql']));
} }

View File

@@ -108,6 +108,9 @@ function min_version($version, $maria_db = "", $connection2 = null) {
$server_info = $match[1]; $server_info = $match[1];
$version = $maria_db; $version = $maria_db;
} }
if ($version == "") {
return false;
}
return (version_compare($server_info, $version) >= 0); return (version_compare($server_info, $version) >= 0);
} }
@@ -611,7 +614,7 @@ function auth_url($vendor, $server, $username, $db = null) {
preg_match('~([^?]*)\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . ($db !== null ? "db|" : "") . session_name()), $match); preg_match('~([^?]*)\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . ($db !== null ? "db|" : "") . session_name()), $match);
return "$match[1]?" return "$match[1]?"
. (sid() ? SID . "&" : "") . (sid() ? SID . "&" : "")
. ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "") . urlencode($vendor) . "=" . urlencode($server) . "&"
. "username=" . urlencode($username) . "username=" . urlencode($username)
. ($db != "" ? "&db=" . urlencode($db) : "") . ($db != "" ? "&db=" . urlencode($db) : "")
. ($match[2] ? "&$match[2]" : "") . ($match[2] ? "&$match[2]" : "")
@@ -830,6 +833,8 @@ function is_utf8($val) {
* @return string escaped string with appended ... * @return string escaped string with appended ...
*/ */
function shorten_utf8($string, $length = 80, $suffix = "") { function shorten_utf8($string, $length = 80, $suffix = "") {
if ($string == "") return $suffix;
if (!preg_match("(^(" . repeat_pattern("[\t\r\n -\x{10FFFF}]", $length) . ")($)?)u", $string, $match)) { // ~s causes trash in $match[2] under some PHP versions, (.|\n) is slow if (!preg_match("(^(" . repeat_pattern("[\t\r\n -\x{10FFFF}]", $length) . ")($)?)u", $string, $match)) { // ~s causes trash in $match[2] under some PHP versions, (.|\n) is slow
preg_match("(^(" . repeat_pattern("[\t\r\n -~]", $length) . ")($)?)", $string, $match); preg_match("(^(" . repeat_pattern("[\t\r\n -~]", $length) . ")($)?)", $string, $match);
} }
@@ -967,7 +972,7 @@ function input($field, $value, $function) {
$has_function = (in_array($function, $functions) || isset($functions[$function])); $has_function = (in_array($function, $functions) || isset($functions[$function]));
echo (count($functions) > 1 echo (count($functions) > 1
? "<select name='function[$name]' $disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>" ? "<select name='function[$name]' $disabled>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1) . help_script_command("value.replace(/^SQL\$/, '')", true)
. script("qsl('select').onchange = functionChange;", "") . script("qsl('select').onchange = functionChange;", "")
: h(reset($functions)) : h(reset($functions))
) . '<td>'; ) . '<td>';
@@ -1486,13 +1491,26 @@ function lzw_decompress($binary) {
return $return; return $return;
} }
/** Return events to display help on mouse over /**
* @param string JS expression * @param string $text Help text.
* @param bool JS expression * @param bool $side Side position.
* @return string *
*/ * @return string
function on_help($command, $side = 0) { */
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", ""); function help_script($text, $side = false)
{
return script("initHelpFor(qsl('select, input'), '" . h($text) . "', $side);", "");
}
/**
* @param string $command JS expression for returning the help text.
* @param bool $side Side position.
*
* @return string
*/
function help_script_command($command, $side = false)
{
return script("initHelpFor(qsl('select, input'), (value) => { return $command; }, $side);", "");
} }
/** Print edit data form /** Print edit data form
@@ -1560,6 +1578,10 @@ function edit_form($table, $fields, $row, $update) {
$value = ""; $value = "";
$function = "now"; $function = "now";
} }
if ($field["type"] == "uuid" && $value == "uuid()") {
$value = "";
$function = "uuid";
}
input($field, $value, $function); input($field, $value, $function);
echo "\n"; echo "\n";
} }
@@ -1586,7 +1608,7 @@ function edit_form($table, $fields, $row, $update) {
} }
} }
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n" echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[1].firstChild);")) : ($_POST || !$fields ? "" : script("focus(qsa('td', gid('form'))[1].firstChild);"))
); );
if (isset($_GET["select"])) { if (isset($_GET["select"])) {
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"])); hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));

View File

@@ -1,7 +1,6 @@
<?php <?php
// not used in a single language version
$langs = array( $languages = [
'en' => 'English', // Jakub Vrána - https://www.vrana.cz 'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr 'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev 'bg' => 'Български', // Deyan Delchev
@@ -25,8 +24,8 @@ $langs = array(
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/ 'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org 'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
'ko' => '한국어', // dalli - skcha67@gmail.com 'ko' => '한국어', // dalli - skcha67@gmail.com
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com 'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt 'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
'ms' => 'Bahasa Melayu', // Pisyek 'ms' => 'Bahasa Melayu', // Pisyek
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be 'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com 'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
@@ -46,24 +45,59 @@ $langs = array(
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail 'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com 'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
'zh-tw' => '繁體中文', // http://tzangms.com 'zh-tw' => '繁體中文', // http://tzangms.com
); ];
/** Get current language /**
* @return string * Returns the list of available languages.
*/ * In compiled version, only selected languages are returned.
function get_lang() { *
* @return array
*/
function get_available_languages()
{
global $languages;
return $languages; // compile: available languages
}
/**
* Converts translation key into the right form.
* In compiled version, string keys used in plugins are dynamically translated to numeric keys.
*
* @param string|int $key
*
* @return string|int
*/
function convert_translation_key($key)
{
return $key; // compile: convert translation key
}
/**
* Returns current language.
*
* @return string
*/
function get_lang()
{
global $LANG; global $LANG;
return $LANG; return $LANG;
} }
/** Translate string /**
* @param string * Returns translated text.
* @param int *
* @return string * @param string|int $key Numeric key is used in compiled version.
*/ * @param ?int $number
function lang($idf, $number = null) { *
* @return string
*/
function lang($key, $number = null)
{
global $LANG, $translations; global $LANG, $translations;
$translation = ($translations[$idf] ? $translations[$idf] : $idf);
$key = convert_translation_key($key);
$translation = $translations[$key] ?: $key;
if (is_array($translation)) { if (is_array($translation)) {
$pos = ($number == 1 ? 0 $pos = ($number == 1 ? 0
: ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other : ($LANG == 'cs' || $LANG == 'sk' ? ($number && $number < 5 ? 1 : 2) // different forms for 1, 2-4, other
@@ -74,21 +108,39 @@ function lang($idf, $number = null) {
: ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other : ($LANG == 'bs' || $LANG == 'ru' || $LANG == 'sr' || $LANG == 'uk' ? ($number % 10 == 1 && $number % 100 != 11 ? 0 : ($number % 10 > 1 && $number % 10 < 5 && $number / 10 % 10 != 1 ? 1 : 2)) // different forms for 1 except 11, 2-4 except 12-14, other
: 1 // different forms for 1, other : 1 // different forms for 1, other
))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html ))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
$translation = $translation[$pos]; $translation = $translation[$pos];
} }
$args = func_get_args(); $args = func_get_args();
array_shift($args); array_shift($args);
$format = str_replace("%d", "%s", $translation); $format = str_replace("%d", "%s", $translation);
if ($format != $translation) { if ($format != $translation) {
$args[0] = format_number($number); $args[0] = format_number($number);
} }
return vsprintf($format, $args); return vsprintf($format, $args);
} }
function switch_lang() { function language_select()
global $LANG, $langs; {
global $LANG, $languages;
$available_languages = get_available_languages();
if (count($available_languages) == 1) {
return;
}
$options = [];
foreach ($languages as $language => $title) {
if (isset($available_languages[$language])) {
$options[$language] = $title;
}
}
echo "<div id='lang'><form action='' method='post'>\n"; echo "<div id='lang'><form action='' method='post'>\n";
echo lang('Language') . ": " . html_select("lang", $langs, $LANG, "this.form.submit();"); echo lang('Language') . ": " . html_select("lang", $options, $LANG, "this.form.submit();");
echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n"; echo " <input type='submit' value='" . lang('Use') . "' class='hidden'>\n";
echo "<input type='hidden' name='token' value='" . get_token() . "'>\n"; // $token may be empty in auth.inc.php echo "<input type='hidden' name='token' value='" . get_token() . "'>\n"; // $token may be empty in auth.inc.php
echo "</form></div>\n"; echo "</form></div>\n";
@@ -96,31 +148,37 @@ function switch_lang() {
if (isset($_POST["lang"]) && verify_token()) { // $error not yet available if (isset($_POST["lang"]) && verify_token()) { // $error not yet available
cookie("adminer_lang", $_POST["lang"]); cookie("adminer_lang", $_POST["lang"]);
$_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled $_SESSION["lang"] = $_POST["lang"]; // cookies may be disabled
$_SESSION["translations"] = array(); // used in compiled version $_SESSION["translations"] = []; // used in compiled version
redirect(remove_from_uri()); redirect(remove_from_uri());
} }
$LANG = "en"; $available_languages = get_available_languages();
if (isset($langs[$_COOKIE["adminer_lang"]])) { $LANG = $available_languages[0];
if (isset($available_languages[$_COOKIE["adminer_lang"]])) {
cookie("adminer_lang", $_COOKIE["adminer_lang"]); cookie("adminer_lang", $_COOKIE["adminer_lang"]);
$LANG = $_COOKIE["adminer_lang"]; $LANG = $_COOKIE["adminer_lang"];
} elseif (isset($langs[$_SESSION["lang"]])) { } elseif (isset($available_languages[$_SESSION["lang"]])) {
$LANG = $_SESSION["lang"]; $LANG = $_SESSION["lang"];
} else { } else {
$accept_language = array(); $accept_language = [];
preg_match_all('~([-a-z]+)(;q=([0-9.]+))?~', str_replace("_", "-", strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"])), $matches, PREG_SET_ORDER); preg_match_all('~([-a-z]+)(;q=([0-9.]+))?~', str_replace("_", "-", strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"])), $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
$accept_language[$match[1]] = (isset($match[3]) ? $match[3] : 1); $accept_language[$match[1]] = (isset($match[3]) ? $match[3] : 1);
} }
arsort($accept_language); arsort($accept_language);
foreach ($accept_language as $key => $q) { foreach ($accept_language as $key => $q) {
if (isset($langs[$key])) { if (isset($available_languages[$key])) {
$LANG = $key; $LANG = $key;
break; break;
} }
$key = preg_replace('~-.*~', '', $key); $key = preg_replace('~-.*~', '', $key);
if (!isset($accept_language[$key]) && isset($langs[$key])) { if (!isset($accept_language[$key]) && isset($available_languages[$key])) {
$LANG = $key; $LANG = $key;
break; break;
} }

View File

@@ -12,9 +12,9 @@ if (extension_loaded('pdo')) {
} }
} }
function dsn($dsn, $username, $password, $options = array()) { function dsn($dsn, $username, $password, $options = []) {
$options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT; $options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
$options[PDO::ATTR_STATEMENT_CLASS] = array('Min_PDOStatement'); $options[PDO::ATTR_STATEMENT_CLASS] = [Min_PDOStatement::class];
try { try {
$this->pdo = new PDO($dsn, $username, $password, $options); $this->pdo = new PDO($dsn, $username, $password, $options);
} catch (Exception $ex) { } catch (Exception $ex) {

View File

@@ -1,2 +1,2 @@
<?php <?php
$VERSION = "4.10"; $VERSION = "4.12";

View File

@@ -1,11 +1,14 @@
<?php <?php
/** Adminer - Compact database management /**
* @link https://www.adminer.org/ * Adminer - Database management in a single PHP file
* @author Jakub Vrana, https://www.vrana.cz/ *
* @copyright 2007 Jakub Vrana * @link https://github.com/pematon/adminer
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @author Jakub Vrana (https://www.vrana.cz/)
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @author Peter Knut
*/ * @copyright 2007-2021 Jakub Vrana, 2024 Peter Knut
* @license Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
* @license GNU General Public License, version 2 (https://www.gnu.org/licenses/gpl-2.0.html)
*/
include "./include/bootstrap.inc.php"; include "./include/bootstrap.inc.php";
include "./include/tmpfile.inc.php"; include "./include/tmpfile.inc.php";

View File

@@ -31,7 +31,6 @@ $translations = array(
'Create database' => 'إنشاء قاعدة بيانات', 'Create database' => 'إنشاء قاعدة بيانات',
'SQL command' => 'استعلام SQL', 'SQL command' => 'استعلام SQL',
'Logout' => 'تسجيل الخروج', 'Logout' => 'تسجيل الخروج',
'database' => 'قاعدة بيانات',
'Use' => 'استعمال', 'Use' => 'استعمال',
'No tables.' => 'لا توجد جداول.', 'No tables.' => 'لا توجد جداول.',
'select' => 'تحديد', 'select' => 'تحديد',
@@ -68,7 +67,6 @@ $translations = array(
'Unable to select the table' => 'يتعذر اختيار الجدول', 'Unable to select the table' => 'يتعذر اختيار الجدول',
'Invalid CSRF token. Send the form again.' => 'رمز CSRF غير صالح. المرجو إرسال الاستمارة مرة أخرى.', 'Invalid CSRF token. Send the form again.' => 'رمز CSRF غير صالح. المرجو إرسال الاستمارة مرة أخرى.',
'Comment' => 'تعليق', 'Comment' => 'تعليق',
'Default values' => 'القيم الافتراضية',
'%d byte(s)' => '%d بايت', '%d byte(s)' => '%d بايت',
'No commands to execute.' => 'لا توجد أوامر للتنفيذ.', 'No commands to execute.' => 'لا توجد أوامر للتنفيذ.',
'Unable to upload a file.' => 'يتعذر رفع ملف ما.', 'Unable to upload a file.' => 'يتعذر رفع ملف ما.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -17,6 +17,8 @@ $translations = array(
'Language' => 'Език', 'Language' => 'Език',
'Invalid CSRF token. Send the form again.' => 'Невалиден шифроващ ключ. Попълнете и изпратете формуляра отново.', 'Invalid CSRF token. Send the form again.' => 'Невалиден шифроващ ключ. Попълнете и изпратете формуляра отново.',
'If you did not send this request from Adminer then close this page.' => 'Ако не сте изпратили тази заявка през Adminer, затворете тази страница.', 'If you did not send this request from Adminer then close this page.' => 'Ако не сте изпратили тази заявка през Adminer, затворете тази страница.',
'No driver' => null,
'Database driver not found.' => null,
'No extension' => 'Няма разширение', 'No extension' => 'Няма разширение',
'None of the supported PHP extensions (%s) are available.' => 'Никое от поддържаните PHP разширения (%s) не е налично.', 'None of the supported PHP extensions (%s) are available.' => 'Никое от поддържаните PHP разширения (%s) не е налично.',
'Session support must be enabled.' => 'Поддръжката на сесии трябва да е разрешена.', 'Session support must be enabled.' => 'Поддръжката на сесии трябва да е разрешена.',
@@ -79,7 +81,6 @@ $translations = array(
'Data' => 'Данни', 'Data' => 'Данни',
'Database' => 'База данни', 'Database' => 'База данни',
'database' => 'база данни',
'Use' => 'Избор', 'Use' => 'Избор',
'Select database' => 'Избор на база данни', 'Select database' => 'Избор на база данни',
'Invalid database.' => 'Невалидна база данни.', 'Invalid database.' => 'Невалидна база данни.',
@@ -166,7 +167,6 @@ $translations = array(
'Options' => 'Опции', 'Options' => 'Опции',
'Comment' => 'Коментар', 'Comment' => 'Коментар',
'Default value' => 'Стойност по подразбиране', 'Default value' => 'Стойност по подразбиране',
'Default values' => 'Стойности по подразбиране',
'Drop' => 'Премахване', 'Drop' => 'Премахване',
'Are you sure?' => 'Сигурни ли сте?', 'Are you sure?' => 'Сигурни ли сте?',
'Size' => 'Големина', 'Size' => 'Големина',
@@ -314,12 +314,15 @@ $translations = array(
'Please use one of the extensions %s.' => 'Моля, използвайте някое от разширенията %s.', 'Please use one of the extensions %s.' => 'Моля, използвайте някое от разширенията %s.',
// PostgreSQL and MS SQL schema support // PostgreSQL and MS SQL schema support
'Schema' => 'Схема',
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'Alter schema' => 'Промяна на схемата', 'Alter schema' => 'Промяна на схемата',
'Create schema' => 'Създаване на схема', 'Create schema' => 'Създаване на схема',
'Schema has been dropped.' => 'Схемата беше премахната.', 'Schema has been dropped.' => 'Схемата беше премахната.',
'Schema has been created.' => 'Схемата беше създадена.', 'Schema has been created.' => 'Схемата беше създадена.',
'Schema has been altered.' => 'Схемата беше променена.', 'Schema has been altered.' => 'Схемата беше променена.',
'Schema' => 'Схема',
'Invalid schema.' => 'Невалидна схема.', 'Invalid schema.' => 'Невалидна схема.',
// PostgreSQL sequences support // PostgreSQL sequences support

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'ডাটাবেজ তৈরী করুন', 'Create database' => 'ডাটাবেজ তৈরী করুন',
'SQL command' => 'SQL-কমান্ড', 'SQL command' => 'SQL-কমান্ড',
'Logout' => 'লগআউট', 'Logout' => 'লগআউট',
'database' => 'ডাটাবেজ',
'Use' => 'ব্যবহার', 'Use' => 'ব্যবহার',
'No tables.' => 'কোন টেবিল নাই।', 'No tables.' => 'কোন টেবিল নাই।',
'select' => 'নির্বাচন', 'select' => 'নির্বাচন',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'টেবিল নির্বাচন করতে অক্ষম', 'Unable to select the table' => 'টেবিল নির্বাচন করতে অক্ষম',
'Invalid CSRF token. Send the form again.' => 'অবৈধ CSRF টোকেন। ফর্মটি আবার পাঠান।', 'Invalid CSRF token. Send the form again.' => 'অবৈধ CSRF টোকেন। ফর্মটি আবার পাঠান।',
'Comment' => 'মন্তব্য', 'Comment' => 'মন্তব্য',
'Default values' => 'ডিফল্ট মান',
'%d byte(s)' => array('%d বাইট', '%d বাইটসমূহ'), '%d byte(s)' => array('%d বাইট', '%d বাইটসমূহ'),
'No commands to execute.' => 'সম্পাদন করার মত কোন নির্দেশ নেই।', 'No commands to execute.' => 'সম্পাদন করার মত কোন নির্দেশ নেই।',
'Unable to upload a file.' => 'ফাইল আপলোড করা সম্ভব হচ্ছে না।', 'Unable to upload a file.' => 'ফাইল আপলোড করা সম্ভব হচ্ছে না।',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -74,7 +74,6 @@ $translations = array(
'Data' => 'Podaci', 'Data' => 'Podaci',
'Database' => 'Baza podataka', 'Database' => 'Baza podataka',
'database' => 'baza podataka',
'Use' => 'Koristi', 'Use' => 'Koristi',
'Select database' => 'Izaberite bazu', 'Select database' => 'Izaberite bazu',
'Invalid database.' => 'Neispravna baza podataka.', 'Invalid database.' => 'Neispravna baza podataka.',
@@ -159,7 +158,6 @@ $translations = array(
'Auto Increment' => 'Auto-priraštaj', 'Auto Increment' => 'Auto-priraštaj',
'Options' => 'Opcije', 'Options' => 'Opcije',
'Comment' => 'Komentar', 'Comment' => 'Komentar',
'Default values' => 'Podrazumijevane vrijednosti',
'Drop' => 'Izbriši', 'Drop' => 'Izbriši',
'Are you sure?' => 'Da li ste sigurni?', 'Are you sure?' => 'Da li ste sigurni?',
'Move up' => 'Pomijeri na gore', 'Move up' => 'Pomijeri na gore',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Ne', 'No' => 'Ne',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Crea una base de dades', 'Create database' => 'Crea una base de dades',
'SQL command' => 'Ordre SQL', 'SQL command' => 'Ordre SQL',
'Logout' => 'Desconnecta', 'Logout' => 'Desconnecta',
'database' => 'base de dades',
'Use' => 'Utilitza', 'Use' => 'Utilitza',
'No tables.' => 'No hi ha cap taula.', 'No tables.' => 'No hi ha cap taula.',
'select' => 'registres', 'select' => 'registres',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Impossible seleccionar la taula', 'Unable to select the table' => 'Impossible seleccionar la taula',
'Invalid CSRF token. Send the form again.' => 'Token CSRF invàlid. Torna a enviar el formulari.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF invàlid. Torna a enviar el formulari.',
'Comment' => 'Comentari', 'Comment' => 'Comentari',
'Default values' => 'Valors per defecte',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Cap comanda per executar.', 'No commands to execute.' => 'Cap comanda per executar.',
'Unable to upload a file.' => 'Impossible adjuntar el fitxer.', 'Unable to upload a file.' => 'Impossible adjuntar el fitxer.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -21,6 +21,8 @@ $translations = array(
'Language' => 'Jazyk', 'Language' => 'Jazyk',
'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odešlete formulář znovu.', 'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odešlete formulář znovu.',
'If you did not send this request from Adminer then close this page.' => 'Pokud jste tento požadavek neposlali z Adminera, tak tuto stránku zavřete.', 'If you did not send this request from Adminer then close this page.' => 'Pokud jste tento požadavek neposlali z Adminera, tak tuto stránku zavřete.',
'No driver' => 'Žádný ovladač',
'Database driver not found.' => 'Databázový ovladač se nenašel.',
'No extension' => 'Žádné rozšíření', 'No extension' => 'Žádné rozšíření',
'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Není dostupné žádné z podporovaných PHP rozšíření (%s).',
'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.', 'Connecting to privileged ports is not allowed.' => 'Připojování k privilegovaným portům není povoleno.',
@@ -89,7 +91,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Databáze', 'Database' => 'Databáze',
'database' => 'databáze',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Vybrat', 'Use' => 'Vybrat',
'Select database' => 'Vybrat databázi', 'Select database' => 'Vybrat databázi',
@@ -178,7 +179,6 @@ $translations = array(
'Options' => 'Volby', 'Options' => 'Volby',
'Comment' => 'Komentář', 'Comment' => 'Komentář',
'Default value' => 'Výchozí hodnota', 'Default value' => 'Výchozí hodnota',
'Default values' => 'Výchozí hodnoty',
'Drop' => 'Odstranit', 'Drop' => 'Odstranit',
'Drop %s?' => 'Odstranit %s?', 'Drop %s?' => 'Odstranit %s?',
'Are you sure?' => 'Opravdu?', 'Are you sure?' => 'Opravdu?',
@@ -259,8 +259,8 @@ $translations = array(
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'), '%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
'Page' => 'Stránka', 'Page' => 'Stránka',
'last' => 'poslední', 'last' => 'poslední',
'Load more data' => 'Nahrát další data', 'Load more data' => 'Načíst další data',
'Loading' => 'Nahrává se', 'Loading' => 'Načítá se',
'Whole result' => 'Celý výsledek', 'Whole result' => 'Celý výsledek',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'), '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtů'),
@@ -327,12 +327,15 @@ $translations = array(
'Please use one of the extensions %s.' => 'Prosím použijte jednu z koncovek %s.', 'Please use one of the extensions %s.' => 'Prosím použijte jednu z koncovek %s.',
// PostgreSQL and MS SQL schema support // PostgreSQL and MS SQL schema support
'Schema' => 'Schéma',
'Schemas' => 'Schémy',
'No schemas.' => 'Žádné schémy.',
'Show schema' => 'Zobrazit schéma',
'Alter schema' => 'Pozměnit schéma', 'Alter schema' => 'Pozměnit schéma',
'Create schema' => 'Vytvořit schéma', 'Create schema' => 'Vytvořit schéma',
'Schema has been dropped.' => 'Schéma bylo odstraněno.', 'Schema has been dropped.' => 'Schéma bylo odstraněno.',
'Schema has been created.' => 'Schéma bylo vytvořeno.', 'Schema has been created.' => 'Schéma bylo vytvořeno.',
'Schema has been altered.' => 'Schéma bylo změněno.', 'Schema has been altered.' => 'Schéma bylo změněno.',
'Schema' => 'Schéma',
'Invalid schema.' => 'Nesprávné schéma.', 'Invalid schema.' => 'Nesprávné schéma.',
// PostgreSQL sequences support // PostgreSQL sequences support

View File

@@ -65,7 +65,6 @@ $translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Brug', 'Use' => 'Brug',
'Select database' => 'Vælg database', 'Select database' => 'Vælg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -144,7 +143,6 @@ $translations = array(
'Auto Increment' => 'Auto Increment', 'Auto Increment' => 'Auto Increment',
'Options' => 'Valg', 'Options' => 'Valg',
'Comment' => 'Kommentarer', 'Comment' => 'Kommentarer',
'Default values' => 'Standardværdier',
'Drop' => 'Drop', 'Drop' => 'Drop',
'Are you sure?' => 'Er du sikker?', 'Are you sure?' => 'Er du sikker?',
'Move up' => 'Flyt op', 'Move up' => 'Flyt op',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Nej', 'No' => 'Nej',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -33,7 +33,6 @@ $translations = array(
'Create database' => 'Datenbank erstellen', 'Create database' => 'Datenbank erstellen',
'SQL command' => 'SQL-Kommando', 'SQL command' => 'SQL-Kommando',
'Logout' => 'Abmelden', 'Logout' => 'Abmelden',
'database' => 'Datenbank',
'Use' => 'Benutzung', 'Use' => 'Benutzung',
'No tables.' => 'Keine Tabellen.', 'No tables.' => 'Keine Tabellen.',
'select' => 'zeigen', 'select' => 'zeigen',
@@ -71,7 +70,6 @@ $translations = array(
'Unable to select the table' => 'Auswahl der Tabelle fehlgeschlagen', 'Unable to select the table' => 'Auswahl der Tabelle fehlgeschlagen',
'Invalid CSRF token. Send the form again.' => 'CSRF Token ungültig. Bitte die Formulardaten erneut abschicken.', 'Invalid CSRF token. Send the form again.' => 'CSRF Token ungültig. Bitte die Formulardaten erneut abschicken.',
'Comment' => 'Kommentar', 'Comment' => 'Kommentar',
'Default values' => 'Vorgabewerte festlegen',
'%d byte(s)' => array('%d Byte', '%d Bytes'), '%d byte(s)' => array('%d Byte', '%d Bytes'),
'No commands to execute.' => 'Kein Kommando vorhanden.', 'No commands to execute.' => 'Kein Kommando vorhanden.',
'Unable to upload a file.' => 'Hochladen von Datei fehlgeschlagen.', 'Unable to upload a file.' => 'Hochladen von Datei fehlgeschlagen.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Nein', 'No' => 'Nein',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -80,7 +80,6 @@ $translations = array(
'Data' => 'Δεδομένα', 'Data' => 'Δεδομένα',
'Database' => 'Β. Δεδομένων', 'Database' => 'Β. Δεδομένων',
'database' => 'β. δεδομένων',
'Use' => 'χρήση', 'Use' => 'χρήση',
'Select database' => 'Επιλέξτε Β.Δ.', 'Select database' => 'Επιλέξτε Β.Δ.',
'Invalid database.' => 'Λανθασμένη Β.Δ.', 'Invalid database.' => 'Λανθασμένη Β.Δ.',
@@ -167,7 +166,6 @@ $translations = array(
'Options' => 'Επιλογές', 'Options' => 'Επιλογές',
'Comment' => 'Σχόλιο', 'Comment' => 'Σχόλιο',
'Default value' => 'Προεπιλεγμένη τιμή', 'Default value' => 'Προεπιλεγμένη τιμή',
'Default values' => 'Προεπιλεγμένες τιμές',
'Drop' => 'Διαγραφή', 'Drop' => 'Διαγραφή',
'Are you sure?' => 'Είστε σίγουρος;', 'Are you sure?' => 'Είστε σίγουρος;',
'Size' => 'Μέγεθος', 'Size' => 'Μέγεθος',
@@ -358,4 +356,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -3,7 +3,7 @@ $translations = array(
'Home' => null, 'Home' => null,
'Login' => 'Login', 'Login' => 'Login',
'Logout successful.' => 'Sesión finalizada con éxito.', 'Logout successful.' => 'Sesión finalizada con éxito.',
'Invalid server or credentials.' => null, 'Invalid server or credentials.' => 'Servidor o credenciales no válidos.',
'Server' => 'Servidor', 'Server' => 'Servidor',
'Username' => 'Usuario', 'Username' => 'Usuario',
'Password' => 'Contraseña', 'Password' => 'Contraseña',
@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Cerrar sesión', 'Logout' => 'Cerrar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'No existen tablas.', 'No tables.' => 'No existen tablas.',
'select' => 'registros', 'select' => 'registros',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'No es posible seleccionar la tabla', 'Unable to select the table' => 'No es posible seleccionar la tabla',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Vuelva a enviar los datos del formulario.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Vuelva a enviar los datos del formulario.',
'Comment' => 'Comentario', 'Comment' => 'Comentario',
'Default values' => 'Valores predeterminados',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'No es posible ejecutar ningún comando.', 'No commands to execute.' => 'No es posible ejecutar ningún comando.',
'Unable to upload a file.' => 'No es posible importar el archivo.', 'Unable to upload a file.' => 'No es posible importar el archivo.',
@@ -226,7 +224,7 @@ $translations = array(
'Permanent login' => 'Guardar contraseña', 'Permanent login' => 'Guardar contraseña',
'Databases have been dropped.' => 'Bases de datos eliminadas.', 'Databases have been dropped.' => 'Bases de datos eliminadas.',
'Search data in tables' => 'Buscar datos en tablas', 'Search data in tables' => 'Buscar datos en tablas',
'as a regular expression' => null, 'as a regular expression' => 'como una expresión regular',
'Schema' => 'Esquema', 'Schema' => 'Esquema',
'Alter schema' => 'Modificar esquema', 'Alter schema' => 'Modificar esquema',
'Create schema' => 'Crear esquema', 'Create schema' => 'Crear esquema',
@@ -269,42 +267,42 @@ $translations = array(
'Edit all' => 'Editar todos', 'Edit all' => 'Editar todos',
'HH:MM:SS' => 'HH:MM:SS', 'HH:MM:SS' => 'HH:MM:SS',
'Drop %s?' => null, 'Drop %s?' => '¿Eliminar %s?',
'Tables have been optimized.' => null, 'Tables have been optimized.' => 'Tablas optimizadas.',
'Materialized view' => null, 'Materialized view' => 'Vista materializada',
'Vacuum' => null, 'Vacuum' => 'Vacio',
'Selected' => null, 'Selected' => 'Seleccionado',
'overwrite' => null, 'overwrite' => 'sobreescribir',
'DB' => null, 'DB' => 'DB',
'File must be in UTF-8 encoding.' => null, 'File must be in UTF-8 encoding.' => 'El archivo debe estar codificado en UTF-8.',
'Modify' => null, 'Modify' => 'Modificar',
'Load more data' => null, 'Load more data' => 'Cargar mas datos',
'Loading' => null, 'Loading' => 'Cargando',
'ATTACH queries are not supported.' => null, 'ATTACH queries are not supported.' => 'ATTACH consultas no está soportado.',
'Warnings' => null, 'Warnings' => 'Advertencias',
'%d / ' => array(), '%d / ' => '%d / ',
'Limit rows' => null, 'Limit rows' => 'Limitar filas',
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null, 'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => 'Adminer no soporta el acceso a bases de datos sin contraseña, <a href="https://www.adminer.org/en/password/"%s>más informacion</a>.',
'Default value' => null, 'Default value' => 'Valor por defecto',
'Full table scan' => null, 'Full table scan' => null,
'Too many unsuccessful logins, try again in %d minute(s).' => array(), 'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos erroneos, pruebe de nuevo en %d minuto.', 'Demasiados intentos erroneos, pruebe de nuevo en %d minutos.'),
'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null, 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' => null,
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null, 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'La contraseña Maestra ha expirado. <a href="https://www.adminer.org/en/extension/"%s>Implementar</a> %s un metodo para hacerla permanente.',
'The action will be performed after successful login with the same credentials.' => null, 'The action will be performed after successful login with the same credentials.' => 'La acción se realizará tras iniciar sesión de nuevo con las mismas credenciales.',
'Connecting to privileged ports is not allowed.' => null, 'Connecting to privileged ports is not allowed.' => 'La conexion a puertos especiales no está permitida.',
'There is a space in the input password which might be the cause.' => null, 'There is a space in the input password which might be the cause.' => 'Hay un espacio en la contraseña introducida, lo que puede ser la causa.',
'If you did not send this request from Adminer then close this page.' => null, 'If you did not send this request from Adminer then close this page.' => 'Si no mandó ésta solicitud desde Adminer entonces cierre esta página.',
'You can upload a big SQL file via FTP and import it from server.' => null, 'You can upload a big SQL file via FTP and import it from server.' => 'Puede cargar un fichero SQL grande por FTP e importarlo desde el servidor.',
'Size' => null, 'Size' => 'Tamaño',
'Compute' => null, 'Compute' => 'Procesar',
'You are offline.' => null, 'You are offline.' => 'Se encuentra desconectado.',
'You have no privileges to update this table.' => null, 'You have no privileges to update this table.' => 'No tiene privilegios para actualizar esta tabla.',
'Saving' => null, 'Saving' => 'Guardando',
'Unknown error.' => null, 'Unknown error.' => 'Error desconocido.',
'Database does not support password.' => null, 'Database does not support password.' => 'La Base de Datos no soporta el uso de contraseña.',
'Disable %s or enable %s or %s extensions.' => null, 'Disable %s or enable %s or %s extensions.' => 'Deshabilitar %s o habilitar %s o %s extensiones.',
'yes' => null, 'yes' => 'si',
'no' => null, 'no' => 'no',
'Columns' => null, 'Columns' => null,
'Nullable' => null, 'Nullable' => null,
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Loo uus andmebaas', 'Create database' => 'Loo uus andmebaas',
'SQL command' => 'SQL-Päring', 'SQL command' => 'SQL-Päring',
'Logout' => 'Logi välja', 'Logout' => 'Logi välja',
'database' => 'andmebaas',
'Use' => 'Kasuta', 'Use' => 'Kasuta',
'No tables.' => 'Tabeleid ei leitud.', 'No tables.' => 'Tabeleid ei leitud.',
'select' => 'kuva', 'select' => 'kuva',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Tabeli valimine ebaõnnestus', 'Unable to select the table' => 'Tabeli valimine ebaõnnestus',
'Invalid CSRF token. Send the form again.' => 'Sobimatu CSRF, palun postitage vorm uuesti.', 'Invalid CSRF token. Send the form again.' => 'Sobimatu CSRF, palun postitage vorm uuesti.',
'Comment' => 'Kommentaar', 'Comment' => 'Kommentaar',
'Default values' => 'Vaikimisi väärtused',
'%d byte(s)' => array('%d bait', '%d baiti'), '%d byte(s)' => array('%d bait', '%d baiti'),
'No commands to execute.' => 'Käsk puudub.', 'No commands to execute.' => 'Käsk puudub.',
'Unable to upload a file.' => 'Faili üleslaadimine pole võimalik.', 'Unable to upload a file.' => 'Faili üleslaadimine pole võimalik.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -78,7 +78,6 @@ $translations = array(
'Data' => 'داده', 'Data' => 'داده',
'Database' => 'پایگاه داده', 'Database' => 'پایگاه داده',
'database' => 'پایگاه داده',
'Use' => 'استفاده', 'Use' => 'استفاده',
'Select database' => 'انتخاب پایگاه داده', 'Select database' => 'انتخاب پایگاه داده',
'Invalid database.' => 'پایگاه داده نامعتبر.', 'Invalid database.' => 'پایگاه داده نامعتبر.',
@@ -165,7 +164,6 @@ $translations = array(
'Options' => 'اختیارات', 'Options' => 'اختیارات',
'Comment' => 'توضیح', 'Comment' => 'توضیح',
'Default value' => 'مقدار پیش فرض', 'Default value' => 'مقدار پیش فرض',
'Default values' => 'مقادیر پیش فرض',
'Drop' => 'حذف', 'Drop' => 'حذف',
'Are you sure?' => 'مطمئن هستید؟', 'Are you sure?' => 'مطمئن هستید؟',
'Size' => 'حجم', 'Size' => 'حجم',
@@ -358,4 +356,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -80,7 +80,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Tietokanta', 'Database' => 'Tietokanta',
'database' => 'tietokanta',
'Use' => 'Käytä', 'Use' => 'Käytä',
'Select database' => 'Valitse tietokanta', 'Select database' => 'Valitse tietokanta',
'Invalid database.' => 'Tietokanta ei kelpaa.', 'Invalid database.' => 'Tietokanta ei kelpaa.',
@@ -167,7 +166,6 @@ $translations = array(
'Options' => 'Asetukset', 'Options' => 'Asetukset',
'Comment' => 'Kommentit', 'Comment' => 'Kommentit',
'Default value' => 'Oletusarvo', 'Default value' => 'Oletusarvo',
'Default values' => 'Oletusarvot',
'Drop' => 'Poista', 'Drop' => 'Poista',
'Are you sure?' => 'Oletko varma?', 'Are you sure?' => 'Oletko varma?',
'Size' => 'Koko', 'Size' => 'Koko',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Ei', 'No' => 'Ei',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -31,7 +31,6 @@ $translations = array(
'Create database' => 'Créer une base de données', 'Create database' => 'Créer une base de données',
'SQL command' => 'Requête SQL', 'SQL command' => 'Requête SQL',
'Logout' => 'Déconnexion', 'Logout' => 'Déconnexion',
'database' => 'base de données',
'Use' => 'Utiliser', 'Use' => 'Utiliser',
'No tables.' => 'Aucune table.', 'No tables.' => 'Aucune table.',
'select' => 'select', 'select' => 'select',
@@ -68,7 +67,6 @@ $translations = array(
'Unable to select the table' => 'Impossible de sélectionner la table', 'Unable to select the table' => 'Impossible de sélectionner la table',
'Invalid CSRF token. Send the form again.' => 'Token CSRF invalide. Veuillez renvoyer le formulaire.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF invalide. Veuillez renvoyer le formulaire.',
'Comment' => 'Commentaire', 'Comment' => 'Commentaire',
'Default values' => 'Valeurs par défaut',
'%d byte(s)' => array('%d octet', '%d octets'), '%d byte(s)' => array('%d octet', '%d octets'),
'No commands to execute.' => 'Aucune commande à exécuter.', 'No commands to execute.' => 'Aucune commande à exécuter.',
'Unable to upload a file.' => 'Impossible d\'importer le fichier.', 'Unable to upload a file.' => 'Impossible d\'importer le fichier.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Non', 'No' => 'Non',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Crear Base de datos', 'Create database' => 'Crear Base de datos',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Pechar sesión', 'Logout' => 'Pechar sesión',
'database' => 'base de datos',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Nengunha táboa.', 'No tables.' => 'Nengunha táboa.',
'select' => 'selecciona', 'select' => 'selecciona',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'No é posible seleccionar a táboa', 'Unable to select the table' => 'No é posible seleccionar a táboa',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Envíe de novo os datos do formulario.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Envíe de novo os datos do formulario.',
'Comment' => 'Comentario', 'Comment' => 'Comentario',
'Default values' => 'Valores predeterminados',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Non hai comandos para executar.', 'No commands to execute.' => 'Non hai comandos para executar.',
'Unable to upload a file.' => 'Non é posible importar o ficheiro.', 'Unable to upload a file.' => 'Non é posible importar o ficheiro.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Non', 'No' => 'Non',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -31,7 +31,6 @@ $translations = array(
'Create database' => 'צור מסד נתונים', 'Create database' => 'צור מסד נתונים',
'SQL command' => 'שאילתת SQL', 'SQL command' => 'שאילתת SQL',
'Logout' => 'התנתק', 'Logout' => 'התנתק',
'database' => 'מסד נתונים',
'Use' => 'השתמש', 'Use' => 'השתמש',
'No tables.' => 'אין טבלאות', 'No tables.' => 'אין טבלאות',
'select' => 'בחר', 'select' => 'בחר',
@@ -68,7 +67,6 @@ $translations = array(
'Unable to select the table' => 'בחירת הטבלה נכשלה', 'Unable to select the table' => 'בחירת הטבלה נכשלה',
'Invalid CSRF token. Send the form again.' => 'כשל באבטחת נתונים, שלח טופס שוב', 'Invalid CSRF token. Send the form again.' => 'כשל באבטחת נתונים, שלח טופס שוב',
'Comment' => 'הערה', 'Comment' => 'הערה',
'Default values' => 'ערכי ברירת מחדל',
'%d byte(s)' => '%d בתים', '%d byte(s)' => '%d בתים',
'No commands to execute.' => 'לא נמצאו פקודות להרצה', 'No commands to execute.' => 'לא נמצאו פקודות להרצה',
'Unable to upload a file.' => 'העלאת הקובץ נכשלה', 'Unable to upload a file.' => 'העלאת הקובץ נכשלה',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Adatbázis létrehozása', 'Create database' => 'Adatbázis létrehozása',
'SQL command' => 'SQL parancs', 'SQL command' => 'SQL parancs',
'Logout' => 'Kilépés', 'Logout' => 'Kilépés',
'database' => 'adatbázis',
'Use' => 'Használ', 'Use' => 'Használ',
'No tables.' => 'Nincs tábla.', 'No tables.' => 'Nincs tábla.',
'select' => 'kiválasztás', 'select' => 'kiválasztás',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Nem tudom kiválasztani a táblát', 'Unable to select the table' => 'Nem tudom kiválasztani a táblát',
'Invalid CSRF token. Send the form again.' => 'Érvénytelen CSRF azonosító. Küldd újra az űrlapot.', 'Invalid CSRF token. Send the form again.' => 'Érvénytelen CSRF azonosító. Küldd újra az űrlapot.',
'Comment' => 'Megjegyzés', 'Comment' => 'Megjegyzés',
'Default values' => 'Alapértelmezett értékek',
'%d byte(s)' => array('%d bájt', '%d bájt', '%d bájt'), '%d byte(s)' => array('%d bájt', '%d bájt', '%d bájt'),
'No commands to execute.' => 'Nincs végrehajtható parancs.', 'No commands to execute.' => 'Nincs végrehajtható parancs.',
'Unable to upload a file.' => 'Nem tudom feltölteni a fájlt.', 'Unable to upload a file.' => 'Nem tudom feltölteni a fájlt.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -74,7 +74,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Basis data', 'Database' => 'Basis data',
'database' => 'basis data',
'Use' => 'Gunakan', 'Use' => 'Gunakan',
'Select database' => 'Pilih basis data', 'Select database' => 'Pilih basis data',
'Invalid database.' => 'Basis data tidak sah.', 'Invalid database.' => 'Basis data tidak sah.',
@@ -159,7 +158,6 @@ $translations = array(
'Auto Increment' => 'Inkrementasi Otomatis', 'Auto Increment' => 'Inkrementasi Otomatis',
'Options' => 'Opsi', 'Options' => 'Opsi',
'Comment' => 'Komentar', 'Comment' => 'Komentar',
'Default values' => 'Nilai bawaan',
'Drop' => 'Hapus', 'Drop' => 'Hapus',
'Are you sure?' => 'Anda yakin?', 'Are you sure?' => 'Anda yakin?',
'Move up' => 'Naik', 'Move up' => 'Naik',
@@ -358,4 +356,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Crea database', 'Create database' => 'Crea database',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Esci', 'Logout' => 'Esci',
'database' => 'database',
'Use' => 'Usa', 'Use' => 'Usa',
'No tables.' => 'No tabelle.', 'No tables.' => 'No tabelle.',
'select' => 'seleziona', 'select' => 'seleziona',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Selezione della tabella non riuscita', 'Unable to select the table' => 'Selezione della tabella non riuscita',
'Invalid CSRF token. Send the form again.' => 'Token CSRF non valido. Reinvia la richiesta.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF non valido. Reinvia la richiesta.',
'Comment' => 'Commento', 'Comment' => 'Commento',
'Default values' => 'Valori predefiniti',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Nessun commando da eseguire.', 'No commands to execute.' => 'Nessun commando da eseguire.',
'Unable to upload a file.' => 'Caricamento del file non riuscito.', 'Unable to upload a file.' => 'Caricamento del file non riuscito.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'No', 'No' => 'No',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'データベースを作成', 'Create database' => 'データベースを作成',
'SQL command' => 'SQLコマンド', 'SQL command' => 'SQLコマンド',
'Logout' => 'ログアウト', 'Logout' => 'ログアウト',
'database' => 'データベース',
'Use' => '使用', 'Use' => '使用',
'No tables.' => 'テーブルがありません。', 'No tables.' => 'テーブルがありません。',
'select' => '選択', 'select' => '選択',
@@ -69,7 +68,6 @@ $translations = array(
'Unable to select the table' => 'テーブルを選択できません', 'Unable to select the table' => 'テーブルを選択できません',
'Invalid CSRF token. Send the form again.' => '不正なCSRFトークン。再送信してください', 'Invalid CSRF token. Send the form again.' => '不正なCSRFトークン。再送信してください',
'Comment' => 'コメント', 'Comment' => 'コメント',
'Default values' => '規定値',
'%d byte(s)' => '%d バイト', '%d byte(s)' => '%d バイト',
'No commands to execute.' => '実行するコマンドがありません', 'No commands to execute.' => '実行するコマンドがありません',
'Unable to upload a file.' => 'ファイルをアップロードできません', 'Unable to upload a file.' => 'ファイルをアップロードできません',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'ბაზის შექმნა', 'Create database' => 'ბაზის შექმნა',
'SQL command' => 'SQL-ბრძანება', 'SQL command' => 'SQL-ბრძანება',
'Logout' => 'გასვლა', 'Logout' => 'გასვლა',
'database' => 'ბაზა',
'Use' => 'არჩევა', 'Use' => 'არჩევა',
'No tables.' => 'ბაზაში ცხრილი არაა.', 'No tables.' => 'ბაზაში ცხრილი არაა.',
'select' => 'არჩევა', 'select' => 'არჩევა',
@@ -69,7 +68,6 @@ $translations = array(
'Unable to select the table' => 'ცხრილიდან ინფორმაცია ვერ მოვიპოვე', 'Unable to select the table' => 'ცხრილიდან ინფორმაცია ვერ მოვიპოვე',
'Invalid CSRF token. Send the form again.' => 'უმოქმედო CSRF-ტოკენი. ფორმის კიდევ ერთხელ გაგზავნა.', 'Invalid CSRF token. Send the form again.' => 'უმოქმედო CSRF-ტოკენი. ფორმის კიდევ ერთხელ გაგზავნა.',
'Comment' => 'კომენტარები', 'Comment' => 'კომენტარები',
'Default values' => 'სტანდარტული მნიშვნელობა',
'%d byte(s)' => '%d ბაიტი', '%d byte(s)' => '%d ბაიტი',
'No commands to execute.' => 'შესასრულებელი ბრძანება არაა.', 'No commands to execute.' => 'შესასრულებელი ბრძანება არაა.',
'Unable to upload a file.' => 'ფაილი არ აიტვირთა სერვერზე.', 'Unable to upload a file.' => 'ფაილი არ აიტვირთა სერვერზე.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -72,11 +72,9 @@ $translations = array(
'Database has been dropped.' => '데이터베이스를 삭제했습니다.', 'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.', 'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
'Database schema' => '데이터베이스 구조', 'Database schema' => '데이터베이스 구조',
'database' => '데이터베이스',
'Database' => '데이터베이스', 'Database' => '데이터베이스',
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.', 'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
'Date and time' => '시간', 'Date and time' => '시간',
'Default values' => '기본값',
'Delete' => '삭제', 'Delete' => '삭제',
'descending' => '역순', 'descending' => '역순',
'Drop' => '삭제', 'Drop' => '삭제',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -74,7 +74,6 @@ $translations = array(
'Data' => 'Duomenys', 'Data' => 'Duomenys',
'Database' => 'Duomenų bazė', 'Database' => 'Duomenų bazė',
'database' => 'duomenų bazė',
'Use' => 'Naudoti', 'Use' => 'Naudoti',
'Select database' => 'Pasirinkti duomenų bazę', 'Select database' => 'Pasirinkti duomenų bazę',
'Invalid database.' => 'Neteisinga duomenų bazė.', 'Invalid database.' => 'Neteisinga duomenų bazė.',
@@ -158,7 +157,6 @@ $translations = array(
'Auto Increment' => 'Auto Increment', 'Auto Increment' => 'Auto Increment',
'Options' => 'Nustatymai', 'Options' => 'Nustatymai',
'Comment' => 'Komentaras', 'Comment' => 'Komentaras',
'Default values' => 'Reikšmės pagal nutylėjimą',
'Drop' => 'Pašalinti', 'Drop' => 'Pašalinti',
'Are you sure?' => 'Tikrai?', 'Are you sure?' => 'Tikrai?',
'Move up' => 'Perkelti į viršų', 'Move up' => 'Perkelti į viršų',
@@ -358,4 +356,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Izveidot datubāzi', 'Create database' => 'Izveidot datubāzi',
'SQL command' => 'SQL pieprasījums', 'SQL command' => 'SQL pieprasījums',
'Logout' => 'Iziet', 'Logout' => 'Iziet',
'database' => 'datubāze',
'Use' => 'Lietot', 'Use' => 'Lietot',
'No tables.' => 'Datubāzē nav tabulu.', 'No tables.' => 'Datubāzē nav tabulu.',
'select' => 'izvēlēties', 'select' => 'izvēlēties',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Tabula nav pieejama', 'Unable to select the table' => 'Tabula nav pieejama',
'Invalid CSRF token. Send the form again.' => 'Nederīgs CSRF žetons. Nosūtiet formu vēl vienu reizi.', 'Invalid CSRF token. Send the form again.' => 'Nederīgs CSRF žetons. Nosūtiet formu vēl vienu reizi.',
'Comment' => 'Komentārs', 'Comment' => 'Komentārs',
'Default values' => 'Noklusētā vērtība',
'%d byte(s)' => array('%d baits', '%d baiti', '%d baiti'), '%d byte(s)' => array('%d baits', '%d baiti', '%d baiti'),
'No commands to execute.' => 'Nav izpildāmu komandu.', 'No commands to execute.' => 'Nav izpildāmu komandu.',
'Unable to upload a file.' => 'Neizdevās ielādēt failu uz servera.', 'Unable to upload a file.' => 'Neizdevās ielādēt failu uz servera.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Nē', 'No' => 'Nē',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -83,7 +83,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Pangkalan data', 'Database' => 'Pangkalan data',
'database' => 'pangkalan data',
'Use' => 'Guna', 'Use' => 'Guna',
'Select database' => 'Pilih pangkalan data', 'Select database' => 'Pilih pangkalan data',
'Invalid database.' => 'Pangkalan data tidak sah.', 'Invalid database.' => 'Pangkalan data tidak sah.',
@@ -170,7 +169,6 @@ $translations = array(
'Options' => 'Pilihan', 'Options' => 'Pilihan',
'Comment' => 'Komen', 'Comment' => 'Komen',
'Default value' => 'Nilai lalai', 'Default value' => 'Nilai lalai',
'Default values' => 'Nilai lalai',
'Drop' => 'Jatuh', 'Drop' => 'Jatuh',
'Drop %s?' => 'Jatuhkan %s?', 'Drop %s?' => 'Jatuhkan %s?',
'Are you sure?' => 'Anda pasti?', 'Are you sure?' => 'Anda pasti?',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Tidak', 'No' => 'Tidak',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -33,7 +33,6 @@ $translations = array(
'Create database' => 'Database aanmaken', 'Create database' => 'Database aanmaken',
'SQL command' => 'SQL opdracht', 'SQL command' => 'SQL opdracht',
'Logout' => 'Afmelden', 'Logout' => 'Afmelden',
'database' => 'database',
'Use' => 'Gebruik', 'Use' => 'Gebruik',
'No tables.' => 'Geen tabellen.', 'No tables.' => 'Geen tabellen.',
'select' => 'kies', 'select' => 'kies',
@@ -71,7 +70,6 @@ $translations = array(
'Unable to select the table' => 'Onmogelijk tabel te selecteren', 'Unable to select the table' => 'Onmogelijk tabel te selecteren',
'Invalid CSRF token. Send the form again.' => 'Ongeldig CSRF token. Verstuur het formulier opnieuw.', 'Invalid CSRF token. Send the form again.' => 'Ongeldig CSRF token. Verstuur het formulier opnieuw.',
'Comment' => 'Commentaar', 'Comment' => 'Commentaar',
'Default values' => 'Standaard waarden',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Geen opdrachten uit te voeren.', 'No commands to execute.' => 'Geen opdrachten uit te voeren.',
'Unable to upload a file.' => 'Onmogelijk bestand te uploaden.', 'Unable to upload a file.' => 'Onmogelijk bestand te uploaden.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Neen', 'No' => 'Neen',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -65,7 +65,6 @@ $translations = array(
'Format' => 'Format', 'Format' => 'Format',
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Database', 'Database' => 'Database',
'database' => 'database',
'Use' => 'Bruk', 'Use' => 'Bruk',
'Select database' => 'Velg database', 'Select database' => 'Velg database',
'Invalid database.' => 'Ugyldig database.', 'Invalid database.' => 'Ugyldig database.',
@@ -144,7 +143,6 @@ $translations = array(
'Auto Increment' => 'Autoinkrement', 'Auto Increment' => 'Autoinkrement',
'Options' => 'Valg', 'Options' => 'Valg',
'Comment' => 'Kommentarer', 'Comment' => 'Kommentarer',
'Default values' => 'Standardverdier',
'Drop' => 'Dropp', 'Drop' => 'Dropp',
'Are you sure?' => 'Er du sikker?', 'Are you sure?' => 'Er du sikker?',
'Move up' => 'Flytt opp', 'Move up' => 'Flytt opp',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Nei', 'No' => 'Nei',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -82,7 +82,6 @@ $translations = array(
'Data' => 'Dane', 'Data' => 'Dane',
'Database' => 'Baza danych', 'Database' => 'Baza danych',
'database' => 'baza danych',
'Use' => 'Wybierz', 'Use' => 'Wybierz',
'Select database' => 'Wybierz bazę danych', 'Select database' => 'Wybierz bazę danych',
'Invalid database.' => 'Nie znaleziono bazy danych.', 'Invalid database.' => 'Nie znaleziono bazy danych.',
@@ -169,7 +168,6 @@ $translations = array(
'Options' => 'Opcje', 'Options' => 'Opcje',
'Comment' => 'Komentarz', 'Comment' => 'Komentarz',
'Default value' => 'Wartość domyślna', 'Default value' => 'Wartość domyślna',
'Default values' => 'Wartości domyślne',
'Drop' => 'Usuń', 'Drop' => 'Usuń',
'Drop %s?' => 'Usunąć %s?', 'Drop %s?' => 'Usunąć %s?',
'Are you sure?' => 'Czy jesteś pewien?', 'Are you sure?' => 'Czy jesteś pewien?',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Nie', 'No' => 'Nie',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Sair', 'Logout' => 'Sair',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'selecionar', 'select' => 'selecionar',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Não é possível selecionar a Tabela', 'Unable to select the table' => 'Não é possível selecionar a Tabela',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulário novamente.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulário novamente.',
'Comment' => 'Comentário', 'Comment' => 'Comentário',
'Default values' => 'Valores padrões',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Nenhum comando para executar.', 'No commands to execute.' => 'Nenhum comando para executar.',
'Unable to upload a file.' => 'Não é possível enviar o arquivo.', 'Unable to upload a file.' => 'Não é possível enviar o arquivo.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Criar Base de dados', 'Create database' => 'Criar Base de dados',
'SQL command' => 'Comando SQL', 'SQL command' => 'Comando SQL',
'Logout' => 'Terminar sessão', 'Logout' => 'Terminar sessão',
'database' => 'base de dados',
'Use' => 'Usar', 'Use' => 'Usar',
'No tables.' => 'Não existem tabelas.', 'No tables.' => 'Não existem tabelas.',
'select' => 'registos', 'select' => 'registos',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Não é possivel selecionar a Tabela', 'Unable to select the table' => 'Não é possivel selecionar a Tabela',
'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulario novamente.', 'Invalid CSRF token. Send the form again.' => 'Token CSRF inválido. Enviar o formulario novamente.',
'Comment' => 'Comentário', 'Comment' => 'Comentário',
'Default values' => 'Valores predeterminados',
'%d byte(s)' => array('%d byte', '%d bytes'), '%d byte(s)' => array('%d byte', '%d bytes'),
'No commands to execute.' => 'Nenhum comando para executar.', 'No commands to execute.' => 'Nenhum comando para executar.',
'Unable to upload a file.' => 'Não é possível enviar o ficheiro.', 'Unable to upload a file.' => 'Não é possível enviar o ficheiro.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Crează baza de date', 'Create database' => 'Crează baza de date',
'SQL command' => 'SQL query', 'SQL command' => 'SQL query',
'Logout' => 'Ieșire', 'Logout' => 'Ieșire',
'database' => 'baza de date',
'Use' => 'Alege', 'Use' => 'Alege',
'No tables.' => 'În baza de date nu sunt tabele.', 'No tables.' => 'În baza de date nu sunt tabele.',
'select' => 'selectează', 'select' => 'selectează',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Nu am putut selecta date din tabel', 'Unable to select the table' => 'Nu am putut selecta date din tabel',
'Invalid CSRF token. Send the form again.' => 'CSRF token imposibil. Retrimite forma.', 'Invalid CSRF token. Send the form again.' => 'CSRF token imposibil. Retrimite forma.',
'Comment' => 'Comentariu', 'Comment' => 'Comentariu',
'Default values' => 'Valoarea inițială',
'%d byte(s)' => array('%d octet', '%d octeți'), '%d byte(s)' => array('%d octet', '%d octeți'),
'No commands to execute.' => 'Nu sunt comenzi de executat.', 'No commands to execute.' => 'Nu sunt comenzi de executat.',
'Unable to upload a file.' => 'Nu am putut încărca fișierul pe server.', 'Unable to upload a file.' => 'Nu am putut încărca fișierul pe server.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'Создать базу данных', 'Create database' => 'Создать базу данных',
'SQL command' => 'SQL-запрос', 'SQL command' => 'SQL-запрос',
'Logout' => 'Выйти', 'Logout' => 'Выйти',
'database' => 'база данных',
'Use' => 'Выбрать', 'Use' => 'Выбрать',
'No tables.' => 'В базе данных нет таблиц.', 'No tables.' => 'В базе данных нет таблиц.',
'select' => 'выбрать', 'select' => 'выбрать',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'Не удалось получить данные из таблицы', 'Unable to select the table' => 'Не удалось получить данные из таблицы',
'Invalid CSRF token. Send the form again.' => 'Недействительный CSRF-токен. Отправите форму ещё раз.', 'Invalid CSRF token. Send the form again.' => 'Недействительный CSRF-токен. Отправите форму ещё раз.',
'Comment' => 'Комментарий', 'Comment' => 'Комментарий',
'Default values' => 'Значения по умолчанию',
'%d byte(s)' => array('%d байт', '%d байта', '%d байтов'), '%d byte(s)' => array('%d байт', '%d байта', '%d байтов'),
'No commands to execute.' => 'Нет команд для выполнения.', 'No commands to execute.' => 'Нет команд для выполнения.',
'Unable to upload a file.' => 'Не удалось загрузить файл на сервер.', 'Unable to upload a file.' => 'Не удалось загрузить файл на сервер.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => 'Нет', 'No' => 'Нет',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -33,7 +33,6 @@ $translations = array(
'Create database' => 'Vytvoriť databázu', 'Create database' => 'Vytvoriť databázu',
'SQL command' => 'SQL príkaz', 'SQL command' => 'SQL príkaz',
'Logout' => 'Odhlásiť', 'Logout' => 'Odhlásiť',
'database' => 'databáza',
'Use' => 'Vybrať', 'Use' => 'Vybrať',
'No tables.' => 'Žiadne tabuľky.', 'No tables.' => 'Žiadne tabuľky.',
'select' => 'vypísať', 'select' => 'vypísať',
@@ -71,7 +70,6 @@ $translations = array(
'Unable to select the table' => 'Tabuľku sa nepodarilo vypísať', 'Unable to select the table' => 'Tabuľku sa nepodarilo vypísať',
'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odošlite formulár znova.', 'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odošlite formulár znova.',
'Comment' => 'Komentár', 'Comment' => 'Komentár',
'Default values' => 'Predvolené hodnoty',
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'), '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'),
'No commands to execute.' => 'Žiadne príkazy na vykonanie.', 'No commands to execute.' => 'Žiadne príkazy na vykonanie.',
'Unable to upload a file.' => 'Súbor sa nepodarilo nahrať.', 'Unable to upload a file.' => 'Súbor sa nepodarilo nahrať.',
@@ -79,6 +77,8 @@ $translations = array(
'File uploads are disabled.' => 'Nahrávánie súborov nie je povolené.', 'File uploads are disabled.' => 'Nahrávánie súborov nie je povolené.',
'Routine has been called, %d row(s) affected.' => array('Procedúra bola zavolaná, bol zmenený %d záznam.', 'Procedúra bola zavolaná, boli zmenené %d záznamy.', 'Procedúra bola zavolaná, bolo zmenených %d záznamov.'), 'Routine has been called, %d row(s) affected.' => array('Procedúra bola zavolaná, bol zmenený %d záznam.', 'Procedúra bola zavolaná, boli zmenené %d záznamy.', 'Procedúra bola zavolaná, bolo zmenených %d záznamov.'),
'Call' => 'Zavolať', 'Call' => 'Zavolať',
'No driver' => 'Žiadny ovládač',
'Database driver not found.' => 'Databázový ovládač sa nenašiel.',
'No extension' => 'Žiadne rozšírenie', 'No extension' => 'Žiadne rozšírenie',
'None of the supported PHP extensions (%s) are available.' => 'Nie je dostupné žiadne z podporovaných rozšírení (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Nie je dostupné žiadne z podporovaných rozšírení (%s).',
'Session support must be enabled.' => 'Session premenné musia byť povolené.', 'Session support must be enabled.' => 'Session premenné musia byť povolené.',
@@ -259,7 +259,7 @@ $translations = array(
'%d query(s) executed OK.' => array('Bol vykonaný %d dotaz.', 'Boli vykonané %d dotazy.', 'Bolo vykonaných %d dotazov.'), '%d query(s) executed OK.' => array('Bol vykonaný %d dotaz.', 'Boli vykonané %d dotazy.', 'Bolo vykonaných %d dotazov.'),
'Show only errors' => 'Zobraziť iba chyby', 'Show only errors' => 'Zobraziť iba chyby',
'Refresh' => 'Obnoviť', 'Refresh' => 'Obnoviť',
'Invalid schema.' => 'Neplatné schéma.', 'Invalid schema.' => 'Neplatná schéma.',
'Please use one of the extensions %s.' => 'Prosím vyberte jednu z koncoviek %s.', 'Please use one of the extensions %s.' => 'Prosím vyberte jednu z koncoviek %s.',
'now' => 'teraz', 'now' => 'teraz',
'ltr' => 'ltr', 'ltr' => 'ltr',
@@ -277,8 +277,8 @@ $translations = array(
'DB' => 'DB', 'DB' => 'DB',
'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.', 'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.',
'Modify' => 'Zmeniť', 'Modify' => 'Zmeniť',
'Load more data' => 'Nahráť ďalšie dáta', 'Load more data' => 'Načítať ďalšie dáta',
'Loading' => 'Nahráva sa', 'Loading' => 'Načítava sa',
'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.', 'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.',
'Warnings' => 'Varovania', 'Warnings' => 'Varovania',
'%d / ' => '%d / ', '%d / ' => '%d / ',
@@ -311,4 +311,7 @@ $translations = array(
'Default' => 'Predvolené', 'Default' => 'Predvolené',
'One Time Password' => 'Jednorázové heslo', 'One Time Password' => 'Jednorázové heslo',
'Invalid OTP code.' => 'Neplatný kód OTP.', 'Invalid OTP code.' => 'Neplatný kód OTP.',
'Schemas' => 'Schémy',
'No schemas.' => 'Žiadne schémy.',
'Show schema' => 'Zobraziť schému',
); );

View File

@@ -73,7 +73,6 @@ $translations = array(
'Data' => 'Podatki', 'Data' => 'Podatki',
'Database' => 'Baza', 'Database' => 'Baza',
'database' => 'baza',
'Use' => 'Uporabi', 'Use' => 'Uporabi',
'Select database' => 'Izberi bazo', 'Select database' => 'Izberi bazo',
'Invalid database.' => 'Neveljavna baza.', 'Invalid database.' => 'Neveljavna baza.',
@@ -154,7 +153,6 @@ $translations = array(
'Auto Increment' => 'Samodejno povečevanje', 'Auto Increment' => 'Samodejno povečevanje',
'Options' => 'Možnosti', 'Options' => 'Možnosti',
'Comment' => 'Komentar', 'Comment' => 'Komentar',
'Default values' => 'Privzete vrednosti',
'Drop' => 'Zavrzi', 'Drop' => 'Zavrzi',
'Are you sure?' => 'Ste prepričani?', 'Are you sure?' => 'Ste prepričani?',
'Move up' => 'Premakni gor', 'Move up' => 'Premakni gor',
@@ -355,4 +353,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -74,7 +74,6 @@ $translations = array(
'Data' => 'Податци', 'Data' => 'Податци',
'Database' => 'База података', 'Database' => 'База података',
'database' => 'база података',
'Use' => 'Користи', 'Use' => 'Користи',
'Select database' => 'Изаберите базу', 'Select database' => 'Изаберите базу',
'Invalid database.' => 'Неисправна база података.', 'Invalid database.' => 'Неисправна база података.',
@@ -159,7 +158,6 @@ $translations = array(
'Auto Increment' => 'Ауто-прираштај', 'Auto Increment' => 'Ауто-прираштај',
'Options' => 'Опције', 'Options' => 'Опције',
'Comment' => 'Коментар', 'Comment' => 'Коментар',
'Default values' => 'Подразумеване вредности',
'Drop' => 'Избриши', 'Drop' => 'Избриши',
'Are you sure?' => 'Да ли сте сигурни?', 'Are you sure?' => 'Да ли сте сигурни?',
'Move up' => 'Помери на горе', 'Move up' => 'Помери на горе',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Не', 'No' => 'Не',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -90,7 +90,6 @@ $translations = array(
'Data' => 'Data', 'Data' => 'Data',
'Database' => 'Databas', 'Database' => 'Databas',
'database' => 'databas',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Använd', 'Use' => 'Använd',
'Select database' => 'Välj databas', 'Select database' => 'Välj databas',
@@ -179,7 +178,6 @@ $translations = array(
'Options' => 'Inställningar', 'Options' => 'Inställningar',
'Comment' => 'Kommentar', 'Comment' => 'Kommentar',
'Default value' => 'Standardvärde', 'Default value' => 'Standardvärde',
'Default values' => 'Standardvärden',
'Drop' => 'Ta bort', 'Drop' => 'Ta bort',
'Drop %s?' => 'Ta bort %s?', 'Drop %s?' => 'Ta bort %s?',
'Are you sure?' => 'Är du säker?', 'Are you sure?' => 'Är du säker?',
@@ -357,4 +355,10 @@ $translations = array(
'No' => 'Nej', 'No' => 'Nej',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு', 'Create database' => 'த‌க‌வ‌ல்த‌ள‌த்தை உருவாக்கு',
'SQL command' => 'SQL க‌ட்ட‌ளை', 'SQL command' => 'SQL க‌ட்ட‌ளை',
'Logout' => 'வெளியேறு', 'Logout' => 'வெளியேறு',
'database' => 'த‌க‌வ‌ல்த‌ள‌ம்',
'Use' => 'உப‌யோகி', 'Use' => 'உப‌யோகி',
'No tables.' => 'அட்ட‌வ‌ணை இல்லை.', 'No tables.' => 'அட்ட‌வ‌ணை இல்லை.',
'select' => 'தேர்வு செய்', 'select' => 'தேர்வு செய்',
@@ -69,7 +68,6 @@ $translations = array(
'Unable to select the table' => 'அட்ட‌வ‌ணையை தேர்வு செய்ய‌ முடிய‌வில்லை', 'Unable to select the table' => 'அட்ட‌வ‌ணையை தேர்வு செய்ய‌ முடிய‌வில்லை',
'Invalid CSRF token. Send the form again.' => 'CSRF டோக்க‌ன் செல்லாது. ப‌டிவ‌த்தை மீண்டும் அனுப்ப‌வும்.', 'Invalid CSRF token. Send the form again.' => 'CSRF டோக்க‌ன் செல்லாது. ப‌டிவ‌த்தை மீண்டும் அனுப்ப‌வும்.',
'Comment' => 'குறிப்பு', 'Comment' => 'குறிப்பு',
'Default values' => 'உள்ளிருக்கும் (Default) ம‌திப்புக‌ள் ',
'%d byte(s)' => array('%d பைட்', '%d பைட்டுக‌ள்'), '%d byte(s)' => array('%d பைட்', '%d பைட்டுக‌ள்'),
'No commands to execute.' => 'செய‌ல் ப‌டுத்த‌ எந்த‌ க‌ட்ட‌ளைக‌ளும் இல்லை.', 'No commands to execute.' => 'செய‌ல் ப‌டுத்த‌ எந்த‌ க‌ட்ட‌ளைக‌ளும் இல்லை.',
'Unable to upload a file.' => 'கோப்பை மேலேற்ற‌ம் (upload) செய்ய‌ இயல‌வில்லை.', 'Unable to upload a file.' => 'கோப்பை மேலேற்ற‌ம் (upload) செய்ய‌ இயல‌வில்லை.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -32,7 +32,6 @@ $translations = array(
'Create database' => 'สร้างฐานข้อมูล', 'Create database' => 'สร้างฐานข้อมูล',
'SQL command' => 'คำสั่ง SQL', 'SQL command' => 'คำสั่ง SQL',
'Logout' => 'ออกจากระบบ', 'Logout' => 'ออกจากระบบ',
'database' => 'ฐานข้อมูล',
'Use' => 'ใช้งาน', 'Use' => 'ใช้งาน',
'No tables.' => 'ไม่พบตาราง.', 'No tables.' => 'ไม่พบตาราง.',
'select' => 'เลือก', 'select' => 'เลือก',
@@ -70,7 +69,6 @@ $translations = array(
'Unable to select the table' => 'ไม่สามารถเลือกตารางได้', 'Unable to select the table' => 'ไม่สามารถเลือกตารางได้',
'Invalid CSRF token. Send the form again.' => 'เครื่องหมาย CSRF ไม่ถูกต้อง ส่งข้อมูลใหม่อีกครั้ง.', 'Invalid CSRF token. Send the form again.' => 'เครื่องหมาย CSRF ไม่ถูกต้อง ส่งข้อมูลใหม่อีกครั้ง.',
'Comment' => 'หมายเหตุ', 'Comment' => 'หมายเหตุ',
'Default values' => 'ค่าเริ่มต้น',
'%d byte(s)' => '%d ไบท์', '%d byte(s)' => '%d ไบท์',
'No commands to execute.' => 'ไม่มีคำสั่งที่จะประมวลผล.', 'No commands to execute.' => 'ไม่มีคำสั่งที่จะประมวลผล.',
'Unable to upload a file.' => 'ไม่สามารถอัปโหลดไฟล์ได้.', 'Unable to upload a file.' => 'ไม่สามารถอัปโหลดไฟล์ได้.',
@@ -313,4 +311,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -85,7 +85,6 @@ $translations = array(
'Data' => 'Veri', 'Data' => 'Veri',
'Database' => 'Veri Tabanı', 'Database' => 'Veri Tabanı',
'database' => 'veri tabanı',
'DB' => 'DB', 'DB' => 'DB',
'Use' => 'Kullan', 'Use' => 'Kullan',
'Select database' => 'Veri tabanı seç', 'Select database' => 'Veri tabanı seç',
@@ -173,7 +172,6 @@ $translations = array(
'Options' => 'Seçenekler', 'Options' => 'Seçenekler',
'Comment' => 'Yorum', 'Comment' => 'Yorum',
'Default value' => 'Varsayılan değer', 'Default value' => 'Varsayılan değer',
'Default values' => 'Varsayılan değerler',
'Drop' => 'Sil', 'Drop' => 'Sil',
'Drop %s?' => 'Sil %s?', 'Drop %s?' => 'Sil %s?',
'Are you sure?' => 'Emin misiniz?', 'Are you sure?' => 'Emin misiniz?',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Hayır', 'No' => 'Hayır',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -74,7 +74,6 @@ $translations = array(
'Data' => 'Дані', 'Data' => 'Дані',
'Database' => 'База даних', 'Database' => 'База даних',
'database' => 'база даних',
'Use' => 'Обрати', 'Use' => 'Обрати',
'Select database' => 'Обрати базу даних', 'Select database' => 'Обрати базу даних',
'Invalid database.' => 'Погана база даних.', 'Invalid database.' => 'Погана база даних.',
@@ -159,7 +158,6 @@ $translations = array(
'Auto Increment' => 'Автоматичне збільшення', 'Auto Increment' => 'Автоматичне збільшення',
'Options' => 'Опції', 'Options' => 'Опції',
'Comment' => 'Коментарі', 'Comment' => 'Коментарі',
'Default values' => 'Значення за замовчуванням',
'Drop' => 'Видалити', 'Drop' => 'Видалити',
'Are you sure?' => 'Ви впевнені?', 'Are you sure?' => 'Ви впевнені?',
'Move up' => 'Пересунути вгору', 'Move up' => 'Пересунути вгору',
@@ -358,4 +356,10 @@ $translations = array(
'No' => 'Ні', 'No' => 'Ні',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -77,7 +77,6 @@ $translations = array(
'Data' => 'Dữ liệu', 'Data' => 'Dữ liệu',
'Database' => 'Cơ sở dữ liệu', 'Database' => 'Cơ sở dữ liệu',
'database' => 'cơ sở dữ liệu',
'Use' => 'Sử dụng', 'Use' => 'Sử dụng',
'Select database' => 'Chọn CSDL', 'Select database' => 'Chọn CSDL',
'Invalid database.' => 'CSDL sai.', 'Invalid database.' => 'CSDL sai.',
@@ -162,7 +161,6 @@ $translations = array(
'Auto Increment' => 'Tăng tự động', 'Auto Increment' => 'Tăng tự động',
'Options' => 'Tuỳ chọn', 'Options' => 'Tuỳ chọn',
'Comment' => 'Chú thích', 'Comment' => 'Chú thích',
'Default values' => 'Giá trị mặc định',
'Drop' => 'Xoá', 'Drop' => 'Xoá',
'Are you sure?' => 'Bạn có chắc', 'Are you sure?' => 'Bạn có chắc',
'Size' => 'Kích thước', 'Size' => 'Kích thước',
@@ -357,4 +355,10 @@ $translations = array(
'No' => 'Không', 'No' => 'Không',
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -21,6 +21,8 @@ $translations = array(
'Language' => 'Xx', 'Language' => 'Xx',
'Invalid CSRF token. Send the form again.' => 'Xx.', 'Invalid CSRF token. Send the form again.' => 'Xx.',
'If you did not send this request from Adminer then close this page.' => 'Xx.', 'If you did not send this request from Adminer then close this page.' => 'Xx.',
'No driver' => 'Xx',
'Database driver not found.' => 'Xx.',
'No extension' => 'Xx', 'No extension' => 'Xx',
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).', 'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
'Connecting to privileged ports is not allowed.' => 'Xx.', 'Connecting to privileged ports is not allowed.' => 'Xx.',
@@ -90,7 +92,6 @@ $translations = array(
'Data' => 'Xx', 'Data' => 'Xx',
'Database' => 'Xx', 'Database' => 'Xx',
'database' => 'xx',
'DB' => 'XX', 'DB' => 'XX',
'Use' => 'Xx', 'Use' => 'Xx',
'Select database' => 'Xx', 'Select database' => 'Xx',
@@ -179,7 +180,6 @@ $translations = array(
'Options' => 'Xx', 'Options' => 'Xx',
'Comment' => 'Xx', 'Comment' => 'Xx',
'Default value' => 'Xx', 'Default value' => 'Xx',
'Default values' => 'Xx',
'Drop' => 'Xx', 'Drop' => 'Xx',
'Drop %s?' => 'Xx %s?', 'Drop %s?' => 'Xx %s?',
'Are you sure?' => 'Xx?', 'Are you sure?' => 'Xx?',
@@ -327,12 +327,15 @@ $translations = array(
'Please use one of the extensions %s.' => 'Xx %s.', 'Please use one of the extensions %s.' => 'Xx %s.',
// PostgreSQL and MS SQL schema support // PostgreSQL and MS SQL schema support
'Schema' => 'Xx',
'Schemas' => 'Xx',
'No schemas.' => 'Xx.',
'Show schema' => 'Xx',
'Alter schema' => 'Xx', 'Alter schema' => 'Xx',
'Create schema' => 'Xx', 'Create schema' => 'Xx',
'Schema has been dropped.' => 'Xx.', 'Schema has been dropped.' => 'Xx.',
'Schema has been created.' => 'Xx.', 'Schema has been created.' => 'Xx.',
'Schema has been altered.' => 'Xx.', 'Schema has been altered.' => 'Xx.',
'Schema' => 'Xx',
'Invalid schema.' => 'Xx.', 'Invalid schema.' => 'Xx.',
// PostgreSQL sequences support // PostgreSQL sequences support

View File

@@ -90,7 +90,6 @@ $translations = array(
'Data' => '資料', 'Data' => '資料',
'Database' => '資料庫', 'Database' => '資料庫',
'database' => '資料庫',
'DB' => '資料庫', 'DB' => '資料庫',
'Use' => '使用', 'Use' => '使用',
'Select database' => '選擇資料庫', 'Select database' => '選擇資料庫',
@@ -179,7 +178,6 @@ $translations = array(
'Options' => '選項', 'Options' => '選項',
'Comment' => '註解', 'Comment' => '註解',
'Default value' => '預設值', 'Default value' => '預設值',
'Default values' => '預設值',
'Drop' => '刪除', 'Drop' => '刪除',
'Drop %s?' => '刪除 %s?', 'Drop %s?' => '刪除 %s?',
'Are you sure?' => '你確定嗎?', 'Are you sure?' => '你確定嗎?',
@@ -358,4 +356,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -90,7 +90,6 @@ $translations = array(
'Data' => '数据', 'Data' => '数据',
'Database' => '数据库', 'Database' => '数据库',
'database' => '数据库',
'DB' => '数据库', 'DB' => '数据库',
'Use' => '使用', 'Use' => '使用',
'Select database' => '选择数据库', 'Select database' => '选择数据库',
@@ -179,7 +178,6 @@ $translations = array(
'Options' => '选项', 'Options' => '选项',
'Comment' => '注释', 'Comment' => '注释',
'Default value' => '默认值', 'Default value' => '默认值',
'Default values' => '默认值',
'Drop' => '删除', 'Drop' => '删除',
'Drop %s?' => '删除 %s?', 'Drop %s?' => '删除 %s?',
'Are you sure?' => '您确定吗?', 'Are you sure?' => '您确定吗?',
@@ -357,4 +355,10 @@ $translations = array(
'No' => null, 'No' => null,
'One Time Password' => null, 'One Time Password' => null,
'Invalid OTP code.' => null, 'Invalid OTP code.' => null,
'Schemas' => null,
'No schemas.' => null,
'Show schema' => null,
'No driver' => null,
'Database driver not found.' => null,
); );

View File

@@ -29,8 +29,8 @@ function adminer_object() {
new AdminerTranslation, new AdminerTranslation,
new AdminerForeignSystem, new AdminerForeignSystem,
new AdminerEnumOption, new AdminerEnumOption,
new AdminerTablesFilter,
new AdminerEditForeign, new AdminerEditForeign,
new AdminerLoginSsl(["TrustServerCertificate" => true]),
); );
/* It is possible to combine customization and plugins: /* It is possible to combine customization and plugins:

View File

@@ -39,12 +39,17 @@ $routine_languages = routine_languages();
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?> <?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<div class="scrollable"> <div class="scrollable">
<table cellspacing="0" class="nowrap"> <table cellspacing="0" class="nowrap" id="edit-fields">
<?php <?php
edit_fields($row["fields"], $collations, $routine); edit_fields($row["fields"], $collations, $routine);
if (isset($_GET["function"])) { if (isset($_GET["function"])) {
echo "<tr><td>" . lang('Return type'); echo "<tbody><tr>",
(support("move_col") ? "<th></th>" : ""),
"<th>", lang('Return type'), "</th>";
edit_type("returns", $row["returns"], $collations, array(), ($jush == "pgsql" ? array("void", "trigger") : array())); edit_type("returns", $row["returns"], $collations, array(), ($jush == "pgsql" ? array("void", "trigger") : array()));
echo "<td></td></tr></tbody>\n";
} }
?> ?>
</table> </table>

View File

@@ -50,9 +50,9 @@ foreach (table_status('', true) as $table => $table_status) {
?> ?>
<div id="schema" style="height: <?php echo $top; ?>em;"> <div id="schema" style="height: <?php echo $top; ?>em;">
<script<?php echo nonce(); ?>> <script<?php echo nonce(); ?>>
qs('#schema').onselectstart = function () { return false; }; gid('schema').onselectstart = function () { return false; };
var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>}; var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
var em = qs('#schema').offsetHeight / <?php echo $top; ?>; var em = gid('schema').offsetHeight / <?php echo $top; ?>;
document.onmousemove = schemaMousemove; document.onmousemove = schemaMousemove;
document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>'); document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>');
</script> </script>

View File

@@ -27,7 +27,7 @@ if (!$row) {
<form action="" method="post"> <form action="" method="post">
<p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off"> <p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php echo script("focus(qs('#name'));"); ?> <?php echo script("focus(gid('name'));"); ?>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">
<?php <?php
if ($_GET["ns"] != "") { if ($_GET["ns"] != "") {

View File

@@ -322,10 +322,10 @@ if (!$columns && support("table")) {
echo "<div class='scrollable'>"; echo "<div class='scrollable'>";
echo "<table id='table' cellspacing='0' class='nowrap checkable'>"; echo "<table id='table' cellspacing='0' class='nowrap checkable'>";
echo script("mixin(qs('#table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});"); echo script("mixin(gid('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true), onkeydown: editingKeydown});");
echo "<thead><tr>" . (!$group && $select echo "<thead><tr>" . (!$group && $select
? "" ? ""
: "<td><input type='checkbox' id='all-page' class='jsonly'>" . script("qs('#all-page').onclick = partial(formCheck, /check/);", "") : "<td><input type='checkbox' id='all-page' class='jsonly'>" . script("gid('all-page').onclick = partial(formCheck, /check/);", "")
. " <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('Modify') . "</a>"); . " <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('Modify') . "</a>");
$names = array(); $names = array();
$functions = array(); $functions = array();
@@ -353,10 +353,10 @@ if (!$columns && support("table")) {
} }
echo "<span class='column hidden'>"; echo "<span class='column hidden'>";
if ($sortable) { if ($sortable) {
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>"; echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
} }
if (!$val["fun"] && isset($field["privileges"]["where"])) { if (!$val["fun"] && isset($field["privileges"]["where"])) {
echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>'; echo '<a href="#fieldset-search" title="' . lang('Search') . '" class="text jsonly"> =</a>';
echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');"); echo script("qsl('a').onclick = partial(selectSearch, '" . js_escape($key) . "');");
} }
echo "</span>"; echo "</span>";

View File

@@ -243,7 +243,7 @@ if (!isset($_GET["import"])) {
} }
echo "<p>"; echo "<p>";
textarea("query", $q, 20); textarea("query", $q, 20);
echo script(($_POST ? "" : "qs('textarea').focus();\n") . "qs('#form').onsubmit = partial(sqlSubmit, qs('#form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');"); echo script(($_POST ? "" : "qs('textarea').focus();\n") . "gid('form').onsubmit = partial(sqlSubmit, gid('form'), '" . js_escape(remove_from_uri("sql|limit|error_stops|only_errors|history")) . "');");
echo "<p>$execute\n"; echo "<p>$execute\n";
echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n"; echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";

View File

@@ -1,7 +1,7 @@
/** @author Ondrej Valka, http://valka.info */ /** @author Ondrej Valka, http://valka.info */
body { color: #000; background: #fff; font: 90%/1.25 Verdana, Arial, Helvetica, sans-serif; margin: 0; width: -moz-fit-content; width: fit-content; } body { color: #000; background: #fff; font: 90%/1.25 Verdana, Arial, Helvetica, sans-serif; margin: 0; width: -moz-fit-content; width: fit-content; }
a { color: blue; text-decoration: none; } a { color: blue; text-decoration: none; }
a:hover { color: red; text-decoration: underline; } a:link:hover { color: red; text-decoration: underline; }
a.text:hover { text-decoration: none; } a.text:hover { text-decoration: none; }
a.jush-help:hover { color: inherit; } a.jush-help:hover { color: inherit; }
h1 { font-size: 150%; margin: 0; padding: .8em 1em; border-bottom: 1px solid #999; font-weight: normal; color: #777; background: #eee; } h1 { font-size: 150%; margin: 0; padding: .8em 1em; border-bottom: 1px solid #999; font-weight: normal; color: #777; background: #eee; }
@@ -24,8 +24,10 @@ pre { margin: 1em 0 0; }
pre code { display: block; font-size: 100%; } pre code { display: block; font-size: 100%; }
pre, textarea { font: 110%/1.25 monospace; } pre, textarea { font: 110%/1.25 monospace; }
pre.jush { background: #fff; } pre.jush { background: #fff; }
pre.comment { white-space: pre-wrap; }
form + pre.comment { margin-top: 2em; }
input, textarea, select { box-sizing: border-box; } input, textarea, select { box-sizing: border-box; }
input:not([type="radio"]), select { vertical-align: middle; } input[type="image"] { vertical-align: middle; margin-top: -3px; }
input[type="number"] { -moz-appearance: textfield; } input[type="number"] { -moz-appearance: textfield; }
input::-webkit-inner-spin-button { -webkit-appearance: none; } input::-webkit-inner-spin-button { -webkit-appearance: none; }
input.default { box-shadow: 1px 1px 1px #777; } input.default { box-shadow: 1px 1px 1px #777; }
@@ -76,7 +78,8 @@ p.nowrap { white-space: pre; }
.handle:before { content: "="; display: inline-block; width: 18px; height: 18px; overflow: hidden; font-size: 130%; text-align: center; line-height: 16px; opacity: 0.2; } .handle:before { content: "="; display: inline-block; width: 18px; height: 18px; overflow: hidden; font-size: 130%; text-align: center; line-height: 16px; opacity: 0.2; }
span.handle { display: inline-block; width: 18px; height: 18px; padding-right: .3em; } span.handle { display: inline-block; width: 18px; height: 18px; padding-right: .3em; }
th.handle:before { vertical-align: middle; } th.handle:before { vertical-align: middle; }
.no-sort .handle { cursor: default; opacity: 0; } .no-sort .handle { cursor: default; }
.no-sort .handle:before { content: "•"; font-size: 100%; }
.placeholder { opacity: 0; } .placeholder { opacity: 0; }
.dragging { position: absolute; margin: 0; background: #fff; } .dragging { position: absolute; margin: 0; background: #fff; }
.dragging * { cursor: grabbing; } .dragging * { cursor: grabbing; }
@@ -108,6 +111,7 @@ table.dragging { background: #eee; }
.rtl .pages { left: auto; right: 21em; } .rtl .pages { left: auto; right: 21em; }
.rtl input.wayoff { left: auto; right: -1000px; } .rtl input.wayoff { left: auto; right: -1000px; }
.rtl #lang, .rtl #menu { left: auto; right: 0; } .rtl #lang, .rtl #menu { left: auto; right: 0; }
.rtl pre, .rtl code { direction: ltr; }
@media all and (max-width: 880px) { @media all and (max-width: 880px) {
.pages { left: auto; } .pages { left: auto; }

View File

@@ -16,17 +16,22 @@ function bodyLoad(version, maria) {
if (maria) { if (maria) {
for (var i = 1; i < obj.length; i++) { for (var i = 1; i < obj.length; i++) {
obj[i] = obj[i] obj[i] = obj[i]
.replace(/\.html/, '/') .replace('.html', '/')
.replace(/-type-syntax/, '-data-types') .replace('-type-syntax', '-data-types')
.replace(/numeric-(data-types)/, '$1-$&') .replace(/numeric-(data-types)/, '$1-$&')
.replace(/#statvar_.*/, '#$$1') .replace(/replication-options-(master|binary-log)\//, 'replication-and-binary-log-system-variables/')
.replace('server-options/', 'server-system-variables/')
.replace('innodb-parameters/', 'innodb-system-variables/')
.replace(/#(statvar|sysvar|option_mysqld)_(.*)/, '#$2')
.replace(/#sysvar_(.*)/, '#$1')
; ;
} }
} }
} }
obj[key] = (maria ? obj[key].replace(/dev\.mysql\.com\/doc\/mysql\/en\//, 'mariadb.com/kb/en/library/') : obj[key]) // MariaDB
.replace(/\/doc\/mysql/, '/doc/refman/' + version) // MySQL obj[key] = (maria ? obj[key].replace('dev.mysql.com/doc/mysql/en/', 'mariadb.com/kb/en/') : obj[key]) // MariaDB
.replace(/\/docs\/current/, '/docs/' + version) // PostgreSQL .replace('/doc/mysql/', '/doc/refman/' + version) // MySQL
.replace('/docs/current/', '/docs/' + version) // PostgreSQL
; ;
} }
} }
@@ -83,13 +88,17 @@ function messagesPrint(el) {
/** Hide or show some login rows for selected driver /**
* @param HTMLSelectElement * Hides or shows some login rows for selected driver.
*/ *
function loginDriver(driver) { * @param {HTMLSelectElement} driverSelect
var trs = parentTag(driver, 'table').rows; */
var disabled = /sqlite/.test(selectValue(driver)); function loginDriver(driverSelect) {
alterClass(trs[1], 'hidden', disabled); // 1 - row with server const trs = parentTag(driverSelect, 'table').rows;
const disabled = /sqlite/.test(selectValue(driverSelect));
// 1 - row with server
trs[1].classList.toggle('hidden', disabled);
trs[1].getElementsByTagName('input')[0].disabled = disabled; trs[1].getElementsByTagName('input')[0].disabled = disabled;
} }
@@ -231,11 +240,13 @@ function editFields() {
els = qsa('[name$="[type]"]'); els = qsa('[name$="[type]"]');
for (var i = 0; i < els.length; i++) { for (var i = 0; i < els.length; i++) {
mixin(els[i], { mixin(els[i], {
onfocus: function () { lastType = selectValue(this); }, onfocus: () => {
lastType = selectValue(this);
},
onchange: editingTypeChange, onchange: editingTypeChange,
onmouseover: function (event) { helpMouseover.call(this, event, getTarget(event).value, 1) },
onmouseout: helpMouseout
}); });
initHelpFor(els[i], (value) => { return value; }, true);
} }
} }
@@ -244,7 +255,7 @@ function editFields() {
* @return boolean false to cancel action * @return boolean false to cancel action
*/ */
function editingClick(event) { function editingClick(event) {
var el = getTarget(event); var el = event.target;
if (!isTag(el, 'input')) { if (!isTag(el, 'input')) {
el = parentTag(el, 'label'); el = parentTag(el, 'label');
el = el && qs('input', el); el = el && qs('input', el);
@@ -273,7 +284,7 @@ function editingClick(event) {
* @param InputEvent * @param InputEvent
*/ */
function editingInput(event) { function editingInput(event) {
var el = getTarget(event); var el = event.target;
if (/\[default]$/.test(el.name)) { if (/\[default]$/.test(el.name)) {
el.previousSibling.checked = true; el.previousSibling.checked = true;
} }
@@ -398,26 +409,26 @@ function editingTypeChange() {
el.checked = false; el.checked = false;
} }
if (el.name === name + '[collation]') { if (el.name === name + '[collation]') {
alterClass(el, 'hidden', !/(char|text|enum|set)$/.test(text)); el.classList.toggle('hidden', !/(char|text|enum|set)$/.test(text));
} }
if (el.name === name + '[unsigned]') { if (el.name === name + '[unsigned]') {
alterClass(el, 'hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text)); el.classList.toggle('hidden', !/(^|[^o])int(?!er)|numeric|real|float|double|decimal|money/.test(text));
} }
if (el.name === name + '[on_update]') { if (el.name === name + '[on_update]') {
alterClass(el, 'hidden', !/timestamp|datetime/.test(text)); // MySQL supports datetime since 5.6.5 // MySQL supports datetime since 5.6.5.
el.classList.toggle('hidden', !/timestamp|datetime/.test(text));
} }
if (el.name === name + '[on_delete]') { if (el.name === name + '[on_delete]') {
alterClass(el, 'hidden', !/`/.test(text)); el.classList.toggle('hidden', !/`/.test(text));
} }
} }
helpClose();
} }
/** Mark length as required /** Mark length as required
* @this HTMLInputElement * @this HTMLInputElement
*/ */
function editingLengthChange() { function editingLengthChange() {
alterClass(this, 'required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild))); this.classList.toggle('required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild)));
} }
/** Edit enum or set /** Edit enum or set
@@ -426,7 +437,7 @@ function editingLengthChange() {
function editingLengthFocus() { function editingLengthFocus() {
var td = this.parentNode; var td = this.parentNode;
if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) { if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) {
var edit = qs('#enum-edit'); var edit = gid('enum-edit');
edit.value = enumValues(this.value); edit.value = enumValues(this.value);
td.appendChild(edit); td.appendChild(edit);
this.style.display = 'none'; this.style.display = 'none';
@@ -470,9 +481,9 @@ function editingLengthBlur() {
* @param number * @param number
*/ */
function columnShow(checked, column) { function columnShow(checked, column) {
var trs = qsa('tr', qs('#edit-fields')); var trs = qsa('tr', gid('edit-fields'));
for (var i=0; i < trs.length; i++) { for (var i=0; i < trs.length; i++) {
alterClass(qsa('td', trs[i])[column], 'hidden', !checked); qsa('td', trs[i])[column].classList.toggle('hidden', !checked);
} }
} }
@@ -481,9 +492,9 @@ function columnShow(checked, column) {
*/ */
function partitionByChange() { function partitionByChange() {
var partitionTable = /RANGE|LIST/.test(selectValue(this)); var partitionTable = /RANGE|LIST/.test(selectValue(this));
alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex);
alterClass(qs('#partition-table'), 'hidden', !partitionTable); this.form['partitions'].classList.toggle('hidden', partitionTable || !this.selectedIndex);
helpClose(); gid('partition-table').classList.toggle('hidden', !partitionTable);
} }
/** Add next partition row /** Add next partition row
@@ -503,7 +514,7 @@ function partitionNameChange() {
function editingCommentsClick(el, focus) { function editingCommentsClick(el, focus) {
var comment = el.form['Comment']; var comment = el.form['Comment'];
columnShow(el.checked, 6); columnShow(el.checked, 6);
alterClass(comment, 'hidden', !el.checked); comment.classList.toggle('hidden', !el.checked);
if (focus && el.checked) { if (focus && el.checked) {
comment.focus(); comment.focus();
} }
@@ -516,7 +527,7 @@ function editingCommentsClick(el, focus) {
* @this HTMLTableElement * @this HTMLTableElement
*/ */
function dumpClick(event) { function dumpClick(event) {
var el = parentTag(getTarget(event), 'label'); var el = parentTag(event.target, 'label');
if (el) { if (el) {
el = qs('input', el); el = qs('input', el);
var match = /(.+)\[]$/.exec(el.name); var match = /(.+)\[]$/.exec(el.name);
@@ -646,7 +657,7 @@ function triggerChange(tableRe, table, form) {
if (tableRe.test(form['Trigger'].value)) { if (tableRe.test(form['Trigger'].value)) {
form['Trigger'].value = table + '_' + (selectValue(form['Timing']).charAt(0) + formEvent.charAt(0)).toLowerCase(); form['Trigger'].value = table + '_' + (selectValue(form['Timing']).charAt(0) + formEvent.charAt(0)).toLowerCase();
} }
alterClass(form['Of'], 'hidden', !/ OF/.test(formEvent)); form['Of'].classList.toggle('hidden', !/ OF/.test(formEvent));
} }
@@ -720,55 +731,114 @@ function schemaMouseup(event, db) {
s += '_' + key + ':' + Math.round(tablePos[key][0] * 10000) / 10000 + 'x' + Math.round(tablePos[key][1] * 10000) / 10000; s += '_' + key + ':' + Math.round(tablePos[key][0] * 10000) / 10000 + 'x' + Math.round(tablePos[key][1] * 10000) / 10000;
} }
s = encodeURIComponent(s.substr(1)); s = encodeURIComponent(s.substr(1));
var link = qs('#schema-link'); var link = gid('schema-link');
link.href = link.href.replace(/[^=]+$/, '') + s; link.href = link.href.replace(/[^=]+$/, '') + s;
cookie('adminer_schema-' + db + '=' + s, 30); //! special chars in db cookie('adminer_schema-' + db + '=' + s, 30); //! special chars in db
} }
} }
// Help.
(function() {
let openTimeout = null;
let closeTimeout = null;
let helpVisible = false;
var helpOpen, helpIgnore; // when mouse outs <option> then it mouse overs border of <select> - ignore it window.initHelpPopup = function () {
const help = gid("help");
/** Display help help.addEventListener("mouseenter", () => {
* @param MouseEvent clearTimeout(closeTimeout);
* @param string closeTimeout = null;
* @param bool display on left side (otherwise on top) });
* @this HTMLElement
*/
function helpMouseover(event, text, side) {
var target = getTarget(event);
if (!text) {
helpClose();
} else if (window.jush && (!helpIgnore || this !== target)) {
helpOpen = 1;
var help = qs('#help');
help.innerHTML = text;
jush.highlight_tag([ help ]);
alterClass(help, 'hidden');
var rect = target.getBoundingClientRect();
var body = document.documentElement;
help.style.top = (body.scrollTop + rect.top - (side ? (help.offsetHeight - target.offsetHeight) / 2 : help.offsetHeight)) + 'px';
help.style.left = (body.scrollLeft + rect.left - (side ? help.offsetWidth : (help.offsetWidth - target.offsetWidth) / 2)) + 'px';
}
}
/** Close help after timeout help.addEventListener("mouseleave", hideHelp);
* @param MouseEvent };
* @this HTMLElement
*/ /**
function helpMouseout(event) { * @param {HTMLElement} element
helpOpen = 0; * @param {string|function} content
helpIgnore = (this !== getTarget(event)); * @param {boolean} side Displays on left side (otherwise on top).
setTimeout(function () { */
if (!helpOpen) { window.initHelpFor = function(element, content, side = false) {
helpClose(); const withCallback = typeof content === "function";
element.addEventListener("mouseenter", (event) => {
showHelp(event.target, withCallback ? content(event.target.value) : content, side)
});
element.addEventListener("mouseleave", hideHelp);
element.addEventListener("blur", hideHelp);
if (withCallback) {
element.addEventListener("change", hideHelp);
} }
}, 200); };
}
/** Close help /**
*/ * Displays help popup after a small delay.
function helpClose() { *
alterClass(qs('#help'), 'hidden', true); * @param {HTMLElement} element
} * @param {string} text
* @param {boolean} side display on left side (otherwise on top)
*/
function showHelp(element, text, side) {
if (!text) {
hideHelp();
return;
}
if (isSorting() || !window.jush) {
return;
}
clearTimeout(openTimeout);
openTimeout = null;
clearTimeout(closeTimeout);
closeTimeout = null;
const help = gid("help");
help.innerHTML = text;
jush.highlight_tag([help]);
// Display help briefly to calculate position properly.
help.classList.remove("hidden");
const rect = element.getBoundingClientRect();
const root = document.documentElement;
help.style.top = (root.scrollTop + rect.top - (side ? (help.offsetHeight - element.offsetHeight) / 2 : help.offsetHeight)) + 'px';
help.style.left = (root.scrollLeft + rect.left - (side ? help.offsetWidth : (help.offsetWidth - element.offsetWidth) / 2)) + 'px';
if (helpVisible) {
return;
}
help.classList.add("hidden");
openTimeout = setTimeout(() => {
gid("help").classList.remove("hidden");
helpVisible = true;
openTimeout = null;
}, 600);
}
/**
* Closes the help popup after a small delay.
*/
function hideHelp() {
if (openTimeout) {
clearTimeout(openTimeout);
openTimeout = null;
return;
}
closeTimeout = setTimeout(() => {
gid("help").classList.add("hidden");
helpVisible = false;
closeTimeout = null;
}, 200);
}
})();

View File

@@ -73,17 +73,6 @@ function mixin(target, source) {
} }
} }
/** Add or remove CSS class
* @param HTMLElement
* @param string
* @param [bool]
*/
function alterClass(el, className, enable) {
if (el) {
el.className = el.className.replace(RegExp('(^|\\s)' + className + '(\\s|$)'), '$2') + (enable ? ' ' + className : '');
}
}
/** /**
* Toggles visibility of element with ID. * Toggles visibility of element with ID.
* *
@@ -110,14 +99,14 @@ function cookie(assign, days) {
/** /**
* Verifies current Adminer version. * Verifies current Adminer version.
* *
* @param currentVersion string
* @param baseUrl string * @param baseUrl string
* @param token string * @param token string
*/ */
function verifyVersion(currentVersion, baseUrl, token) { function verifyVersion(baseUrl, token) {
// Dummy value to prevent repeated verifications after AJAX failure.
cookie('adminer_version=0', 1); cookie('adminer_version=0', 1);
ajax('https://api.github.com/repos/pematon/adminer/releases/latest', function (request) { ajax('https://api.github.com/repos/pematon/adminer/releases/latest', (request) => {
const response = JSON.parse(request.responseText); const response = JSON.parse(request.responseText);
const version = response.tag_name.replace(/^\D*/, ''); const version = response.tag_name.replace(/^\D*/, '');
@@ -126,12 +115,8 @@ function verifyVersion(currentVersion, baseUrl, token) {
cookie('adminer_version=' + version, 1); cookie('adminer_version=' + version, 1);
const data = 'version=' + version + '&token=' + token; const data = 'version=' + version + '&token=' + token;
ajax(baseUrl + 'script=version', function () {}, data); ajax(baseUrl + 'script=version', null, data);
}, null, null, true);
if (currentVersion !== version) {
qs('#version').innerText = version;
}
});
} }
/** Get value of select /** Get value of select
@@ -173,7 +158,7 @@ function parentTag(el, tag) {
*/ */
function trCheck(el) { function trCheck(el) {
var tr = parentTag(el, 'tr'); var tr = parentTag(el, 'tr');
alterClass(tr, 'checked', el.checked); tr.classList.toggle('checked', el.checked);
if (el.form && el.form['all'] && el.form['all'].onclick) { // Opera treats form.all as document.all if (el.form && el.form['all'] && el.form['all'].onclick) { // Opera treats form.all as document.all
el.form['all'].onclick(); el.form['all'].onclick();
} }
@@ -186,7 +171,7 @@ function trCheck(el) {
*/ */
function selectCount(id, count) { function selectCount(id, count) {
setHtml(id, (count === '' ? '' : '(' + (count + '').replace(/\B(?=(\d{3})+$)/g, thousandsSeparator) + ')')); setHtml(id, (count === '' ? '' : '(' + (count + '').replace(/\B(?=(\d{3})+$)/g, thousandsSeparator) + ')'));
var el = qs('#' + id); var el = gid(id);
if (el) { if (el) {
var inputs = qsa('input', el.parentNode.parentNode); var inputs = qsa('input', el.parentNode.parentNode);
for (var i = 0; i < inputs.length; i++) { for (var i = 0; i < inputs.length; i++) {
@@ -259,7 +244,7 @@ function formChecked(el, name) {
* @param [boolean] force click * @param [boolean] force click
*/ */
function tableClick(event, click) { function tableClick(event, click) {
var td = parentTag(getTarget(event), 'td'); var td = parentTag(event.target, 'td');
var text; var text;
if (td && (text = td.getAttribute('data-text'))) { if (td && (text = td.getAttribute('data-text'))) {
if (selectClick.call(td, event, +text, td.getAttribute('data-warning'))) { if (selectClick.call(td, event, +text, td.getAttribute('data-warning'))) {
@@ -267,7 +252,7 @@ function tableClick(event, click) {
} }
} }
click = (click || !window.getSelection || getSelection().isCollapsed); click = (click || !window.getSelection || getSelection().isCollapsed);
var el = getTarget(event); var el = event.target;
while (!isTag(el, 'tr')) { while (!isTag(el, 'tr')) {
if (isTag(el, 'table|a|input|textarea')) { if (isTag(el, 'table|a|input|textarea')) {
if (el.type !== 'checkbox') { if (el.type !== 'checkbox') {
@@ -374,7 +359,7 @@ function initTablesFilter(dbName) {
if (sessionStorage) { if (sessionStorage) {
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
if (dbName === sessionStorage.getItem('adminer_tables_filter_db') && sessionStorage.getItem('adminer_tables_filter')) { if (dbName === sessionStorage.getItem('adminer_tables_filter_db') && sessionStorage.getItem('adminer_tables_filter')) {
qs('#tables-filter').value = sessionStorage.getItem('adminer_tables_filter'); gid('tables-filter').value = sessionStorage.getItem('adminer_tables_filter');
filterTables(); filterTables();
} else { } else {
sessionStorage.removeItem('adminer_tables_filter'); sessionStorage.removeItem('adminer_tables_filter');
@@ -384,7 +369,7 @@ function initTablesFilter(dbName) {
}); });
} }
const filterInput = qs('#tables-filter'); const filterInput = gid('tables-filter');
filterInput.addEventListener('input', function () { filterInput.addEventListener('input', function () {
window.clearTimeout(tablesFilterTimeout); window.clearTimeout(tablesFilterTimeout);
tablesFilterTimeout = window.setTimeout(filterTables, 200); tablesFilterTimeout = window.setTimeout(filterTables, 200);
@@ -401,7 +386,7 @@ function initTablesFilter(dbName) {
} }
function filterTables() { function filterTables() {
const value = qs('#tables-filter').value.toLowerCase(); const value = gid('tables-filter').value.toLowerCase();
if (value === tablesFilterValue) { if (value === tablesFilterValue) {
return; return;
} }
@@ -445,7 +430,7 @@ function filterTables() {
* @this HTMLElement * @this HTMLElement
*/ */
function menuOver(event) { function menuOver(event) {
var a = getTarget(event); var a = event.target;
if (isTag(a, 'a|span') && a.offsetLeft + a.offsetWidth > a.parentNode.offsetWidth - 15) { // 15 - ellipsis if (isTag(a, 'a|span') && a.offsetLeft + a.offsetWidth > a.parentNode.offsetWidth - 15) { // 15 - ellipsis
this.style.overflow = 'visible'; this.style.overflow = 'visible';
} }
@@ -495,10 +480,8 @@ function selectAddRow(event) {
} }
} }
const buttons = qsa('.icon', row); const button = qs('.remove', row);
for (const button of buttons) { button.onclick = selectRemoveRow;
button.onclick = selectRemoveRow;
}
const parent = field.parentNode.parentNode; const parent = field.parentNode.parentNode;
if (parent.classList.contains("sortable")) { if (parent.classList.contains("sortable")) {
@@ -544,13 +527,13 @@ function selectSearchSearch() {
// Sorting. // Sorting.
(function() { (function() {
let placeholderRow, nextRow, dragHelper; let placeholderRow = null, nextRow = null, dragHelper = null;
let startY, minY, maxY; let startY, minY, maxY;
/** /**
* Initializes sortable list of DIV elements. * Initializes sortable list of DIV elements.
* *
* @param {string} parentId * @param {string} parentSelector
*/ */
window.initSortable = function(parentSelector) { window.initSortable = function(parentSelector) {
const parent = qs(parentSelector); const parent = qs(parentSelector);
@@ -572,65 +555,73 @@ function selectSearchSearch() {
row.classList.remove("no-sort"); row.classList.remove("no-sort");
const handle = qs(".handle", row); const handle = qs(".handle", row);
handle.addEventListener("mousedown", (event) => { handle.addEventListener("mousedown", (event) => { startSorting(row, event) });
event.preventDefault(); handle.addEventListener("touchstart", (event) => { startSorting(row, event) });
const parent = row.parentNode;
startY = event.clientY - getOffsetTop(row);
minY = getOffsetTop(parent);
maxY = minY + parent.offsetHeight - row.offsetHeight;
placeholderRow = row.cloneNode(true);
placeholderRow.classList.add("placeholder");
parent.insertBefore(placeholderRow, row);
nextRow = row.nextElementSibling;
let top = event.clientY - startY;
let left = getOffsetLeft(row);
let width = row.getBoundingClientRect().width;
if (row.tagName === "TR") {
const firstChild = row.firstElementChild;
const borderWidth = (firstChild.offsetWidth - firstChild.clientWidth) / 2;
const borderHeight = (firstChild.offsetHeight - firstChild.clientHeight) / 2;
minY -= borderHeight;
maxY -= borderHeight;
top -= borderHeight;
left -= borderWidth;
width += 2 * borderWidth;
for (const child of row.children) {
child.style.width = child.getBoundingClientRect().width + "px";
}
dragHelper = document.createElement("table");
dragHelper.appendChild(row);
} else {
dragHelper = row;
}
dragHelper.style.top = `${top}px`;
dragHelper.style.left = `${left}px`;
dragHelper.style.width = `${width}px`;
dragHelper.classList.add("dragging");
document.body.appendChild(dragHelper);
window.addEventListener("mousemove", updateSorting);
window.addEventListener("mouseup", () => {
dragHelper.classList.remove("dragging");
parent.insertBefore(dragHelper.tagName === "TABLE" ? dragHelper.firstChild : dragHelper, placeholderRow);
placeholderRow.remove();
window.removeEventListener("mousemove", updateSorting);
}, { once: true });
});
}; };
window.isSorting = function () {
return dragHelper !== null;
};
function startSorting(row, event) {
event.preventDefault();
const pointerY = getPointerY(event);
const parent = row.parentNode;
startY = pointerY - getOffsetTop(row);
minY = getOffsetTop(parent);
maxY = minY + parent.offsetHeight - row.offsetHeight;
placeholderRow = row.cloneNode(true);
placeholderRow.classList.add("placeholder");
parent.insertBefore(placeholderRow, row);
nextRow = row.nextElementSibling;
let top = pointerY - startY;
let left = getOffsetLeft(row);
let width = row.getBoundingClientRect().width;
if (row.tagName === "TR") {
const firstChild = row.firstElementChild;
const borderWidth = (firstChild.offsetWidth - firstChild.clientWidth) / 2;
const borderHeight = (firstChild.offsetHeight - firstChild.clientHeight) / 2;
minY -= borderHeight;
maxY -= borderHeight;
top -= borderHeight;
left -= borderWidth;
width += 2 * borderWidth;
for (const child of row.children) {
child.style.width = child.getBoundingClientRect().width + "px";
}
dragHelper = document.createElement("table");
dragHelper.appendChild(row);
} else {
dragHelper = row;
}
dragHelper.style.top = `${top}px`;
dragHelper.style.left = `${left}px`;
dragHelper.style.width = `${width}px`;
dragHelper.classList.add("dragging");
document.body.appendChild(dragHelper);
window.addEventListener("mousemove", updateSorting);
window.addEventListener("touchmove", updateSorting);
window.addEventListener("mouseup", finishSorting);
window.addEventListener("touchend", finishSorting);
window.addEventListener("touchcancel", finishSorting);
}
function updateSorting(event) { function updateSorting(event) {
let top = Math.min(Math.max(event.clientY - startY, minY), maxY); const pointerY = getPointerY(event);
let top = Math.min(Math.max(pointerY - startY, minY), maxY);
dragHelper.style.top = `${top}px`; dragHelper.style.top = `${top}px`;
const parent = placeholderRow.parentNode; const parent = placeholderRow.parentNode;
@@ -656,6 +647,34 @@ function selectSearchSearch() {
} }
} }
} }
function finishSorting() {
dragHelper.classList.remove("dragging");
dragHelper.style.top = null;
dragHelper.style.left = null;
dragHelper.style.width = null;
placeholderRow.parentNode.insertBefore(dragHelper.tagName === "TABLE" ? dragHelper.firstChild : dragHelper, placeholderRow);
placeholderRow.remove();
placeholderRow = nextRow = dragHelper = null;
window.removeEventListener("mousemove", updateSorting);
window.removeEventListener("touchmove", updateSorting);
window.removeEventListener("mouseup", finishSorting);
window.removeEventListener("touchend", finishSorting);
window.removeEventListener("touchcancel", finishSorting);
}
function getPointerY(event) {
if (event.type.includes("touch")) {
const touch = event.touches[0] || event.changedTouches[0];
return touch.clientY;
} else {
return event.clientY;
}
}
})(); })();
@@ -681,7 +700,7 @@ function columnMouse(className) {
* @return boolean false * @return boolean false
*/ */
function selectSearch(name) { function selectSearch(name) {
var el = qs('#fieldset-search'); var el = gid('fieldset-search');
el.className = ''; el.className = '';
var divs = qsa('div', el); var divs = qsa('div', el);
for (var i=0; i < divs.length; i++) { for (var i=0; i < divs.length; i++) {
@@ -708,16 +727,6 @@ function isCtrl(event) {
return (event.ctrlKey || event.metaKey) && !event.altKey; // shiftKey allowed return (event.ctrlKey || event.metaKey) && !event.altKey; // shiftKey allowed
} }
/** Return event target
* @param Event
* @return HTMLElement
*/
function getTarget(event) {
return event.target || event.srcElement;
}
/** Send form by Ctrl+Enter on <select> and <textarea> /** Send form by Ctrl+Enter on <select> and <textarea>
* @param KeyboardEvent * @param KeyboardEvent
* @param [string] * @param [string]
@@ -725,7 +734,7 @@ function getTarget(event) {
*/ */
function bodyKeydown(event, button) { function bodyKeydown(event, button) {
eventStop(event); eventStop(event);
var target = getTarget(event); var target = event.target;
if (target.jushTextarea) { if (target.jushTextarea) {
target = target.jushTextarea; target = target.jushTextarea;
} }
@@ -749,7 +758,7 @@ function bodyKeydown(event, button) {
* @param MouseEvent * @param MouseEvent
*/ */
function bodyClick(event) { function bodyClick(event) {
var target = getTarget(event); var target = event.target;
if ((isCtrl(event) || event.shiftKey) && target.type === 'submit' && isTag(target, 'input')) { if ((isCtrl(event) || event.shiftKey) && target.type === 'submit' && isTag(target, 'input')) {
target.form.target = '_blank'; target.form.target = '_blank';
setTimeout(function () { setTimeout(function () {
@@ -767,7 +776,7 @@ function bodyClick(event) {
*/ */
function editingKeydown(event) { function editingKeydown(event) {
if ((event.keyCode === 40 || event.keyCode === 38) && isCtrl(event)) { // 40 - Down, 38 - Up if ((event.keyCode === 40 || event.keyCode === 38) && isCtrl(event)) { // 40 - Down, 38 - Up
var target = getTarget(event); var target = event.target;
var sibling = (event.keyCode === 40 ? 'nextSibling' : 'previousSibling'); var sibling = (event.keyCode === 40 ? 'nextSibling' : 'previousSibling');
var el = target.parentNode.parentNode[sibling]; var el = target.parentNode.parentNode[sibling];
if (el && (isTag(el, 'tr') || (el = el[sibling])) && isTag(el, 'tr') && (el = el.childNodes[nodePosition(target.parentNode)]) && (el = el.childNodes[nodePosition(target)])) { if (el && (isTag(el, 'tr') || (el = el[sibling])) && isTag(el, 'tr') && (el = el.childNodes[nodePosition(target.parentNode)]) && (el = el.childNodes[nodePosition(target)])) {
@@ -792,7 +801,6 @@ function functionChange() {
// Undefined with the set data type. // Undefined with the set data type.
if (!input) { if (!input) {
helpClose();
return; return;
} }
@@ -822,8 +830,6 @@ function functionChange() {
} }
oninput({target: input}); oninput({target: input});
helpClose();
} }
/** /**
@@ -857,41 +863,51 @@ function fieldChange() {
/** Create AJAX request /**
* @param string * Sends AJAX request.
* @param function (XMLHttpRequest) *
* @param [string] * @param {string} url
* @param [string] * @param {function|null} onSuccess (XMLHttpRequest)
* @return XMLHttpRequest or false in case of an error * @param {string|null} data POST data.
* @uses offlineMessage * @param {string|null} progressMessage
*/ * @param {boolean} failSilently
function ajax(url, callback, data, message) { * @return XMLHttpRequest or false in case of an error
var request = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : false)); * @uses offlineMessage
if (request) { */
var ajaxStatus = qs('#ajaxstatus'); function ajax(url, onSuccess = null, data = null, progressMessage = null, failSilently = false) {
if (message) { const ajaxStatus = gid('ajaxstatus');
ajaxStatus.innerHTML = '<div class="message">' + message + '</div>';
ajaxStatus.className = ajaxStatus.className.replace(/ hidden/g, ''); if (progressMessage) {
} else { ajaxStatus.innerHTML = '<div class="message">' + progressMessage + '</div>';
ajaxStatus.className += ' hidden'; ajaxStatus.classList.remove("hidden");
} } else {
request.open((data ? 'POST' : 'GET'), url); ajaxStatus.classList.add("hidden");
if (data) {
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (/^2/.test(request.status)) {
callback(request);
} else {
ajaxStatus.innerHTML = (request.status ? request.responseText : '<div class="error">' + offlineMessage + '</div>');
ajaxStatus.className = ajaxStatus.className.replace(/ hidden/g, '');
}
}
};
request.send(data);
} }
const request = new XMLHttpRequest();
request.open((data ? 'POST' : 'GET'), url);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
if (data) {
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 300) {
if (onSuccess) {
onSuccess(request);
}
} else if (failSilently) {
console.error(request.status ? request.responseText : "No internet connection");
} else {
ajaxStatus.innerHTML = (request.status ? request.responseText : '<div class="error">' + offlineMessage + '</div>');
ajaxStatus.classList.remove("hidden");
}
}
};
request.send(data);
return request; return request;
} }
@@ -938,9 +954,9 @@ function ajaxForm(form, message, button) {
return ajax(url, function (request) { return ajax(url, function (request) {
setHtml('ajaxstatus', request.responseText); setHtml('ajaxstatus', request.responseText);
if (window.jush) { if (window.jush) {
jush.highlight_tag(qsa('code', qs('#ajaxstatus')), 0); jush.highlight_tag(qsa('code', gid('ajaxstatus')), 0);
} }
messagesPrint(qs('#ajaxstatus')); messagesPrint(gid('ajaxstatus'));
}, data, message); }, data, message);
} }
@@ -955,7 +971,7 @@ function ajaxForm(form, message, button) {
*/ */
function selectClick(event, text, warning) { function selectClick(event, text, warning) {
var td = this; var td = this;
var target = getTarget(event); var target = event.target;
if (!isCtrl(event) || isTag(td.firstChild, 'input|textarea') || isTag(target, 'a')) { if (!isCtrl(event) || isTag(td.firstChild, 'input|textarea') || isTag(target, 'a')) {
return; return;
} }
@@ -1042,7 +1058,7 @@ function selectLoadMore(limit, loading) {
return !ajax(href, function (request) { return !ajax(href, function (request) {
var tbody = document.createElement('tbody'); var tbody = document.createElement('tbody');
tbody.innerHTML = request.responseText; tbody.innerHTML = request.responseText;
qs('#table').appendChild(tbody); gid('table').appendChild(tbody);
if (tbody.children.length < limit) { if (tbody.children.length < limit) {
a.parentNode.removeChild(a); a.parentNode.removeChild(a);
} else { } else {
@@ -1096,9 +1112,9 @@ function setupSubmitHighlightInput(input) {
* @this HTMLInputElement * @this HTMLInputElement
*/ */
function inputFocus() { function inputFocus() {
var submit = findDefaultSubmit(this); const submit = findDefaultSubmit(this);
if (submit) { if (submit) {
alterClass(submit, 'default', true); submit.classList.toggle('default', true);
} }
} }
@@ -1106,16 +1122,18 @@ function inputFocus() {
* @this HTMLInputElement * @this HTMLInputElement
*/ */
function inputBlur() { function inputBlur() {
var submit = findDefaultSubmit(this); const submit = findDefaultSubmit(this);
if (submit) { if (submit) {
alterClass(submit, 'default'); submit.classList.toggle('default', false);
} }
} }
/** Find submit button used by Enter /**
* @param HTMLElement * Finds submit button used by Enter.
* @return HTMLInputElement *
*/ * @param {HTMLElement} el
* @return {HTMLInputElement}
*/
function findDefaultSubmit(el) { function findDefaultSubmit(el) {
if (el.jushTextarea) { if (el.jushTextarea) {
el = el.jushTextarea; el = el.jushTextarea;
@@ -1123,10 +1141,10 @@ function findDefaultSubmit(el) {
if (!el.form) { if (!el.form) {
return null; return null;
} }
var inputs = qsa('input', el.form);
for (var i = 0; i < inputs.length; i++) { const inputs = qsa('input', el.form);
var input = inputs[i]; for (const input of inputs) {
if (input.type === 'submit' && !input.style.zIndex) { if (input.type === 'submit' && !input.classList.contains("wayoff") && !input.style.zIndex) {
return input; return input;
} }
} }
@@ -1190,7 +1208,9 @@ function getOffsetLeft(element) {
} }
oninput = function (event) { oninput = function (event) {
var target = event.target; const target = event.target;
var maxLength = target.getAttribute('data-maxlength'); const maxLength = target.getAttribute('data-maxlength');
alterClass(target, 'maxlength', target.value && maxLength != null && target.value.length > maxLength); // maxLength could be 0
// maxLength could be 0
target.classList.toggle('maxlength', target.value && maxLength != null && target.value.length > maxLength);
}; };

View File

@@ -40,7 +40,7 @@ page_header(($name != "" ? lang('Alter trigger') . ": " . h($name) : lang('Creat
<tr><th><?php echo lang('Type'); ?><td><?php echo html_select("Type", $trigger_options["Type"], $row["Type"]); ?> <tr><th><?php echo lang('Type'); ?><td><?php echo html_select("Type", $trigger_options["Type"], $row["Type"]); ?>
</table> </table>
<p><?php echo lang('Name'); ?>: <input name="Trigger" value="<?php echo h($row["Trigger"]); ?>" data-maxlength="64" autocapitalize="off"> <p><?php echo lang('Name'); ?>: <input name="Trigger" value="<?php echo h($row["Trigger"]); ?>" data-maxlength="64" autocapitalize="off">
<?php echo script("qs('#form')['Timing'].onchange();"); ?> <?php echo script("gid('form')['Timing'].onchange();"); ?>
<p><?php textarea("Statement", $row["Statement"]); ?> <p><?php textarea("Statement", $row["Statement"]); ?>
<p> <p>
<input type="submit" value="<?php echo lang('Save'); ?>"> <input type="submit" value="<?php echo lang('Save'); ?>">

View File

@@ -142,7 +142,7 @@ if ($_POST) {
<tr><th><?php echo lang('Server'); ?><td><input name="host" data-maxlength="60" value="<?php echo h($row["host"]); ?>" autocapitalize="off"> <tr><th><?php echo lang('Server'); ?><td><input name="host" data-maxlength="60" value="<?php echo h($row["host"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Username'); ?><td><input name="user" data-maxlength="80" value="<?php echo h($row["user"]); ?>" autocapitalize="off"> <tr><th><?php echo lang('Username'); ?><td><input name="user" data-maxlength="80" value="<?php echo h($row["user"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Password'); ?><td><input name="pass" id="pass" value="<?php echo h($row["pass"]); ?>" autocomplete="new-password"> <tr><th><?php echo lang('Password'); ?><td><input name="pass" id="pass" value="<?php echo h($row["pass"]); ?>" autocomplete="new-password">
<?php if (!$row["hashed"]) { echo script("typePassword(qs('#pass'));"); } ?> <?php if (!$row["hashed"]) { echo script("typePassword(gid('pass'));"); } ?>
<?php echo (min_version(8) ? "" : checkbox("hashed", 1, $row["hashed"], lang('Hashed'), "typePassword(this.form['pass'], this.checked);")); ?> <?php echo (min_version(8) ? "" : checkbox("hashed", 1, $row["hashed"], lang('Hashed'), "typePassword(this.form['pass'], this.checked);")); ?>
</table> </table>

View File

@@ -6,9 +6,18 @@ function adminer_errors($errno, $errstr) {
error_reporting(6135); // errors and warnings error_reporting(6135); // errors and warnings
set_error_handler('adminer_errors', E_WARNING); set_error_handler('adminer_errors', E_WARNING);
include dirname(__FILE__) . "/adminer/include/debug.inc.php";
include dirname(__FILE__) . "/adminer/include/version.inc.php"; include dirname(__FILE__) . "/adminer/include/version.inc.php";
include dirname(__FILE__) . "/vendor/vrana/jsshrink/jsShrink.php"; include dirname(__FILE__) . "/vendor/vrana/jsshrink/jsShrink.php";
function is_dev_version()
{
global $VERSION;
return (bool)preg_match('~-dev$~', $VERSION);
}
function add_apo_slashes($s) { function add_apo_slashes($s) {
return addcslashes($s, "\\'"); return addcslashes($s, "\\'");
} }
@@ -21,85 +30,85 @@ function add_quo_slashes($s) {
return $return; return $return;
} }
function remove_lang($match) { function replace_lang($match) {
global $translations;
$idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
$s = ($translations[$idf] ? $translations[$idf] : $idf);
if ($match[3] == ",") { // lang() has parameters
return $match[1] . (is_array($s) ? "lang(array('" . implode("', '", array_map('add_apo_slashes', $s)) . "')," : "sprintf('" . add_apo_slashes($s) . "',");
}
return ($match[1] && $match[4] ? $s : "$match[1]'" . add_apo_slashes($s) . "'$match[4]");
}
function lang_ids($match) {
global $lang_ids; global $lang_ids;
$lang_id = &$lang_ids[stripslashes($match[1])];
if ($lang_id === null) { $text = stripslashes($match[1]);
$lang_id = count($lang_ids) - 1; if (!isset($lang_ids[$text])) {
$lang_ids[$text] = count($lang_ids);
} }
return ($_SESSION["lang"] ? $match[0] : "lang($lang_id$match[2]");
return "lang($lang_ids[$text]$match[2]";
} }
function put_file($match) { function put_file($match) {
global $project, $VERSION, $driver; global $project, $selected_languages, $single_driver;
if (basename($match[2]) == '$LANG.inc.php') {
return $match[0]; // processed later
}
$return = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
if (basename($match[2]) == "file.inc.php") {
$return = str_replace("\n// caching headers added in compile.php", (preg_match('~-dev$~', $VERSION) ? '' : '
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
header("HTTP/1.1 304 Not Modified");
exit;
}
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT"); $filename = basename($match[2]);
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: immutable"); // Language is processed later.
'), $return, $count); if ($filename == '$LANG.inc.php') {
return $match[0];
}
$content = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
if ($filename == "file.inc.php") {
$content = str_replace("\n// caching headers added in compile.php", (is_dev_version() ? '' : '
if ($_SERVER["HTTP_IF_MODIFIED_SINCE"]) {
header("HTTP/1.1 304 Not Modified");
exit;
}
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 365*24*60*60) . " GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: immutable");
'), $content, $count);
if (!$count) { if (!$count) {
echo "adminer/file.inc.php: Caching headers placeholder not found\n"; echo "adminer/file.inc.php: Caching headers placeholder not found\n";
} }
} }
if ($driver && dirname($match[2]) == "../adminer/drivers") {
$return = preg_replace('~^if \(isset\(\$_GET\["' . $driver . '"]\)\) \{(.*)^}~ms', '\1', $return);
}
if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
if (basename($match[2]) == "lang.inc.php") {
$return = str_replace('function lang($idf, $number = null) {', 'function lang($idf, $number = null) {
if (is_string($idf)) { // compiled version uses numbers, string comes from a plugin
// English translation is closest to the original identifiers //! pluralized translations are not found
$pos = array_search($idf, get_translations("en")); //! this should be cached
if ($pos !== false) {
$idf = $pos;
}
}', $return, $count);
if (!$count) {
echo "lang() not found\n";
}
}
$tokens = token_get_all($return); // to find out the last token
return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
} elseif (preg_match('~\s*(\$pos = (.+\n).+;)~sU', $return, $match2)) {
// single language lang() is used for plural
return "function get_lang() {
return '$_SESSION[lang]';
}
function lang(\$translation, \$number = null) { if ($filename == "lang.inc.php") {
if (is_array(\$translation)) { $content = str_replace(
\$pos = $match2[2]\t\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . ' 'return $key; // compile: convert translation key',
'static $en_translations = null;
// Convert string key used in plugins to compiled numeric key.
if (is_string($key)) {
if (!$en_translations) {
$en_translations = get_translations("en");
}
// Find text in English translations or plurals map.
if (($index = array_search($key, $en_translations)) !== false) {
$key = $index;
} elseif (($index = get_plural_translation_id($key)) !== null) {
$key = $index;
}
}
return $key;',
$content, $count
); );
$translation = $translation[$pos];
} if (!$count) {
$translation = str_replace("%d", "%s", $translation); echo "function lang() not found\n";
$number = format_number($number); }
return sprintf($translation, $number);
} if ($selected_languages) {
'; $available_languages = array_fill_keys($selected_languages, true);
} else { $content = str_replace(
echo "lang() \$pos not found\n"; 'return $languages; // compile: available languages',
'return ' . var_export($available_languages, true) . ';',
$content
);
}
} }
$tokens = token_get_all($content); // to find out the last token
return "?>\n$content" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
} }
function lzw_compress($string) { function lzw_compress($string) {
@@ -139,45 +148,73 @@ function lzw_compress($string) {
return $return . ($rest_length ? chr($rest << (8 - $rest_length)) : ""); return $return . ($rest_length ? chr($rest << (8 - $rest_length)) : "");
} }
function put_file_lang($match) { function put_file_lang() {
global $lang_ids, $project, $langs; global $lang_ids, $selected_languages;
if ($_SESSION["lang"]) {
return ""; $languages = array_map(function ($filename) {
} preg_match('~/([^/.]+)\.inc\.php$~', $filename, $matches);
$return = ""; return $matches[1];
foreach ($langs as $lang => $val) { }, glob(dirname(__FILE__) . "/adminer/lang/*.inc.php"));
include dirname(__FILE__) . "/adminer/lang/$lang.inc.php"; // assign $translations
$cases = "";
$plurals_map = [];
foreach ($languages as $language) {
// Include only selected language and "en" into single language compilation.
// "en" is used for translations in plugins.
if ($selected_languages && !in_array($language, $selected_languages) && $language != "en") {
continue;
}
// Assign $translations
$translations = [];
include dirname(__FILE__) . "/adminer/lang/$language.inc.php";
$translation_ids = array_flip($lang_ids); // default translation $translation_ids = array_flip($lang_ids); // default translation
foreach ($translations as $key => $val) { foreach ($translations as $key => $val) {
if ($val !== null) { if ($val !== null) {
$translation_ids[$lang_ids[$key]] = implode("\t", (array) $val); $translation_ids[$lang_ids[$key]] = $val;
if ($language == "en" && is_array($val)) {
$plurals_map[$key] = $lang_ids[$key];
}
} }
} }
$return .= '
case "' . $lang . '": $compressed = "' . add_quo_slashes(lzw_compress(implode("\n", $translation_ids))) . '"; break;';
}
$translations_version = crc32($return);
return '$translations = $_SESSION["translations"];
if ($_SESSION["translations_version"] != ' . $translations_version . ') {
$translations = array();
$_SESSION["translations_version"] = ' . $translations_version . ';
}
function get_translations($lang) { $cases .= 'case "' . $language . '": $compressed = "' . add_quo_slashes(lzw_compress(json_encode($translation_ids, JSON_UNESCAPED_UNICODE))) . '"; break;';
switch ($lang) {' . $return . '
} }
$translations = array();
foreach (explode("\n", lzw_decompress($compressed)) as $val) {
$translations[] = (strpos($val, "\t") ? explode("\t", $val) : $val);
}
return $translations;
}
if (!$translations) { $translations_version = crc32($cases);
$translations = get_translations($LANG);
$_SESSION["translations"] = $translations; return '
} function get_translations($lang) {
'; switch ($lang) {' . $cases . '}
return json_decode(lzw_decompress($compressed), true);
}
function get_plural_translation_id($key) {
$plurals_map = ' . var_export($plurals_map, true) . ';
return isset($plurals_map[$key]) ? $plurals_map[$key] : null;
}
$translations = $_SESSION["translations"];
if ($_SESSION["translations_version"] != ' . $translations_version . ') {
$translations = [];
$_SESSION["translations_version"] = ' . $translations_version . ';
}
if ($_SESSION["translations_language"] != $LANG) {
$translations = [];
$_SESSION["translations_language"] = $LANG;
}
if (!$translations) {
$translations = get_translations($LANG);
$_SESSION["translations"] = $translations;
}
';
} }
function short_identifier($number, $chars) { function short_identifier($number, $chars) {
@@ -224,7 +261,7 @@ function php_shrink($input) {
} }
$tokens = array_values($tokens); $tokens = array_values($tokens);
foreach ($tokens as $i => $token) { foreach ($tokens as $token) {
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) { if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$short_variables[$token[1]]++; $short_variables[$token[1]]++;
} }
@@ -258,7 +295,7 @@ function php_shrink($input) {
$tokens[$i+4] = array(0, ';'); $tokens[$i+4] = array(0, ';');
} }
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) { if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
$space = "\n"; $space = " ";
} else { } else {
if ($token[0] == T_DOC_COMMENT) { if ($token[0] == T_DOC_COMMENT) {
$doc_comment = true; $doc_comment = true;
@@ -287,9 +324,13 @@ function php_shrink($input) {
} elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) { } elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
$token[1] = '$' . $short_variables[$token[1]]; $token[1] = '$' . $short_variables[$token[1]];
} }
if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
if ($token[0] == T_FUNCTION || $token[0] == T_CLASS || $token[0] == T_INTERFACE || $token[0] == T_TRAIT) {
$space = "\n";
} elseif (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
$space = ''; $space = '';
} }
$output .= $space . $token[1]; $output .= $space . $token[1];
$space = ''; $space = '';
} }
@@ -340,60 +381,78 @@ function number_type() {
} }
$project = "adminer"; $project = "adminer";
if ($_SERVER["argv"][1] == "editor") { array_shift($argv);
if ($argv[0] == "editor") {
$project = "editor"; $project = "editor";
array_shift($_SERVER["argv"]); array_shift($argv);
} }
$driver = ""; $selected_drivers = [];
if (file_exists(dirname(__FILE__) . "/adminer/drivers/" . $_SERVER["argv"][1] . ".inc.php")) { if ($argv) {
$driver = $_SERVER["argv"][1]; $params = explode(",", $argv[0]);
array_shift($_SERVER["argv"]); if (file_exists(dirname(__FILE__) . "/adminer/drivers/" . $params[0] . ".inc.php")) {
$selected_drivers = $params;
array_shift($argv);
}
} }
$single_driver = count($selected_drivers) == 1 ? $selected_drivers[0] : null;
unset($_COOKIE["adminer_lang"]); $selected_languages = [];
$_SESSION["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from session if ($argv) {
include dirname(__FILE__) . "/adminer/include/lang.inc.php"; $params = explode(",", $argv[0]);
if (isset($langs[$_SESSION["lang"]])) { if (file_exists(dirname(__FILE__) . "/adminer/lang/" . $params[0] . ".inc.php")) {
include dirname(__FILE__) . "/adminer/lang/$_SESSION[lang].inc.php"; $selected_languages = $params;
array_shift($_SERVER["argv"]); array_shift($argv);
}
} }
$single_language = count($selected_languages) == 1 ? $selected_languages[0] : null;
if ($_SERVER["argv"][1]) { if ($argv) {
echo "Usage: php compile.php [editor] [driver] [lang]\n"; echo "Usage: php compile.php [editor] [driver] [language]\n";
echo "Purpose: Compile adminer[-driver][-lang].php or editor[-driver][-lang].php.\n"; echo "Purpose: Compile adminer[-driver][-lang].php or editor[-driver][-lang].php.\n";
exit(1); exit(1);
} }
// check function definition in drivers // Check function definition in drivers.
$file = file_get_contents(dirname(__FILE__) . "/adminer/drivers/mysql.inc.php"); $file = file_get_contents(dirname(__FILE__) . "/adminer/drivers/mysql.inc.php");
$file = preg_replace('~class Min_Driver.*\n\t}~sU', '', $file); $file = preg_replace('~class Min_Driver.*\n\t}~sU', '', $file);
preg_match_all('~\bfunction ([^(]+)~', $file, $matches); //! respect context (extension, class) preg_match_all('~\bfunction ([^(]+)~', $file, $matches); //! respect context (extension, class)
$functions = array_combine($matches[1], $matches[0]); $functions = array_combine($matches[1], $matches[0]);
//! do not warn about functions without declared support() //! do not warn about functions without declared support()
unset($functions["__construct"], $functions["__destruct"], $functions["set_charset"]); unset($functions["__construct"], $functions["__destruct"], $functions["set_charset"]);
foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*") . ".inc.php") as $filename) {
if ($filename != "mysql.inc.php") { foreach (glob(dirname(__FILE__) . "/adminer/drivers/*.inc.php") as $filename) {
$file = file_get_contents($filename); preg_match('~/([^/.]+)\.inc\.php$~', $filename, $matches);
foreach ($functions as $val) { if ($matches[1] == "mysql" || ($selected_drivers && !in_array($matches[1], $selected_drivers))) {
if (!strpos($file, "$val(")) { continue;
fprintf(STDERR, "Missing $val in $filename\n"); }
}
$file = file_get_contents($filename);
foreach ($functions as $function) {
if (!strpos($file, "$function(")) {
fprintf(STDERR, "Missing $function in $filename\n");
} }
} }
} }
include dirname(__FILE__) . "/adminer/include/pdo.inc.php"; include dirname(__FILE__) . "/adminer/include/pdo.inc.php";
include dirname(__FILE__) . "/adminer/include/driver.inc.php"; include dirname(__FILE__) . "/adminer/include/driver.inc.php";
$features = array("call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
$lang_ids = array(); // global variable simplifies usage in a callback function $features = ["call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view"];
$lang_ids = []; // global variable simplifies usage in a callback functions
// Start with index.php.
$file = file_get_contents(dirname(__FILE__) . "/$project/index.php"); $file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
if ($driver) {
$_GET[$driver] = true; // to load the driver // Remove including source code for unsupported features in single-driver file.
include_once dirname(__FILE__) . "/adminer/drivers/$driver.inc.php"; if ($single_driver) {
$_GET[$single_driver] = true; // to load the driver
include_once dirname(__FILE__) . "/adminer/drivers/$single_driver.inc.php";
foreach ($features as $key => $feature) { foreach ($features as $key => $feature) {
if (!support($feature)) { if (!support($feature)) {
if (!is_int($key)) { if (is_string($key)) {
$feature = $key; $feature = $key;
} }
$file = str_replace("} elseif (isset(\$_GET[\"$feature\"])) {\n\tinclude \"./$feature.inc.php\";\n", "", $file); $file = str_replace("} elseif (isset(\$_GET[\"$feature\"])) {\n\tinclude \"./$feature.inc.php\";\n", "", $file);
@@ -403,55 +462,70 @@ if ($driver) {
$file = str_replace("if (isset(\$_GET[\"callf\"])) {\n\t\$_GET[\"call\"] = \$_GET[\"callf\"];\n}\nif (isset(\$_GET[\"function\"])) {\n\t\$_GET[\"procedure\"] = \$_GET[\"function\"];\n}\n", "", $file); $file = str_replace("if (isset(\$_GET[\"callf\"])) {\n\t\$_GET[\"call\"] = \$_GET[\"callf\"];\n}\nif (isset(\$_GET[\"function\"])) {\n\t\$_GET[\"procedure\"] = \$_GET[\"function\"];\n}\n", "", $file);
} }
} }
// Compile files included into the index.php.
$file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file); $file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file);
// Remove including debug files.
$file = str_replace('include "../adminer/include/debug.inc.php";', '', $file);
$file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file); $file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file);
if ($driver) {
$file = preg_replace('(include "../adminer/drivers/(?!' . preg_quote($driver) . '\.).*\s*)', '', $file); // Remove including unwanted drivers.
if ($selected_drivers) {
$file = preg_replace_callback('~include "../adminer/drivers/([^.]+).*\n~', function ($match) use ($selected_drivers) {
return in_array($match[1], $selected_drivers) ? $match[0] : "";
}, $file);
} }
$file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file); // bootstrap.inc.php
if ($driver) { // Compile files included into the bootstrap.inc.php.
$file = preg_replace_callback('~\b(include|require) "([^"]*)";~', 'put_file', $file);
if ($single_driver) {
// Remove source code for unsupported features.
foreach ($features as $feature) { foreach ($features as $feature) {
if (!support($feature)) { if (!support($feature)) {
$file = preg_replace("((\t*)" . preg_quote('if (support("' . $feature . '")') . ".*\n\\1\\})sU", '', $file); $file = preg_replace("((\t*)" . preg_quote('if (support("' . $feature . '")') . ".*\n\\1\\})sU", '', $file);
} }
} }
if (count($drivers) == 1) {
$file = str_replace('<?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>', "<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers), $file); $file = preg_replace('(;\.\./vendor/vrana/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($single_driver == "mysql" ? "sql" : $single_driver) . '\.)[^.]+.js)', '', $file);
} $file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($single_driver) {
$file = preg_replace('(;\.\./vendor/vrana/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($driver == "mysql" ? "sql" : $driver) . '\.)[^.]+.js)', '', $file);
$file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($driver) {
list(, $links) = $match; list(, $links) = $match;
$links = preg_replace("~'(?!(" . ($driver == "mysql" ? "sql|mariadb" : $driver) . ")')[^']*' => [^,]*,?~", '', $links); $links = preg_replace("~'(?!(" . ($single_driver == "mysql" ? "sql|mariadb" : $single_driver) . ")')[^']*' => [^,]*,?~", '', $links);
return (trim($links) ? "doc_link(array($links))" : "''"); return (trim($links) ? "doc_link(array($links))" : "''");
}, $file); }, $file);
//! strip doc_link() definition //! strip doc_link() definition
} }
if ($project == "editor") { if ($project == "editor") {
$file = preg_replace('~;\.\./vendor/vrana/jush/jush\.css~', '', $file); $file = preg_replace('~;\.\./vendor/vrana/jush/jush\.css~', '', $file);
$file = preg_replace('~compile_file\(\'\.\./(vendor/vrana/jush/modules/jush\.js|adminer/static/[^.]+\.gif)[^)]+\)~', "''", $file); $file = preg_replace('~compile_file\(\'\.\./(vendor/vrana/jush/modules/jush\.js|adminer/static/[^.]+\.gif)[^)]+\)~', "''", $file);
} }
$file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file);
$file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'replace_lang', $file);
$file = preg_replace_callback('~\b(include|require) "([^"]*\$LANG.inc.php)";~', 'put_file_lang', $file); $file = preg_replace_callback('~\b(include|require) "([^"]*\$LANG.inc.php)";~', 'put_file_lang', $file);
$file = str_replace("\r", "", $file); $file = str_replace("\r", "", $file);
if ($_SESSION["lang"]) { $file = str_replace('<?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>' . "\n", "", $file);
// single language version
$file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file);
$file = str_replace("<?php switch_lang(); ?>\n", "", $file);
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
}
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
$file = preg_replace('~\s+echo script_src\("\.\./vendor/vrana/jush/modules/jush-(textarea|txt|js|\$jush)\.js"\);~', '', $file); $file = preg_replace('~\s+echo script_src\("\.\./vendor/vrana/jush/modules/jush-(textarea|txt|js|\$jush)\.js"\);~', '', $file);
$file = str_replace('<link rel="stylesheet" type="text/css" href="../vendor/vrana/jush/jush.css">' . "\n", "", $file); $file = str_replace('<link rel="stylesheet" type="text/css" href="../vendor/vrana/jush/jush.css">' . "\n", "", $file);
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files $file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . substr(md5(microtime()), 0, 8) . '"'; $replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\1&version=' . substr(md5(microtime()), 0, 8) . '"';
$file = preg_replace('~\.\./adminer/static/(default\.css|favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file); $file = preg_replace('~\.\./adminer/static/(favicon\.ico)~', '<?php echo h(' . $replace . '); ?>', $file);
$file = preg_replace('~"\.\./adminer/static/(functions\.js)"~', $replace, $file); $file = preg_replace('~\.\./adminer/static/(default\.css)\?.*default.css"\);\s+\?>~', '<?php echo h(' . $replace . '); ?>', $file);
$file = preg_replace('~"\.\./adminer/static/(functions\.js)\?".*functions.js"\)~', $replace, $file);
$file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file); $file = preg_replace('~\.\./adminer/static/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
$file = preg_replace('~"\.\./vendor/vrana/jush/modules/(jush\.js)"~', $replace, $file); $file = preg_replace('~"\.\./vendor/vrana/jush/modules/(jush\.js)"~', $replace, $file);
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file); $file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
$file = php_shrink($file); $file = php_shrink($file);
@mkdir("temp/export", 0777, true); @mkdir("temp", 0777, true);
$filename = "temp/export/$project" . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php"; $filename = "temp/$project"
. (is_dev_version() ? "" : "-$VERSION")
. ($single_driver ? "-$single_driver" : "")
. ($single_language ? "-$single_language" : "")
. ".php";
file_put_contents($filename, $file); file_put_contents($filename, $file);
echo "$filename created (" . strlen($file) . " B).\n"; echo "$filename created (" . strlen($file) . " B).\n";

View File

@@ -1,19 +1,22 @@
{ {
"name": "vrana/adminer", "name": "pematon/adminer",
"description": "Database management in a single PHP file.", "description": "Database management in a single PHP file.",
"homepage": "https://www.adminer.org/", "homepage": "https://github.com/pematon/adminer",
"keywords": [ "keywords": [
"database" "database"
], ],
"support": { "support": {
"issues": "https://sourceforge.net/p/adminer/bugs-and-features/", "issues": "https://github.com/pematon/adminer/issues",
"forum": "https://sourceforge.net/p/adminer/discussion/", "forum": "https://github.com/pematon/adminer/discussions",
"source": "https://github.com/vrana/adminer/" "source": "https://github.com/pematon/adminer"
}, },
"authors": [ "authors": [
{ {
"name": "Jakub Vrána", "name": "Jakub Vrána",
"homepage": "https://www.vrana.cz/" "homepage": "https://www.vrana.cz/"
},
{
"name": "Peter Knut"
} }
], ],
"autoload": { "autoload": {
@@ -29,7 +32,7 @@
"php": "5.6 - 8.3", "php": "5.6 - 8.3",
"ext-pdo": "*", "ext-pdo": "*",
"ext-json": "*", "ext-json": "*",
"vrana/jush": "@dev", "vrana/jush": "2.0.*",
"vrana/jsshrink": "@dev" "vrana/jsshrink": "@dev"
}, },
"suggest": { "suggest": {
@@ -39,6 +42,7 @@
"ext-mysql": "*", "ext-mysql": "*",
"ext-pgsql": "*", "ext-pgsql": "*",
"ext-mongo": "*", "ext-mongo": "*",
"ext-mongodb": "*",
"ext-sqlsrv": "*", "ext-sqlsrv": "*",
"ext-mssql": "*", "ext-mssql": "*",
"ext-oci8": "*", "ext-oci8": "*",
@@ -57,7 +61,7 @@
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/vrana/jush.git" "url": "https://github.com/pematon/jush.git"
}, },
{ {
"type": "vcs", "type": "vcs",

14
docs/upgrade.md Normal file
View File

@@ -0,0 +1,14 @@
Upgrade guide
=============
Migrating to 4.10
-----------------
- Remove plugin AdminerTablesFilter (plugins/tables-filter.php) if you use it. Its functionality was integrated into the
base code.
- If you use complex custom theme, you will probably need to adjust a thing or two.
Migrating to 4.9
----------------
- Minimum required PHP version is 5.6.

View File

@@ -11,7 +11,7 @@ if ($adminer->homepage()) {
echo "<table cellspacing='0' class='nowrap checkable'>\n"; echo "<table cellspacing='0' class='nowrap checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});"); echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo '<thead><tr class="wrap">'; echo '<thead><tr class="wrap">';
echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("qs('#check-all').onclick = partial(formCheck, /^tables\[/);", ""); echo '<td><input id="check-all" type="checkbox" class="jsonly">' . script("gid('check-all').onclick = partial(formCheck, /^tables\[/);", "");
echo '<th>' . lang('Table'); echo '<th>' . lang('Table');
echo '<td>' . lang('Rows'); echo '<td>' . lang('Rows');
echo "</thead>\n"; echo "</thead>\n";

View File

@@ -6,7 +6,7 @@ class Adminer {
var $_values = array(); var $_values = array();
function name() { function name() {
return "<a href='https://www.adminer.org/editor/'" . target_blank() . " id='h1'>" . lang('Editor') . "</a>"; return "<a id='h1' href='" . h(HOME_URL) . "'>" . lang('Editor') . "</a>";
} }
//! driver, ns //! driver, ns
@@ -77,7 +77,7 @@ class Adminer {
function loginForm() { function loginForm() {
echo "<table cellspacing='0' class='layout'>\n"; echo "<table cellspacing='0' class='layout'>\n";
echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(qs('#username'));")); echo $this->loginFormField('username', '<tr><th>' . lang('Username') . '<td>', '<input type="hidden" name="auth[driver]" value="mysql"><input name="auth[username]" id="username" value="' . h($_GET["username"]) . '" autocomplete="username" autocapitalize="off">' . script("focus(gid('username'));"));
echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n"); echo $this->loginFormField('password', '<tr><th>' . lang('Password') . '<td>', '<input type="password" name="auth[password]" autocomplete="current-password">' . "\n");
echo "</table>\n"; echo "</table>\n";
echo "<p><input type='submit' value='" . lang('Login') . "'>\n"; echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
@@ -600,18 +600,26 @@ qsl('div').onclick = whisperClick;", "")
function navigation($missing) { function navigation($missing) {
global $VERSION; global $VERSION;
?> ?>
<h1> <h1>
<?php echo $this->name(); ?> <?php echo $this->name(); ?>
<?php if ($missing != "auth"): ?>
<span class="version"> <?php if ($missing != "auth"): ?>
<?php echo $VERSION; ?> <span class="version">
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version"> <?php echo $VERSION; ?>
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?> <a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
</a> <?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
</span> </a>
</span>
<?php
if (!isset($_COOKIE["adminer_version"])) {
echo script("verifyVersion('" . js_escape(ME) . "', '" . get_token() . "');");
}
?>
<?php endif; ?> <?php endif; ?>
</h1> </h1>
<?php <?php
if ($missing == "auth") { if ($missing == "auth") {
$first = true; $first = true;
@@ -620,7 +628,7 @@ qsl('div').onclick = whisperClick;", "")
if ($password !== null) { if ($password !== null) {
if ($first) { if ($first) {
echo "<ul id='logins'>"; echo "<ul id='logins'>";
echo script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});"); echo script("mixin(gid('logins'), {onmouseover: menuOver, onmouseout: menuOut});");
$first = false; $first = false;
} }
echo "<li><a href='" . h(auth_url($vendor, "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a>\n"; echo "<li><a href='" . h(auth_url($vendor, "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a>\n";
@@ -655,7 +663,7 @@ qsl('div').onclick = whisperClick;", "")
} }
function tablesPrint($tables) { function tablesPrint($tables) {
echo "<ul id='tables'>" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});"); echo "<ul id='tables'>" . script("mixin(gid('tables'), {onmouseover: menuOver, onmouseout: menuOut});");
foreach ($tables as $row) { foreach ($tables as $row) {
// Skip views and tables without a name. // Skip views and tables without a name.

View File

@@ -1,11 +1,14 @@
<?php <?php
/** Adminer Editor - Compact database editor /**
* @link https://www.adminer.org/ * Adminer Editor - Compact database editor for end-users
* @author Jakub Vrana, https://www.vrana.cz/ *
* @copyright 2009 Jakub Vrana * @link https://github.com/pematon/adminer
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 * @author Jakub Vrana (https://www.vrana.cz/)
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other) * @author Peter Knut
*/ * @copyright 2009-2021 Jakub Vrana, 2024 Peter Knut
* @license Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
* @license GNU General Public License, version 2 (https://www.gnu.org/licenses/gpl-2.0.html)
*/
include "../adminer/include/bootstrap.inc.php"; include "../adminer/include/bootstrap.inc.php";
$drivers[DRIVER] = lang('Login'); $drivers[DRIVER] = lang('Login');

View File

@@ -5,7 +5,7 @@ function adminer_object() {
class AdminerCustomization extends AdminerPlugin { class AdminerCustomization extends AdminerPlugin {
function loginFormField($name, $heading, $value) { function loginFormField($name, $heading, $value) {
return parent::loginFormField($name, $heading, str_replace('value="server"', 'value="sqlite"', $value)); return parent::loginFormField($name, $heading, str_replace('value="mysql"', 'value="sqlite"', $value));
} }
function database() { function database() {
return "PATH_TO_YOUR_SQLITE_HERE"; return "PATH_TO_YOUR_SQLITE_HERE";

View File

@@ -6,13 +6,14 @@ function messagesPrint() {
function selectFieldChange() { function selectFieldChange() {
} }
var helpOpen; // Help.
(function() {
window.initHelpPopup = function () {
};
function helpMouseover() { window.initHelpFor = function(element, content, side = false) {
} };
})();
function helpMouseout() {
}
/** Display typeahead /** Display typeahead
* @param string * @param string
@@ -42,7 +43,7 @@ function whisper(url) {
*/ */
function whisperClick(event) { function whisperClick(event) {
var field = this.previousSibling; var field = this.previousSibling;
var el = getTarget(event); var el = event.target;
if (isTag(el, 'a') && !(event.button || event.shiftKey || event.altKey || isCtrl(event))) { if (isTag(el, 'a') && !(event.button || event.shiftKey || event.altKey || isCtrl(event))) {
field.value = el.firstChild.data; field.value = el.firstChild.data;
field.previousSibling.value = decodeURIComponent(el.href.replace(/.*=/, '')); field.previousSibling.value = decodeURIComponent(el.href.replace(/.*=/, ''));

View File

@@ -5,7 +5,7 @@ unset($_COOKIE["adminer_lang"]);
$_SESSION["lang"] = isset($_SERVER["argv"][1]) ? $_SERVER["argv"][1] : null; // Adminer functions read language from session $_SESSION["lang"] = isset($_SERVER["argv"][1]) ? $_SERVER["argv"][1] : null; // Adminer functions read language from session
if (isset($_SESSION["lang"])) { if (isset($_SESSION["lang"])) {
include dirname(__FILE__) . "/adminer/include/lang.inc.php"; include dirname(__FILE__) . "/adminer/include/lang.inc.php";
if (isset($_SERVER["argv"][2]) || (!isset($langs[$_SESSION["lang"]]) && $_SESSION["lang"] != "xx")) { if (isset($_SERVER["argv"][2]) || (!isset($languages[$_SESSION["lang"]]) && $_SESSION["lang"] != "xx")) {
echo "Usage: php lang.php [lang]\nPurpose: Update adminer/lang/*.inc.php from source code messages.\n"; echo "Usage: php lang.php [lang]\nPurpose: Update adminer/lang/*.inc.php from source code messages.\n";
exit(1); exit(1);
} }

View File

@@ -9,7 +9,7 @@
class AdminerDumpAlter { class AdminerDumpAlter {
function dumpFormat() { function dumpFormat() {
if (DRIVER == 'server') { if (DRIVER == 'server' || DRIVER == 'mysql') {
return array('sql_alter' => 'Alter'); return array('sql_alter' => 'Alter');
} }
} }

View File

@@ -9,7 +9,7 @@
class AdminerForeignSystem { class AdminerForeignSystem {
function foreignKeys($table) { function foreignKeys($table) {
if (DRIVER == "server" && DB == "mysql") { if ((DRIVER == "server" || DRIVER == "mysql") && DB == "mysql") {
switch ($table) { switch ($table) {
case "columns_priv": return array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User"))); case "columns_priv": return array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User")));
case "db": return array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User"))); case "db": return array(array("table" => "user", "source" => array("Host", "User"), "target" => array("Host", "User")));

View File

@@ -11,7 +11,7 @@ class AdminerLoginServers {
var $servers; var $servers;
/** Set supported servers /** Set supported servers
* @param array array($description => array("server" => , "driver" => "server|pgsql|sqlite|...")) * @param array array($description => array("server" => , "driver" => "mysql|pgsql|sqlite|..."))
*/ */
function __construct($servers) { function __construct($servers) {
$this->servers = $servers; $this->servers = $servers;

View File

@@ -10,11 +10,12 @@
*/ */
class AdminerLoginSsl class AdminerLoginSsl
{ {
private var $ssl; private $ssl;
/** /**
* MySQL: ["key" => filename, "cert" => filename, "ca" => filename] * MySQL: ["key" => filename, "cert" => filename, "ca" => filename]
* PostgresSQL: ["mode" => sslmode] (https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) * PostgresSQL: ["mode" => sslmode] (https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-SSLMODE)
* MSSQL: ["Encrypt" => true, "TrustServerCertificate" => true] (https://learn.microsoft.com/en-us/sql/connect/php/connection-options)
*/ */
function __construct(array $ssl) function __construct(array $ssl)
{ {

View File

@@ -65,7 +65,7 @@ tinyMCE.init({
return "<textarea$attrs id='fields-" . h($field["field"]) . "' rows='12' cols='50'>" . h($value) . "</textarea>" . script(" return "<textarea$attrs id='fields-" . h($field["field"]) . "' rows='12' cols='50'>" . h($value) . "</textarea>" . script("
tinyMCE.remove(tinyMCE.get('fields-" . js_escape($field["field"]) . "') || { }); tinyMCE.remove(tinyMCE.get('fields-" . js_escape($field["field"]) . "') || { });
tinyMCE.EditorManager.execCommand('mceAddControl', true, 'fields-" . js_escape($field["field"]) . "'); tinyMCE.EditorManager.execCommand('mceAddControl', true, 'fields-" . js_escape($field["field"]) . "');
qs('#form').onsubmit = function () { gid('form').onsubmit = function () {
tinyMCE.each(tinyMCE.editors, function (ed) { tinyMCE.each(tinyMCE.editors, function (ed) {
ed.remove(); ed.remove();
}); });