mirror of
https://github.com/vrana/adminer.git
synced 2026-03-27 06:40:52 +01:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4112aaf26f | ||
|
|
5fdc9dc427 | ||
|
|
cc646de4ca | ||
|
|
b6b379a8ce | ||
|
|
f93db81c0e | ||
|
|
2cafcd7fc8 | ||
|
|
53799ff6ab | ||
|
|
638288cc04 | ||
|
|
99f4c22c72 | ||
|
|
55e0c348b8 | ||
|
|
379003fc8d | ||
|
|
0933e4e67d | ||
|
|
ee26735ac6 | ||
|
|
214d7745a7 | ||
|
|
99b7c08e3a | ||
|
|
b1ecb0649e | ||
|
|
2430ad2702 | ||
|
|
9eeeca6b0e | ||
|
|
d165cd9aec | ||
|
|
a0a0d44c7c | ||
|
|
316754af47 | ||
|
|
47f1f19970 | ||
|
|
5c4dc82081 | ||
|
|
226d4ad54b | ||
|
|
85c0c8f003 | ||
|
|
c815ea875b | ||
|
|
872991fa14 | ||
|
|
35411d8f4e | ||
|
|
81e337bed1 | ||
|
|
18ddbf1d60 | ||
|
|
e4235d21e5 | ||
|
|
10dfc54bf4 | ||
|
|
af3c863be3 | ||
|
|
6cd5495c1b | ||
|
|
78ad8381ab | ||
|
|
87fc82f88e | ||
|
|
0519a0b985 | ||
|
|
f61cf1ba0c | ||
|
|
fc2e025603 | ||
|
|
659e72b692 | ||
|
|
123373ca82 | ||
|
|
e99f2d90cf | ||
|
|
bdabc5aa13 | ||
|
|
92f3e0ca00 | ||
|
|
aa1266e4f2 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
||||
patreon: jakubvrana
|
||||
custom: ["https://sourceforge.net/p/adminer/donate/"]
|
||||
433
CHANGELOG.md
433
CHANGELOG.md
@@ -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 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
|
||||
- Full width design for database select box
|
||||
- Add 'Home' to breadcrumb navigation
|
||||
- Plugin to auto-include adminer.js when present (by Roy Orbitson)
|
||||
- Print username next to the logout button
|
||||
- Show partitioning info in table structure page
|
||||
- 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
|
||||
- Hide edited value if selected function will not use it
|
||||
- Hide arrow buttons in number input fields
|
||||
- Do not display empty action links in main menu
|
||||
- Remove deprecated HTML table parameters
|
||||
- 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: Proper formatting of boolean values
|
||||
- Plugin to auto-include adminer.js when present
|
||||
- Check new version against GitHub pages
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- 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
|
||||
- Unify displaying of 'New item' action based on privileges
|
||||
- Better default value for object definition `(*.*)` while creating new database user
|
||||
@@ -40,49 +100,57 @@
|
||||
- Editor: Fix building links with array parameters
|
||||
- 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: Fix where clause for `JSON` column
|
||||
- MySQL: Fix where clause for `JSON` column (by SeaEagle)
|
||||
- MySQL: Fix editing user's proxy privilege, refactoring
|
||||
- MariaDB: Fix comparing `CURRENT_TIMESTAMP` definition while altering a table
|
||||
- PostgreSQL: Fix editing record that contains a field with `GENERATED ALWAYS` default value
|
||||
- Fix using undefined Min_DB::info property
|
||||
- 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
|
||||
- Hide invalid edit form if table record is not found
|
||||
- CSS: Fix background color of `<pre>` used as edit field
|
||||
- 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 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 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 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
|
||||
- MySQL: Do not show `empty` enum value in strict mode
|
||||
- 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)
|
||||
- Compatibility with PHP 8.3
|
||||
Adminer 4.9.1 (2024-09-09)
|
||||
--------------------------
|
||||
|
||||
- Compatibility with PHP 8.3 (by Sneda8)
|
||||
- Fix compiling jush external files
|
||||
- Improved displaying of long table names in menu
|
||||
- Replace deprecated `<acronym>` with `<abbr>`
|
||||
- Add support for translations in plugins
|
||||
- Add .editorconfig file
|
||||
- MySQL: Add `unix_timestamp` to functions
|
||||
- PostgreSQL: Show only accessible databases
|
||||
- PostgreSQL: Make data length calculation more accurate
|
||||
- MySQL: Add `unix_timestamp` to functions (by Michal Paulovic)
|
||||
- PostgreSQL: Show only accessible databases (by Thomas Daniels)
|
||||
- PostgreSQL: Make data length calculation more accurate (by caltong)
|
||||
- PostgreSQL: Fix documentation link for `SERIAL` type
|
||||
- PostgreSQL: Fix undefined properties on PHP 8
|
||||
- Elasticsearch: Fix field selection
|
||||
- AdminerEditForeign: Refactor and fix the plugin
|
||||
- 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 connection to server in HTTP based drivers
|
||||
- Move dependencies from submodules to Composer
|
||||
@@ -91,13 +159,16 @@
|
||||
- Add new Elasticsearch 7 driver
|
||||
- Set saving to file as a default export option
|
||||
- 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
|
||||
- Skip dump of generated columns
|
||||
- Skip dump of generated columns (by Denitz)
|
||||
- Fix uninitialized string offset (by Adrian Jones)
|
||||
- Update composer.json
|
||||
- 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
|
||||
- MySQL: Use `ST_SRID()` instead of `SRID()` for MySQL 8 (PR #418)
|
||||
- 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
|
||||
- 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)
|
||||
- Fix more PHP 8 warnings (bug #781)
|
||||
- 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)
|
||||
- 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)
|
||||
- Allow SQL pseudo-function in insert
|
||||
- Skip date columns for non-date values in search anywhere
|
||||
@@ -137,7 +212,9 @@
|
||||
- MongoDB: Handle errors
|
||||
- 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)
|
||||
- Elasticsearch, ClickHouse: Do not print response if HTTP code is not 200
|
||||
- Don't syntax highlight during IME composition (bug #747)
|
||||
@@ -163,14 +240,20 @@
|
||||
- Editor: Cast to string when searching (bug #325)
|
||||
- Editor: Avoid trailing dot in export filename
|
||||
|
||||
## Adminer 4.7.8 (2020-12-06)
|
||||
Adminer 4.7.8 (2020-12-06)
|
||||
--------------------------
|
||||
|
||||
- Support PHP 8
|
||||
- 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@
|
||||
|
||||
## Adminer 4.7.6 (2020-01-31)
|
||||
Adminer 4.7.6 (2020-01-31)
|
||||
--------------------------
|
||||
|
||||
- Speed up alter table form (regression from 4.4.0)
|
||||
- Fix clicking on non-input fields in alter table (regression from 4.6.2)
|
||||
- Display time of procedure execution
|
||||
@@ -179,17 +262,23 @@
|
||||
- PostgreSQL: Support exporting views
|
||||
- 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)
|
||||
- PostgreSQL: Fix getting default value in PostgreSQL 12 (bug #719)
|
||||
- PostgreSQL, Oracle: Set schema for EXPLAIN queries in SQL command (bug #706)
|
||||
- ClickHouse: SQL command
|
||||
- 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:
|
||||
|
||||
## 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)
|
||||
- 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)
|
||||
@@ -202,7 +291,9 @@
|
||||
- MS SQL: Support foreign keys to other DB
|
||||
- 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)
|
||||
- Stretch footer over the whole table width (bug #624)
|
||||
- Allow overwriting tables when copying them
|
||||
@@ -217,7 +308,9 @@
|
||||
- MS SQL: Support comments
|
||||
- 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)
|
||||
- Remember visible columns in Create Table form (bug #493)
|
||||
- Add autocomplete attributes to login form
|
||||
@@ -225,7 +318,9 @@
|
||||
- SQLite: Hide server field in login form
|
||||
- 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
|
||||
- Warn when using password with leading or trailing spaces
|
||||
- Hide import from server if importServerPath() returns an empty string
|
||||
@@ -246,7 +341,9 @@
|
||||
- ClickHouse: Connect, databases list, tables list, select, SQL command
|
||||
- Georgian translation
|
||||
|
||||
## Adminer 4.6.3 (2018-06-28)
|
||||
Adminer 4.6.3 (2018-06-28)
|
||||
--------------------------
|
||||
|
||||
- Disallow using password-less databases
|
||||
- Copy triggers when copying table
|
||||
- Stop session before connecting
|
||||
@@ -264,7 +361,9 @@
|
||||
- MS SQL: Support port with sqlsrv
|
||||
- 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
|
||||
- Shorten JSON values in select (bug #594)
|
||||
- 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)
|
||||
- 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
|
||||
- Speed up rendering of long tables (regression from 4.4.0)
|
||||
- Display notification about performing action after relogin
|
||||
@@ -291,7 +392,9 @@
|
||||
- Customization: Support connecting to MySQL via SSL
|
||||
- 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
|
||||
- PHP <5.3 compatibility even with Elasticsearch enabled
|
||||
- Fully support functions in default values
|
||||
@@ -311,7 +414,9 @@
|
||||
- SimpleDB: Document that allow_url_fopen is required
|
||||
- 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 newlines in column comments (bug #573)
|
||||
- Support current_timestamp() as default of time fields (bug #572)
|
||||
@@ -335,7 +440,9 @@
|
||||
- MongoDB: Support mongodb PHP extension
|
||||
- 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
|
||||
- Disallow scripts without nonce
|
||||
- Rate limit password-less login attempts from the same IP address
|
||||
@@ -352,14 +459,18 @@
|
||||
- Customization: Always send security headers
|
||||
- Hebrew translation
|
||||
|
||||
## Adminer 4.3.1 (2017-04-14)
|
||||
Adminer 4.3.1 (2017-04-14)
|
||||
--------------------------
|
||||
|
||||
- Fix permanent login after logout (bug #539)
|
||||
- Fix SQL command autofocus (regression from 4.0.0)
|
||||
- PostgreSQL: Support JSON and JSONB data types
|
||||
- PostgreSQL: Fix index size computation in PostgreSQL < 9.0 (regression from 4.3.0)
|
||||
- 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
|
||||
- Add accessibility labels
|
||||
- Add Cache-Control: immutable to static files
|
||||
@@ -372,34 +483,46 @@
|
||||
- MS SQL: Support pdo_dblib
|
||||
- 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
|
||||
- SQLite: Require credentials to use
|
||||
- PostgreSQL: Support KILL
|
||||
|
||||
## Adminer 4.2.4 (2016-02-06)
|
||||
Adminer 4.2.4 (2016-02-06)
|
||||
--------------------------
|
||||
|
||||
- Fix remote execution in SQLite query
|
||||
- MySQL: Support PHP 7
|
||||
- Bosnian translation
|
||||
- Finnish translation
|
||||
|
||||
## Adminer 4.2.3 (2015-11-15)
|
||||
Adminer 4.2.3 (2015-11-15)
|
||||
--------------------------
|
||||
|
||||
- Fix XSS in indexes (non-MySQL only)
|
||||
- Support PHP 7
|
||||
- Greek translation
|
||||
- Galician 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)
|
||||
|
||||
## Adminer 4.2.1 (2015-03-10)
|
||||
Adminer 4.2.1 (2015-03-10)
|
||||
--------------------------
|
||||
|
||||
- Send referrer header to the same domain
|
||||
- MySQL: Fix usage of utf8mb4 if the client library doesn't support it
|
||||
- MySQL: Use utf8mb4 in export only if required
|
||||
- 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)
|
||||
- Allow limiting number of displayed rows in SQL command
|
||||
- Fix reading routine column collations
|
||||
@@ -422,7 +545,9 @@
|
||||
- Firebird: Alpha version
|
||||
- Danish translation
|
||||
|
||||
## Adminer 4.1.0 (2014-04-18)
|
||||
Adminer 4.1.0 (2014-04-18)
|
||||
--------------------------
|
||||
|
||||
- Provide size of all databases in the overview
|
||||
- Prevent against brute force login attempts from the same IP address
|
||||
- Compute number of tables in the overview explicitly
|
||||
@@ -442,18 +567,24 @@
|
||||
- Translate numbers in ar, bn, fa
|
||||
- Vietnamese translation
|
||||
|
||||
## Adminer 4.0.3 (2014-02-01)
|
||||
Adminer 4.0.3 (2014-02-01)
|
||||
--------------------------
|
||||
|
||||
- MongoDB: insert, truncate, indexes
|
||||
- SimpleDB, MongoDB: insert more fields at once
|
||||
- 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
|
||||
- Norweigan translation
|
||||
|
||||
## Adminer 4.0.2 (2014-01-11)
|
||||
Adminer 4.0.2 (2014-01-11)
|
||||
--------------------------
|
||||
|
||||
- Fix handling of long text in SQL textarea
|
||||
- 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
|
||||
- Disable highlighting in textareas with long texts
|
||||
- Don't autofocus SQL textarea in Firefox
|
||||
@@ -463,7 +594,9 @@
|
||||
- MongoDB: Count tables, display ObjectIds, sort, limit, offset, count rows
|
||||
- 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
|
||||
- Highlight SQL in textareas
|
||||
- Save and continue edit by AJAX
|
||||
@@ -496,7 +629,9 @@
|
||||
- Portugal Portuguese translation
|
||||
- Thai translation
|
||||
|
||||
## Adminer 3.7.1 (2013-06-29)
|
||||
Adminer 3.7.1 (2013-06-29)
|
||||
--------------------------
|
||||
|
||||
- Increase click target for checkboxes
|
||||
- Use shadow for highlighting default button
|
||||
- Don't use LIMIT 1 if inline updating unique row
|
||||
@@ -514,7 +649,9 @@
|
||||
- PostgreSQL: Handle timestamp types (bug #324)
|
||||
- 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
|
||||
- Print run time next to executed queries
|
||||
- Don't drop original view and routine before creating the new one
|
||||
@@ -540,7 +677,9 @@
|
||||
- SQLite: Export views
|
||||
- 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
|
||||
- Increase default select limit to 50
|
||||
- Display SQL edit form on Ctrl+click on the select query
|
||||
@@ -563,14 +702,18 @@
|
||||
- MySQL: Link processlist documentation
|
||||
- SQLite: Export indexes
|
||||
|
||||
## Adminer 3.6.3 (2013-01-23)
|
||||
Adminer 3.6.3 (2013-01-23)
|
||||
--------------------------
|
||||
|
||||
- Display error code in SQL query
|
||||
- Allow specifying external links
|
||||
- Treat Meta key same as Ctrl
|
||||
- Fix XSS in displaying non-UTF-8 strings
|
||||
- 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
|
||||
- Don't select row on double click
|
||||
- Support NULL in routine calls
|
||||
@@ -585,10 +728,14 @@
|
||||
- PostgreSQL: Fix process list in version 9.2
|
||||
- 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
|
||||
|
||||
## Adminer 3.6.0 (2012-09-16)
|
||||
Adminer 3.6.0 (2012-09-16)
|
||||
--------------------------
|
||||
|
||||
- Load more data in select
|
||||
- Edit strings with \n in textarea
|
||||
- Time out long running database list and select count
|
||||
@@ -602,11 +749,15 @@
|
||||
- selectQueryBuild() method (customization)
|
||||
- Serbian translation
|
||||
|
||||
## Adminer 3.5.1 (2012-08-10)
|
||||
Adminer 3.5.1 (2012-08-10)
|
||||
--------------------------
|
||||
|
||||
- Support same name fields in CSV 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
|
||||
- Autohide column context menu in select
|
||||
- Autodisplay long table names in tables list
|
||||
@@ -615,7 +766,9 @@
|
||||
- SQLite: Better editing in tables without primary key
|
||||
- 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
|
||||
- Shift+click on checkbox to select consecutive rows
|
||||
- Print current time next to executed SQL queries
|
||||
@@ -637,7 +790,9 @@
|
||||
- Ukrainian translation
|
||||
- Bengali translation
|
||||
|
||||
## Adminer 3.3.4 (2012-03-07)
|
||||
Adminer 3.3.4 (2012-03-07)
|
||||
--------------------------
|
||||
|
||||
- Foreign keys default actions (bug #188)
|
||||
- SET DEFAULT foreign key action
|
||||
- Fix minor parser bug in SQL command with webserver file
|
||||
@@ -660,14 +815,18 @@
|
||||
- Boolean search (Editor)
|
||||
- Persian translation
|
||||
|
||||
## Adminer 3.3.3 (2011-08-12)
|
||||
Adminer 3.3.3 (2011-08-12)
|
||||
--------------------------
|
||||
|
||||
- Highlight checked rows
|
||||
- Titles of links in database overview and navigation
|
||||
- Fix trigger export (SQLite)
|
||||
- Default trigger statement (SQLite, PostgreSQL)
|
||||
- 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
|
||||
- Fix minor parser bug in SQL command with webserver file
|
||||
- Fix SQL command Stop on error
|
||||
@@ -675,12 +834,16 @@
|
||||
- Fast number of rows with big tables (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 altering default values (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
|
||||
- Shortcut for database privileges
|
||||
- Editable index names
|
||||
@@ -706,10 +869,14 @@
|
||||
- Easier sending of default headers (customization)
|
||||
- Lithuanian and Romanian translation
|
||||
|
||||
## Adminer 3.2.2 (2011-03-28)
|
||||
Adminer 3.2.2 (2011-03-28)
|
||||
--------------------------
|
||||
|
||||
- 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
|
||||
- Respect default database collation (bug #119)
|
||||
- Don't export triggers without table (bug #123)
|
||||
@@ -730,7 +897,9 @@
|
||||
- Allow own code in `<head>` (customization)
|
||||
- Polish translation
|
||||
|
||||
## Adminer 3.2.0 (2011-02-24)
|
||||
Adminer 3.2.0 (2011-02-24)
|
||||
--------------------------
|
||||
|
||||
- Get long texts and slow information by AJAX
|
||||
- Most links and forms by AJAX in browsers with support for history.pushState
|
||||
- Copy tables
|
||||
@@ -753,7 +922,9 @@
|
||||
- Fix saving schema to cookie in Opera
|
||||
- Portuguese, Slovenian and Turkish translation
|
||||
|
||||
## Adminer 3.1.0 (2010-11-16)
|
||||
Adminer 3.1.0 (2010-11-16)
|
||||
--------------------------
|
||||
|
||||
- TSV export and import
|
||||
- Customizable export
|
||||
- Option to show only errors in SQL command
|
||||
@@ -770,7 +941,9 @@
|
||||
- Arabic translation and RTL support
|
||||
- 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
|
||||
- Disable creating SQLite databases with extension other than db, sdb, sqlite
|
||||
- Ability to use Adminer in a frame through customization
|
||||
@@ -778,7 +951,9 @@
|
||||
- MS SQL 2005 compatibility
|
||||
- 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
|
||||
- Allow concurrent logins on the same server
|
||||
- Allow permanent login without customization
|
||||
@@ -804,18 +979,24 @@
|
||||
- Defer table information in database overview to JavaScript (performance)
|
||||
- Big tables optimizations (performance)
|
||||
|
||||
## Adminer 2.3.2 (2010-04-21)
|
||||
Adminer 2.3.2 (2010-04-21)
|
||||
--------------------------
|
||||
|
||||
- Fix COUNT(*) link
|
||||
- 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)
|
||||
- Link COUNT(*) result to listing
|
||||
- Newlines in select query edit
|
||||
- Return to referrer after edit
|
||||
- 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)
|
||||
- Search in all tables
|
||||
- Show status variables
|
||||
@@ -827,14 +1008,18 @@
|
||||
- Delete length when changing type in alter table
|
||||
- Ability to check table prefix in export
|
||||
|
||||
## Adminer 2.2.1 (2009-11-26)
|
||||
Adminer 2.2.1 (2009-11-26)
|
||||
--------------------------
|
||||
|
||||
- Highlight current links
|
||||
- Improve concurrency
|
||||
- Move number of tables to DB info (performance)
|
||||
- Search by foreign 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
|
||||
- Enlarge field for enum and set definition
|
||||
- Display table links above table structure
|
||||
@@ -851,7 +1036,9 @@
|
||||
- Move `<h1>` to $adminer->navigation (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
|
||||
- Execute SQL file stored on server disk
|
||||
- Display EXPLAIN in SQL query
|
||||
@@ -865,7 +1052,9 @@
|
||||
- Speed up simple alter table
|
||||
- Traditional Chinese translation
|
||||
|
||||
## Adminer 2.0.0 (2009-08-06)
|
||||
Adminer 2.0.0 (2009-08-06)
|
||||
--------------------------
|
||||
|
||||
- Editor: User friendly data editor
|
||||
- Customization: Adminer class
|
||||
- Create single column foreign key in table structure
|
||||
@@ -891,10 +1080,14 @@
|
||||
- Fix CSV import
|
||||
- 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
|
||||
|
||||
## Adminer 1.11.0 (2009-07-02)
|
||||
Adminer 1.11.0 (2009-07-02)
|
||||
--------------------------
|
||||
|
||||
- Connection through socket by server :/path/to/socket
|
||||
- Simplify export
|
||||
- Display execution time in SQL query
|
||||
@@ -915,12 +1108,16 @@
|
||||
- Automatically add new fields in table creation
|
||||
- Use \n in SQL commands
|
||||
|
||||
## phpMinAdmin 1.10.1 (2009-05-07)
|
||||
phpMinAdmin 1.10.1 (2009-05-07)
|
||||
-------------------------------
|
||||
|
||||
- Highlight odd and hover rows
|
||||
- Partition editing comfort (bug #12)
|
||||
- Allow full length in limited int
|
||||
|
||||
## phpMinAdmin 1.10.0 (2009-04-28)
|
||||
phpMinAdmin 1.10.0 (2009-04-28)
|
||||
-------------------------------
|
||||
|
||||
- Partitioning (MySQL 5.1)
|
||||
- CSV import
|
||||
- Plus and minus functions
|
||||
@@ -932,10 +1129,14 @@
|
||||
- Size reduction by minification of variables and functions
|
||||
- Russian translation
|
||||
|
||||
## phpMinAdmin 1.9.1 (2008-10-27)
|
||||
phpMinAdmin 1.9.1 (2008-10-27)
|
||||
------------------------------
|
||||
|
||||
- Update translations
|
||||
|
||||
## phpMinAdmin 1.9.0 (2008-10-16)
|
||||
phpMinAdmin 1.9.0 (2008-10-16)
|
||||
------------------------------
|
||||
|
||||
- List of tables and views with maintenance commands
|
||||
- Clone rows
|
||||
- Bulk edit and clone
|
||||
@@ -951,7 +1152,9 @@
|
||||
- Order by function result working also in older MySQL versions
|
||||
- Tested on IIS
|
||||
|
||||
## phpMinAdmin 1.8.0 (2008-09-12)
|
||||
phpMinAdmin 1.8.0 (2008-09-12)
|
||||
------------------------------
|
||||
|
||||
- Events (MySQL 5.1)
|
||||
- Access without login - accept ?username=
|
||||
- Print SQL query in select, messages and warnings
|
||||
@@ -960,7 +1163,9 @@
|
||||
- Italian and Estonian translation
|
||||
- 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)
|
||||
- Ability to alter existing tables and drop old tables in export
|
||||
- Choose columns in select, aggregation
|
||||
@@ -974,10 +1179,14 @@
|
||||
- Cache static files
|
||||
- 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
|
||||
|
||||
## phpMinAdmin 1.6.0 (2008-05-16)
|
||||
phpMinAdmin 1.6.0 (2008-05-16)
|
||||
------------------------------
|
||||
|
||||
- Order of columns in table
|
||||
- Set max_allowed_packet in dump and use extended insert
|
||||
- Spanish and German translations
|
||||
@@ -989,7 +1198,9 @@
|
||||
- Last-Modified header for files
|
||||
- Several bug fixes
|
||||
|
||||
## phpMinAdmin 1.5.0 (2008-01-09)
|
||||
phpMinAdmin 1.5.0 (2008-01-09)
|
||||
------------------------------
|
||||
|
||||
- Mass delete
|
||||
- Vertical privileges
|
||||
- Specify connection port by colon in server
|
||||
@@ -1000,14 +1211,18 @@
|
||||
- Uncheck NULL by change
|
||||
- Mark shortened fields in select
|
||||
|
||||
## phpMinAdmin 1.4.0 (2007-08-15)
|
||||
phpMinAdmin 1.4.0 (2007-08-15)
|
||||
------------------------------
|
||||
|
||||
- Privileges
|
||||
- New design
|
||||
- Dutch translation
|
||||
- Use NULL for auto_increment (bug #1)
|
||||
- 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
|
||||
- Set time zone in dump
|
||||
- Refresh lang cookie
|
||||
@@ -1015,12 +1230,16 @@
|
||||
- Move vertical lines in schema properly
|
||||
- Fix maximum page in select
|
||||
|
||||
## phpMinAdmin 1.3.1 (2007-07-31)
|
||||
phpMinAdmin 1.3.1 (2007-07-31)
|
||||
------------------------------
|
||||
|
||||
- Move references lines in schema
|
||||
- Fix dump
|
||||
- Fix update links
|
||||
|
||||
## phpMinAdmin 1.3.0 (2007-07-27)
|
||||
phpMinAdmin 1.3.0 (2007-07-27)
|
||||
------------------------------
|
||||
|
||||
- Breadcrumb navigation
|
||||
- Operator IN
|
||||
- Timestamp default values
|
||||
@@ -1030,13 +1249,17 @@
|
||||
- More friendly user interface
|
||||
- Slovak translation
|
||||
|
||||
## phpMinAdmin 1.2.0 (2007-07-25)
|
||||
phpMinAdmin 1.2.0 (2007-07-25)
|
||||
------------------------------
|
||||
|
||||
- Manipulate triggers
|
||||
- PDO Abstraction
|
||||
- Auto_increment value
|
||||
- JavaScript for adding rows
|
||||
|
||||
## phpMinAdmin 1.1.0 (2007-07-19)
|
||||
phpMinAdmin 1.1.0 (2007-07-19)
|
||||
------------------------------
|
||||
|
||||
- Routines manipulation
|
||||
- Views manipulation
|
||||
- Foreign keys manipulation
|
||||
@@ -1047,5 +1270,7 @@
|
||||
- JavaScript for next rows in table edit
|
||||
- Cache databases list
|
||||
|
||||
## phpMinAdmin 1.0.0 (2007-07-11)
|
||||
phpMinAdmin 1.0.0 (2007-07-11)
|
||||
------------------------------
|
||||
|
||||
- First official release
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# Licenses
|
||||
Licenses
|
||||
========
|
||||
|
||||
You may use Adminer under the terms of either the Apache License Version 2.0
|
||||
or the GNU General Public License (GPL) version 2.
|
||||
43
README.md
43
README.md
@@ -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
|
||||
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
|
||||
- With plugin: SimpleDB, Elasticsearch (beta), Firebird (alpha), ClickHouse (alpha)
|
||||
|
||||
## Requirements
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- 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
|
||||
switch to this project.
|
||||
- Remove plugin AdminerTablesFilter (plugins/tables-filter.php).
|
||||
- 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
|
||||
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
|
||||
# Adminer
|
||||
php compile.php <driver> <language>
|
||||
php compile.php <drivers> <languages>
|
||||
|
||||
# Editor
|
||||
php compile.php editor <driver> <language>
|
||||
php compile.php editor <drivers> <languages>
|
||||
```
|
||||
|
||||
For example:
|
||||
```shell
|
||||
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),
|
||||
[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
|
||||
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
|
||||
(e.g. to require an OTP).
|
||||
|
||||
## Plugins
|
||||
Plugins
|
||||
-------
|
||||
|
||||
* Download plugins you want and place them into the `plugins` folder.
|
||||
* 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).
|
||||
|
||||
## Main project files
|
||||
Main project files
|
||||
------------------
|
||||
|
||||
- adminer/index.php - Run development version of Adminer.
|
||||
- editor/index.php - Run development version of Adminer Editor.
|
||||
- editor/example.php - Example customization.
|
||||
@@ -118,7 +131,8 @@ include "./adminer.php";
|
||||
- lang.php - Update translations.
|
||||
- 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/).
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
### Version 4.x
|
||||
|
||||
Original design and backward compatibility is kept. Many issues were fixed, and we introduced several functional and
|
||||
UI improvements.
|
||||
|
||||
### 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 😉
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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,
|
||||
or the advisory has been declined.
|
||||
|
||||
## Supported versions
|
||||
Supported versions
|
||||
------------------
|
||||
|
||||
Only the last published version and the last development version (last commit) are supported.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]);
|
||||
|
||||
$PROCEDURE = ($_GET["name"] ?: $_GET["call"]);
|
||||
page_header(lang('Call') . ": " . h($PROCEDURE), $error);
|
||||
|
||||
$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
|
||||
@@ -28,13 +29,13 @@ if (!$error && $_POST) {
|
||||
}
|
||||
$call[] = (isset($out[$key]) ? "@" . idf_escape($field["field"]) : $val);
|
||||
}
|
||||
|
||||
|
||||
$query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")";
|
||||
$start = microtime(true);
|
||||
$result = $connection->multi_query($query);
|
||||
$affected = $connection->affected_rows; // getting warnigns overwrites this
|
||||
echo $adminer->selectQuery($query, $start, !$result);
|
||||
|
||||
|
||||
if (!$result) {
|
||||
echo "<p class='error'>" . error() . "\n";
|
||||
} else {
|
||||
@@ -42,7 +43,7 @@ if (!$error && $_POST) {
|
||||
if (is_object($connection2)) {
|
||||
$connection2->select_db(DB);
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
$result = $connection->store_result();
|
||||
if (is_object($result)) {
|
||||
@@ -53,16 +54,15 @@ if (!$error && $_POST) {
|
||||
;
|
||||
}
|
||||
} while ($connection->next_result());
|
||||
|
||||
|
||||
if ($out) {
|
||||
select($connection->query("SELECT " . implode(", ", $out)));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<form action="" method="post">
|
||||
<?php
|
||||
echo "<form action='' method='post'>\n";
|
||||
|
||||
if ($in) {
|
||||
echo "<table cellspacing='0' class='layout'>\n";
|
||||
foreach ($in as $key) {
|
||||
@@ -83,8 +83,28 @@ if ($in) {
|
||||
}
|
||||
echo "</table>\n";
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
<input type="submit" value="<?php echo lang('Call'); ?>">
|
||||
<input type="hidden" name="token" value="<?php echo $token; ?>">
|
||||
</form>
|
||||
|
||||
echo "<p>",
|
||||
"<input type='submit' value='", lang('Call'), "'>",
|
||||
"<input type='hidden' name='token' value='$token'>",
|
||||
"</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";
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ foreach ($engines as $engine) {
|
||||
<p>
|
||||
<?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 if ($TABLE == "" && !$_POST) { echo script("focus(qs('#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 if ($TABLE == "" && !$_POST) { echo script("focus(gid('form')['name']);"); } ?>
|
||||
<?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"]) : ""); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php } ?>
|
||||
@@ -221,7 +221,7 @@ if (support("partitioning")) {
|
||||
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
|
||||
?>
|
||||
<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"]); ?>">)
|
||||
<?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'"); ?>>
|
||||
|
||||
@@ -66,7 +66,7 @@ echo ($_POST["add_x"] || strpos($name, "\n")
|
||||
'mariadb' => "supported-character-sets-and-collations/",
|
||||
'mssql' => "ms187963.aspx",
|
||||
)) : "");
|
||||
echo script("focus(qs('#name'));");
|
||||
echo script("focus(gid('name'));");
|
||||
?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<?php
|
||||
|
||||
@@ -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);
|
||||
|
||||
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";
|
||||
$tables_list = tables_list();
|
||||
if (!$tables_list) {
|
||||
@@ -73,7 +94,7 @@ if ($adminer->homepage()) {
|
||||
echo "<table cellspacing='0' class='nowrap checkable'>\n";
|
||||
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
|
||||
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 '<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/'));
|
||||
@@ -126,17 +147,17 @@ if ($adminer->homepage()) {
|
||||
echo "</div>\n";
|
||||
if (!information_schema(DB)) {
|
||||
echo "<div class='footer'><div>\n";
|
||||
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . on_help("'VACUUM'");
|
||||
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help($jush == "sql" ? "'OPTIMIZE TABLE'" : "'VACUUM OPTIMIZE'");
|
||||
$vacuum = "<input type='submit' value='" . lang('Vacuum') . "'> " . help_script("VACUUM");
|
||||
$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>"
|
||||
. ($jush == "sqlite" ? $vacuum
|
||||
: ($jush == "pgsql" ? $vacuum . $optimize
|
||||
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . on_help("'ANALYZE TABLE'") . $optimize
|
||||
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . on_help("'CHECK TABLE'")
|
||||
. "<input type='submit' name='repair' value='" . lang('Repair') . "'> " . on_help("'REPAIR TABLE'")
|
||||
: ($jush == "sql" ? "<input type='submit' value='" . lang('Analyze') . "'> " . help_script("ANALYZE TABLE") . $optimize
|
||||
. "<input type='submit' name='check' value='" . lang('Check') . "'> " . help_script("CHECK 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='drop' value='" . lang('Drop') . "'>" . on_help("'DROP TABLE'") . confirm() . "\n";
|
||||
. "<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') . "'>" . help_script("DROP TABLE") . confirm() . "\n";
|
||||
$databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
|
||||
if (count($databases) != 1 && $jush != "sqlite") {
|
||||
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
|
||||
@@ -161,37 +182,59 @@ if ($adminer->homepage()) {
|
||||
|
||||
if (support("routine")) {
|
||||
echo "<h3 id='routines'>" . lang('Routines') . "</h3>\n";
|
||||
|
||||
$routines = routines();
|
||||
if ($routines) {
|
||||
$commentsSupported = $routines[0]["ROUTINE_COMMENT"] !== null;
|
||||
|
||||
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('');
|
||||
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
|
||||
echo '<tr' . odd() . '>';
|
||||
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 '<td>' . h($row["DTD_IDENTIFIER"]);
|
||||
echo '<td><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . lang('Alter') . "</a>";
|
||||
// not computed on the pages to be able to print the header first
|
||||
$name = ($row["SPECIFIC_NAME"] == $row["ROUTINE_NAME"] ? "" : "&name=" . urlencode($row["ROUTINE_NAME"]));
|
||||
|
||||
echo '<tr', odd(), '>',
|
||||
'<th><a href="', h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'callf=' : 'call=') . urlencode($row["SPECIFIC_NAME"]) . $name), '">', h($row["ROUTINE_NAME"]), '</a></th>',
|
||||
'<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 '<p class="links">'
|
||||
. (support("procedure") ? '<a href="' . h(ME) . 'procedure=">' . lang('Create procedure') . '</a>' : '')
|
||||
. '<a href="' . h(ME) . 'function=">' . lang('Create function') . "</a>\n"
|
||||
;
|
||||
|
||||
echo '<p class="links">',
|
||||
(support("procedure") ? '<a href="' . h(ME) . 'procedure=">' . lang('Create procedure') . '</a>' : ''),
|
||||
'<a href="' . h(ME) . 'function=">' . lang('Create function') . "</a>\n";
|
||||
}
|
||||
|
||||
if (support("sequence")) {
|
||||
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");
|
||||
if ($sequences) {
|
||||
echo "<table>\n";
|
||||
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
|
||||
echo "<table>\n",
|
||||
"<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
|
||||
|
||||
odd('');
|
||||
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 "<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";
|
||||
$user_types = types();
|
||||
if ($user_types) {
|
||||
echo "<table>\n";
|
||||
echo "<thead><tr><th>" . lang('Name') . "</thead>\n";
|
||||
echo "<table>\n",
|
||||
"<thead><tr><th>", lang('Name'), "</th><td></td></tr></thead>\n";
|
||||
|
||||
odd('');
|
||||
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 "<p class='links'><a href='" . h(ME) . "type='>" . lang('Create type') . "</a>\n";
|
||||
|
||||
@@ -205,9 +205,6 @@ if (isset($_GET["mongo"])) {
|
||||
return $connection->_db->selectCollection($_GET["select"])->count($where);
|
||||
}
|
||||
|
||||
$operators = array("=");
|
||||
$operator_regexp = null;
|
||||
|
||||
} elseif (class_exists('MongoDB\Driver\Manager')) {
|
||||
class Min_DB {
|
||||
var $extension = "MongoDB", $server_info = MONGODB_VERSION, $affected_rows, $error, $last_id;
|
||||
@@ -216,15 +213,14 @@ if (isset($_GET["mongo"])) {
|
||||
var $_db, $_db_name;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
function executeCommand($db, $command) {
|
||||
$class = 'MongoDB\Driver\Command';
|
||||
try {
|
||||
return $this->_link->executeCommand($db, new $class($command));
|
||||
return $this->_link->executeCommand($db, new MongoDB\Driver\Command($command));
|
||||
} catch (Exception $e) {
|
||||
$this->error = $e->getMessage();
|
||||
return array();
|
||||
@@ -341,9 +337,8 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
$limit = min(200, max(1, (int) $limit));
|
||||
$skip = $page * $limit;
|
||||
$class = 'MongoDB\Driver\Query';
|
||||
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) {
|
||||
$connection->error = $e->getMessage();
|
||||
return false;
|
||||
@@ -354,8 +349,7 @@ if (isset($_GET["mongo"])) {
|
||||
global $connection;
|
||||
$db = $connection->_db_name;
|
||||
$where = sql_query_where_parser($queryWhere);
|
||||
$class = 'MongoDB\Driver\BulkWrite';
|
||||
$bulk = new $class(array());
|
||||
$bulk = new MongoDB\Driver\BulkWrite(array());
|
||||
if (isset($set['_id'])) {
|
||||
unset($set['_id']);
|
||||
}
|
||||
@@ -378,8 +372,7 @@ if (isset($_GET["mongo"])) {
|
||||
global $connection;
|
||||
$db = $connection->_db_name;
|
||||
$where = sql_query_where_parser($queryWhere);
|
||||
$class = 'MongoDB\Driver\BulkWrite';
|
||||
$bulk = new $class(array());
|
||||
$bulk = new MongoDB\Driver\BulkWrite(array());
|
||||
$bulk->delete($where, array('limit' => $limit));
|
||||
return $connection->executeBulkWrite("$db.$table", $bulk, 'getDeletedCount');
|
||||
}
|
||||
@@ -387,8 +380,7 @@ if (isset($_GET["mongo"])) {
|
||||
function insert($table, $set) {
|
||||
global $connection;
|
||||
$db = $connection->_db_name;
|
||||
$class = 'MongoDB\Driver\BulkWrite';
|
||||
$bulk = new $class(array());
|
||||
$bulk = new MongoDB\Driver\BulkWrite(array());
|
||||
if ($set['_id'] == '') {
|
||||
unset($set['_id']);
|
||||
}
|
||||
@@ -483,7 +475,11 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
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);
|
||||
$wheresOr = explode(') OR (', $queryWhere);
|
||||
$where = array();
|
||||
@@ -517,8 +513,7 @@ if (isset($_GET["mongo"])) {
|
||||
$op = $match[1];
|
||||
} elseif (preg_match('~^\(date\)(.+)~', $op, $match)) {
|
||||
$dateTime = new DateTime($val);
|
||||
$class = 'MongoDB\BSON\UTCDatetime';
|
||||
$val = new $class($dateTime->getTimestamp() * 1000);
|
||||
$val = new MongoDB\BSON\UTCDatetime($dateTime->getTimestamp() * 1000);
|
||||
$op = $match[1];
|
||||
}
|
||||
switch ($op) {
|
||||
@@ -556,30 +551,6 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
$operators = array(
|
||||
"=",
|
||||
"!=",
|
||||
">",
|
||||
"<",
|
||||
">=",
|
||||
"<=",
|
||||
"regex",
|
||||
"(f)=",
|
||||
"(f)!=",
|
||||
"(f)>",
|
||||
"(f)<",
|
||||
"(f)>=",
|
||||
"(f)<=",
|
||||
"(date)=",
|
||||
"(date)!=",
|
||||
"(date)>",
|
||||
"(date)<",
|
||||
"(date)>=",
|
||||
"(date)<=",
|
||||
);
|
||||
|
||||
$operator_regexp = 'regex';
|
||||
}
|
||||
|
||||
function table($idf) {
|
||||
@@ -629,6 +600,11 @@ if (isset($_GET["mongo"])) {
|
||||
global $adminer;
|
||||
$connection = new Min_DB;
|
||||
list($server, $username, $password) = $adminer->credentials();
|
||||
|
||||
if ($server == "") {
|
||||
$server = "localhost:27017";
|
||||
}
|
||||
|
||||
$options = array();
|
||||
if ($username . $password != "") {
|
||||
$options["username"] = $username;
|
||||
@@ -736,7 +712,38 @@ if (isset($_GET["mongo"])) {
|
||||
}
|
||||
|
||||
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(
|
||||
'possible_drivers' => array("mongo", "mongodb"),
|
||||
'jush' => "mongo",
|
||||
|
||||
@@ -24,11 +24,26 @@ if (isset($_GET["mssql"])) {
|
||||
|
||||
function connect($server, $username, $password) {
|
||||
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();
|
||||
$connection_info = array("UID" => $username, "PWD" => $password, "CharacterSet" => "UTF-8");
|
||||
if ($db != "") {
|
||||
$connection_info["Database"] = $db;
|
||||
}
|
||||
|
||||
$this->_link = @sqlsrv_connect(preg_replace('~:~', ',', $server), $connection_info);
|
||||
if ($this->_link) {
|
||||
$info = sqlsrv_server_info($this->_link);
|
||||
@@ -36,11 +51,13 @@ if (isset($_GET["mssql"])) {
|
||||
} else {
|
||||
$this->_get_error();
|
||||
}
|
||||
|
||||
return (bool) $this->_link;
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
return "'" . str_replace("'", "''", $string) . "'";
|
||||
$unicode = strlen($string) != strlen(utf8_decode($string));
|
||||
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
@@ -163,7 +180,8 @@ if (isset($_GET["mssql"])) {
|
||||
}
|
||||
|
||||
function quote($string) {
|
||||
return "'" . str_replace("'", "''", $string) . "'";
|
||||
$unicode = strlen($string) != strlen(utf8_decode($string));
|
||||
return ($unicode ? "N" : "") . "'" . str_replace("'", "''", $string) . "'";
|
||||
}
|
||||
|
||||
function select_db($database) {
|
||||
@@ -301,6 +319,11 @@ if (isset($_GET["mssql"])) {
|
||||
global $adminer;
|
||||
$connection = new Min_DB;
|
||||
$credentials = $adminer->credentials();
|
||||
|
||||
if ($credentials[0] == "") {
|
||||
$credentials[0] = "localhost:1433";
|
||||
}
|
||||
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
return $connection;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
$drivers = array("server" => "MySQL") + $drivers;
|
||||
$drivers["mysql"] = "MySQL";
|
||||
|
||||
if (!defined("DRIVER")) {
|
||||
define("DRIVER", "server"); // server - backwards compatibility
|
||||
if (isset($_GET["mysql"])) {
|
||||
define("DRIVER", "mysql");
|
||||
// MySQLi supports everything, MySQL doesn't support multiple result sets, PDO_MySQL doesn't support orgtable
|
||||
if (extension_loaded("mysqli")) {
|
||||
class Min_DB extends MySQLi {
|
||||
@@ -371,16 +371,28 @@ if (!defined("DRIVER")) {
|
||||
* @return mixed Min_DB or string for error
|
||||
*/
|
||||
function connect() {
|
||||
global $adminer, $types, $structured_types;
|
||||
global $adminer, $types, $structured_types, $edit_functions;
|
||||
|
||||
$connection = new Min_DB;
|
||||
$credentials = $adminer->credentials();
|
||||
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
|
||||
$connection->set_charset(charset($connection));
|
||||
$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";
|
||||
$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->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
|
||||
*/
|
||||
function table_status($name = "", $fast = false) {
|
||||
$return = array();
|
||||
foreach (get_rows($fast && min_version(5)
|
||||
? "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")
|
||||
: "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "")
|
||||
) as $row) {
|
||||
if ($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");
|
||||
} else {
|
||||
$query = "SHOW TABLE STATUS" . ($name != "" ? " LIKE " . q(addcslashes($name, "%_\\")) : "");
|
||||
}
|
||||
|
||||
$tables = [];
|
||||
foreach (get_rows($query) as $row) {
|
||||
if ($row["Engine"] == "InnoDB") {
|
||||
// ignore internal comment, unnecessary since MySQL 5.1.21
|
||||
$row["Comment"] = preg_replace('~(?:(.+); )?InnoDB free: .*~', '\1', $row["Comment"]);
|
||||
@@ -513,11 +528,15 @@ if (!defined("DRIVER")) {
|
||||
$row["Comment"] = "";
|
||||
}
|
||||
if ($name != "") {
|
||||
// MariaDB: Table name is returned as lowercase on macOS, so we fix it here.
|
||||
$row["Name"] = $name;
|
||||
return $row;
|
||||
}
|
||||
$return[$row["Name"]] = $row;
|
||||
|
||||
$tables[$row["Name"]] = $row;
|
||||
}
|
||||
return $return;
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
/** Find out whether the identifier is view
|
||||
@@ -894,23 +913,30 @@ if (!defined("DRIVER")) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Get information about stored routine
|
||||
* @param string
|
||||
* @param string "FUNCTION" or "PROCEDURE"
|
||||
* @return array ("fields" => array("field" => , "type" => , "length" => , "unsigned" => , "inout" => , "collation" => ), "returns" => , "definition" => , "language" => )
|
||||
*/
|
||||
/**
|
||||
* Gets information about stored routine.
|
||||
*
|
||||
* @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) {
|
||||
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)";
|
||||
$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";
|
||||
$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);
|
||||
$fields = array();
|
||||
$fields = [];
|
||||
preg_match_all("~$pattern\\s*,?~is", $match[1], $matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $param) {
|
||||
$fields[] = array(
|
||||
$fields[] = [
|
||||
"field" => str_replace("``", "`", $param[2]) . $param[3],
|
||||
"type" => strtolower($param[5]),
|
||||
"length" => preg_replace_callback("~$enum_length~s", 'normalize_enum', $param[6]),
|
||||
@@ -919,24 +945,29 @@ if (!defined("DRIVER")) {
|
||||
"full_type" => $param[4],
|
||||
"inout" => strtoupper($param[1]),
|
||||
"collation" => strtolower($param[9]),
|
||||
);
|
||||
];
|
||||
}
|
||||
if ($type != "FUNCTION") {
|
||||
return array("fields" => $fields, "definition" => $match[11]);
|
||||
}
|
||||
return array(
|
||||
|
||||
return $type == "FUNCTION" ? [
|
||||
"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],
|
||||
"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
|
||||
* @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => )
|
||||
*/
|
||||
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
|
||||
|
||||
@@ -668,23 +668,29 @@ ORDER BY connamespace, conname") as $row) {
|
||||
}
|
||||
|
||||
function routine($name, $type) {
|
||||
$rows = get_rows('SELECT routine_definition AS definition, LOWER(external_language) AS language, *
|
||||
FROM information_schema.routines
|
||||
WHERE routine_schema = current_schema() AND specific_name = ' . q($name));
|
||||
$return = $rows[0];
|
||||
$return["returns"] = array("type" => $return["type_udt_name"]);
|
||||
$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
|
||||
WHERE specific_schema = current_schema() AND specific_name = ' . q($name) . '
|
||||
ORDER BY ordinal_position');
|
||||
return $return;
|
||||
$info = get_rows('SELECT routine_definition, external_language, type_udt_name
|
||||
FROM information_schema.routines
|
||||
WHERE routine_schema = current_schema() AND specific_name = ' . q($name))[0];
|
||||
|
||||
$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
|
||||
WHERE specific_schema = current_schema() AND specific_name = ' . q($name) . '
|
||||
ORDER BY ordinal_position');
|
||||
|
||||
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() {
|
||||
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"
|
||||
FROM information_schema.routines
|
||||
WHERE routine_schema = current_schema()
|
||||
ORDER BY SPECIFIC_NAME');
|
||||
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
|
||||
WHERE routine_schema = current_schema()
|
||||
ORDER BY SPECIFIC_NAME');
|
||||
}
|
||||
|
||||
function routine_languages() {
|
||||
|
||||
@@ -182,8 +182,8 @@ $prefixes = array();
|
||||
if (DB != "") {
|
||||
$checked = ($TABLE != "" ? "" : " checked");
|
||||
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: 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: 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("gid('check-data').onclick = partial(formCheck, /^data\\[/);", "");
|
||||
echo "</thead>\n";
|
||||
|
||||
$views = "";
|
||||
@@ -208,7 +208,7 @@ if (DB != "") {
|
||||
} else {
|
||||
echo "<thead><tr><th style='text-align: left;'>";
|
||||
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";
|
||||
$databases = $adminer->databases();
|
||||
if ($databases) {
|
||||
|
||||
@@ -13,7 +13,7 @@ class Adminer {
|
||||
* @return string HTML code
|
||||
*/
|
||||
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
|
||||
@@ -129,7 +129,7 @@ class Adminer {
|
||||
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('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('db', '<tr><th>' . lang('Database') . '<td>', '<input name="auth[db]" value="' . h($_GET["db"]) . '" autocapitalize="off">' . "\n");
|
||||
echo "</table>\n";
|
||||
@@ -424,8 +424,8 @@ class Adminer {
|
||||
echo "<select name='columns[$i][fun]'>",
|
||||
optionlist([-1 => ""] + array_filter([lang('Functions') => $functions, lang('Aggregation') => $grouping]), $val["fun"]),
|
||||
"</select>",
|
||||
on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1),
|
||||
script("qsl('select').onchange = (event) => { helpClose();" . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""),
|
||||
help_script_command("value && value.replace(/ |\$/, '(') + ')'", true),
|
||||
script("qsl('select').onchange = (event) => { " . ($key !== "" ? "" : " qsl('select, input:not(.remove)', event.target.parentNode).onchange();") . " };", ""),
|
||||
"($column)";
|
||||
} else {
|
||||
echo $column;
|
||||
@@ -557,7 +557,7 @@ class Adminer {
|
||||
json_row($key);
|
||||
}
|
||||
echo ";\n";
|
||||
echo "selectFieldChange.call(qs('#form')['select']);\n";
|
||||
echo "selectFieldChange.call(gid('form')['select']);\n";
|
||||
echo "</script>\n";
|
||||
echo "</div></fieldset>\n";
|
||||
}
|
||||
@@ -1038,18 +1038,26 @@ class Adminer {
|
||||
*/
|
||||
function navigation($missing) {
|
||||
global $VERSION, $jush, $drivers, $connection;
|
||||
?>
|
||||
?>
|
||||
|
||||
<h1>
|
||||
<?php echo $this->name(); ?>
|
||||
<?php if ($missing != "auth"): ?>
|
||||
<span class="version">
|
||||
<?php echo $VERSION; ?>
|
||||
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
|
||||
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
|
||||
</a>
|
||||
</span>
|
||||
<?php echo $this->name(); ?>
|
||||
|
||||
<?php if ($missing != "auth"): ?>
|
||||
<span class="version">
|
||||
<?php echo $VERSION; ?>
|
||||
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
|
||||
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
|
||||
</a>
|
||||
</span>
|
||||
<?php
|
||||
if (!isset($_COOKIE["adminer_version"])) {
|
||||
echo script("verifyVersion('" . js_escape(ME) . "', '" . get_token() . "');");
|
||||
}
|
||||
?>
|
||||
<?php endif; ?>
|
||||
</h1>
|
||||
|
||||
<?php
|
||||
if ($missing == "auth") {
|
||||
$output = "";
|
||||
@@ -1073,7 +1081,7 @@ class Adminer {
|
||||
}
|
||||
}
|
||||
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 {
|
||||
$tables = array();
|
||||
@@ -1156,7 +1164,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
|
||||
if ($databases) {
|
||||
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 {
|
||||
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)) {
|
||||
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"] != "") {
|
||||
set_schema($_GET["ns"]);
|
||||
@@ -1200,7 +1208,7 @@ bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\d\.?\d).*~s', '
|
||||
* @return null
|
||||
*/
|
||||
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) {
|
||||
$name = $this->tableName($status);
|
||||
|
||||
@@ -71,7 +71,7 @@ if (!function_exists('is_server_host_valid')) {
|
||||
*/
|
||||
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
|
||||
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
|
||||
$this->error = lang('Invalid server or credentials.');
|
||||
auth_error(lang('Invalid server or credentials.'));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ if ($auth) {
|
||||
set_session($key, null);
|
||||
}
|
||||
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"]) {
|
||||
session_regenerate_id();
|
||||
@@ -214,6 +214,12 @@ function auth_error($error) {
|
||||
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")) {
|
||||
unset($_SESSION["pwds"][DRIVER]);
|
||||
unset_permanent();
|
||||
|
||||
@@ -39,7 +39,7 @@ if ($_GET["script"] == "version") {
|
||||
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
|
||||
$_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("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/lang/$LANG.inc.php";
|
||||
|
||||
include "../adminer/include/pdo.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/sqlite.inc.php";
|
||||
include "../adminer/drivers/oracle.inc.php";
|
||||
include "../adminer/drivers/mssql.inc.php";
|
||||
include "../adminer/drivers/mongo.inc.php";
|
||||
|
||||
include "./include/adminer.inc.php";
|
||||
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer);
|
||||
include "../adminer/drivers/mysql.inc.php"; // must be included as last driver
|
||||
$adminer = (function_exists('adminer_object') ? adminer_object() : new Adminer());
|
||||
|
||||
$config = driver_config();
|
||||
$possible_drivers = $config['possible_drivers'];
|
||||
$jush = $config['jush'];
|
||||
$types = $config['types'];
|
||||
$structured_types = $config['structured_types'];
|
||||
$unsigned = $config['unsigned'];
|
||||
$operators = $config['operators'];
|
||||
$operator_like = $config['operator_like'];
|
||||
$operator_regexp = $config['operator_regexp'];
|
||||
$functions = $config['functions'];
|
||||
$grouping = $config['grouping'];
|
||||
$edit_functions = $config['edit_functions'];
|
||||
if (defined("DRIVER")) {
|
||||
$config = driver_config();
|
||||
$possible_drivers = $config['possible_drivers'];
|
||||
$jush = $config['jush'];
|
||||
$types = $config['types'];
|
||||
$structured_types = $config['structured_types'];
|
||||
$unsigned = $config['unsigned'];
|
||||
$operators = $config['operators'];
|
||||
$operator_like = $config['operator_like'];
|
||||
$operator_regexp = $config['operator_regexp'];
|
||||
$functions = $config['functions'];
|
||||
$grouping = $config['grouping'];
|
||||
$edit_functions = $config['edit_functions'];
|
||||
|
||||
if ($adminer->operators === null) {
|
||||
$adminer->operators = $operators;
|
||||
$adminer->operator_like = $operator_like;
|
||||
$adminer->operator_regexp = $operator_regexp;
|
||||
if ($adminer->operators === null) {
|
||||
$adminer->operators = $operators;
|
||||
$adminer->operator_like = $operator_like;
|
||||
$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("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
|
||||
. (sid() ? SID . '&' : '')
|
||||
@@ -113,6 +147,7 @@ define("ME", preg_replace('~\?.*~', '', relative_uri()) . '?'
|
||||
. (isset($_GET["username"]) ? "username=" . urlencode($_GET["username"]) . '&' : '')
|
||||
. (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/design.inc.php";
|
||||
|
||||
@@ -2,9 +2,22 @@
|
||||
|
||||
function dump($value)
|
||||
{
|
||||
echo "<pre>";
|
||||
var_export($value);
|
||||
echo "</pre>\n";
|
||||
$cli = PHP_SAPI == 'cli';
|
||||
|
||||
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)
|
||||
|
||||
@@ -18,10 +18,11 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
|
||||
|
||||
// Load Adminer version from file if cookie is missing.
|
||||
$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));
|
||||
|
||||
$_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>
|
||||
@@ -29,9 +30,9 @@ function page_header($title, $error = "", $breadcrumb = [], $title2 = "") {
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="robots" content="noindex">
|
||||
<title><?php echo $title_page; ?></title>
|
||||
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css">
|
||||
<?php echo script_src("../adminer/static/functions.js"); ?>
|
||||
<?php echo script_src("static/editing.js"); ?>
|
||||
<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?" . filemtime("../adminer/static/functions.js")); ?>
|
||||
<?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>
|
||||
<?php if ($adminer->head()) { ?>
|
||||
<link rel="shortcut icon" type="image/x-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">
|
||||
<script<?php echo nonce(); ?>>
|
||||
document.body.onkeydown = bodyKeydown;
|
||||
document.body.onclick = bodyClick;
|
||||
<?php if (!isset($_COOKIE["adminer_version"])): ?>
|
||||
document.body.onload = function () { verifyVersion('<?php echo $VERSION; ?>', '<?php echo js_escape(ME); ?>', '<?php echo get_token(); ?>') };
|
||||
<?php endif; ?>
|
||||
document.body.className = document.body.className.replace(/ nojs/, ' js');
|
||||
const body = document.body;
|
||||
|
||||
body.onkeydown = bodyKeydown;
|
||||
body.onclick = bodyClick;
|
||||
body.classList.remove("nojs");
|
||||
body.classList.add("js");
|
||||
|
||||
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
|
||||
var thousandsSeparator = '<?php echo js_escape(lang(',')); ?>';
|
||||
</script>
|
||||
|
||||
<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">
|
||||
<?php
|
||||
if ($breadcrumb !== null) {
|
||||
echo '<p id="breadcrumb">';
|
||||
|
||||
$link = substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1);
|
||||
echo '<a href="' . h($link ?: ".") . '">' . lang('Home') . '</a> » ';
|
||||
echo '<a href="' . h(HOME_URL) . '">' . lang('Home') . '</a> » ';
|
||||
|
||||
$server = "";
|
||||
if ($breadcrumb === false) {
|
||||
@@ -188,19 +188,19 @@ function page_messages($error) {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
echo "</div>"; // #content
|
||||
|
||||
echo "<div id='footer'>\n";
|
||||
switch_lang();
|
||||
language_select();
|
||||
|
||||
if ($missing != "auth") {
|
||||
?>
|
||||
?>
|
||||
|
||||
<div class="logout">
|
||||
<form action="" method="post">
|
||||
|
||||
@@ -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>
|
||||
<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><?php echo lang('Options'); /* no label required, options have their own label */ ?></td>
|
||||
<?php if ($type == "TABLE") { ?>
|
||||
@@ -621,7 +621,7 @@ function doc_link(array $paths, $text = "<sup>?</sup>") {
|
||||
];
|
||||
|
||||
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']));
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ function min_version($version, $maria_db = "", $connection2 = null) {
|
||||
$server_info = $match[1];
|
||||
$version = $maria_db;
|
||||
}
|
||||
if ($version == "") {
|
||||
return false;
|
||||
}
|
||||
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);
|
||||
return "$match[1]?"
|
||||
. (sid() ? SID . "&" : "")
|
||||
. ($vendor != "server" || $server != "" ? urlencode($vendor) . "=" . urlencode($server) . "&" : "")
|
||||
. urlencode($vendor) . "=" . urlencode($server) . "&"
|
||||
. "username=" . urlencode($username)
|
||||
. ($db != "" ? "&db=" . urlencode($db) : "")
|
||||
. ($match[2] ? "&$match[2]" : "")
|
||||
@@ -830,6 +833,8 @@ function is_utf8($val) {
|
||||
* @return string escaped string with appended ...
|
||||
*/
|
||||
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
|
||||
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]));
|
||||
echo (count($functions) > 1
|
||||
? "<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;", "")
|
||||
: h(reset($functions))
|
||||
) . '<td>';
|
||||
@@ -1486,13 +1491,26 @@ function lzw_decompress($binary) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Return events to display help on mouse over
|
||||
* @param string JS expression
|
||||
* @param bool JS expression
|
||||
* @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});", "");
|
||||
/**
|
||||
* @param string $text Help text.
|
||||
* @param bool $side Side position.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
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
|
||||
@@ -1560,6 +1578,10 @@ function edit_form($table, $fields, $row, $update) {
|
||||
$value = "";
|
||||
$function = "now";
|
||||
}
|
||||
if ($field["type"] == "uuid" && $value == "uuid()") {
|
||||
$value = "";
|
||||
$function = "uuid";
|
||||
}
|
||||
input($field, $value, $function);
|
||||
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"
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[1].firstChild);"))
|
||||
: ($_POST || !$fields ? "" : script("focus(qsa('td', gid('form'))[1].firstChild);"))
|
||||
);
|
||||
if (isset($_GET["select"])) {
|
||||
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
// not used in a single language version
|
||||
|
||||
$langs = array(
|
||||
$languages = [
|
||||
'en' => 'English', // Jakub Vrána - https://www.vrana.cz
|
||||
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
|
||||
'bg' => 'Български', // Deyan Delchev
|
||||
@@ -25,8 +24,8 @@ $langs = array(
|
||||
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
|
||||
'ka' => 'ქართული', // Saba Khmaladze skhmaladze@uglt.org
|
||||
'ko' => '한국어', // dalli - skcha67@gmail.com
|
||||
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
|
||||
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
|
||||
'lv' => 'Latviešu', // Kristaps Lediņš - https://krysits.com
|
||||
'lt' => 'Lietuvių', // Paulius Leščinskas - http://www.lescinskas.lt
|
||||
'ms' => 'Bahasa Melayu', // Pisyek
|
||||
'nl' => 'Nederlands', // Maarten Balliauw - http://blog.maartenballiauw.be
|
||||
'no' => 'Norsk', // Iver Odin Kvello, mupublishing.com
|
||||
@@ -46,24 +45,59 @@ $langs = array(
|
||||
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail
|
||||
'zh' => '简体中文', // Mr. Lodar, vea - urn2.net - vea.urn2@gmail.com
|
||||
'zh-tw' => '繁體中文', // http://tzangms.com
|
||||
);
|
||||
];
|
||||
|
||||
/** Get current language
|
||||
* @return string
|
||||
*/
|
||||
function get_lang() {
|
||||
/**
|
||||
* Returns the list of available languages.
|
||||
* In compiled version, only selected languages are returned.
|
||||
*
|
||||
* @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;
|
||||
return $LANG;
|
||||
}
|
||||
|
||||
/** Translate string
|
||||
* @param string
|
||||
* @param int
|
||||
* @return string
|
||||
*/
|
||||
function lang($idf, $number = null) {
|
||||
/**
|
||||
* Returns translated text.
|
||||
*
|
||||
* @param string|int $key Numeric key is used in compiled version.
|
||||
* @param ?int $number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function lang($key, $number = null)
|
||||
{
|
||||
global $LANG, $translations;
|
||||
$translation = ($translations[$idf] ? $translations[$idf] : $idf);
|
||||
|
||||
$key = convert_translation_key($key);
|
||||
$translation = $translations[$key] ?: $key;
|
||||
|
||||
if (is_array($translation)) {
|
||||
$pos = ($number == 1 ? 0
|
||||
: ($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
|
||||
: 1 // different forms for 1, other
|
||||
))))))); // http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
|
||||
|
||||
$translation = $translation[$pos];
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
|
||||
$format = str_replace("%d", "%s", $translation);
|
||||
if ($format != $translation) {
|
||||
$args[0] = format_number($number);
|
||||
}
|
||||
|
||||
return vsprintf($format, $args);
|
||||
}
|
||||
|
||||
function switch_lang() {
|
||||
global $LANG, $langs;
|
||||
function language_select()
|
||||
{
|
||||
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 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='hidden' name='token' value='" . get_token() . "'>\n"; // $token may be empty in auth.inc.php
|
||||
echo "</form></div>\n";
|
||||
@@ -96,31 +148,37 @@ function switch_lang() {
|
||||
|
||||
if (isset($_POST["lang"]) && verify_token()) { // $error not yet available
|
||||
cookie("adminer_lang", $_POST["lang"]);
|
||||
|
||||
$_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());
|
||||
}
|
||||
|
||||
$LANG = "en";
|
||||
if (isset($langs[$_COOKIE["adminer_lang"]])) {
|
||||
$available_languages = get_available_languages();
|
||||
$LANG = $available_languages[0];
|
||||
|
||||
if (isset($available_languages[$_COOKIE["adminer_lang"]])) {
|
||||
cookie("adminer_lang", $_COOKIE["adminer_lang"]);
|
||||
$LANG = $_COOKIE["adminer_lang"];
|
||||
} elseif (isset($langs[$_SESSION["lang"]])) {
|
||||
} elseif (isset($available_languages[$_SESSION["lang"]])) {
|
||||
$LANG = $_SESSION["lang"];
|
||||
} 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);
|
||||
foreach ($matches as $match) {
|
||||
$accept_language[$match[1]] = (isset($match[3]) ? $match[3] : 1);
|
||||
}
|
||||
|
||||
arsort($accept_language);
|
||||
foreach ($accept_language as $key => $q) {
|
||||
if (isset($langs[$key])) {
|
||||
if (isset($available_languages[$key])) {
|
||||
$LANG = $key;
|
||||
break;
|
||||
}
|
||||
|
||||
$key = preg_replace('~-.*~', '', $key);
|
||||
if (!isset($accept_language[$key]) && isset($langs[$key])) {
|
||||
if (!isset($accept_language[$key]) && isset($available_languages[$key])) {
|
||||
$LANG = $key;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
if (extension_loaded('pdo')) {
|
||||
/*abstract*/ class Min_PDO {
|
||||
var $_result, $server_info, $affected_rows, $errno, $error, $pdo;
|
||||
|
||||
|
||||
function __construct() {
|
||||
global $adminer;
|
||||
$pos = array_search("SQL", $adminer->operators);
|
||||
@@ -11,10 +11,10 @@ if (extension_loaded('pdo')) {
|
||||
unset($adminer->operators[$pos]);
|
||||
}
|
||||
}
|
||||
|
||||
function dsn($dsn, $username, $password, $options = array()) {
|
||||
|
||||
function dsn($dsn, $username, $password, $options = []) {
|
||||
$options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
|
||||
$options[PDO::ATTR_STATEMENT_CLASS] = array('Min_PDOStatement');
|
||||
$options[PDO::ATTR_STATEMENT_CLASS] = [Min_PDOStatement::class];
|
||||
try {
|
||||
$this->pdo = new PDO($dsn, $username, $password, $options);
|
||||
} catch (Exception $ex) {
|
||||
@@ -22,13 +22,13 @@ if (extension_loaded('pdo')) {
|
||||
}
|
||||
$this->server_info = @$this->pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
}
|
||||
|
||||
|
||||
/*abstract function select_db($database);*/
|
||||
|
||||
|
||||
function quote($string) {
|
||||
return $this->pdo->quote($string);
|
||||
}
|
||||
|
||||
|
||||
function query($query, $unbuffered = false) {
|
||||
$result = $this->pdo->query($query);
|
||||
$this->error = "";
|
||||
@@ -42,11 +42,11 @@ if (extension_loaded('pdo')) {
|
||||
$this->store_result($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
function multi_query($query) {
|
||||
return $this->_result = $this->query($query);
|
||||
}
|
||||
|
||||
|
||||
function store_result($result = null) {
|
||||
if (!$result) {
|
||||
$result = $this->_result;
|
||||
@@ -61,7 +61,7 @@ if (extension_loaded('pdo')) {
|
||||
$this->affected_rows = $result->rowCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function next_result() {
|
||||
if (!$this->_result) {
|
||||
return false;
|
||||
@@ -69,7 +69,7 @@ if (extension_loaded('pdo')) {
|
||||
$this->_result->_offset = 0;
|
||||
return @$this->_result->nextRowset(); // @ - PDO_PgSQL doesn't support it
|
||||
}
|
||||
|
||||
|
||||
function result($query, $field = 0) {
|
||||
$result = $this->query($query);
|
||||
if (!$result) {
|
||||
@@ -79,18 +79,18 @@ if (extension_loaded('pdo')) {
|
||||
return $row[$field];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Min_PDOStatement extends PDOStatement {
|
||||
var $_offset = 0, $num_rows;
|
||||
|
||||
|
||||
function fetch_assoc() {
|
||||
return $this->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
|
||||
function fetch_row() {
|
||||
return $this->fetch(PDO::FETCH_NUM);
|
||||
}
|
||||
|
||||
|
||||
function fetch_field() {
|
||||
$row = (object) $this->getColumnMeta($this->_offset++);
|
||||
$row->orgtable = $row->table;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
<?php
|
||||
$VERSION = "4.10";
|
||||
$VERSION = "4.12";
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<?php
|
||||
/** Adminer - Compact database management
|
||||
* @link https://www.adminer.org/
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @copyright 2007 Jakub Vrana
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
/**
|
||||
* Adminer - Database management in a single PHP file
|
||||
*
|
||||
* @link https://github.com/pematon/adminer
|
||||
* @author Jakub Vrana (https://www.vrana.cz/)
|
||||
* @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/tmpfile.inc.php";
|
||||
|
||||
@@ -31,7 +31,6 @@ $translations = array(
|
||||
'Create database' => 'إنشاء قاعدة بيانات',
|
||||
'SQL command' => 'استعلام SQL',
|
||||
'Logout' => 'تسجيل الخروج',
|
||||
'database' => 'قاعدة بيانات',
|
||||
'Use' => 'استعمال',
|
||||
'No tables.' => 'لا توجد جداول.',
|
||||
'select' => 'تحديد',
|
||||
@@ -68,7 +67,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'يتعذر اختيار الجدول',
|
||||
'Invalid CSRF token. Send the form again.' => 'رمز CSRF غير صالح. المرجو إرسال الاستمارة مرة أخرى.',
|
||||
'Comment' => 'تعليق',
|
||||
'Default values' => 'القيم الافتراضية',
|
||||
'%d byte(s)' => '%d بايت',
|
||||
'No commands to execute.' => 'لا توجد أوامر للتنفيذ.',
|
||||
'Unable to upload a file.' => 'يتعذر رفع ملف ما.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -17,6 +17,8 @@ $translations = array(
|
||||
'Language' => 'Език',
|
||||
'Invalid CSRF token. Send the form again.' => 'Невалиден шифроващ ключ. Попълнете и изпратете формуляра отново.',
|
||||
'If you did not send this request from Adminer then close this page.' => 'Ако не сте изпратили тази заявка през Adminer, затворете тази страница.',
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
'No extension' => 'Няма разширение',
|
||||
'None of the supported PHP extensions (%s) are available.' => 'Никое от поддържаните PHP разширения (%s) не е налично.',
|
||||
'Session support must be enabled.' => 'Поддръжката на сесии трябва да е разрешена.',
|
||||
@@ -79,7 +81,6 @@ $translations = array(
|
||||
'Data' => 'Данни',
|
||||
|
||||
'Database' => 'База данни',
|
||||
'database' => 'база данни',
|
||||
'Use' => 'Избор',
|
||||
'Select database' => 'Избор на база данни',
|
||||
'Invalid database.' => 'Невалидна база данни.',
|
||||
@@ -166,7 +167,6 @@ $translations = array(
|
||||
'Options' => 'Опции',
|
||||
'Comment' => 'Коментар',
|
||||
'Default value' => 'Стойност по подразбиране',
|
||||
'Default values' => 'Стойности по подразбиране',
|
||||
'Drop' => 'Премахване',
|
||||
'Are you sure?' => 'Сигурни ли сте?',
|
||||
'Size' => 'Големина',
|
||||
@@ -314,12 +314,15 @@ $translations = array(
|
||||
'Please use one of the extensions %s.' => 'Моля, използвайте някое от разширенията %s.',
|
||||
|
||||
// PostgreSQL and MS SQL schema support
|
||||
'Schema' => 'Схема',
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'Alter schema' => 'Промяна на схемата',
|
||||
'Create schema' => 'Създаване на схема',
|
||||
'Schema has been dropped.' => 'Схемата беше премахната.',
|
||||
'Schema has been created.' => 'Схемата беше създадена.',
|
||||
'Schema has been altered.' => 'Схемата беше променена.',
|
||||
'Schema' => 'Схема',
|
||||
'Invalid schema.' => 'Невалидна схема.',
|
||||
|
||||
// PostgreSQL sequences support
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'ডাটাবেজ তৈরী করুন',
|
||||
'SQL command' => 'SQL-কমান্ড',
|
||||
'Logout' => 'লগআউট',
|
||||
'database' => 'ডাটাবেজ',
|
||||
'Use' => 'ব্যবহার',
|
||||
'No tables.' => 'কোন টেবিল নাই।',
|
||||
'select' => 'নির্বাচন',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'টেবিল নির্বাচন করতে অক্ষম',
|
||||
'Invalid CSRF token. Send the form again.' => 'অবৈধ CSRF টোকেন। ফর্মটি আবার পাঠান।',
|
||||
'Comment' => 'মন্তব্য',
|
||||
'Default values' => 'ডিফল্ট মান',
|
||||
'%d byte(s)' => array('%d বাইট', '%d বাইটসমূহ'),
|
||||
'No commands to execute.' => 'সম্পাদন করার মত কোন নির্দেশ নেই।',
|
||||
'Unable to upload a file.' => 'ফাইল আপলোড করা সম্ভব হচ্ছে না।',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -74,7 +74,6 @@ $translations = array(
|
||||
'Data' => 'Podaci',
|
||||
|
||||
'Database' => 'Baza podataka',
|
||||
'database' => 'baza podataka',
|
||||
'Use' => 'Koristi',
|
||||
'Select database' => 'Izaberite bazu',
|
||||
'Invalid database.' => 'Neispravna baza podataka.',
|
||||
@@ -159,7 +158,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Auto-priraštaj',
|
||||
'Options' => 'Opcije',
|
||||
'Comment' => 'Komentar',
|
||||
'Default values' => 'Podrazumijevane vrijednosti',
|
||||
'Drop' => 'Izbriši',
|
||||
'Are you sure?' => 'Da li ste sigurni?',
|
||||
'Move up' => 'Pomijeri na gore',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Ne',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Crea una base de dades',
|
||||
'SQL command' => 'Ordre SQL',
|
||||
'Logout' => 'Desconnecta',
|
||||
'database' => 'base de dades',
|
||||
'Use' => 'Utilitza',
|
||||
'No tables.' => 'No hi ha cap taula.',
|
||||
'select' => 'registres',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Comentari',
|
||||
'Default values' => 'Valors per defecte',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Cap comanda per executar.',
|
||||
'Unable to upload a file.' => 'Impossible adjuntar el fitxer.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -21,6 +21,8 @@ $translations = array(
|
||||
'Language' => 'Jazyk',
|
||||
'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.',
|
||||
'No driver' => 'Žádný ovladač',
|
||||
'Database driver not found.' => 'Databázový ovladač se nenašel.',
|
||||
'No extension' => 'Žádné rozšíření',
|
||||
'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.',
|
||||
@@ -89,7 +91,6 @@ $translations = array(
|
||||
'Data' => 'Data',
|
||||
|
||||
'Database' => 'Databáze',
|
||||
'database' => 'databáze',
|
||||
'DB' => 'DB',
|
||||
'Use' => 'Vybrat',
|
||||
'Select database' => 'Vybrat databázi',
|
||||
@@ -178,7 +179,6 @@ $translations = array(
|
||||
'Options' => 'Volby',
|
||||
'Comment' => 'Komentář',
|
||||
'Default value' => 'Výchozí hodnota',
|
||||
'Default values' => 'Výchozí hodnoty',
|
||||
'Drop' => 'Odstranit',
|
||||
'Drop %s?' => 'Odstranit %s?',
|
||||
'Are you sure?' => 'Opravdu?',
|
||||
@@ -259,8 +259,8 @@ $translations = array(
|
||||
'%d row(s)' => array('%d řádek', '%d řádky', '%d řádků'),
|
||||
'Page' => 'Stránka',
|
||||
'last' => 'poslední',
|
||||
'Load more data' => 'Nahrát další data',
|
||||
'Loading' => 'Nahrává se',
|
||||
'Load more data' => 'Načíst další data',
|
||||
'Loading' => 'Načítá se',
|
||||
'Whole result' => 'Celý výsledek',
|
||||
'%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.',
|
||||
|
||||
// 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',
|
||||
'Create schema' => 'Vytvořit schéma',
|
||||
'Schema has been dropped.' => 'Schéma bylo odstraněno.',
|
||||
'Schema has been created.' => 'Schéma bylo vytvořeno.',
|
||||
'Schema has been altered.' => 'Schéma bylo změněno.',
|
||||
'Schema' => 'Schéma',
|
||||
'Invalid schema.' => 'Nesprávné schéma.',
|
||||
|
||||
// PostgreSQL sequences support
|
||||
|
||||
@@ -65,7 +65,6 @@ $translations = array(
|
||||
'Format' => 'Format',
|
||||
'Data' => 'Data',
|
||||
'Database' => 'Database',
|
||||
'database' => 'database',
|
||||
'Use' => 'Brug',
|
||||
'Select database' => 'Vælg database',
|
||||
'Invalid database.' => 'Ugyldig database.',
|
||||
@@ -144,7 +143,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Auto Increment',
|
||||
'Options' => 'Valg',
|
||||
'Comment' => 'Kommentarer',
|
||||
'Default values' => 'Standardværdier',
|
||||
'Drop' => 'Drop',
|
||||
'Are you sure?' => 'Er du sikker?',
|
||||
'Move up' => 'Flyt op',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Nej',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -33,7 +33,6 @@ $translations = array(
|
||||
'Create database' => 'Datenbank erstellen',
|
||||
'SQL command' => 'SQL-Kommando',
|
||||
'Logout' => 'Abmelden',
|
||||
'database' => 'Datenbank',
|
||||
'Use' => 'Benutzung',
|
||||
'No tables.' => 'Keine Tabellen.',
|
||||
'select' => 'zeigen',
|
||||
@@ -71,7 +70,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Kommentar',
|
||||
'Default values' => 'Vorgabewerte festlegen',
|
||||
'%d byte(s)' => array('%d Byte', '%d Bytes'),
|
||||
'No commands to execute.' => 'Kein Kommando vorhanden.',
|
||||
'Unable to upload a file.' => 'Hochladen von Datei fehlgeschlagen.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Nein',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -80,7 +80,6 @@ $translations = array(
|
||||
'Data' => 'Δεδομένα',
|
||||
|
||||
'Database' => 'Β. Δεδομένων',
|
||||
'database' => 'β. δεδομένων',
|
||||
'Use' => 'χρήση',
|
||||
'Select database' => 'Επιλέξτε Β.Δ.',
|
||||
'Invalid database.' => 'Λανθασμένη Β.Δ.',
|
||||
@@ -167,7 +166,6 @@ $translations = array(
|
||||
'Options' => 'Επιλογές',
|
||||
'Comment' => 'Σχόλιο',
|
||||
'Default value' => 'Προεπιλεγμένη τιμή',
|
||||
'Default values' => 'Προεπιλεγμένες τιμές',
|
||||
'Drop' => 'Διαγραφή',
|
||||
'Are you sure?' => 'Είστε σίγουρος;',
|
||||
'Size' => 'Μέγεθος',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ $translations = array(
|
||||
'Home' => null,
|
||||
'Login' => 'Login',
|
||||
'Logout successful.' => 'Sesión finalizada con éxito.',
|
||||
'Invalid server or credentials.' => null,
|
||||
'Invalid server or credentials.' => 'Servidor o credenciales no válidos.',
|
||||
'Server' => 'Servidor',
|
||||
'Username' => 'Usuario',
|
||||
'Password' => 'Contraseña',
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Crear Base de datos',
|
||||
'SQL command' => 'Comando SQL',
|
||||
'Logout' => 'Cerrar sesión',
|
||||
'database' => 'base de datos',
|
||||
'Use' => 'Usar',
|
||||
'No tables.' => 'No existen tablas.',
|
||||
'select' => 'registros',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Comentario',
|
||||
'Default values' => 'Valores predeterminados',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'No es posible ejecutar ningún comando.',
|
||||
'Unable to upload a file.' => 'No es posible importar el archivo.',
|
||||
@@ -226,7 +224,7 @@ $translations = array(
|
||||
'Permanent login' => 'Guardar contraseña',
|
||||
'Databases have been dropped.' => 'Bases de datos eliminadas.',
|
||||
'Search data in tables' => 'Buscar datos en tablas',
|
||||
'as a regular expression' => null,
|
||||
'as a regular expression' => 'como una expresión regular',
|
||||
'Schema' => 'Esquema',
|
||||
'Alter schema' => 'Modificar esquema',
|
||||
'Create schema' => 'Crear esquema',
|
||||
@@ -269,42 +267,42 @@ $translations = array(
|
||||
'Edit all' => 'Editar todos',
|
||||
'HH:MM:SS' => 'HH:MM:SS',
|
||||
|
||||
'Drop %s?' => null,
|
||||
'Tables have been optimized.' => null,
|
||||
'Materialized view' => null,
|
||||
'Vacuum' => null,
|
||||
'Selected' => null,
|
||||
'overwrite' => null,
|
||||
'DB' => null,
|
||||
'File must be in UTF-8 encoding.' => null,
|
||||
'Modify' => null,
|
||||
'Load more data' => null,
|
||||
'Loading' => null,
|
||||
'ATTACH queries are not supported.' => null,
|
||||
'Warnings' => null,
|
||||
'%d / ' => array(),
|
||||
'Limit rows' => null,
|
||||
'Adminer does not support accessing a database without a password, <a href="https://www.adminer.org/en/password/"%s>more information</a>.' => null,
|
||||
'Default value' => null,
|
||||
'Drop %s?' => '¿Eliminar %s?',
|
||||
'Tables have been optimized.' => 'Tablas optimizadas.',
|
||||
'Materialized view' => 'Vista materializada',
|
||||
'Vacuum' => 'Vacio',
|
||||
'Selected' => 'Seleccionado',
|
||||
'overwrite' => 'sobreescribir',
|
||||
'DB' => 'DB',
|
||||
'File must be in UTF-8 encoding.' => 'El archivo debe estar codificado en UTF-8.',
|
||||
'Modify' => 'Modificar',
|
||||
'Load more data' => 'Cargar mas datos',
|
||||
'Loading' => 'Cargando',
|
||||
'ATTACH queries are not supported.' => 'ATTACH consultas no está soportado.',
|
||||
'Warnings' => 'Advertencias',
|
||||
'%d / ' => '%d / ',
|
||||
'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>.' => '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' => 'Valor por defecto',
|
||||
'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,
|
||||
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => null,
|
||||
'The action will be performed after successful login with the same credentials.' => null,
|
||||
'Connecting to privileged ports is not allowed.' => null,
|
||||
'There is a space in the input password which might be the cause.' => null,
|
||||
'If you did not send this request from Adminer then close this page.' => null,
|
||||
'You can upload a big SQL file via FTP and import it from server.' => null,
|
||||
'Size' => null,
|
||||
'Compute' => null,
|
||||
'You are offline.' => null,
|
||||
'You have no privileges to update this table.' => null,
|
||||
'Saving' => null,
|
||||
'Unknown error.' => null,
|
||||
'Database does not support password.' => null,
|
||||
'Disable %s or enable %s or %s extensions.' => null,
|
||||
'yes' => null,
|
||||
'no' => 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.' => 'La acción se realizará tras iniciar sesión de nuevo con las mismas credenciales.',
|
||||
'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.' => '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.' => '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.' => 'Puede cargar un fichero SQL grande por FTP e importarlo desde el servidor.',
|
||||
'Size' => 'Tamaño',
|
||||
'Compute' => 'Procesar',
|
||||
'You are offline.' => 'Se encuentra desconectado.',
|
||||
'You have no privileges to update this table.' => 'No tiene privilegios para actualizar esta tabla.',
|
||||
'Saving' => 'Guardando',
|
||||
'Unknown error.' => 'Error desconocido.',
|
||||
'Database does not support password.' => 'La Base de Datos no soporta el uso de contraseña.',
|
||||
'Disable %s or enable %s or %s extensions.' => 'Deshabilitar %s o habilitar %s o %s extensiones.',
|
||||
'yes' => 'si',
|
||||
'no' => 'no',
|
||||
|
||||
'Columns' => null,
|
||||
'Nullable' => null,
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Loo uus andmebaas',
|
||||
'SQL command' => 'SQL-Päring',
|
||||
'Logout' => 'Logi välja',
|
||||
'database' => 'andmebaas',
|
||||
'Use' => 'Kasuta',
|
||||
'No tables.' => 'Tabeleid ei leitud.',
|
||||
'select' => 'kuva',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'Tabeli valimine ebaõnnestus',
|
||||
'Invalid CSRF token. Send the form again.' => 'Sobimatu CSRF, palun postitage vorm uuesti.',
|
||||
'Comment' => 'Kommentaar',
|
||||
'Default values' => 'Vaikimisi väärtused',
|
||||
'%d byte(s)' => array('%d bait', '%d baiti'),
|
||||
'No commands to execute.' => 'Käsk puudub.',
|
||||
'Unable to upload a file.' => 'Faili üleslaadimine pole võimalik.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -78,7 +78,6 @@ $translations = array(
|
||||
'Data' => 'داده',
|
||||
|
||||
'Database' => 'پایگاه داده',
|
||||
'database' => 'پایگاه داده',
|
||||
'Use' => 'استفاده',
|
||||
'Select database' => 'انتخاب پایگاه داده',
|
||||
'Invalid database.' => 'پایگاه داده نامعتبر.',
|
||||
@@ -165,7 +164,6 @@ $translations = array(
|
||||
'Options' => 'اختیارات',
|
||||
'Comment' => 'توضیح',
|
||||
'Default value' => 'مقدار پیش فرض',
|
||||
'Default values' => 'مقادیر پیش فرض',
|
||||
'Drop' => 'حذف',
|
||||
'Are you sure?' => 'مطمئن هستید؟',
|
||||
'Size' => 'حجم',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -80,7 +80,6 @@ $translations = array(
|
||||
'Data' => 'Data',
|
||||
|
||||
'Database' => 'Tietokanta',
|
||||
'database' => 'tietokanta',
|
||||
'Use' => 'Käytä',
|
||||
'Select database' => 'Valitse tietokanta',
|
||||
'Invalid database.' => 'Tietokanta ei kelpaa.',
|
||||
@@ -167,7 +166,6 @@ $translations = array(
|
||||
'Options' => 'Asetukset',
|
||||
'Comment' => 'Kommentit',
|
||||
'Default value' => 'Oletusarvo',
|
||||
'Default values' => 'Oletusarvot',
|
||||
'Drop' => 'Poista',
|
||||
'Are you sure?' => 'Oletko varma?',
|
||||
'Size' => 'Koko',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Ei',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -31,7 +31,6 @@ $translations = array(
|
||||
'Create database' => 'Créer une base de données',
|
||||
'SQL command' => 'Requête SQL',
|
||||
'Logout' => 'Déconnexion',
|
||||
'database' => 'base de données',
|
||||
'Use' => 'Utiliser',
|
||||
'No tables.' => 'Aucune table.',
|
||||
'select' => 'select',
|
||||
@@ -68,7 +67,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Commentaire',
|
||||
'Default values' => 'Valeurs par défaut',
|
||||
'%d byte(s)' => array('%d octet', '%d octets'),
|
||||
'No commands to execute.' => 'Aucune commande à exécuter.',
|
||||
'Unable to upload a file.' => 'Impossible d\'importer le fichier.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Non',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Crear Base de datos',
|
||||
'SQL command' => 'Comando SQL',
|
||||
'Logout' => 'Pechar sesión',
|
||||
'database' => 'base de datos',
|
||||
'Use' => 'Usar',
|
||||
'No tables.' => 'Nengunha táboa.',
|
||||
'select' => 'selecciona',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Comentario',
|
||||
'Default values' => 'Valores predeterminados',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Non hai comandos para executar.',
|
||||
'Unable to upload a file.' => 'Non é posible importar o ficheiro.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Non',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -31,7 +31,6 @@ $translations = array(
|
||||
'Create database' => 'צור מסד נתונים',
|
||||
'SQL command' => 'שאילתת SQL',
|
||||
'Logout' => 'התנתק',
|
||||
'database' => 'מסד נתונים',
|
||||
'Use' => 'השתמש',
|
||||
'No tables.' => 'אין טבלאות',
|
||||
'select' => 'בחר',
|
||||
@@ -68,7 +67,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'בחירת הטבלה נכשלה',
|
||||
'Invalid CSRF token. Send the form again.' => 'כשל באבטחת נתונים, שלח טופס שוב',
|
||||
'Comment' => 'הערה',
|
||||
'Default values' => 'ערכי ברירת מחדל',
|
||||
'%d byte(s)' => '%d בתים',
|
||||
'No commands to execute.' => 'לא נמצאו פקודות להרצה',
|
||||
'Unable to upload a file.' => 'העלאת הקובץ נכשלה',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Adatbázis létrehozása',
|
||||
'SQL command' => 'SQL parancs',
|
||||
'Logout' => 'Kilépés',
|
||||
'database' => 'adatbázis',
|
||||
'Use' => 'Használ',
|
||||
'No tables.' => 'Nincs tábla.',
|
||||
'select' => 'kiválasztás',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Megjegyzés',
|
||||
'Default values' => 'Alapértelmezett értékek',
|
||||
'%d byte(s)' => array('%d bájt', '%d bájt', '%d bájt'),
|
||||
'No commands to execute.' => 'Nincs végrehajtható parancs.',
|
||||
'Unable to upload a file.' => 'Nem tudom feltölteni a fájlt.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -74,7 +74,6 @@ $translations = array(
|
||||
'Data' => 'Data',
|
||||
|
||||
'Database' => 'Basis data',
|
||||
'database' => 'basis data',
|
||||
'Use' => 'Gunakan',
|
||||
'Select database' => 'Pilih basis data',
|
||||
'Invalid database.' => 'Basis data tidak sah.',
|
||||
@@ -159,7 +158,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Inkrementasi Otomatis',
|
||||
'Options' => 'Opsi',
|
||||
'Comment' => 'Komentar',
|
||||
'Default values' => 'Nilai bawaan',
|
||||
'Drop' => 'Hapus',
|
||||
'Are you sure?' => 'Anda yakin?',
|
||||
'Move up' => 'Naik',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Crea database',
|
||||
'SQL command' => 'Comando SQL',
|
||||
'Logout' => 'Esci',
|
||||
'database' => 'database',
|
||||
'Use' => 'Usa',
|
||||
'No tables.' => 'No tabelle.',
|
||||
'select' => 'seleziona',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'Selezione della tabella non riuscita',
|
||||
'Invalid CSRF token. Send the form again.' => 'Token CSRF non valido. Reinvia la richiesta.',
|
||||
'Comment' => 'Commento',
|
||||
'Default values' => 'Valori predefiniti',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Nessun commando da eseguire.',
|
||||
'Unable to upload a file.' => 'Caricamento del file non riuscito.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'No',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'データベースを作成',
|
||||
'SQL command' => 'SQLコマンド',
|
||||
'Logout' => 'ログアウト',
|
||||
'database' => 'データベース',
|
||||
'Use' => '使用',
|
||||
'No tables.' => 'テーブルがありません。',
|
||||
'select' => '選択',
|
||||
@@ -69,7 +68,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'テーブルを選択できません',
|
||||
'Invalid CSRF token. Send the form again.' => '不正なCSRFトークン。再送信してください',
|
||||
'Comment' => 'コメント',
|
||||
'Default values' => '規定値',
|
||||
'%d byte(s)' => '%d バイト',
|
||||
'No commands to execute.' => '実行するコマンドがありません',
|
||||
'Unable to upload a file.' => 'ファイルをアップロードできません',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'ბაზის შექმნა',
|
||||
'SQL command' => 'SQL-ბრძანება',
|
||||
'Logout' => 'გასვლა',
|
||||
'database' => 'ბაზა',
|
||||
'Use' => 'არჩევა',
|
||||
'No tables.' => 'ბაზაში ცხრილი არაა.',
|
||||
'select' => 'არჩევა',
|
||||
@@ -69,7 +68,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'ცხრილიდან ინფორმაცია ვერ მოვიპოვე',
|
||||
'Invalid CSRF token. Send the form again.' => 'უმოქმედო CSRF-ტოკენი. ფორმის კიდევ ერთხელ გაგზავნა.',
|
||||
'Comment' => 'კომენტარები',
|
||||
'Default values' => 'სტანდარტული მნიშვნელობა',
|
||||
'%d byte(s)' => '%d ბაიტი',
|
||||
'No commands to execute.' => 'შესასრულებელი ბრძანება არაა.',
|
||||
'Unable to upload a file.' => 'ფაილი არ აიტვირთა სერვერზე.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -72,11 +72,9 @@ $translations = array(
|
||||
'Database has been dropped.' => '데이터베이스를 삭제했습니다.',
|
||||
'Database has been renamed.' => '데이터베이스의 이름을 바꾸었습니다.',
|
||||
'Database schema' => '데이터베이스 구조',
|
||||
'database' => '데이터베이스',
|
||||
'Database' => '데이터베이스',
|
||||
'Databases have been dropped.' => '데이터베이스를 삭제했습니다.',
|
||||
'Date and time' => '시간',
|
||||
'Default values' => '기본값',
|
||||
'Delete' => '삭제',
|
||||
'descending' => '역순',
|
||||
'Drop' => '삭제',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -74,7 +74,6 @@ $translations = array(
|
||||
'Data' => 'Duomenys',
|
||||
|
||||
'Database' => 'Duomenų bazė',
|
||||
'database' => 'duomenų bazė',
|
||||
'Use' => 'Naudoti',
|
||||
'Select database' => 'Pasirinkti duomenų bazę',
|
||||
'Invalid database.' => 'Neteisinga duomenų bazė.',
|
||||
@@ -158,7 +157,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Auto Increment',
|
||||
'Options' => 'Nustatymai',
|
||||
'Comment' => 'Komentaras',
|
||||
'Default values' => 'Reikšmės pagal nutylėjimą',
|
||||
'Drop' => 'Pašalinti',
|
||||
'Are you sure?' => 'Tikrai?',
|
||||
'Move up' => 'Perkelti į viršų',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Izveidot datubāzi',
|
||||
'SQL command' => 'SQL pieprasījums',
|
||||
'Logout' => 'Iziet',
|
||||
'database' => 'datubāze',
|
||||
'Use' => 'Lietot',
|
||||
'No tables.' => 'Datubāzē nav tabulu.',
|
||||
'select' => 'izvēlēties',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Komentārs',
|
||||
'Default values' => 'Noklusētā vērtība',
|
||||
'%d byte(s)' => array('%d baits', '%d baiti', '%d baiti'),
|
||||
'No commands to execute.' => 'Nav izpildāmu komandu.',
|
||||
'Unable to upload a file.' => 'Neizdevās ielādēt failu uz servera.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Nē',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -83,7 +83,6 @@ $translations = array(
|
||||
'Data' => 'Data',
|
||||
|
||||
'Database' => 'Pangkalan data',
|
||||
'database' => 'pangkalan data',
|
||||
'Use' => 'Guna',
|
||||
'Select database' => 'Pilih pangkalan data',
|
||||
'Invalid database.' => 'Pangkalan data tidak sah.',
|
||||
@@ -170,7 +169,6 @@ $translations = array(
|
||||
'Options' => 'Pilihan',
|
||||
'Comment' => 'Komen',
|
||||
'Default value' => 'Nilai lalai',
|
||||
'Default values' => 'Nilai lalai',
|
||||
'Drop' => 'Jatuh',
|
||||
'Drop %s?' => 'Jatuhkan %s?',
|
||||
'Are you sure?' => 'Anda pasti?',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Tidak',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -33,7 +33,6 @@ $translations = array(
|
||||
'Create database' => 'Database aanmaken',
|
||||
'SQL command' => 'SQL opdracht',
|
||||
'Logout' => 'Afmelden',
|
||||
'database' => 'database',
|
||||
'Use' => 'Gebruik',
|
||||
'No tables.' => 'Geen tabellen.',
|
||||
'select' => 'kies',
|
||||
@@ -71,7 +70,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'Onmogelijk tabel te selecteren',
|
||||
'Invalid CSRF token. Send the form again.' => 'Ongeldig CSRF token. Verstuur het formulier opnieuw.',
|
||||
'Comment' => 'Commentaar',
|
||||
'Default values' => 'Standaard waarden',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Geen opdrachten uit te voeren.',
|
||||
'Unable to upload a file.' => 'Onmogelijk bestand te uploaden.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Neen',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -65,7 +65,6 @@ $translations = array(
|
||||
'Format' => 'Format',
|
||||
'Data' => 'Data',
|
||||
'Database' => 'Database',
|
||||
'database' => 'database',
|
||||
'Use' => 'Bruk',
|
||||
'Select database' => 'Velg database',
|
||||
'Invalid database.' => 'Ugyldig database.',
|
||||
@@ -144,7 +143,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Autoinkrement',
|
||||
'Options' => 'Valg',
|
||||
'Comment' => 'Kommentarer',
|
||||
'Default values' => 'Standardverdier',
|
||||
'Drop' => 'Dropp',
|
||||
'Are you sure?' => 'Er du sikker?',
|
||||
'Move up' => 'Flytt opp',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Nei',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -82,7 +82,6 @@ $translations = array(
|
||||
'Data' => 'Dane',
|
||||
|
||||
'Database' => 'Baza danych',
|
||||
'database' => 'baza danych',
|
||||
'Use' => 'Wybierz',
|
||||
'Select database' => 'Wybierz bazę danych',
|
||||
'Invalid database.' => 'Nie znaleziono bazy danych.',
|
||||
@@ -169,7 +168,6 @@ $translations = array(
|
||||
'Options' => 'Opcje',
|
||||
'Comment' => 'Komentarz',
|
||||
'Default value' => 'Wartość domyślna',
|
||||
'Default values' => 'Wartości domyślne',
|
||||
'Drop' => 'Usuń',
|
||||
'Drop %s?' => 'Usunąć %s?',
|
||||
'Are you sure?' => 'Czy jesteś pewien?',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Nie',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Criar Base de dados',
|
||||
'SQL command' => 'Comando SQL',
|
||||
'Logout' => 'Sair',
|
||||
'database' => 'base de dados',
|
||||
'Use' => 'Usar',
|
||||
'No tables.' => 'Não existem tabelas.',
|
||||
'select' => 'selecionar',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Comentário',
|
||||
'Default values' => 'Valores padrões',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Nenhum comando para executar.',
|
||||
'Unable to upload a file.' => 'Não é possível enviar o arquivo.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Criar Base de dados',
|
||||
'SQL command' => 'Comando SQL',
|
||||
'Logout' => 'Terminar sessão',
|
||||
'database' => 'base de dados',
|
||||
'Use' => 'Usar',
|
||||
'No tables.' => 'Não existem tabelas.',
|
||||
'select' => 'registos',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Comentário',
|
||||
'Default values' => 'Valores predeterminados',
|
||||
'%d byte(s)' => array('%d byte', '%d bytes'),
|
||||
'No commands to execute.' => 'Nenhum comando para executar.',
|
||||
'Unable to upload a file.' => 'Não é possível enviar o ficheiro.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Crează baza de date',
|
||||
'SQL command' => 'SQL query',
|
||||
'Logout' => 'Ieșire',
|
||||
'database' => 'baza de date',
|
||||
'Use' => 'Alege',
|
||||
'No tables.' => 'În baza de date nu sunt tabele.',
|
||||
'select' => 'selectează',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'Nu am putut selecta date din tabel',
|
||||
'Invalid CSRF token. Send the form again.' => 'CSRF token imposibil. Retrimite forma.',
|
||||
'Comment' => 'Comentariu',
|
||||
'Default values' => 'Valoarea inițială',
|
||||
'%d byte(s)' => array('%d octet', '%d octeți'),
|
||||
'No commands to execute.' => 'Nu sunt comenzi de executat.',
|
||||
'Unable to upload a file.' => 'Nu am putut încărca fișierul pe server.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'Создать базу данных',
|
||||
'SQL command' => 'SQL-запрос',
|
||||
'Logout' => 'Выйти',
|
||||
'database' => 'база данных',
|
||||
'Use' => 'Выбрать',
|
||||
'No tables.' => 'В базе данных нет таблиц.',
|
||||
'select' => 'выбрать',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'Не удалось получить данные из таблицы',
|
||||
'Invalid CSRF token. Send the form again.' => 'Недействительный CSRF-токен. Отправите форму ещё раз.',
|
||||
'Comment' => 'Комментарий',
|
||||
'Default values' => 'Значения по умолчанию',
|
||||
'%d byte(s)' => array('%d байт', '%d байта', '%d байтов'),
|
||||
'No commands to execute.' => 'Нет команд для выполнения.',
|
||||
'Unable to upload a file.' => 'Не удалось загрузить файл на сервер.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => 'Нет',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -33,7 +33,6 @@ $translations = array(
|
||||
'Create database' => 'Vytvoriť databázu',
|
||||
'SQL command' => 'SQL príkaz',
|
||||
'Logout' => 'Odhlásiť',
|
||||
'database' => 'databáza',
|
||||
'Use' => 'Vybrať',
|
||||
'No tables.' => 'Žiadne tabuľky.',
|
||||
'select' => 'vypísať',
|
||||
@@ -71,7 +70,6 @@ $translations = array(
|
||||
'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.',
|
||||
'Comment' => 'Komentár',
|
||||
'Default values' => 'Predvolené hodnoty',
|
||||
'%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'),
|
||||
'No commands to execute.' => 'Žiadne príkazy na vykonanie.',
|
||||
'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é.',
|
||||
'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ť',
|
||||
'No driver' => 'Žiadny ovládač',
|
||||
'Database driver not found.' => 'Databázový ovládač sa nenašiel.',
|
||||
'No extension' => 'Žiadne rozšírenie',
|
||||
'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é.',
|
||||
@@ -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.'),
|
||||
'Show only errors' => 'Zobraziť iba chyby',
|
||||
'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.',
|
||||
'now' => 'teraz',
|
||||
'ltr' => 'ltr',
|
||||
@@ -277,8 +277,8 @@ $translations = array(
|
||||
'DB' => 'DB',
|
||||
'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.',
|
||||
'Modify' => 'Zmeniť',
|
||||
'Load more data' => 'Nahráť ďalšie dáta',
|
||||
'Loading' => 'Nahráva sa',
|
||||
'Load more data' => 'Načítať ďalšie dáta',
|
||||
'Loading' => 'Načítava sa',
|
||||
'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.',
|
||||
'Warnings' => 'Varovania',
|
||||
'%d / ' => '%d / ',
|
||||
@@ -311,4 +311,7 @@ $translations = array(
|
||||
'Default' => 'Predvolené',
|
||||
'One Time Password' => 'Jednorázové heslo',
|
||||
'Invalid OTP code.' => 'Neplatný kód OTP.',
|
||||
'Schemas' => 'Schémy',
|
||||
'No schemas.' => 'Žiadne schémy.',
|
||||
'Show schema' => 'Zobraziť schému',
|
||||
);
|
||||
|
||||
@@ -73,7 +73,6 @@ $translations = array(
|
||||
'Data' => 'Podatki',
|
||||
|
||||
'Database' => 'Baza',
|
||||
'database' => 'baza',
|
||||
'Use' => 'Uporabi',
|
||||
'Select database' => 'Izberi bazo',
|
||||
'Invalid database.' => 'Neveljavna baza.',
|
||||
@@ -154,7 +153,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Samodejno povečevanje',
|
||||
'Options' => 'Možnosti',
|
||||
'Comment' => 'Komentar',
|
||||
'Default values' => 'Privzete vrednosti',
|
||||
'Drop' => 'Zavrzi',
|
||||
'Are you sure?' => 'Ste prepričani?',
|
||||
'Move up' => 'Premakni gor',
|
||||
@@ -355,4 +353,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -74,7 +74,6 @@ $translations = array(
|
||||
'Data' => 'Податци',
|
||||
|
||||
'Database' => 'База података',
|
||||
'database' => 'база података',
|
||||
'Use' => 'Користи',
|
||||
'Select database' => 'Изаберите базу',
|
||||
'Invalid database.' => 'Неисправна база података.',
|
||||
@@ -159,7 +158,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Ауто-прираштај',
|
||||
'Options' => 'Опције',
|
||||
'Comment' => 'Коментар',
|
||||
'Default values' => 'Подразумеване вредности',
|
||||
'Drop' => 'Избриши',
|
||||
'Are you sure?' => 'Да ли сте сигурни?',
|
||||
'Move up' => 'Помери на горе',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Не',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -90,7 +90,6 @@ $translations = array(
|
||||
'Data' => 'Data',
|
||||
|
||||
'Database' => 'Databas',
|
||||
'database' => 'databas',
|
||||
'DB' => 'DB',
|
||||
'Use' => 'Använd',
|
||||
'Select database' => 'Välj databas',
|
||||
@@ -179,7 +178,6 @@ $translations = array(
|
||||
'Options' => 'Inställningar',
|
||||
'Comment' => 'Kommentar',
|
||||
'Default value' => 'Standardvärde',
|
||||
'Default values' => 'Standardvärden',
|
||||
'Drop' => 'Ta bort',
|
||||
'Drop %s?' => 'Ta bort %s?',
|
||||
'Are you sure?' => 'Är du säker?',
|
||||
@@ -357,4 +355,10 @@ $translations = array(
|
||||
'No' => 'Nej',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'தகவல்தளத்தை உருவாக்கு',
|
||||
'SQL command' => 'SQL கட்டளை',
|
||||
'Logout' => 'வெளியேறு',
|
||||
'database' => 'தகவல்தளம்',
|
||||
'Use' => 'உபயோகி',
|
||||
'No tables.' => 'அட்டவணை இல்லை.',
|
||||
'select' => 'தேர்வு செய்',
|
||||
@@ -69,7 +68,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'அட்டவணையை தேர்வு செய்ய முடியவில்லை',
|
||||
'Invalid CSRF token. Send the form again.' => 'CSRF டோக்கன் செல்லாது. படிவத்தை மீண்டும் அனுப்பவும்.',
|
||||
'Comment' => 'குறிப்பு',
|
||||
'Default values' => 'உள்ளிருக்கும் (Default) மதிப்புகள் ',
|
||||
'%d byte(s)' => array('%d பைட்', '%d பைட்டுகள்'),
|
||||
'No commands to execute.' => 'செயல் படுத்த எந்த கட்டளைகளும் இல்லை.',
|
||||
'Unable to upload a file.' => 'கோப்பை மேலேற்றம் (upload) செய்ய இயலவில்லை.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -32,7 +32,6 @@ $translations = array(
|
||||
'Create database' => 'สร้างฐานข้อมูล',
|
||||
'SQL command' => 'คำสั่ง SQL',
|
||||
'Logout' => 'ออกจากระบบ',
|
||||
'database' => 'ฐานข้อมูล',
|
||||
'Use' => 'ใช้งาน',
|
||||
'No tables.' => 'ไม่พบตาราง.',
|
||||
'select' => 'เลือก',
|
||||
@@ -70,7 +69,6 @@ $translations = array(
|
||||
'Unable to select the table' => 'ไม่สามารถเลือกตารางได้',
|
||||
'Invalid CSRF token. Send the form again.' => 'เครื่องหมาย CSRF ไม่ถูกต้อง ส่งข้อมูลใหม่อีกครั้ง.',
|
||||
'Comment' => 'หมายเหตุ',
|
||||
'Default values' => 'ค่าเริ่มต้น',
|
||||
'%d byte(s)' => '%d ไบท์',
|
||||
'No commands to execute.' => 'ไม่มีคำสั่งที่จะประมวลผล.',
|
||||
'Unable to upload a file.' => 'ไม่สามารถอัปโหลดไฟล์ได้.',
|
||||
@@ -313,4 +311,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -85,7 +85,6 @@ $translations = array(
|
||||
'Data' => 'Veri',
|
||||
|
||||
'Database' => 'Veri Tabanı',
|
||||
'database' => 'veri tabanı',
|
||||
'DB' => 'DB',
|
||||
'Use' => 'Kullan',
|
||||
'Select database' => 'Veri tabanı seç',
|
||||
@@ -173,7 +172,6 @@ $translations = array(
|
||||
'Options' => 'Seçenekler',
|
||||
'Comment' => 'Yorum',
|
||||
'Default value' => 'Varsayılan değer',
|
||||
'Default values' => 'Varsayılan değerler',
|
||||
'Drop' => 'Sil',
|
||||
'Drop %s?' => 'Sil %s?',
|
||||
'Are you sure?' => 'Emin misiniz?',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Hayır',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -74,7 +74,6 @@ $translations = array(
|
||||
'Data' => 'Дані',
|
||||
|
||||
'Database' => 'База даних',
|
||||
'database' => 'база даних',
|
||||
'Use' => 'Обрати',
|
||||
'Select database' => 'Обрати базу даних',
|
||||
'Invalid database.' => 'Погана база даних.',
|
||||
@@ -159,7 +158,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Автоматичне збільшення',
|
||||
'Options' => 'Опції',
|
||||
'Comment' => 'Коментарі',
|
||||
'Default values' => 'Значення за замовчуванням',
|
||||
'Drop' => 'Видалити',
|
||||
'Are you sure?' => 'Ви впевнені?',
|
||||
'Move up' => 'Пересунути вгору',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => 'Ні',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -77,7 +77,6 @@ $translations = array(
|
||||
'Data' => 'Dữ liệu',
|
||||
|
||||
'Database' => 'Cơ sở dữ liệu',
|
||||
'database' => 'cơ sở dữ liệu',
|
||||
'Use' => 'Sử dụng',
|
||||
'Select database' => 'Chọn CSDL',
|
||||
'Invalid database.' => 'CSDL sai.',
|
||||
@@ -162,7 +161,6 @@ $translations = array(
|
||||
'Auto Increment' => 'Tăng tự động',
|
||||
'Options' => 'Tuỳ chọn',
|
||||
'Comment' => 'Chú thích',
|
||||
'Default values' => 'Giá trị mặc định',
|
||||
'Drop' => 'Xoá',
|
||||
'Are you sure?' => 'Bạn có chắc',
|
||||
'Size' => 'Kích thước',
|
||||
@@ -357,4 +355,10 @@ $translations = array(
|
||||
'No' => 'Không',
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -21,6 +21,8 @@ $translations = array(
|
||||
'Language' => 'Xx',
|
||||
'Invalid CSRF token. Send the form again.' => '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',
|
||||
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
|
||||
'Connecting to privileged ports is not allowed.' => 'Xx.',
|
||||
@@ -90,7 +92,6 @@ $translations = array(
|
||||
'Data' => 'Xx',
|
||||
|
||||
'Database' => 'Xx',
|
||||
'database' => 'xx',
|
||||
'DB' => 'XX',
|
||||
'Use' => 'Xx',
|
||||
'Select database' => 'Xx',
|
||||
@@ -179,7 +180,6 @@ $translations = array(
|
||||
'Options' => 'Xx',
|
||||
'Comment' => 'Xx',
|
||||
'Default value' => 'Xx',
|
||||
'Default values' => 'Xx',
|
||||
'Drop' => 'Xx',
|
||||
'Drop %s?' => 'Xx %s?',
|
||||
'Are you sure?' => 'Xx?',
|
||||
@@ -327,12 +327,15 @@ $translations = array(
|
||||
'Please use one of the extensions %s.' => 'Xx %s.',
|
||||
|
||||
// PostgreSQL and MS SQL schema support
|
||||
'Schema' => 'Xx',
|
||||
'Schemas' => 'Xx',
|
||||
'No schemas.' => 'Xx.',
|
||||
'Show schema' => 'Xx',
|
||||
'Alter schema' => 'Xx',
|
||||
'Create schema' => 'Xx',
|
||||
'Schema has been dropped.' => 'Xx.',
|
||||
'Schema has been created.' => 'Xx.',
|
||||
'Schema has been altered.' => 'Xx.',
|
||||
'Schema' => 'Xx',
|
||||
'Invalid schema.' => 'Xx.',
|
||||
|
||||
// PostgreSQL sequences support
|
||||
|
||||
@@ -90,7 +90,6 @@ $translations = array(
|
||||
'Data' => '資料',
|
||||
|
||||
'Database' => '資料庫',
|
||||
'database' => '資料庫',
|
||||
'DB' => '資料庫',
|
||||
'Use' => '使用',
|
||||
'Select database' => '選擇資料庫',
|
||||
@@ -179,7 +178,6 @@ $translations = array(
|
||||
'Options' => '選項',
|
||||
'Comment' => '註解',
|
||||
'Default value' => '預設值',
|
||||
'Default values' => '預設值',
|
||||
'Drop' => '刪除',
|
||||
'Drop %s?' => '刪除 %s?',
|
||||
'Are you sure?' => '你確定嗎?',
|
||||
@@ -358,4 +356,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -90,7 +90,6 @@ $translations = array(
|
||||
'Data' => '数据',
|
||||
|
||||
'Database' => '数据库',
|
||||
'database' => '数据库',
|
||||
'DB' => '数据库',
|
||||
'Use' => '使用',
|
||||
'Select database' => '选择数据库',
|
||||
@@ -179,7 +178,6 @@ $translations = array(
|
||||
'Options' => '选项',
|
||||
'Comment' => '注释',
|
||||
'Default value' => '默认值',
|
||||
'Default values' => '默认值',
|
||||
'Drop' => '删除',
|
||||
'Drop %s?' => '删除 %s?',
|
||||
'Are you sure?' => '您确定吗?',
|
||||
@@ -357,4 +355,10 @@ $translations = array(
|
||||
'No' => null,
|
||||
'One Time Password' => null,
|
||||
'Invalid OTP code.' => null,
|
||||
|
||||
'Schemas' => null,
|
||||
'No schemas.' => null,
|
||||
'Show schema' => null,
|
||||
'No driver' => null,
|
||||
'Database driver not found.' => null,
|
||||
);
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
function adminer_object() {
|
||||
// required to run any plugin
|
||||
include_once "../plugins/plugin.php";
|
||||
|
||||
|
||||
// autoloader
|
||||
foreach (glob("../plugins/*.php") as $filename) {
|
||||
include_once $filename;
|
||||
}
|
||||
|
||||
|
||||
// enable extra drivers just by including them
|
||||
//~ include "../plugins/drivers/simpledb.php";
|
||||
|
||||
|
||||
$plugins = array(
|
||||
// specify enabled plugins here
|
||||
new AdminerDatabaseHide(array('information_schema')),
|
||||
@@ -29,16 +29,16 @@ function adminer_object() {
|
||||
new AdminerTranslation,
|
||||
new AdminerForeignSystem,
|
||||
new AdminerEnumOption,
|
||||
new AdminerTablesFilter,
|
||||
new AdminerEditForeign,
|
||||
new AdminerLoginSsl(["TrustServerCertificate" => true]),
|
||||
);
|
||||
|
||||
|
||||
/* It is possible to combine customization and plugins:
|
||||
class AdminerCustomization extends AdminerPlugin {
|
||||
}
|
||||
return new AdminerCustomization($plugins);
|
||||
*/
|
||||
|
||||
|
||||
return new AdminerPlugin($plugins);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,12 +39,17 @@ $routine_languages = routine_languages();
|
||||
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
<div class="scrollable">
|
||||
<table cellspacing="0" class="nowrap">
|
||||
<table cellspacing="0" class="nowrap" id="edit-fields">
|
||||
<?php
|
||||
edit_fields($row["fields"], $collations, $routine);
|
||||
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()));
|
||||
|
||||
echo "<td></td></tr></tbody>\n";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
||||
@@ -50,9 +50,9 @@ foreach (table_status('', true) as $table => $table_status) {
|
||||
?>
|
||||
<div id="schema" style="height: <?php echo $top; ?>em;">
|
||||
<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 em = qs('#schema').offsetHeight / <?php echo $top; ?>;
|
||||
var em = gid('schema').offsetHeight / <?php echo $top; ?>;
|
||||
document.onmousemove = schemaMousemove;
|
||||
document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>');
|
||||
</script>
|
||||
@@ -61,12 +61,12 @@ foreach ($schema as $name => $table) {
|
||||
echo "<div class='table' style='top: " . $table["pos"][0] . "em; left: " . $table["pos"][1] . "em;'>";
|
||||
echo '<a href="' . h(ME) . 'table=' . urlencode($name) . '"><b>' . h($name) . "</b></a>";
|
||||
echo script("qsl('div').onmousedown = schemaMousedown;");
|
||||
|
||||
|
||||
foreach ($table["fields"] as $field) {
|
||||
$val = '<span' . type_class($field["type"]) . ' title="' . h($field["full_type"] . ($field["null"] ? " NULL" : '')) . '">' . h($field["field"]) . '</span>';
|
||||
echo "<br>" . ($field["primary"] ? "<i>$val</i>" : $val);
|
||||
}
|
||||
|
||||
|
||||
foreach ((array) $table["references"] as $target_name => $refs) {
|
||||
foreach ($refs as $left => $ref) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
@@ -76,7 +76,7 @@ foreach ($schema as $name => $table) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ((array) $referenced[$name] as $target_name => $refs) {
|
||||
foreach ($refs as $left => $columns) {
|
||||
$left1 = $left - $table_pos[$name][1];
|
||||
@@ -86,7 +86,7 @@ foreach ($schema as $name => $table) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo "\n</div>\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ if (!$row) {
|
||||
|
||||
<form action="" method="post">
|
||||
<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'); ?>">
|
||||
<?php
|
||||
if ($_GET["ns"] != "") {
|
||||
|
||||
@@ -322,10 +322,10 @@ if (!$columns && support("table")) {
|
||||
|
||||
echo "<div class='scrollable'>";
|
||||
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
|
||||
? ""
|
||||
: "<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>");
|
||||
$names = array();
|
||||
$functions = array();
|
||||
@@ -353,10 +353,10 @@ if (!$columns && support("table")) {
|
||||
}
|
||||
echo "<span class='column hidden'>";
|
||||
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"])) {
|
||||
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 "</span>";
|
||||
|
||||
@@ -243,7 +243,7 @@ if (!isset($_GET["import"])) {
|
||||
}
|
||||
echo "<p>";
|
||||
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 lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/** @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; }
|
||||
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.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; }
|
||||
@@ -24,8 +24,10 @@ pre { margin: 1em 0 0; }
|
||||
pre code { display: block; font-size: 100%; }
|
||||
pre, textarea { font: 110%/1.25 monospace; }
|
||||
pre.jush { background: #fff; }
|
||||
pre.comment { white-space: pre-wrap; }
|
||||
form + pre.comment { margin-top: 2em; }
|
||||
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::-webkit-inner-spin-button { -webkit-appearance: none; }
|
||||
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; }
|
||||
span.handle { display: inline-block; width: 18px; height: 18px; padding-right: .3em; }
|
||||
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; }
|
||||
.dragging { position: absolute; margin: 0; background: #fff; }
|
||||
.dragging * { cursor: grabbing; }
|
||||
@@ -108,6 +111,7 @@ table.dragging { background: #eee; }
|
||||
.rtl .pages { left: auto; right: 21em; }
|
||||
.rtl input.wayoff { left: auto; right: -1000px; }
|
||||
.rtl #lang, .rtl #menu { left: auto; right: 0; }
|
||||
.rtl pre, .rtl code { direction: ltr; }
|
||||
|
||||
@media all and (max-width: 880px) {
|
||||
.pages { left: auto; }
|
||||
|
||||
@@ -16,17 +16,22 @@ function bodyLoad(version, maria) {
|
||||
if (maria) {
|
||||
for (var i = 1; i < obj.length; i++) {
|
||||
obj[i] = obj[i]
|
||||
.replace(/\.html/, '/')
|
||||
.replace(/-type-syntax/, '-data-types')
|
||||
.replace('.html', '/')
|
||||
.replace('-type-syntax', '-data-types')
|
||||
.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
|
||||
.replace(/\/docs\/current/, '/docs/' + version) // PostgreSQL
|
||||
|
||||
obj[key] = (maria ? obj[key].replace('dev.mysql.com/doc/mysql/en/', 'mariadb.com/kb/en/') : obj[key]) // MariaDB
|
||||
.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
|
||||
*/
|
||||
function loginDriver(driver) {
|
||||
var trs = parentTag(driver, 'table').rows;
|
||||
var disabled = /sqlite/.test(selectValue(driver));
|
||||
alterClass(trs[1], 'hidden', disabled); // 1 - row with server
|
||||
/**
|
||||
* Hides or shows some login rows for selected driver.
|
||||
*
|
||||
* @param {HTMLSelectElement} driverSelect
|
||||
*/
|
||||
function loginDriver(driverSelect) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -231,11 +240,13 @@ function editFields() {
|
||||
els = qsa('[name$="[type]"]');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
mixin(els[i], {
|
||||
onfocus: function () { lastType = selectValue(this); },
|
||||
onfocus: () => {
|
||||
lastType = selectValue(this);
|
||||
},
|
||||
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
|
||||
*/
|
||||
function editingClick(event) {
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (!isTag(el, 'input')) {
|
||||
el = parentTag(el, 'label');
|
||||
el = el && qs('input', el);
|
||||
@@ -273,7 +284,7 @@ function editingClick(event) {
|
||||
* @param InputEvent
|
||||
*/
|
||||
function editingInput(event) {
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (/\[default]$/.test(el.name)) {
|
||||
el.previousSibling.checked = true;
|
||||
}
|
||||
@@ -398,26 +409,26 @@ function editingTypeChange() {
|
||||
el.checked = false;
|
||||
}
|
||||
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]') {
|
||||
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]') {
|
||||
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]') {
|
||||
alterClass(el, 'hidden', !/`/.test(text));
|
||||
el.classList.toggle('hidden', !/`/.test(text));
|
||||
}
|
||||
}
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/** Mark length as required
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
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
|
||||
@@ -426,7 +437,7 @@ function editingLengthChange() {
|
||||
function editingLengthFocus() {
|
||||
var td = this.parentNode;
|
||||
if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) {
|
||||
var edit = qs('#enum-edit');
|
||||
var edit = gid('enum-edit');
|
||||
edit.value = enumValues(this.value);
|
||||
td.appendChild(edit);
|
||||
this.style.display = 'none';
|
||||
@@ -470,9 +481,9 @@ function editingLengthBlur() {
|
||||
* @param number
|
||||
*/
|
||||
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++) {
|
||||
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() {
|
||||
var partitionTable = /RANGE|LIST/.test(selectValue(this));
|
||||
alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex);
|
||||
alterClass(qs('#partition-table'), 'hidden', !partitionTable);
|
||||
helpClose();
|
||||
|
||||
this.form['partitions'].classList.toggle('hidden', partitionTable || !this.selectedIndex);
|
||||
gid('partition-table').classList.toggle('hidden', !partitionTable);
|
||||
}
|
||||
|
||||
/** Add next partition row
|
||||
@@ -503,7 +514,7 @@ function partitionNameChange() {
|
||||
function editingCommentsClick(el, focus) {
|
||||
var comment = el.form['Comment'];
|
||||
columnShow(el.checked, 6);
|
||||
alterClass(comment, 'hidden', !el.checked);
|
||||
comment.classList.toggle('hidden', !el.checked);
|
||||
if (focus && el.checked) {
|
||||
comment.focus();
|
||||
}
|
||||
@@ -516,7 +527,7 @@ function editingCommentsClick(el, focus) {
|
||||
* @this HTMLTableElement
|
||||
*/
|
||||
function dumpClick(event) {
|
||||
var el = parentTag(getTarget(event), 'label');
|
||||
var el = parentTag(event.target, 'label');
|
||||
if (el) {
|
||||
el = qs('input', el);
|
||||
var match = /(.+)\[]$/.exec(el.name);
|
||||
@@ -646,7 +657,7 @@ function triggerChange(tableRe, table, form) {
|
||||
if (tableRe.test(form['Trigger'].value)) {
|
||||
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 = encodeURIComponent(s.substr(1));
|
||||
var link = qs('#schema-link');
|
||||
var link = gid('schema-link');
|
||||
link.href = link.href.replace(/[^=]+$/, '') + s;
|
||||
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
|
||||
* @param MouseEvent
|
||||
* @param string
|
||||
* @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';
|
||||
}
|
||||
}
|
||||
help.addEventListener("mouseenter", () => {
|
||||
clearTimeout(closeTimeout);
|
||||
closeTimeout = null;
|
||||
});
|
||||
|
||||
/** Close help after timeout
|
||||
* @param MouseEvent
|
||||
* @this HTMLElement
|
||||
*/
|
||||
function helpMouseout(event) {
|
||||
helpOpen = 0;
|
||||
helpIgnore = (this !== getTarget(event));
|
||||
setTimeout(function () {
|
||||
if (!helpOpen) {
|
||||
helpClose();
|
||||
help.addEventListener("mouseleave", hideHelp);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} element
|
||||
* @param {string|function} content
|
||||
* @param {boolean} side Displays on left side (otherwise on top).
|
||||
*/
|
||||
window.initHelpFor = function(element, content, side = false) {
|
||||
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
|
||||
*/
|
||||
function helpClose() {
|
||||
alterClass(qs('#help'), 'hidden', true);
|
||||
}
|
||||
/**
|
||||
* Displays help popup after a small delay.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -110,14 +99,14 @@ function cookie(assign, days) {
|
||||
/**
|
||||
* Verifies current Adminer version.
|
||||
*
|
||||
* @param currentVersion string
|
||||
* @param baseUrl 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);
|
||||
|
||||
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 version = response.tag_name.replace(/^\D*/, '');
|
||||
@@ -126,12 +115,8 @@ function verifyVersion(currentVersion, baseUrl, token) {
|
||||
cookie('adminer_version=' + version, 1);
|
||||
|
||||
const data = 'version=' + version + '&token=' + token;
|
||||
ajax(baseUrl + 'script=version', function () {}, data);
|
||||
|
||||
if (currentVersion !== version) {
|
||||
qs('#version').innerText = version;
|
||||
}
|
||||
});
|
||||
ajax(baseUrl + 'script=version', null, data);
|
||||
}, null, null, true);
|
||||
}
|
||||
|
||||
/** Get value of select
|
||||
@@ -173,7 +158,7 @@ function parentTag(el, tag) {
|
||||
*/
|
||||
function trCheck(el) {
|
||||
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
|
||||
el.form['all'].onclick();
|
||||
}
|
||||
@@ -186,7 +171,7 @@ function trCheck(el) {
|
||||
*/
|
||||
function selectCount(id, count) {
|
||||
setHtml(id, (count === '' ? '' : '(' + (count + '').replace(/\B(?=(\d{3})+$)/g, thousandsSeparator) + ')'));
|
||||
var el = qs('#' + id);
|
||||
var el = gid(id);
|
||||
if (el) {
|
||||
var inputs = qsa('input', el.parentNode.parentNode);
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
@@ -259,7 +244,7 @@ function formChecked(el, name) {
|
||||
* @param [boolean] force click
|
||||
*/
|
||||
function tableClick(event, click) {
|
||||
var td = parentTag(getTarget(event), 'td');
|
||||
var td = parentTag(event.target, 'td');
|
||||
var text;
|
||||
if (td && (text = td.getAttribute('data-text'))) {
|
||||
if (selectClick.call(td, event, +text, td.getAttribute('data-warning'))) {
|
||||
@@ -267,7 +252,7 @@ function tableClick(event, click) {
|
||||
}
|
||||
}
|
||||
click = (click || !window.getSelection || getSelection().isCollapsed);
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
while (!isTag(el, 'tr')) {
|
||||
if (isTag(el, 'table|a|input|textarea')) {
|
||||
if (el.type !== 'checkbox') {
|
||||
@@ -374,7 +359,7 @@ function initTablesFilter(dbName) {
|
||||
if (sessionStorage) {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
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();
|
||||
} else {
|
||||
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 () {
|
||||
window.clearTimeout(tablesFilterTimeout);
|
||||
tablesFilterTimeout = window.setTimeout(filterTables, 200);
|
||||
@@ -401,7 +386,7 @@ function initTablesFilter(dbName) {
|
||||
}
|
||||
|
||||
function filterTables() {
|
||||
const value = qs('#tables-filter').value.toLowerCase();
|
||||
const value = gid('tables-filter').value.toLowerCase();
|
||||
if (value === tablesFilterValue) {
|
||||
return;
|
||||
}
|
||||
@@ -445,7 +430,7 @@ function filterTables() {
|
||||
* @this HTMLElement
|
||||
*/
|
||||
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
|
||||
this.style.overflow = 'visible';
|
||||
}
|
||||
@@ -495,10 +480,8 @@ function selectAddRow(event) {
|
||||
}
|
||||
}
|
||||
|
||||
const buttons = qsa('.icon', row);
|
||||
for (const button of buttons) {
|
||||
button.onclick = selectRemoveRow;
|
||||
}
|
||||
const button = qs('.remove', row);
|
||||
button.onclick = selectRemoveRow;
|
||||
|
||||
const parent = field.parentNode.parentNode;
|
||||
if (parent.classList.contains("sortable")) {
|
||||
@@ -544,13 +527,13 @@ function selectSearchSearch() {
|
||||
|
||||
// Sorting.
|
||||
(function() {
|
||||
let placeholderRow, nextRow, dragHelper;
|
||||
let placeholderRow = null, nextRow = null, dragHelper = null;
|
||||
let startY, minY, maxY;
|
||||
|
||||
/**
|
||||
* Initializes sortable list of DIV elements.
|
||||
*
|
||||
* @param {string} parentId
|
||||
* @param {string} parentSelector
|
||||
*/
|
||||
window.initSortable = function(parentSelector) {
|
||||
const parent = qs(parentSelector);
|
||||
@@ -572,65 +555,73 @@ function selectSearchSearch() {
|
||||
row.classList.remove("no-sort");
|
||||
|
||||
const handle = qs(".handle", row);
|
||||
handle.addEventListener("mousedown", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
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 });
|
||||
});
|
||||
handle.addEventListener("mousedown", (event) => { startSorting(row, event) });
|
||||
handle.addEventListener("touchstart", (event) => { startSorting(row, event) });
|
||||
};
|
||||
|
||||
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) {
|
||||
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`;
|
||||
|
||||
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
|
||||
*/
|
||||
function selectSearch(name) {
|
||||
var el = qs('#fieldset-search');
|
||||
var el = gid('fieldset-search');
|
||||
el.className = '';
|
||||
var divs = qsa('div', el);
|
||||
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 target
|
||||
* @param Event
|
||||
* @return HTMLElement
|
||||
*/
|
||||
function getTarget(event) {
|
||||
return event.target || event.srcElement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Send form by Ctrl+Enter on <select> and <textarea>
|
||||
* @param KeyboardEvent
|
||||
* @param [string]
|
||||
@@ -725,7 +734,7 @@ function getTarget(event) {
|
||||
*/
|
||||
function bodyKeydown(event, button) {
|
||||
eventStop(event);
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if (target.jushTextarea) {
|
||||
target = target.jushTextarea;
|
||||
}
|
||||
@@ -749,7 +758,7 @@ function bodyKeydown(event, button) {
|
||||
* @param MouseEvent
|
||||
*/
|
||||
function bodyClick(event) {
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if ((isCtrl(event) || event.shiftKey) && target.type === 'submit' && isTag(target, 'input')) {
|
||||
target.form.target = '_blank';
|
||||
setTimeout(function () {
|
||||
@@ -767,7 +776,7 @@ function bodyClick(event) {
|
||||
*/
|
||||
function editingKeydown(event) {
|
||||
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 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)])) {
|
||||
@@ -792,7 +801,6 @@ function functionChange() {
|
||||
|
||||
// Undefined with the set data type.
|
||||
if (!input) {
|
||||
helpClose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -822,8 +830,6 @@ function functionChange() {
|
||||
}
|
||||
|
||||
oninput({target: input});
|
||||
|
||||
helpClose();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -857,41 +863,51 @@ function fieldChange() {
|
||||
|
||||
|
||||
|
||||
/** Create AJAX request
|
||||
* @param string
|
||||
* @param function (XMLHttpRequest)
|
||||
* @param [string]
|
||||
* @param [string]
|
||||
* @return XMLHttpRequest or false in case of an error
|
||||
* @uses offlineMessage
|
||||
*/
|
||||
function ajax(url, callback, data, message) {
|
||||
var request = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : false));
|
||||
if (request) {
|
||||
var ajaxStatus = qs('#ajaxstatus');
|
||||
if (message) {
|
||||
ajaxStatus.innerHTML = '<div class="message">' + message + '</div>';
|
||||
ajaxStatus.className = ajaxStatus.className.replace(/ hidden/g, '');
|
||||
} else {
|
||||
ajaxStatus.className += ' hidden';
|
||||
}
|
||||
request.open((data ? 'POST' : 'GET'), url);
|
||||
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);
|
||||
/**
|
||||
* Sends AJAX request.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {function|null} onSuccess (XMLHttpRequest)
|
||||
* @param {string|null} data POST data.
|
||||
* @param {string|null} progressMessage
|
||||
* @param {boolean} failSilently
|
||||
* @return XMLHttpRequest or false in case of an error
|
||||
* @uses offlineMessage
|
||||
*/
|
||||
function ajax(url, onSuccess = null, data = null, progressMessage = null, failSilently = false) {
|
||||
const ajaxStatus = gid('ajaxstatus');
|
||||
|
||||
if (progressMessage) {
|
||||
ajaxStatus.innerHTML = '<div class="message">' + progressMessage + '</div>';
|
||||
ajaxStatus.classList.remove("hidden");
|
||||
} else {
|
||||
ajaxStatus.classList.add("hidden");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -938,9 +954,9 @@ function ajaxForm(form, message, button) {
|
||||
return ajax(url, function (request) {
|
||||
setHtml('ajaxstatus', request.responseText);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -955,7 +971,7 @@ function ajaxForm(form, message, button) {
|
||||
*/
|
||||
function selectClick(event, text, warning) {
|
||||
var td = this;
|
||||
var target = getTarget(event);
|
||||
var target = event.target;
|
||||
if (!isCtrl(event) || isTag(td.firstChild, 'input|textarea') || isTag(target, 'a')) {
|
||||
return;
|
||||
}
|
||||
@@ -1042,7 +1058,7 @@ function selectLoadMore(limit, loading) {
|
||||
return !ajax(href, function (request) {
|
||||
var tbody = document.createElement('tbody');
|
||||
tbody.innerHTML = request.responseText;
|
||||
qs('#table').appendChild(tbody);
|
||||
gid('table').appendChild(tbody);
|
||||
if (tbody.children.length < limit) {
|
||||
a.parentNode.removeChild(a);
|
||||
} else {
|
||||
@@ -1096,9 +1112,9 @@ function setupSubmitHighlightInput(input) {
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
function inputFocus() {
|
||||
var submit = findDefaultSubmit(this);
|
||||
const submit = findDefaultSubmit(this);
|
||||
if (submit) {
|
||||
alterClass(submit, 'default', true);
|
||||
submit.classList.toggle('default', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,16 +1122,18 @@ function inputFocus() {
|
||||
* @this HTMLInputElement
|
||||
*/
|
||||
function inputBlur() {
|
||||
var submit = findDefaultSubmit(this);
|
||||
const submit = findDefaultSubmit(this);
|
||||
if (submit) {
|
||||
alterClass(submit, 'default');
|
||||
submit.classList.toggle('default', false);
|
||||
}
|
||||
}
|
||||
|
||||
/** Find submit button used by Enter
|
||||
* @param HTMLElement
|
||||
* @return HTMLInputElement
|
||||
*/
|
||||
/**
|
||||
* Finds submit button used by Enter.
|
||||
*
|
||||
* @param {HTMLElement} el
|
||||
* @return {HTMLInputElement}
|
||||
*/
|
||||
function findDefaultSubmit(el) {
|
||||
if (el.jushTextarea) {
|
||||
el = el.jushTextarea;
|
||||
@@ -1123,10 +1141,10 @@ function findDefaultSubmit(el) {
|
||||
if (!el.form) {
|
||||
return null;
|
||||
}
|
||||
var inputs = qsa('input', el.form);
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
if (input.type === 'submit' && !input.style.zIndex) {
|
||||
|
||||
const inputs = qsa('input', el.form);
|
||||
for (const input of inputs) {
|
||||
if (input.type === 'submit' && !input.classList.contains("wayoff") && !input.style.zIndex) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
@@ -1190,7 +1208,9 @@ function getOffsetLeft(element) {
|
||||
}
|
||||
|
||||
oninput = function (event) {
|
||||
var target = event.target;
|
||||
var maxLength = target.getAttribute('data-maxlength');
|
||||
alterClass(target, 'maxlength', target.value && maxLength != null && target.value.length > maxLength); // maxLength could be 0
|
||||
const target = event.target;
|
||||
const maxLength = target.getAttribute('data-maxlength');
|
||||
|
||||
// maxLength could be 0
|
||||
target.classList.toggle('maxlength', target.value && maxLength != null && target.value.length > maxLength);
|
||||
};
|
||||
|
||||
@@ -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"]); ?>
|
||||
</table>
|
||||
<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>
|
||||
<input type="submit" value="<?php echo lang('Save'); ?>">
|
||||
|
||||
@@ -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('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">
|
||||
<?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);")); ?>
|
||||
</table>
|
||||
|
||||
|
||||
374
compile.php
374
compile.php
@@ -6,9 +6,18 @@ function adminer_errors($errno, $errstr) {
|
||||
|
||||
error_reporting(6135); // errors and warnings
|
||||
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__) . "/vendor/vrana/jsshrink/jsShrink.php";
|
||||
|
||||
function is_dev_version()
|
||||
{
|
||||
global $VERSION;
|
||||
|
||||
return (bool)preg_match('~-dev$~', $VERSION);
|
||||
}
|
||||
|
||||
function add_apo_slashes($s) {
|
||||
return addcslashes($s, "\\'");
|
||||
}
|
||||
@@ -21,85 +30,85 @@ function add_quo_slashes($s) {
|
||||
return $return;
|
||||
}
|
||||
|
||||
function remove_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) {
|
||||
function replace_lang($match) {
|
||||
global $lang_ids;
|
||||
$lang_id = &$lang_ids[stripslashes($match[1])];
|
||||
if ($lang_id === null) {
|
||||
$lang_id = count($lang_ids) - 1;
|
||||
|
||||
$text = stripslashes($match[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) {
|
||||
global $project, $VERSION, $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;
|
||||
}
|
||||
global $project, $selected_languages, $single_driver;
|
||||
|
||||
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");
|
||||
'), $return, $count);
|
||||
$filename = basename($match[2]);
|
||||
|
||||
// Language is processed later.
|
||||
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) {
|
||||
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 (is_array(\$translation)) {
|
||||
\$pos = $match2[2]\t\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
|
||||
if ($filename == "lang.inc.php") {
|
||||
$content = str_replace(
|
||||
'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];
|
||||
}
|
||||
$translation = str_replace("%d", "%s", $translation);
|
||||
$number = format_number($number);
|
||||
return sprintf($translation, $number);
|
||||
}
|
||||
';
|
||||
} else {
|
||||
echo "lang() \$pos not found\n";
|
||||
|
||||
if (!$count) {
|
||||
echo "function lang() not found\n";
|
||||
}
|
||||
|
||||
if ($selected_languages) {
|
||||
$available_languages = array_fill_keys($selected_languages, true);
|
||||
$content = str_replace(
|
||||
'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) {
|
||||
@@ -139,45 +148,73 @@ function lzw_compress($string) {
|
||||
return $return . ($rest_length ? chr($rest << (8 - $rest_length)) : "");
|
||||
}
|
||||
|
||||
function put_file_lang($match) {
|
||||
global $lang_ids, $project, $langs;
|
||||
if ($_SESSION["lang"]) {
|
||||
return "";
|
||||
}
|
||||
$return = "";
|
||||
foreach ($langs as $lang => $val) {
|
||||
include dirname(__FILE__) . "/adminer/lang/$lang.inc.php"; // assign $translations
|
||||
function put_file_lang() {
|
||||
global $lang_ids, $selected_languages;
|
||||
|
||||
$languages = array_map(function ($filename) {
|
||||
preg_match('~/([^/.]+)\.inc\.php$~', $filename, $matches);
|
||||
return $matches[1];
|
||||
}, glob(dirname(__FILE__) . "/adminer/lang/*.inc.php"));
|
||||
|
||||
$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
|
||||
foreach ($translations as $key => $val) {
|
||||
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) {
|
||||
switch ($lang) {' . $return . '
|
||||
$cases .= 'case "' . $language . '": $compressed = "' . add_quo_slashes(lzw_compress(json_encode($translation_ids, JSON_UNESCAPED_UNICODE))) . '"; break;';
|
||||
}
|
||||
$translations = array();
|
||||
foreach (explode("\n", lzw_decompress($compressed)) as $val) {
|
||||
$translations[] = (strpos($val, "\t") ? explode("\t", $val) : $val);
|
||||
}
|
||||
return $translations;
|
||||
}
|
||||
|
||||
if (!$translations) {
|
||||
$translations = get_translations($LANG);
|
||||
$_SESSION["translations"] = $translations;
|
||||
}
|
||||
';
|
||||
$translations_version = crc32($cases);
|
||||
|
||||
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) {
|
||||
@@ -224,7 +261,7 @@ function php_shrink($input) {
|
||||
}
|
||||
$tokens = array_values($tokens);
|
||||
|
||||
foreach ($tokens as $i => $token) {
|
||||
foreach ($tokens as $token) {
|
||||
if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
|
||||
$short_variables[$token[1]]++;
|
||||
}
|
||||
@@ -258,7 +295,7 @@ function php_shrink($input) {
|
||||
$tokens[$i+4] = array(0, ';');
|
||||
}
|
||||
if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
|
||||
$space = "\n";
|
||||
$space = " ";
|
||||
} else {
|
||||
if ($token[0] == T_DOC_COMMENT) {
|
||||
$doc_comment = true;
|
||||
@@ -287,9 +324,13 @@ function php_shrink($input) {
|
||||
} elseif ($token[0] === T_VARIABLE && !isset($special_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 = '';
|
||||
}
|
||||
|
||||
$output .= $space . $token[1];
|
||||
$space = '';
|
||||
}
|
||||
@@ -340,60 +381,78 @@ function number_type() {
|
||||
}
|
||||
|
||||
$project = "adminer";
|
||||
if ($_SERVER["argv"][1] == "editor") {
|
||||
array_shift($argv);
|
||||
|
||||
if ($argv[0] == "editor") {
|
||||
$project = "editor";
|
||||
array_shift($_SERVER["argv"]);
|
||||
array_shift($argv);
|
||||
}
|
||||
|
||||
$driver = "";
|
||||
if (file_exists(dirname(__FILE__) . "/adminer/drivers/" . $_SERVER["argv"][1] . ".inc.php")) {
|
||||
$driver = $_SERVER["argv"][1];
|
||||
array_shift($_SERVER["argv"]);
|
||||
$selected_drivers = [];
|
||||
if ($argv) {
|
||||
$params = explode(",", $argv[0]);
|
||||
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"]);
|
||||
$_SESSION["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from session
|
||||
include dirname(__FILE__) . "/adminer/include/lang.inc.php";
|
||||
if (isset($langs[$_SESSION["lang"]])) {
|
||||
include dirname(__FILE__) . "/adminer/lang/$_SESSION[lang].inc.php";
|
||||
array_shift($_SERVER["argv"]);
|
||||
$selected_languages = [];
|
||||
if ($argv) {
|
||||
$params = explode(",", $argv[0]);
|
||||
if (file_exists(dirname(__FILE__) . "/adminer/lang/" . $params[0] . ".inc.php")) {
|
||||
$selected_languages = $params;
|
||||
array_shift($argv);
|
||||
}
|
||||
}
|
||||
$single_language = count($selected_languages) == 1 ? $selected_languages[0] : null;
|
||||
|
||||
if ($_SERVER["argv"][1]) {
|
||||
echo "Usage: php compile.php [editor] [driver] [lang]\n";
|
||||
if ($argv) {
|
||||
echo "Usage: php compile.php [editor] [driver] [language]\n";
|
||||
echo "Purpose: Compile adminer[-driver][-lang].php or editor[-driver][-lang].php.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// check function definition in drivers
|
||||
// Check function definition in drivers.
|
||||
$file = file_get_contents(dirname(__FILE__) . "/adminer/drivers/mysql.inc.php");
|
||||
$file = preg_replace('~class Min_Driver.*\n\t}~sU', '', $file);
|
||||
preg_match_all('~\bfunction ([^(]+)~', $file, $matches); //! respect context (extension, class)
|
||||
$functions = array_combine($matches[1], $matches[0]);
|
||||
//! do not warn about functions without declared support()
|
||||
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") {
|
||||
$file = file_get_contents($filename);
|
||||
foreach ($functions as $val) {
|
||||
if (!strpos($file, "$val(")) {
|
||||
fprintf(STDERR, "Missing $val in $filename\n");
|
||||
}
|
||||
|
||||
foreach (glob(dirname(__FILE__) . "/adminer/drivers/*.inc.php") as $filename) {
|
||||
preg_match('~/([^/.]+)\.inc\.php$~', $filename, $matches);
|
||||
if ($matches[1] == "mysql" || ($selected_drivers && !in_array($matches[1], $selected_drivers))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$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/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");
|
||||
if ($driver) {
|
||||
$_GET[$driver] = true; // to load the driver
|
||||
include_once dirname(__FILE__) . "/adminer/drivers/$driver.inc.php";
|
||||
|
||||
// Remove including source code for unsupported features in single-driver file.
|
||||
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) {
|
||||
if (!support($feature)) {
|
||||
if (!is_int($key)) {
|
||||
if (is_string($key)) {
|
||||
$feature = $key;
|
||||
}
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
// Compile files included into the index.php.
|
||||
$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);
|
||||
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) {
|
||||
if (!support($feature)) {
|
||||
$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($driver == "mysql" ? "sql" : $driver) . '\.)[^.]+.js)', '', $file);
|
||||
$file = preg_replace_callback('~doc_link\(array\((.*)\)\)~sU', function ($match) use ($driver) {
|
||||
|
||||
$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) {
|
||||
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))" : "''");
|
||||
}, $file);
|
||||
|
||||
//! strip doc_link() definition
|
||||
}
|
||||
|
||||
if ($project == "editor") {
|
||||
$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_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 = str_replace("\r", "", $file);
|
||||
if ($_SESSION["lang"]) {
|
||||
// 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 = str_replace('<?php echo script_src("static/editing.js?" . filemtime("../adminer/static/editing.js")); ?>' . "\n", "", $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 = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
|
||||
$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/(functions\.js)"~', $replace, $file);
|
||||
$file = preg_replace('~\.\./adminer/static/(favicon\.ico)~', '<?php echo h(' . $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('~"\.\./vendor/vrana/jush/modules/(jush\.js)"~', $replace, $file);
|
||||
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
|
||||
$file = php_shrink($file);
|
||||
|
||||
@mkdir("temp/export", 0777, true);
|
||||
$filename = "temp/export/$project" . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
|
||||
@mkdir("temp", 0777, true);
|
||||
$filename = "temp/$project"
|
||||
. (is_dev_version() ? "" : "-$VERSION")
|
||||
. ($single_driver ? "-$single_driver" : "")
|
||||
. ($single_language ? "-$single_language" : "")
|
||||
. ".php";
|
||||
|
||||
file_put_contents($filename, $file);
|
||||
echo "$filename created (" . strlen($file) . " B).\n";
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
{
|
||||
"name": "vrana/adminer",
|
||||
"name": "pematon/adminer",
|
||||
"description": "Database management in a single PHP file.",
|
||||
"homepage": "https://www.adminer.org/",
|
||||
"homepage": "https://github.com/pematon/adminer",
|
||||
"keywords": [
|
||||
"database"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://sourceforge.net/p/adminer/bugs-and-features/",
|
||||
"forum": "https://sourceforge.net/p/adminer/discussion/",
|
||||
"source": "https://github.com/vrana/adminer/"
|
||||
"issues": "https://github.com/pematon/adminer/issues",
|
||||
"forum": "https://github.com/pematon/adminer/discussions",
|
||||
"source": "https://github.com/pematon/adminer"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jakub Vrána",
|
||||
"homepage": "https://www.vrana.cz/"
|
||||
},
|
||||
{
|
||||
"name": "Peter Knut"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
@@ -29,7 +32,7 @@
|
||||
"php": "5.6 - 8.3",
|
||||
"ext-pdo": "*",
|
||||
"ext-json": "*",
|
||||
"vrana/jush": "@dev",
|
||||
"vrana/jush": "2.0.*",
|
||||
"vrana/jsshrink": "@dev"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -39,6 +42,7 @@
|
||||
"ext-mysql": "*",
|
||||
"ext-pgsql": "*",
|
||||
"ext-mongo": "*",
|
||||
"ext-mongodb": "*",
|
||||
"ext-sqlsrv": "*",
|
||||
"ext-mssql": "*",
|
||||
"ext-oci8": "*",
|
||||
@@ -57,7 +61,7 @@
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/vrana/jush.git"
|
||||
"url": "https://github.com/pematon/jush.git"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
|
||||
14
docs/upgrade.md
Normal file
14
docs/upgrade.md
Normal 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.
|
||||
@@ -11,11 +11,11 @@ if ($adminer->homepage()) {
|
||||
echo "<table cellspacing='0' class='nowrap checkable'>\n";
|
||||
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
|
||||
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 '<td>' . lang('Rows');
|
||||
echo "</thead>\n";
|
||||
|
||||
|
||||
foreach (table_status() as $table => $row) {
|
||||
$name = $adminer->tableName($row);
|
||||
if (isset($row["Engine"]) && $name != "") {
|
||||
@@ -25,7 +25,7 @@ if ($adminer->homepage()) {
|
||||
echo "<td align='right'><a href='" . h(ME . "edit=") . urlencode($table) . "'>" . ($row["Engine"] == "InnoDB" && $val ? "~ $val" : $val) . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo "</table>\n";
|
||||
echo "</div>\n";
|
||||
echo "</form>\n";
|
||||
|
||||
@@ -6,7 +6,7 @@ class Adminer {
|
||||
var $_values = array();
|
||||
|
||||
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
|
||||
@@ -77,7 +77,7 @@ class Adminer {
|
||||
|
||||
function loginForm() {
|
||||
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 "</table>\n";
|
||||
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
|
||||
@@ -600,18 +600,26 @@ qsl('div').onclick = whisperClick;", "")
|
||||
|
||||
function navigation($missing) {
|
||||
global $VERSION;
|
||||
?>
|
||||
?>
|
||||
|
||||
<h1>
|
||||
<?php echo $this->name(); ?>
|
||||
<?php if ($missing != "auth"): ?>
|
||||
<span class="version">
|
||||
<?php echo $VERSION; ?>
|
||||
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
|
||||
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
|
||||
</a>
|
||||
</span>
|
||||
<?php echo $this->name(); ?>
|
||||
|
||||
<?php if ($missing != "auth"): ?>
|
||||
<span class="version">
|
||||
<?php echo $VERSION; ?>
|
||||
<a href="https://github.com/pematon/adminer/releases"<?php echo target_blank(); ?> id="version">
|
||||
<?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?>
|
||||
</a>
|
||||
</span>
|
||||
<?php
|
||||
if (!isset($_COOKIE["adminer_version"])) {
|
||||
echo script("verifyVersion('" . js_escape(ME) . "', '" . get_token() . "');");
|
||||
}
|
||||
?>
|
||||
<?php endif; ?>
|
||||
</h1>
|
||||
|
||||
<?php
|
||||
if ($missing == "auth") {
|
||||
$first = true;
|
||||
@@ -620,7 +628,7 @@ qsl('div').onclick = whisperClick;", "")
|
||||
if ($password !== null) {
|
||||
if ($first) {
|
||||
echo "<ul id='logins'>";
|
||||
echo script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
echo script("mixin(gid('logins'), {onmouseover: menuOver, onmouseout: menuOut});");
|
||||
$first = false;
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
// Skip views and tables without a name.
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<?php
|
||||
/** Adminer Editor - Compact database editor
|
||||
* @link https://www.adminer.org/
|
||||
* @author Jakub Vrana, https://www.vrana.cz/
|
||||
* @copyright 2009 Jakub Vrana
|
||||
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
/**
|
||||
* Adminer Editor - Compact database editor for end-users
|
||||
*
|
||||
* @link https://github.com/pematon/adminer
|
||||
* @author Jakub Vrana (https://www.vrana.cz/)
|
||||
* @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";
|
||||
$drivers[DRIVER] = lang('Login');
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
function adminer_object() {
|
||||
include_once "../plugins/plugin.php";
|
||||
include_once "../plugins/login-password-less.php";
|
||||
|
||||
|
||||
class AdminerCustomization extends AdminerPlugin {
|
||||
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() {
|
||||
return "PATH_TO_YOUR_SQLITE_HERE";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new AdminerCustomization(array(
|
||||
// TODO: inline the result of password_hash() so that the password is not visible in source codes
|
||||
new AdminerLoginPasswordLess(password_hash("YOUR_PASSWORD_HERE", PASSWORD_DEFAULT)),
|
||||
|
||||
@@ -6,13 +6,14 @@ function messagesPrint() {
|
||||
function selectFieldChange() {
|
||||
}
|
||||
|
||||
var helpOpen;
|
||||
// Help.
|
||||
(function() {
|
||||
window.initHelpPopup = function () {
|
||||
};
|
||||
|
||||
function helpMouseover() {
|
||||
}
|
||||
|
||||
function helpMouseout() {
|
||||
}
|
||||
window.initHelpFor = function(element, content, side = false) {
|
||||
};
|
||||
})();
|
||||
|
||||
/** Display typeahead
|
||||
* @param string
|
||||
@@ -42,7 +43,7 @@ function whisper(url) {
|
||||
*/
|
||||
function whisperClick(event) {
|
||||
var field = this.previousSibling;
|
||||
var el = getTarget(event);
|
||||
var el = event.target;
|
||||
if (isTag(el, 'a') && !(event.button || event.shiftKey || event.altKey || isCtrl(event))) {
|
||||
field.value = el.firstChild.data;
|
||||
field.previousSibling.value = decodeURIComponent(el.href.replace(/.*=/, ''));
|
||||
|
||||
2
lang.php
2
lang.php
@@ -5,7 +5,7 @@ unset($_COOKIE["adminer_lang"]);
|
||||
$_SESSION["lang"] = isset($_SERVER["argv"][1]) ? $_SERVER["argv"][1] : null; // Adminer functions read language from session
|
||||
if (isset($_SESSION["lang"])) {
|
||||
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";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
class AdminerDumpAlter {
|
||||
|
||||
|
||||
function dumpFormat() {
|
||||
if (DRIVER == 'server') {
|
||||
if (DRIVER == 'server' || DRIVER == 'mysql') {
|
||||
return array('sql_alter' => 'Alter');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _database() {
|
||||
// drop old tables
|
||||
$query = "SELECT TABLE_NAME, ENGINE, TABLE_COLLATION, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()";
|
||||
@@ -52,7 +52,7 @@ DROP PROCEDURE adminer_alter;
|
||||
SELECT @adminer_alter;
|
||||
";
|
||||
}
|
||||
|
||||
|
||||
function dumpDatabase($db) {
|
||||
static $first = true;
|
||||
if ($_POST["format"] == "sql_alter") {
|
||||
@@ -66,7 +66,7 @@ SELECT @adminer_alter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function dumpTable($table, $style, $is_view = 0) {
|
||||
if ($_POST["format"] == "sql_alter") {
|
||||
$create = create_sql($table, $_POST["auto_increment"], $style);
|
||||
@@ -146,7 +146,7 @@ DROP PROCEDURE adminer_alter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function dumpData() {
|
||||
if ($_POST["format"] == "sql_alter") {
|
||||
return true;
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
class AdminerForeignSystem {
|
||||
|
||||
|
||||
function foreignKeys($table) {
|
||||
if (DRIVER == "server" && DB == "mysql") {
|
||||
if ((DRIVER == "server" || DRIVER == "mysql") && DB == "mysql") {
|
||||
switch ($table) {
|
||||
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")));
|
||||
@@ -52,5 +52,5 @@ class AdminerForeignSystem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
class AdminerLoginServers {
|
||||
/** @access protected */
|
||||
var $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) {
|
||||
$this->servers = $servers;
|
||||
@@ -20,17 +20,17 @@ class AdminerLoginServers {
|
||||
$_POST["auth"]["driver"] = $this->servers[$key]["driver"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function credentials() {
|
||||
return array($this->servers[SERVER]["server"], $_GET["username"], get_password());
|
||||
}
|
||||
|
||||
|
||||
function login($login, $password) {
|
||||
if (!$this->servers[SERVER]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function loginFormField($name, $heading, $value) {
|
||||
if ($name == 'driver') {
|
||||
return '';
|
||||
@@ -38,5 +38,5 @@ class AdminerLoginServers {
|
||||
return $heading . "<select name='auth[server]'>" . optionlist(array_keys($this->servers), SERVER) . "</select>\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
*/
|
||||
class AdminerLoginSsl
|
||||
{
|
||||
private var $ssl;
|
||||
private $ssl;
|
||||
|
||||
/**
|
||||
* MySQL: ["key" => filename, "cert" => filename, "ca" => filename]
|
||||
* 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)
|
||||
{
|
||||
|
||||
@@ -65,7 +65,7 @@ tinyMCE.init({
|
||||
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.EditorManager.execCommand('mceAddControl', true, 'fields-" . js_escape($field["field"]) . "');
|
||||
qs('#form').onsubmit = function () {
|
||||
gid('form').onsubmit = function () {
|
||||
tinyMCE.each(tinyMCE.editors, function (ed) {
|
||||
ed.remove();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user