1
0
mirror of https://github.com/vrana/adminer.git synced 2025-08-30 01:30:12 +02:00

Compare commits

...

231 Commits

Author SHA1 Message Date
Jakub Vrana
d2ed0f7810 Release 4.6.0 2018-02-05 09:30:33 +01:00
Jakub Vrana
7b0c58af32 Fix affected rows after getting warnings 2018-02-05 09:23:07 +01:00
Jakub Vrana
d3cdfc17de Fix number of affected rows after getting warnings 2018-02-05 09:09:41 +01:00
Jakub Vrana
f097817386 Fix test 2018-02-05 08:43:31 +01:00
Jakub Vrana
3b55c4c0f7 Fix 5.1 being displayed as 5.09999... 2018-02-05 08:42:25 +01:00
Jakub Vrana
6636434378 PRIMARY KEY in SQLite 2018-02-05 08:32:51 +01:00
Jakub Vrana
dd3e57086b Add design Esterka 2018-02-02 09:18:38 +01:00
Jakub Vrana
473b60361b Disable autocompleting password on create user page 2018-02-02 08:52:15 +01:00
Jakub Vrana
f128c2d1ea Use primary key to edit rows even if not selected 2018-02-01 23:09:40 +01:00
Jakub Vrana
c75096f173 Space between DB and Use 2018-02-01 22:22:29 +01:00
Jakub Vrana
c0b2c506bc Translate DB 2018-02-01 22:20:56 +01:00
Jakub Vrana
0ebf710d41 Select converted fields only once 2018-02-01 22:03:48 +01:00
Jakub Vrana
fa41126c37 Don't count rows if we reached the end 2018-02-01 20:59:05 +01:00
Jakub Vrana
09920e0056 Fix count_rows with more than one group by column 2018-02-01 20:45:49 +01:00
Jakub Vrana
685bf29abc Use separator in limit1 2018-02-01 18:53:53 +01:00
Jakub Vrana
0866c79afb SQLite: Limit rows in data manipulation without unique key 2018-02-01 18:47:57 +01:00
Jakub Vrana
e8e3ced948 Document that tests don't work with oninput 2018-02-01 17:04:50 +01:00
Jakub Vrana
52d98e16fa PostgreSQL: Limit rows in data manipulation without unique key 2018-02-01 16:58:01 +01:00
Jakub Vrana
763e66a148 Don't use ctid as it's not stable 2018-02-01 16:45:31 +01:00
Jakub Vrana
8868b48e4c Move variables close to their usage 2018-02-01 16:40:58 +01:00
Jakub Vrana
4961588f7d Limit non-unique where updates 2018-02-01 16:25:30 +01:00
Jakub Vrana
f4625da53d Use Oid as the name of the column 2018-02-01 16:15:36 +01:00
Jakub Vrana
dc94b2ec38 Save bytes 2018-02-01 16:00:40 +01:00
Jakub Vrana
f8af8c9cbf Update rmsoft design 2018-02-01 15:38:15 +01:00
Jakub Vrana
e55f0d7cb2 MySQL: Add FIND_IN_SET search operator 2018-02-01 15:25:38 +01:00
Jakub Vrana
5b7f2d9086 Add rmsoft design 2018-02-01 14:54:18 +01:00
Jakub Vrana
6d55395d9e MySQL: Add floor and ceil functions 2018-02-01 14:32:01 +01:00
Jakub Vrana
2e6190fdf1 Fix links to PostgreSQL 10 documentation 2018-02-01 14:02:25 +01:00
Jakub Vrana
b9ad864b75 Delete unused variable 2018-02-01 13:57:46 +01:00
Jakub Vrana
7296f017fb Display options for timestamp columns when creating a new table (thanks to Robert Vlach) 2018-02-01 13:55:11 +01:00
Jakub Vrana
ae91088cb3 Don't display warnings for failed queries 2018-02-01 13:16:37 +01:00
Jakub Vrana
51a574926d Fix variable name 2018-02-01 13:08:28 +01:00
Jakub Vrana
532a4ee083 Reorder variables 2018-02-01 12:27:22 +01:00
Jakub Vrana
6b9c0dee14 Use pg_last_notice only with pgsql 2018-02-01 12:03:11 +01:00
Jakub Vrana
be75939344 Print warnings in call 2018-02-01 11:58:04 +01:00
Jakub Vrana
d667f585e0 Pass start time to selectQuery 2018-02-01 11:54:56 +01:00
Jakub Vrana
ebb23a7a88 PostgreSQL: Display warnings 2018-02-01 11:50:15 +01:00
Jakub Vrana
e9add6d985 Return string from warnings() 2018-02-01 11:43:44 +01:00
Jakub Vrana
e3346fb0bc Display warnings in messages 2018-02-01 09:21:50 +01:00
Jakub Vrana
ae2ea56681 Show select warnings 2018-02-01 08:59:46 +01:00
Colin Mollenhour
080fd0f374 Support X-Forwarded-Prefix (e.g. Traefik PathPrefixStrip feature) 2018-01-31 20:38:14 +01:00
Jakub Vrana
e32f90f8ff Lowercase EXPLAIN but don't translate it 2018-01-31 20:25:41 +01:00
Jakub Vrana
7ad09d2cb4 Move explain below warnings 2018-01-31 20:25:11 +01:00
Jakub Vrana
40038d4210 Fix return type 2018-01-31 18:29:01 +01:00
Jakub Vrana
2adc174541 MySQL: Display warnings in SQL command 2018-01-31 17:28:12 +01:00
Jakub Vrana
2fb2d208c0 Quote default values not starting with a letter 2018-01-31 16:46:50 +01:00
Jakub Vrana
4de6e3180d Stop redirecting links via adminer.org 2018-01-31 11:11:34 +01:00
Jakub Vrana
8829ccdf93 Fix min_version use 2018-01-30 23:53:04 +01:00
Jakub Vrana
0320bcdda6 Quote dates in default value 2018-01-30 17:00:34 +01:00
Jakub Vrana
851700516d Fully support functions in default values 2018-01-30 16:50:37 +01:00
Jakub Vrana
d542843fdd Fix min_version use 2018-01-30 16:42:13 +01:00
Jakub Vrana
4bb2f806b1 PostgreSQL: Allow now() as default value (bug #525) 2018-01-30 16:24:31 +01:00
Jakub Vrana
cc31a69b65 Fix edit_type after 1f21cd43 2018-01-30 16:21:04 +01:00
Jakub Vrana
78f0a1152e PostgreSQL: Allow editing views with uppercase letters (bug #467) 2018-01-30 16:03:13 +01:00
Jakub Vrana
1f21cd4329 PostgreSQL: Allow creating trigger functions 2018-01-30 15:55:50 +01:00
Jakub Vrana
9f69160797 Add placeholders 2018-01-30 15:24:01 +01:00
Jakub Vrana
e81334ef87 PostgreSQL: Support functions 2018-01-30 15:18:26 +01:00
Jakub Vrana
6c3e1e2768 Add min_version to compile.php 2018-01-30 14:47:22 +01:00
Jakub Vrana
92739f48ce SimpleDB: Document that allow_url_fopen is required (bug #340) 2018-01-30 13:19:21 +01:00
Jakub Vrana
d28d01e76c Focus correct field in selectSearch 2018-01-29 21:19:11 +01:00
Jakub Vrana
75450548b3 Support JSON since MariaDB 10.2 (bug #590) 2018-01-29 21:08:38 +01:00
Jakub Vrana
c3b4208853 Use min_version 2018-01-29 20:54:24 +01:00
Jakub Vrana
d38c673e2a Add min_version 2018-01-29 19:34:26 +01:00
Jakub Vrana
93686eab65 Save bytes 2018-01-29 18:33:26 +01:00
Pisyek
224ddb5a33 add malay translation 2018-01-29 18:25:58 +01:00
Radosław Kowalewski
4db23fd471 Added and translated missing keys in polish translation 2018-01-29 18:13:50 +01:00
Steven Adger
a003866a55 Update compatibility with TinyMCE v4 (#247) 2018-01-29 18:09:35 +01:00
Jakub Vrana
0d90f1f1dd Fix elastic after ef5a7639 2018-01-27 11:08:56 +01:00
helix84
ef5a76392d fix elastic.inc.php to work on PHP 5.2
Without this change, I get the following syntax error on PHP 5.2.6:
PHP Parse error:  syntax error, unexpected ':' in /var/www/adminer/adminer/drivers/elastic.inc.php on line 415

I haven't actually tested the alter_table() method.
2018-01-26 16:48:34 +01:00
Jakub Vrana
8d0cbb6eb4 Fix counting selected rows after going back to select page 2018-01-26 08:52:12 +01:00
Jakub Vrana
536999d4dc Release 4.5.0 2018-01-24 21:55:47 +01:00
Jakub Vrana
827a2b8a54 Fix tests after 95d02bb9 2018-01-24 20:52:44 +01:00
Jakub Vrana
a954f7d4b4 Simplify drop object confirmation questions 2018-01-24 18:36:19 +01:00
Jakub Vrana
a137f248f7 Translate message added in 4.4.0 2018-01-24 18:22:20 +01:00
Jakub Vrana
95d02bb924 Display name of the object in confirmation when dropping it 2018-01-24 18:13:05 +01:00
Jakub Vrana
921e57b9aa Display error when getting row to edit 2018-01-24 17:37:35 +01:00
Jakub Vrana
25f9655a38 Avoid CONVERT() except in MySQL (bug #509) 2018-01-24 17:37:14 +01:00
Jakub Vrana
919204dd38 Bump version 2018-01-24 16:51:53 +01:00
Jakub Vrana
34f25afe90 MySQL: Support routines with comments in parameters (bug #460) 2018-01-24 16:37:38 +01:00
Jakub Vrana
8b29ae910f Verify if adminer.version was created on www.adminer.org 2018-01-24 15:10:44 +01:00
Jakub Vrana
6c96b060e7 Store current Adminer version server-side to avoid excessive requests 2018-01-24 15:09:11 +01:00
Jakub Vrana
f4662d5e27 Send token as last param 2018-01-24 13:44:31 +01:00
Jakub Vrana
b15618fcfd Allow using adminer.invalid by other users in a group 2018-01-24 12:11:26 +01:00
Jakub Vrana
03e3f517a8 Extract file_open_lock and file_write_unlock 2018-01-24 12:04:53 +01:00
Jakub Vrana
f0d2af329a Display boolean values as code (bug #562) 2018-01-24 10:53:25 +01:00
Jakub Vrana
452b9ad7f1 MariaDB: Support fulltext and spatial indexes in InnoDB (bug #583) 2018-01-24 09:18:19 +01:00
Jakub Vrana
fb18e814de PostgreSQL: Display foreign tables (bug #576) 2018-01-23 15:03:53 +01:00
Jakub Vrana
75413c56d2 Add designs.php 2018-01-23 14:36:32 +01:00
Jakub Vrana
c3d83d5412 Fix compiled version after 5cc831c1 2018-01-23 14:10:21 +01:00
Jakub Vrana
b14aa75a98 Hide window.opener from pages opened in a new window (bug #561) 2018-01-23 12:53:22 +01:00
Jakub Vrana
dbc76a2b1e Fix GPL version 2018-01-23 12:21:42 +01:00
Jakub Vrana
6d774794c8 Add plugin for switching designs 2018-01-23 12:15:38 +01:00
Jakub Vrana
81be5edb97 Display bold parts of error (bug #565) 2018-01-23 11:16:28 +01:00
Jakub Vrana
e30e5dd059 Add bottom border to last cells 2018-01-23 11:11:41 +01:00
Jakub Vrana
0cdd8beab1 Editor: Fix displaying of false values in PostgreSQL (bug #568) 2018-01-23 11:02:15 +01:00
Jakub Vrana
7b9d5a29aa Decrease float precision (bug #578) 2018-01-23 10:52:57 +01:00
Andrea Giacobino
5cc831c1e1 Add ability to override file name (path) when loading dump from webserver 2018-01-23 09:24:57 +01:00
Jakub Vrana
72aa3c5127 Support current_timestamp() as default of time fields (bug #572) 2018-01-23 08:36:11 +01:00
Jakub Vrana
43ccfcef8f Display newlines in column comments (bug #573) 2018-01-22 21:05:56 +01:00
Jakub Vrana
c789c147b7 MySQL: Support geometry in MySQL 8 (bug #574) 2018-01-22 20:56:35 +01:00
Uherkovich Péter
a2adb67d2f MSSQL driver fixed for freetds drivers. See bug #167, #291 2018-01-22 18:35:08 +01:00
Jakub Vrana
34e2f47761 Fix search focus (regression from 4.4.0) 2018-01-22 18:34:16 +01:00
Jakub Vrana
0d2b232bd7 Compatibility with PHP < 5.3 2018-01-22 17:30:12 +01:00
Jakub Vrana
83e16e059f Add mongodb as a possible driver 2018-01-22 17:12:48 +01:00
Jakub Vrana
6e4dc3911f Save bytes 2018-01-22 17:05:49 +01:00
Vladimir Goncharov
2a08a11e89 php7 support with minimal changes of original code 2018-01-22 16:59:55 +01:00
Jakub Vrana
993dce398d PostgreSQL: Export DROP SEQUENCE if dropping table 2018-01-22 14:33:21 +01:00
Jakub Vrana
eee9a62c8f PostgreSQL: Do not export triggers if not requested 2018-01-22 14:25:27 +01:00
Jakub Vrana
ce17b6cf46 Ignore removed CREATE+ALTER mode in trigger_sql() 2018-01-22 14:14:42 +01:00
Jakub Vrana
923c0ffc87 Fix whitespace 2018-01-22 13:51:47 +01:00
Jakub Vrana
48ed20323f CSP: Allow any CSS 2018-01-22 12:22:25 +01:00
Troy
9a4cd8936d adminer-theme-mancave2-2.0.alpha 2018-01-22 12:20:33 +01:00
Jáchym Toušek
019ada8da5 Fix NULL value in edit form with Postgres 2018-01-22 12:06:15 +01:00
Jakub Vrana
6a95b71164 Do not warn about MySQL specific functions 2018-01-22 12:00:38 +01:00
Jakub Vrana
3b4ce4a0b4 Fix single driver non-MySQL compiled versions (regression from 150301ed) 2018-01-22 11:42:17 +01:00
Jakub Vrana
a414896885 Hide driver selection in single-driver version (regression from e762a6aa) 2018-01-22 11:34:25 +01:00
Peter Knut
47734d8ff4 Unify HTML for list of tables in Editor according to Adminer 2018-01-22 10:57:20 +01:00
Peter Knut
fef1808288 Encapsulate fulltext part in search box into <div> 2018-01-22 10:53:50 +01:00
Fabio Montefuscolo
d2c82fdeca Enhance ElasticSearch integration 2018-01-19 18:32:41 +01:00
Jakub Vrana
e657cdbc3a Allow PHP 5.6 in Travis 2018-01-19 18:20:02 +01:00
Jakub Vrana
bc14e8432f Select numeric database name in DB list (bug #580) 2018-01-19 17:39:27 +01:00
Jakub Vrana
34b03ef835 SQLite: Enable foreign key checks 2018-01-19 14:57:58 +01:00
Jakub Vrana
329b7de9cc CSP: Allow any images, media and fonts, disallow base-uri 2018-01-19 11:05:26 +01:00
Jakub Vrana
2dcad1f284 Define JS functions in AdminerTablesFilter sooner 2018-01-19 10:55:51 +01:00
Jakub Vrana
1b98a10100 Adminer: Fix Search data in tables 2018-01-19 10:46:35 +01:00
Jakub Vrana
187dd56b1c Release 4.4.0 2018-01-17 12:41:38 +01:00
Jakub Vrana
ba9099f084 Allow sending multiple CSP headers 2018-01-17 11:05:59 +01:00
Jakub Vrana
16e05167a4 Use __construct for constructor 2018-01-16 20:05:07 +01:00
Jakub Vrana
756e304c92 Set session cache limiter only without session.auto_start (bug #586) 2018-01-16 16:56:14 +01:00
Jakub Vrana
e762a6aa95 Add missing newline 2018-01-16 16:44:49 +01:00
Jakub Vrana
b3d5c9affe Require specifying credentials in login-sqlite plugin 2018-01-16 16:37:59 +01:00
Jakub Vrana
0268aba85a Avoid count(null) 2018-01-16 16:22:24 +01:00
Jakub Vrana
9ca92309a1 Disallow PHP 5.3 in Travis 2018-01-16 13:51:02 +01:00
Jakub Vrana
0fae40fb61 Disallow connecting to privileged ports (thanks to hyp3rlinx) 2018-01-16 11:18:32 +01:00
Jakub Vrana
0e5df34ea8 Rate limit password-less login attempts from the same IP address (thanks to hyp3rlinx) 2018-01-16 11:17:25 +01:00
Jakub Vrana
f3938c1a66 Use HTTPS 2018-01-14 11:03:54 +01:00
Jakub Vrana
07aa80048a Use HTTPS in doc_link() 2018-01-14 10:38:01 +01:00
Jakub Vrana
c57e7ac3e3 Do not set '' for empty enum 2018-01-14 10:19:56 +01:00
Jakub Vrana
6d14b47d02 Fix select function onchange 2018-01-14 10:18:38 +01:00
Jakub Vrana
ef3b468626 Clone all event handlers in cloneNode() 2018-01-14 10:04:53 +01:00
Jakub Vrana
4d38c09db5 Use border-collapse to prevent unnecessary wrapping in Chrome 2018-01-14 09:35:13 +01:00
Jakub Vrana
3ba99a1c2a Fix whitespace 2018-01-14 08:52:22 +01:00
Jakub Vrana
9cbdb6262b Fix selectCount() in information_schema 2018-01-14 08:36:10 +01:00
Jakub Vrana
cc268428b8 Fix SQL command toggle 2018-01-14 00:10:42 +01:00
Jakub Vrana
80d030f51a Disallow scripts without nonce 2018-01-13 22:19:16 +01:00
Jakub Vrana
e23da5da0e Fix wrapping in Create table 2018-01-13 17:40:21 +01:00
Jakub Vrana
9d532fc0a1 Use script_src for <script src> 2018-01-13 16:25:11 +01:00
Jakub Vrana
144c7de27f Fix typo in script() 2018-01-13 15:23:47 +01:00
Jakub Vrana
b7fcebfba8 Do not send empty CSP 2018-01-13 14:21:54 +01:00
Jakub Vrana
d39a6e59c7 Move inline event handlers to <script> 2018-01-13 09:34:01 +01:00
Jakub Vrana
fc559a1cf6 Move inline event handlers to <script> 2018-01-13 09:21:21 +01:00
Jakub Vrana
f457053d85 Use the fact that we handle oninput in whisper() 2018-01-13 09:07:35 +01:00
Jakub Vrana
e255ba9aa4 Move inline event handlers to <script> 2018-01-13 08:58:01 +01:00
Jakub Vrana
3fe0d88f98 Editor: Fix Search data in tables 2018-01-12 23:59:04 +01:00
Jakub Vrana
68c6b1c942 Move inline event handlers to <script> 2018-01-12 23:42:20 +01:00
Jakub Vrana
001c37e240 Use <script> instead of inline event handler for skipping original 2018-01-12 23:27:14 +01:00
Jakub Vrana
b6cc584f48 Move inline event handlers to <script> 2018-01-12 22:46:16 +01:00
Jakub Vrana
af1ad47a64 Return false from editingMoveRow() 2018-01-12 22:35:05 +01:00
Jakub Vrana
2eaac2e94e Move inline event handlers to <script> 2018-01-12 22:25:38 +01:00
Jakub Vrana
40abffe8de Use oninput instead of onchange 2018-01-12 22:18:54 +01:00
Jakub Vrana
259a465125 Move inline event handlers to <script> 2018-01-12 21:57:54 +01:00
Jakub Vrana
6c1fbf13c6 Fix fieldChange() after 6353a898 2018-01-12 21:49:45 +01:00
Jakub Vrana
6353a89816 Use oninput instead of onkeyup 2018-01-12 18:46:44 +01:00
Jakub Vrana
38aac7ada2 Move inline event handlers to <script> 2018-01-12 18:34:19 +01:00
Jakub Vrana
24245867d7 Use <script> instead of inline event handler in on_help() 2018-01-12 18:11:00 +01:00
Jakub Vrana
1459df56bc Move inline event handlers to <script> 2018-01-12 17:59:46 +01:00
Jakub Vrana
dc3a0e1a32 Clone onchange in cloneNode() 2018-01-12 17:33:23 +01:00
Jakub Vrana
0411495d20 Move inline event handlers to <script> 2018-01-12 17:19:47 +01:00
Jakub Vrana
3d69fbf5f7 Allow searching data in tables by Ctrl+Enter 2018-01-12 17:11:29 +01:00
Jakub Vrana
5e9df49fd1 Move inline event handlers to <script> 2018-01-12 17:11:29 +01:00
Jakub Vrana
565a5ca0eb Fix selectors in schema after 58b2904d 2018-01-12 17:11:29 +01:00
Jakub Vrana
9061583538 Rely on event always passed to handlers 2018-01-12 17:11:29 +01:00
Jakub Vrana
35b1db6974 Move inline event handlers to <script> 2018-01-12 17:11:29 +01:00
Jakub Vrana
068ee71bf7 Return false from editingRemoveRow 2018-01-12 17:11:29 +01:00
Jakub Vrana
efcf37d162 Move inline event handlers to <script> 2018-01-12 17:11:29 +01:00
Jakub Vrana
e645693147 Use script() for <script> 2018-01-12 17:10:33 +01:00
Jakub Vrana
12fbfc9847 Move inline event handlers to <script> 2018-01-12 17:09:41 +01:00
Jakub Vrana
6b2ba65084 Use <script> instead of inline event handler in print_fieldset() 2018-01-12 17:09:41 +01:00
Jakub Vrana
a5ee3451ac Use <script> instead of inline event handler in confirm() 2018-01-12 17:09:41 +01:00
Jakub Vrana
da671df728 Move inline event handlers to <script> 2018-01-12 17:09:41 +01:00
Jakub Vrana
650221357d Return false from ajaxSetHtml() 2018-01-12 17:09:41 +01:00
Jakub Vrana
d996b48cfa Move inline event handlers to <script> 2018-01-12 17:09:41 +01:00
Jakub Vrana
22b4322710 Revert using @this in formChecked 2018-01-12 17:09:41 +01:00
Jakub Vrana
36edd445a6 Move inline event handlers to <script> 2018-01-12 17:09:41 +01:00
Jakub Vrana
7305783c21 Return false from toggle() 2018-01-12 17:09:41 +01:00
Jakub Vrana
ee3a88d574 onchange='selectFieldChange 2018-01-12 17:09:41 +01:00
Jakub Vrana
e5c52589ec Use @this in selectFieldChange 2018-01-12 17:09:41 +01:00
Jakub Vrana
3b0e1cf289 Move inline event handlers to <script> 2018-01-12 17:09:41 +01:00
Jakub Vrana
767fc0e47e Fix indexesAddColumn after 14778165 2018-01-12 17:09:41 +01:00
Jakub Vrana
63581af0f6 Move inline event handlers to <script> 2018-01-12 17:09:35 +01:00
Jakub Vrana
813ada6661 Revert using @this in formChecked 2018-01-11 18:58:00 +01:00
Jakub Vrana
4be72a2a0d Allow customizing CSP 2018-01-11 18:39:49 +01:00
Jakub Vrana
541c3c1fed Allow img-src data: common in skins 2018-01-11 18:39:49 +01:00
Jakub Vrana
3408d4ad78 Use JSON.parse if available 2018-01-11 18:39:49 +01:00
Jakub Vrana
e614ae08c4 Add Content Security Policy 2018-01-11 18:39:49 +01:00
Jakub Vrana
552d2a6be4 Always send security headers in customization 2018-01-11 18:39:49 +01:00
Jakub Vrana
415253b1b1 Add nosniff header 2018-01-11 18:39:22 +01:00
Jakub Vrana
d07b7e3773 Use Referrer-Policy instead of <meta name="referrer">
To make securityheaders.io happy.

Also fix a typo in the value (https://lists.w3.org/Archives/Public/public-webappsec/2015May/0059.html).
2018-01-11 18:38:15 +01:00
Jakub Vrana
3de101dff4 Editor: Fix doubleclick on database page 2018-01-11 17:24:57 +01:00
Jakub Vrana
48dacd1e97 Fix a typo from 9cb28186 2018-01-11 17:05:37 +01:00
Jakub Vrana
14778165a8 Use @this in JavaScript (prepares for removing inline event handlers) 2018-01-11 17:01:29 +01:00
Jakub Vrana
72b199378a Prevent PHP 7.1 warning about non-numeric values 2018-01-11 16:22:29 +01:00
Jakub Vrana
329fa55af5 Unindent doc-comments 2018-01-11 15:14:05 +01:00
Jakub Vrana
ecf34769ad Delete type="text/css" from <style> as it is the default in HTML5 2018-01-11 14:14:15 +01:00
Jakub Vrana
dc85ba2d86 Delete type="text/javascript" from <script> as it is the default in HTML5 2018-01-11 14:13:43 +01:00
Jakub Vrana
741b76fbd4 Replace getElementsByTagName by shortcut for querySelectorAll 2018-01-11 14:00:04 +01:00
Jakub Vrana
58b2904d62 Use querySelector 2018-01-11 13:55:48 +01:00
Jakub Vrana
9cb281868f Replace getElementById by shortcut for querySelector (requires IE8) 2018-01-11 13:51:32 +01:00
Jakub Vrana
67f6aea77f Fix skin for Chrome 61 (thanks to Dominik Ulrich) 2017-10-28 15:05:07 +02:00
Jakub Vrana
7bcba262df Editor: Display field comment's text inside [] only in edit form 2017-10-01 08:45:17 -07:00
Itamar Schen
75c0786d2e Fix hebrew typos (#228) 2017-09-29 09:25:32 +02:00
Jakub Vrana
c4f6cbb32e Add new Hebrew translations 2017-09-11 13:25:49 +02:00
Jakub Vrana
b10e9e127e Add Hebrew translation 2017-09-09 12:06:14 +02:00
Lukas Tribus
32f1e856ad Editor: Don't set time zone from PHP
Current implementation checks the delta between the local time and
UTC, and applies the delta as time zone for MySQL.

This assumption is wrong if the current time is DST enabled, but the
time that is converted isn't - and vice versa.

For example, Europe/Prague is "CET-1CEST,M3.5.0,M10.5.0/3", when
the MySQL connections is setup now (September, DST enabled) and
we are reading a TIMESTAMP from November, then MySQL applies +0200
instead of +0100 to that timestamp even though November is supposed
to be DST disabled.

There is no reliable and portable way in PHP to understand the
time zone, especially since PHP >= 5.4.0 ignores environment
variable and OS settings [1].

MySQL needs to be properly setup (TZ data loaded [2] and default
TZ set [3]), then everything will work just fine.

The current implementation however causes wrong data 50% of the
time, even when OS/MySQL/PHP is properly setup. As a MySQL
connection will converte timestamps from both DST enabled and
DST disabled dates, a static UTC offset must never be set at
connection level (set time_zone = ...).

This change removes the current implementation, therefor maintaining
OS/MySQL defaults, fixing the DST issue in properly configured
environments.

[1] http://php.net/manual/en/function.date-default-timezone-get.php
[2] https://dev.mysql.com/doc/refman/5.5/en/mysql-tzinfo-to-sql.html
[3] https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
2017-09-09 11:44:42 +02:00
Jonathan Vollebregt
17e45e9a9c Make sure all sidebar elements are pushed down, not just the form.
This was breaking the #logins block at the log in screen.
2017-09-09 11:39:47 +02:00
Jonathan Vollebregt
e1f43da8df Update AdminerTablesFilter to produce li as per c9801e2e24 2017-05-19 11:23:35 +02:00
Jakub Vrana
70aef8a55a MySQL: Remove dedicated view for replication status 2017-05-19 11:11:44 +02:00
Jakub Vrana
0b824dad29 Sort table names (bug #552) 2017-05-19 10:57:20 +02:00
Alfonso Montero
65fa4b4e31 Update es.inc.php 2017-04-22 10:07:55 +02:00
Jakub Vrana
c0a3f30060 Add a donate link 2017-04-16 10:42:27 +02:00
Jakub Vrana
7af1ee3702 Release 4.3.1 2017-04-14 09:48:11 +02:00
Jakub Vrana
3cbece1ec0 Fix SQL command autofocus 2017-04-09 12:30:34 +02:00
Jakub Vrana
0d73372c50 Add a todo 2017-04-09 12:13:18 +02:00
Jakub Vrana
fb7bd02713 Don't overwrite previous cookies (bug #539) 2017-04-09 11:04:57 +02:00
Jakub Vrana
fb71941daa PostgreSQL: Fix JSONB version support 2017-04-08 20:17:08 +02:00
Jakub Vrana
504c56216c PostgreSQL: Support JSON and JSONB data types (bug #542) 2017-04-08 19:59:13 +02:00
Jakub Vrana
88803c6d0e Update haeckel design (thanks to Klemens Haeckel) 2017-04-08 19:51:13 +02:00
Andre Polykanine A.K.A. Menelion Elensúlë
b585ee8261 Updating Russian translation 2017-04-08 19:41:36 +02:00
Deni
f4817e8568 Fix table dependency on export 2017-04-08 19:38:03 +02:00
Deni
105aca9b04 Fix PostgreSQL nullable fields in export 2017-04-08 19:37:56 +02:00
Jakub Vrana
f556f6acb1 PostgreSQL: Fix index size computation in PostgreSQL < 9.0 (reverts 4c78976c) 2017-04-08 19:33:46 +02:00
124 changed files with 4886 additions and 1274 deletions

View File

@@ -1,5 +1,5 @@
language: php
php:
- '5.3'
- '5.6'
- '7.1'
script: git diff --name-only $TRAVIS_COMMIT_RANGE | grep '\.php$' | xargs -n1 -P8 php -l | grep -v 'No syntax errors'; test $? -eq 1

View File

@@ -1,8 +1,8 @@
<?php
$PROCEDURE = $_GET["call"];
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["call"]);
page_header(lang('Call') . ": " . h($PROCEDURE), $error);
$routine = routine($PROCEDURE, (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
$routine = routine($_GET["call"], (isset($_GET["callf"]) ? "FUNCTION" : "PROCEDURE"));
$in = array();
$out = array();
foreach ($routine["fields"] as $i => $field) {
@@ -30,9 +30,12 @@ if (!$error && $_POST) {
}
$query = (isset($_GET["callf"]) ? "SELECT" : "CALL") . " " . table($PROCEDURE) . "(" . implode(", ", $call) . ")";
echo "<p><code class='jush-$jush'>" . h($query) . "</code> <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>\n";
$start = microtime(true);
$result = $connection->multi_query($query);
$affected = $connection->affected_rows; // getting warnigns overwrites this
echo $adminer->selectQuery($query, $start, !$result);
if (!$connection->multi_query($query)) {
if (!$result) {
echo "<p class='error'>" . error() . "\n";
} else {
$connection2 = connect();
@@ -45,7 +48,7 @@ if (!$error && $_POST) {
if (is_object($result)) {
select($result, $connection2);
} else {
echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $connection->affected_rows) . "\n";
echo "<p class='message'>" . lang('Routine has been called, %d row(s) affected.', $affected) . "\n";
}
} while ($connection->next_result());

View File

@@ -120,7 +120,7 @@ page_header(($TABLE != "" ? lang('Alter table') : lang('Create table')), $error,
if (!$_POST) {
$row = array(
"Engine" => $_COOKIE["adminer_engine"],
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")))),
"fields" => array(array("field" => "", "type" => (isset($types["int"]) ? "int" : (isset($types["integer"]) ? "integer" : "")), "on_update" => "")),
"partition_names" => array(""),
);
@@ -163,8 +163,8 @@ foreach ($engines as $engine) {
<p>
<?php if (support("columns") || $TABLE == "") { ?>
<?php echo lang('Table name'); ?>: <input name="name" maxlength="64" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<?php if ($TABLE == "" && !$_POST) { ?><script type='text/javascript'>focus(document.getElementById('form')['name']);</script><?php } ?>
<?php echo ($engines ? "<select name='Engine' onchange='helpClose();'" . on_help("getTarget(event).value", 1) . ">" . optionlist(array("" => "(" . lang('engine') . ")") + $engines, $row["Engine"]) . "</select>" : ""); ?>
<?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 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 } ?>
@@ -187,24 +187,25 @@ edit_fields($row["fields"], $collations, "TABLE", $foreign_keys, $comments);
<p>
<?php echo lang('Auto Increment'); ?>: <input type="number" name="Auto_increment" size="6" value="<?php echo h($row["Auto_increment"]); ?>">
<?php echo checkbox("defaults", 1, true, lang('Default values'), "columnShow(this.checked, 5)", "jsonly"); ?>
<?php if (!$_POST["defaults"]) { ?><script type="text/javascript">editingHideDefaults()</script><?php } ?>
<?php if (!$_POST["defaults"]) { echo script("editingHideDefaults();"); } ?>
<?php echo (support("comment")
? "<label><input type='checkbox' name='comments' value='1' class='jsonly' onclick=\"columnShow(this.checked, 6); toggle('Comment'); if (this.checked) this.form['Comment'].focus();\"" . ($comments ? " checked" : "") . ">" . lang('Comment') . "</label>"
. ' <input name="Comment" id="Comment" value="' . h($row["Comment"]) . '" maxlength="' . ($connection->server_info >= 5.5 ? 2048 : 60) . '"' . ($comments ? '' : ' class="hidden"') . '>'
? "<label><input type='checkbox' name='comments' value='1' class='jsonly'" . ($comments ? " checked" : "") . ">" . lang('Comment') . "</label>"
. script("qsl('input').onclick = function () { columnShow(this.checked, 6); toggle('Comment'); if (this.checked) this.form['Comment'].focus(); };")
. ' <input name="Comment" id="Comment" value="' . h($row["Comment"]) . '" maxlength="' . (min_version(5.5) ? 2048 : 60) . '"' . ($comments ? '' : ' class="hidden"') . '>'
: '')
; ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php } ?>
<?php if ($TABLE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($TABLE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?><?php } ?>
<?php
if (support("partitioning")) {
$partition_table = preg_match('~RANGE|LIST~', $row["partition_by"]);
print_fieldset("partition", lang('Partition by'), $row["partition_by"]);
?>
<p>
<?php echo "<select name='partition_by' onchange='partitionByChange(this);'" . on_help("getTarget(event).value.replace(/./, 'PARTITION BY \$&')", 1) . ">" . optionlist(array("" => "") + $partition_by, $row["partition_by"]) . "</select>"; ?>
<?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;"); ?>
(<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'"); ?>>
@@ -212,7 +213,8 @@ if (support("partitioning")) {
<?php
foreach ($row["partition_names"] as $key => $val) {
echo '<tr>';
echo '<td><input name="partition_names[]" value="' . h($val) . '"' . ($key == count($row["partition_names"]) - 1 ? ' onchange="partitionNameChange(this);"' : '') . ' autocapitalize="off">';
echo '<td><input name="partition_names[]" value="' . h($val) . '" autocapitalize="off">';
echo ($key == count($row["partition_names"]) - 1 ? script("qsl('input').oninput = partitionNameChange;") : '');
echo '<td><input name="partition_values[]" value="' . h($row["partition_values"][$key]) . '">';
}
?>

View File

@@ -65,12 +65,12 @@ echo ($_POST["add_x"] || strpos($name, "\n")
'sql' => "charset-charsets.html",
'mssql' => "ms187963.aspx",
)) : "");
echo script("focus(qs('#name'));");
?>
<script type='text/javascript'>focus(document.getElementById('name'));</script>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php
if (DB != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . ">\n";
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', DB)) . "\n";
} elseif (!$_POST["add_x"] && $_GET["db"] == "") {
echo "<input type='image' class='icon' name='add' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>\n";
}

View File

@@ -4,7 +4,7 @@ $tables_views = array_merge((array) $_POST["tables"], (array) $_POST["views"]);
if ($tables_views && !$error && !$_POST["search"]) {
$result = true;
$message = "";
if ($jush == "sql" && count($_POST["tables"]) > 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) {
if ($jush == "sql" && $_POST["tables"] && count($_POST["tables"]) > 1 && ($_POST["drop"] || $_POST["truncate"] || $_POST["copy"])) {
queries("SET foreign_key_checks = 0"); // allows to truncate or drop several tables at once
}
@@ -56,15 +56,19 @@ if ($adminer->homepage()) {
echo "<form action='' method='post'>\n";
if (support("table")) {
echo "<fieldset><legend>" . lang('Search data in tables') . " <span id='selected2'></span></legend><div>";
echo "<input type='search' name='query' value='" . h($_POST["query"]) . "'> <input type='submit' name='search' value='" . lang('Search') . "'>\n";
echo "<input type='search' name='query' value='" . h($_POST["query"]) . "'>";
echo script("qsl('input').onkeydown = partialArg(bodyKeydown, 'search');", "");
echo " <input type='submit' name='search' value='" . lang('Search') . "'>\n";
echo "</div></fieldset>\n";
if ($_POST["search"] && $_POST["query"] != "") {
search_tables();
}
}
$doc_link = doc_link(array('sql' => 'show-table-status.html'));
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n";
echo '<thead><tr class="wrap"><td><input id="check-all" type="checkbox" onclick="formCheck(this, /^(tables|views)\[/);" class="jsonly">';
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 '<th>' . lang('Table');
echo '<td>' . lang('Engine') . doc_link(array('sql' => 'storage-engines.html'));
echo '<td>' . lang('Collation') . doc_link(array('sql' => 'charset-mysql.html'));
@@ -115,17 +119,17 @@ if ($adminer->homepage()) {
echo "</table>\n";
if (!information_schema(DB)) {
$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') . "'> " . on_help("'VACUUM'");
$optimize = "<input type='submit' name='optimize' value='" . lang('Optimize') . "'> " . on_help($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') . "'> " . 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'")
: "")))
. "<input type='submit' name='truncate' value='" . lang('Truncate') . "'" . confirm() . on_help($jush == "sqlite" ? "'DELETE'" : "'TRUNCATE" . ($jush == "pgsql" ? "'" : " TABLE'")) . "> "
. "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . on_help("'DROP TABLE'") . ">\n";
. "<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";
$databases = (support("scheme") ? $adminer->schemas() : $adminer->databases());
if (count($databases) != 1 && $jush != "sqlite") {
$db = (isset($_POST["target"]) ? $_POST["target"] : (support("scheme") ? $_GET["ns"] : DB));
@@ -135,12 +139,13 @@ if ($adminer->homepage()) {
echo (support("copy") ? " <input type='submit' name='copy' value='" . lang('Copy') . "'>" : "");
echo "\n";
}
echo "<input type='hidden' name='all' value='' onclick=\"selectCount('selected', formChecked(this, /^(tables|views)\[/));" . (support("table") ? " selectCount('selected2', formChecked(this, /^tables\[/) || $tables);" : "") . "\">\n"; // used by trCheck()
echo "<input type='hidden' name='all' value=''>"; // used by trCheck()
echo script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^(tables|views)\[/));" . (support("table") ? " selectCount('selected2', formChecked(this, /^tables\[/) || $tables);" : "") . " }");
echo "<input type='hidden' name='token' value='$token'>\n";
echo "</div></fieldset>\n";
}
echo "</form>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo script("tableCheck();");
}
echo '<p class="links"><a href="' . h(ME) . 'create=">' . lang('Create table') . "</a>\n";
@@ -154,11 +159,12 @@ if ($adminer->homepage()) {
echo '<thead><tr><th>' . lang('Name') . '<td>' . lang('Type') . '<td>' . lang('Return type') . "<td>&nbsp;</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["ROUTINE_NAME"]) . '">' . h($row["ROUTINE_NAME"]) . '</a>';
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["ROUTINE_NAME"]) . '">' . lang('Alter') . "</a>";
echo '<td><a href="' . h(ME . ($row["ROUTINE_TYPE"] != "PROCEDURE" ? 'function=' : 'procedure=') . urlencode($row["SPECIFIC_NAME"]) . $name) . '">' . lang('Alter') . "</a>";
}
echo "</table>\n";
}
@@ -221,7 +227,7 @@ if ($adminer->homepage()) {
}
if ($tables_list) {
echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=db');</script>\n";
echo script("ajaxSetHtml('" . js_escape(ME) . "script=db');");
}
}
}

14
adminer/designs.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/designs.php";
$designs = array();
foreach (glob("../designs/*", GLOB_ONLYDIR) as $filename) {
$designs["$filename/adminer.css"] = basename($filename);
}
return new AdminerPlugin(array(
new AdminerDesigns($designs),
));
}
include "./index.php";

View File

@@ -17,9 +17,10 @@ if (isset($_GET["elastic"])) {
*/
function rootQuery($path, $content = array(), $method = 'GET') {
@ini_set('track_errors', 1); // @ - may be disabled
$file = @file_get_contents($this->_url . '/' . ltrim($path, '/'), false, stream_context_create(array('http' => array(
$file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array(
'method' => $method,
'content' => json_encode($content),
'content' => $content === null ? $content : json_encode($content),
'header' => 'Content-Type: application/json',
'ignore_errors' => 1, // available since PHP 5.2.10
))));
if (!$file) {
@@ -60,7 +61,7 @@ if (isset($_GET["elastic"])) {
function connect($server, $username, $password) {
preg_match('~^(https?://)?(.*)~', $server, $match);
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]/";
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
$return = $this->query('');
if ($return) {
$this->server_info = $return['version']['number'];
@@ -147,7 +148,7 @@ if (isset($_GET["elastic"])) {
$start = microtime(true);
$search = $this->_conn->query($query, $data);
if ($print) {
echo $adminer->selectQuery("$query: " . print_r($data, true), format_time($start));
echo $adminer->selectQuery("$query: " . print_r($data, true), $start, !$search);
}
if (!$search) {
return false;
@@ -156,7 +157,7 @@ if (isset($_GET["elastic"])) {
foreach ($search['hits']['hits'] as $hit) {
$row = array();
if ($select == array("*")) {
$row["_id"] = $hit["_id"];
$row["_id"] = $hit["_id"];
}
$fields = $hit['_source'];
if ($select != array("*")) {
@@ -176,6 +177,47 @@ if (isset($_GET["elastic"])) {
return new Min_Result($return);
}
function update($type, $record, $queryWhere) {
$parts = preg_split('~ *= *~', $queryWhere);
if (count($parts) == 2) {
$id = trim($parts[1]);
$query = "$type/$id";
return $this->_conn->query($query, $record, 'POST');
}
return false;
}
function insert($type, $record) {
$id = ""; //! user should be able to inform _id
$query = "$type/$id";
$response = $this->_conn->query($query, $record, 'POST');
$this->_conn->last_id = $response['_id'];
return $response['created'];
}
function delete($type, $queryWhere) {
$ids = array();
if (is_array($_GET["where"]) && $_GET["where"]["_id"]) {
$ids[] = $_GET["where"]["_id"];
}
if (is_array($_POST['check'])) {
foreach ($_POST['check'] as $check) {
$parts = preg_split('~ *= *~', $check);
if (count($parts) == 2) {
$ids[] = trim($parts[1]);
}
}
}
$this->_conn->affected_rows = 0;
foreach ($ids as $id) {
$query = "{$type}/{$id}";
$response = $this->_conn->query($query, '{}', 'DELETE');
if (is_array($response) && $response['found'] == true) {
$this->_conn->affected_rows++;
}
}
return $this->_conn->affected_rows;
}
}
@@ -223,9 +265,14 @@ if (isset($_GET["elastic"])) {
function count_tables($databases) {
global $connection;
$return = $connection->query('_mapping');
if ($return) {
$return = array_map('count', $return);
$return = array();
$result = $connection->query('_stats');
if ($result && $result['indices']) {
$indices = $result['indices'];
foreach($indices as $indice => $stats) {
$indexing = $stats['total']['indexing'];
$return[$indice] = $indexing['index_total'];
}
}
return $return;
}
@@ -241,24 +288,26 @@ if (isset($_GET["elastic"])) {
function table_status($name = "", $fast = false) {
global $connection;
$search = $connection->query("_search?search_type=count", array(
"facets" => array(
$search = $connection->query("_search", array(
"size" => 0,
"aggregations" => array(
"count_by_type" => array(
"terms" => array(
"field" => "_type",
"field" => "_type"
)
)
)
), "POST");
$return = array();
if ($search) {
foreach ($search["facets"]["count_by_type"]["terms"] as $table) {
$return[$table["term"]] = array(
"Name" => $table["term"],
$tables = $search["aggregations"]["count_by_type"]["buckets"];
foreach ($tables as $table) {
$return[$table["key"]] = array(
"Name" => $table["key"],
"Engine" => "table",
"Rows" => $table["count"],
"Rows" => $table["doc_count"],
);
if ($name != "" && $name == $table["term"]) {
if ($name != "" && $name == $table["key"]) {
return $return[$name];
}
}
@@ -336,16 +385,16 @@ if (isset($_GET["elastic"])) {
return null;
}
/** Create database
/** Create index
* @param string
* @return mixed
*/
function create_database($db) {
global $connection;
return $connection->rootQuery(urlencode($db), array(), 'PUT');
return $connection->rootQuery(urlencode($db), null, 'PUT');
}
/** Drop databases
/** Remove index
* @param array
* @return mixed
*/
@@ -354,7 +403,27 @@ if (isset($_GET["elastic"])) {
return $connection->rootQuery(urlencode(implode(',', $databases)), array(), 'DELETE');
}
/** Drop tables
/** Alter type
* @param array
* @return mixed
*/
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
$properties = array();
foreach($fields as $f) {
$field_name = trim($f[1][0]);
$field_type = trim($f[1][1] ? $f[1][1] : "text");
$properties[$field_name] = array(
'type' => $field_type
);
}
if (!empty($properties)) {
$properties = array('properties' => $properties);
}
return $connection->query("_mapping/{$name}", $properties, 'PUT');
}
/** Drop types
* @param array
* @return bool
*/
@@ -367,9 +436,25 @@ if (isset($_GET["elastic"])) {
return $return;
}
function last_id() {
global $connection;
return $connection->last_id;
}
$jush = "elastic";
$operators = array("=", "query");
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));
$types = array(); ///< @var array ($type => $maximum_unsigned_length, ...)
$structured_types = array(); ///< @var array ($description => array($type, ...), ...)
foreach (array(
lang('Numbers') => array("long" => 3, "integer" => 5, "short" => 8, "byte" => 10, "double" => 20, "float" => 66, "half_float" => 12, "scaled_float" => 21),
lang('Date and time') => array("date" => 10),
lang('Strings') => array("string" => 65535, "text" => 65535),
lang('Binary') => array("binary" => 255),
) as $key => $val) {
$types += $val;
$structured_types[$key] = array_keys($val);
}
}

View File

@@ -147,8 +147,8 @@ if (isset($_GET["firebird"])) {
return $return;
}
function limit1($query, $where) {
return limit($query, $where, 1);
function limit1($table, $query, $where, $separator = "\n") {
return limit($query, $where, 1, 0, $separator);
}
function db_collation($db, $collations) {

View File

@@ -2,7 +2,7 @@
$drivers["mongo"] = "MongoDB (beta)";
if (isset($_GET["mongo"])) {
$possible_drivers = array("mongo");
$possible_drivers = array("mongo", "mongodb");
define("DRIVER", "mongo");
if (class_exists('MongoDB')) {
@@ -109,97 +109,502 @@ if (isset($_GET["mongo"])) {
}
}
}
class Min_Driver extends Min_SQL {
public $primary = "_id";
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
$select = ($select == array("*")
? array()
: array_fill_keys($select, true)
);
$sort = array();
foreach ($order as $val) {
$val = preg_replace('~ DESC$~', '', $val, 1, $count);
$sort[$val] = ($count ? -1 : 1);
class Min_Driver extends Min_SQL {
public $primary = "_id";
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
$select = ($select == array("*")
? array()
: array_fill_keys($select, true)
);
$sort = array();
foreach ($order as $val) {
$val = preg_replace('~ DESC$~', '', $val, 1, $count);
$sort[$val] = ($count ? -1 : 1);
}
return new Min_Result($this->_conn->_db->selectCollection($table)
->find(array(), $select)
->sort($sort)
->limit($limit != "" ? +$limit : 0)
->skip($page * $limit)
);
}
function insert($table, $set) {
try {
$return = $this->_conn->_db->selectCollection($table)->insert($set);
$this->_conn->errno = $return['code'];
$this->_conn->error = $return['err'];
$this->_conn->last_id = $set['_id'];
return !$return['err'];
} catch (Exception $ex) {
$this->_conn->error = $ex->getMessage();
return false;
}
}
return new Min_Result($this->_conn->_db->selectCollection($table)
->find(array(), $select)
->sort($sort)
->limit(+$limit)
->skip($page * $limit)
);
}
function insert($table, $set) {
try {
$return = $this->_conn->_db->selectCollection($table)->insert($set);
$this->_conn->errno = $return['code'];
$this->_conn->error = $return['err'];
$this->_conn->last_id = $set['_id'];
return !$return['err'];
} catch (Exception $ex) {
$this->_conn->error = $ex->getMessage();
function get_databases($flush) {
global $connection;
$return = array();
$dbs = $connection->_link->listDBs();
foreach ($dbs['databases'] as $db) {
$return[] = $db['name'];
}
return $return;
}
function count_tables($databases) {
global $connection;
$return = array();
foreach ($databases as $db) {
$return[$db] = count($connection->_link->selectDB($db)->getCollectionNames(true));
}
return $return;
}
function tables_list() {
global $connection;
return array_fill_keys($connection->_db->getCollectionNames(true), 'table');
}
function drop_databases($databases) {
global $connection;
foreach ($databases as $db) {
$response = $connection->_link->selectDB($db)->drop();
if (!$response['ok']) {
return false;
}
}
return true;
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
foreach ($connection->_db->selectCollection($table)->getIndexInfo() as $index) {
$descs = array();
foreach ($index["key"] as $column => $type) {
$descs[] = ($type == -1 ? '1' : null);
}
$return[$index["name"]] = array(
"type" => ($index["name"] == "_id_" ? "PRIMARY" : ($index["unique"] ? "UNIQUE" : "INDEX")),
"columns" => array_keys($index["key"]),
"lengths" => array(),
"descs" => $descs,
);
}
return $return;
}
function fields($table) {
return fields_from_edit();
}
function found_rows($table_status, $where) {
global $connection;
//! don't call count_rows()
return $connection->_db->selectCollection($_GET["select"])->count($where);
}
$operators = array("=");
} elseif (class_exists('MongoDB\Driver\Manager')) {
class Min_DB {
var $extension = "MongoDB", $error, $last_id;
/** @var MongoDB\Driver\Manager */
var $_link;
var $_db, $_db_name;
function connect($server, $username, $password) {
global $adminer;
$db = $adminer->database();
$options = array();
if ($username != "") {
$options["username"] = $username;
$options["password"] = $password;
}
if ($db != "") {
$options["db"] = $db;
}
try {
$class = 'MongoDB\Driver\Manager';
$this->_link = new $class("mongodb://$server", $options);
return true;
} catch (Exception $ex) {
$this->error = $ex->getMessage();
return false;
}
}
function query($query) {
return false;
}
function select_db($database) {
try {
$this->_db_name = $database;
return true;
} catch (Exception $ex) {
$this->error = $ex->getMessage();
return false;
}
}
function quote($string) {
return $string;
}
}
}
class Min_Result {
var $num_rows, $_rows = array(), $_offset = 0, $_charset = array();
function __construct($result) {
foreach ($result as $item) {
$row = array();
foreach ($item as $key => $val) {
if (is_a($val, 'MongoDB\BSON\Binary')) {
$this->_charset[$key] = 63;
}
$row[$key] =
(is_a($val, 'MongoDB\BSON\ObjectID') ? 'MongoDB\BSON\ObjectID("' . strval($val) . '")' :
(is_a($val, 'MongoDB\BSON\UTCDatetime') ? $val->toDateTime()->format('Y-m-d H:i:s') :
(is_a($val, 'MongoDB\BSON\Binary') ? $val->bin : //! allow downloading
(is_a($val, 'MongoDB\BSON\Regex') ? strval($val) :
(is_object($val) ? json_encode($val, 256) : // 256 = JSON_UNESCAPED_UNICODE
$val // MongoMinKey, MongoMaxKey
)))));
}
$this->_rows[] = $row;
foreach ($row as $key => $val) {
if (!isset($this->_rows[0][$key])) {
$this->_rows[0][$key] = null;
}
}
}
$this->num_rows = $result->count;
}
function fetch_assoc() {
$row = current($this->_rows);
if (!$row) {
return $row;
}
$return = array();
foreach ($this->_rows[0] as $key => $val) {
$return[$key] = $row[$key];
}
next($this->_rows);
return $return;
}
function fetch_row() {
$return = $this->fetch_assoc();
if (!$return) {
return $return;
}
return array_values($return);
}
function fetch_field() {
$keys = array_keys($this->_rows[0]);
$name = $keys[$this->_offset++];
return (object) array(
'name' => $name,
'charsetnr' => $this->_charset[$name],
);
}
function connect() {
global $adminer;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection;
}
return $connection->error;
}
function error() {
global $connection;
return h($connection->error);
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
return $credentials[1];
}
class Min_Driver extends Min_SQL {
public $primary = "_id";
function get_databases($flush) {
global $connection;
$return = array();
$dbs = $connection->_link->listDBs();
foreach ($dbs['databases'] as $db) {
$return[] = $db['name'];
function select($table, $select, $where, $group, $order = array(), $limit = 1, $page = 0, $print = false) {
global $connection;
$select = ($select == array("*")
? array()
: array_fill_keys($select, 1)
);
if (count($select) && !isset($select['_id'])) {
$select['_id'] = 0;
}
$where = where_to_query($where);
$sort = array();
foreach ($order as $val) {
$val = preg_replace('~ DESC$~', '', $val, 1, $count);
$sort[$val] = ($count ? -1 : 1);
}
if (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] > 0) {
$limit = $_GET['limit'];
}
$limit = min(200, max(1, (int) $limit));
$skip = $page * $limit;
$class = 'MongoDB\Driver\Query';
$query = new $class($where, array('projection' => $select, 'limit' => $limit, 'skip' => $skip, 'sort' => $sort));
$results = $connection->_link->executeQuery("$connection->_db_name.$table", $query);
return new Min_Result($results);
}
function update($table, $set, $queryWhere, $limit = 0, $separator = "\n") {
global $connection;
$db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if (isset($set['_id'])) {
unset($set['_id']);
}
$removeFields = array();
foreach ($set as $key => $value) {
if ($value == 'NULL') {
$removeFields[$key] = 1;
unset($set[$key]);
}
}
$update = array('$set' => $set);
if (count($removeFields)) {
$update['$unset'] = $removeFields;
}
$bulk->update($where, $update, array('upsert' => false));
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getModifiedCount();
return true;
}
function delete($table, $queryWhere, $limit = 0) {
global $connection;
$db = $connection->_db_name;
$where = sql_query_where_parser($queryWhere);
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
$bulk->delete($where, array('limit' => $limit));
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getDeletedCount();
return true;
}
function insert($table, $set) {
global $connection;
$db = $connection->_db_name;
$class = 'MongoDB\Driver\BulkWrite';
$bulk = new $class(array());
if (isset($set['_id']) && empty($set['_id'])) {
unset($set['_id']);
}
$bulk->insert($set);
$results = $connection->_link->executeBulkWrite("$db.$table", $bulk);
$connection->affected_rows = $results->getInsertedCount();
return true;
}
}
return $return;
}
function collations() {
return array();
}
function db_collation($db, $collations) {
}
function count_tables($databases) {
global $connection;
$return = array();
foreach ($databases as $db) {
$return[$db] = count($connection->_link->selectDB($db)->getCollectionNames(true));
function get_databases($flush) {
/** @var $connection Min_DB */
global $connection;
$return = array();
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listDatabases' => 1));
$results = $connection->_link->executeCommand('admin', $command);
foreach ($results as $dbs) {
foreach ($dbs->databases as $db) {
$return[] = $db->name;
}
}
return $return;
}
return $return;
function count_tables($databases) {
$return = array();
return $return;
}
function tables_list() {
global $connection;
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listCollections' => 1));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$collections = array();
foreach ($results as $result) {
$collections[$result->name] = 'table';
}
return $collections;
}
function drop_databases($databases) {
return false;
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
$class = 'MongoDB\Driver\Command';
$command = new $class(array('listIndexes' => $table));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
foreach ($results as $index) {
$descs = array();
$columns = array();
foreach (get_object_vars($index->key) as $column => $type) {
$descs[] = ($type == -1 ? '1' : null);
$columns[] = $column;
}
$return[$index->name] = array(
"type" => ($index->name == "_id_" ? "PRIMARY" : (isset($index->unique) ? "UNIQUE" : "INDEX")),
"columns" => $columns,
"lengths" => array(),
"descs" => $descs,
);
}
return $return;
}
function fields($table) {
$fields = fields_from_edit();
if (!count($fields)) {
global $driver;
$result = $driver->select($table, array("*"), null, null, array(), 10);
while ($row = $result->fetch_assoc()) {
foreach ($row as $key => $val) {
$row[$key] = null;
$fields[$key] = array(
"field" => $key,
"type" => "string",
"null" => ($key != $driver->primary),
"auto_increment" => ($key == $driver->primary),
"privileges" => array(
"insert" => 1,
"select" => 1,
"update" => 1,
),
);
}
}
}
return $fields;
}
function found_rows($table_status, $where) {
global $connection;
$where = where_to_query($where);
$class = 'MongoDB\Driver\Command';
$command = new $class(array('count' => $table_status['Name'], 'query' => $where));
$results = $connection->_link->executeCommand($connection->_db_name, $command);
$toArray = $results->toArray();
return $toArray[0]->n;
}
function sql_query_where_parser($queryWhere) {
$queryWhere = trim(preg_replace('/WHERE[\s]?[(]?\(?/', '', $queryWhere));
$queryWhere = preg_replace('/\)\)\)$/', ')', $queryWhere);
$wheres = explode(' AND ', $queryWhere);
$wheresOr = explode(') OR (', $queryWhere);
$where = array();
foreach ($wheres as $whereStr) {
$where[] = trim($whereStr);
}
if (count($wheresOr) == 1) {
$wheresOr = array();
} elseif (count($wheresOr) > 1) {
$where = array();
}
return where_to_query($where, $wheresOr);
}
function where_to_query($whereAnd = array(), $whereOr = array()) {
global $operators;
$data = array();
foreach (array('and' => $whereAnd, 'or' => $whereOr) as $type => $where) {
if (is_array($where)) {
foreach ($where as $expression) {
list($col, $op, $val) = explode(" ", $expression, 3);
if ($col == "_id") {
$val = str_replace('MongoDB\BSON\ObjectID("', "", $val);
$val = str_replace('")', "", $val);
$class = 'MongoDB\BSON\ObjectID';
$val = new $class($val);
}
if (!in_array($op, $operators)) {
continue;
}
if (preg_match('~^\(f\)(.+)~', $op, $match)) {
$val = (float) $val;
$op = $match[1];
} elseif (preg_match('~^\(date\)(.+)~', $op, $match)) {
$dateTime = new DateTime($val);
$class = 'MongoDB\BSON\UTCDatetime';
$val = new $class($dateTime->getTimestamp() * 1000);
$op = $match[1];
}
switch ($op) {
case '=':
$op = '$eq';
break;
case '!=':
$op = '$ne';
break;
case '>':
$op = '$gt';
break;
case '<':
$op = '$lt';
break;
case '>=':
$op = '$gte';
break;
case '<=':
$op = '$lte';
break;
case 'regex':
$op = '$regex';
break;
default:
continue;
}
if ($type == 'and') {
$data['$and'][] = array($col => array($op => $val));
} elseif ($type == 'or') {
$data['$or'][] = array($col => array($op => $val));
}
}
}
}
return $data;
}
$operators = array(
"=",
"!=",
">",
"<",
">=",
"<=",
"regex",
"(f)=",
"(f)!=",
"(f)>",
"(f)<",
"(f)>=",
"(f)<=",
"(date)=",
"(date)!=",
"(date)>",
"(date)<",
"(date)>=",
"(date)<=",
);
}
function tables_list() {
global $connection;
return array_fill_keys($connection->_db->getCollectionNames(true), 'table');
function table($idf) {
return $idf;
}
function idf_escape($idf) {
return $idf;
}
function table_status($name = "", $fast = false) {
@@ -213,43 +618,73 @@ if (isset($_GET["mongo"])) {
return $return;
}
function information_schema() {
}
function is_view($table_status) {
}
function drop_databases($databases) {
function last_id() {
global $connection;
foreach ($databases as $db) {
$response = $connection->_link->selectDB($db)->drop();
if (!$response['ok']) {
return $connection->last_id;
}
function error() {
global $connection;
return h($connection->error);
}
function collations() {
return array();
}
function logged_user() {
global $adminer;
$credentials = $adminer->credentials();
return $credentials[1];
}
function connect() {
global $adminer;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
return $connection;
}
return $connection->error;
}
function alter_indexes($table, $alter) {
global $connection;
foreach ($alter as $val) {
list($type, $name, $set) = $val;
if ($set == "DROP") {
$return = $connection->_db->command(array("deleteIndexes" => $table, "index" => $name));
} else {
$columns = array();
foreach ($set as $column) {
$column = preg_replace('~ DESC$~', '', $column, 1, $count);
$columns[$column] = ($count ? -1 : 1);
}
$return = $connection->_db->selectCollection($table)->ensureIndex($columns, array(
"unique" => ($type == "UNIQUE"),
"name" => $name,
//! "sparse"
));
}
if ($return['errmsg']) {
$connection->error = $return['errmsg'];
return false;
}
}
return true;
}
function indexes($table, $connection2 = null) {
global $connection;
$return = array();
foreach ($connection->_db->selectCollection($table)->getIndexInfo() as $index) {
$descs = array();
foreach ($index["key"] as $column => $type) {
$descs[] = ($type == -1 ? '1' : null);
}
$return[$index["name"]] = array(
"type" => ($index["name"] == "_id_" ? "PRIMARY" : ($index["unique"] ? "UNIQUE" : "INDEX")),
"columns" => array_keys($index["key"]),
"lengths" => array(),
"descs" => $descs,
);
}
return $return;
function support($feature) {
return preg_match("~database|indexes~", $feature);
}
function fields($table) {
return fields_from_edit();
function db_collation($db, $collations) {
}
function information_schema() {
}
function is_view($table_status) {
}
function convert_field($field) {
@@ -270,12 +705,6 @@ if (isset($_GET["mongo"])) {
return array();
}
function found_rows($table_status, $where) {
global $connection;
//! don't call count_rows()
return $connection->_db->selectCollection($_GET["select"])->count($where);
}
function alter_table($table, $name, $fields, $foreign, $comment, $engine, $collation, $auto_increment, $partitioning) {
global $connection;
if ($table == "") {
@@ -306,51 +735,7 @@ if (isset($_GET["mongo"])) {
return true;
}
function alter_indexes($table, $alter) {
global $connection;
foreach ($alter as $val) {
list($type, $name, $set) = $val;
if ($set == "DROP") {
$return = $connection->_db->command(array("deleteIndexes" => $table, "index" => $name));
} else {
$columns = array();
foreach ($set as $column) {
$column = preg_replace('~ DESC$~', '', $column, 1, $count);
$columns[$column] = ($count ? -1 : 1);
}
$return = $connection->_db->selectCollection($table)->ensureIndex($columns, array(
"unique" => ($type == "UNIQUE"),
"name" => $name,
//! "sparse"
));
}
if ($return['errmsg']) {
$connection->error = $return['errmsg'];
return false;
}
}
return true;
}
function last_id() {
global $connection;
return $connection->last_id;
}
function table($idf) {
return $idf;
}
function idf_escape($idf) {
return $idf;
}
function support($feature) {
return preg_match("~database|indexes~", $feature);
}
$jush = "mongo";
$operators = array("=");
$functions = array();
$grouping = array();
$edit_functions = array(array("json"));

View File

@@ -308,13 +308,13 @@ if (isset($_GET["mssql"])) {
return ($limit !== null ? " TOP (" . ($limit + $offset) . ")" : "") . " $query$where"; // seek later
}
function limit1($query, $where) {
return limit($query, $where, 1);
function limit1($table, $query, $where, $separator = "\n") {
return limit($query, $where, 1, 0, $separator);
}
function db_collation($db, $collations) {
global $connection;
return $connection->result("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
return $connection->result("SELECT collation_name FROM sys.databases WHERE name = " . q($db));
}
function engines() {
@@ -361,7 +361,7 @@ if (isset($_GET["mssql"])) {
function fields($table) {
$return = array();
foreach (get_rows("SELECT c.*, t.name type, d.definition [default]
foreach (get_rows("SELECT c.max_length, c.precision, c.scale, c.name, c.is_nullable, c.is_identity, c.collation_name, t.name type, CAST(d.definition as text) [default]
FROM sys.all_columns c
JOIN sys.all_objects o ON c.object_id = o.object_id
JOIN sys.types t ON c.user_type_id = t.user_type_id

View File

@@ -276,6 +276,15 @@ if (!defined("DRIVER")) {
}
return queries($prefix . implode(",\n", $values) . $suffix);
}
function warnings() {
$result = $this->_conn->query("SHOW WARNINGS");
if ($result && $result->num_rows) {
ob_start();
select($result); // select() usually needs to print a big table progressively
return ob_get_clean();
}
}
}
@@ -307,7 +316,7 @@ if (!defined("DRIVER")) {
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
$connection->set_charset(charset($connection)); // available in MySQLi since PHP 5.0.5
$connection->query("SET sql_quote_show_create = 1, autocommit = 1");
if (version_compare($connection->server_info, '5.7.8') >= 0) {
if (min_version('5.7.8', 10.2, $connection)) {
$structured_types[lang('Strings')][] = "json";
$types["json"] = 4294967295;
}
@@ -325,11 +334,10 @@ if (!defined("DRIVER")) {
* @return array
*/
function get_databases($flush) {
global $connection;
// SHOW DATABASES can take a very long time so it is cached
$return = get_session("dbs");
if ($return === null) {
$query = ($connection->server_info >= 5
$query = (min_version(5)
? "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA"
: "SHOW DATABASES"
); // SHOW DATABASES can be disabled by skip_show_database
@@ -354,12 +362,14 @@ if (!defined("DRIVER")) {
}
/** Formulate SQL modification query with limit 1
* @param string
* @param string everything after UPDATE or DELETE
* @param string
* @param string
* @return string
*/
function limit1($query, $where) {
return limit($query, $where, 1);
function limit1($table, $query, $where, $separator = "\n") {
return limit($query, $where, 1, 0, $separator);
}
/** Get database collation
@@ -405,8 +415,7 @@ if (!defined("DRIVER")) {
* @return array array($name => $type)
*/
function tables_list() {
global $connection;
return get_key_vals($connection->server_info >= 5
return get_key_vals(min_version(5)
? "SELECT TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME"
: "SHOW TABLES"
);
@@ -430,9 +439,8 @@ 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) {
global $connection;
$return = array();
foreach (get_rows($fast && $connection->server_info >= 5
foreach (get_rows($fast && min_version(5)
? "SELECT TABLE_NAME AS Name, ENGINE AS Engine, 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) {
@@ -464,9 +472,8 @@ if (!defined("DRIVER")) {
* @return bool
*/
function fk_support($table_status) {
global $connection;
return preg_match('~InnoDB|IBMDB2I~i', $table_status["Engine"])
|| (preg_match('~NDB~i', $table_status["Engine"]) && version_compare($connection->server_info, '5.6') >= 0);
|| (preg_match('~NDB~i', $table_status["Engine"]) && min_version(5.6));
}
/** Get information about fields
@@ -573,9 +580,8 @@ if (!defined("DRIVER")) {
* @return bool
*/
function information_schema($db) {
global $connection;
return ($connection->server_info >= 5 && $db == "information_schema")
|| ($connection->server_info >= 5.5 && $db == "performance_schema");
return (min_version(5) && $db == "information_schema")
|| (min_version(5.5) && $db == "performance_schema");
}
/** Get escaped error message
@@ -813,8 +819,9 @@ if (!defined("DRIVER")) {
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");
$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 = "\\s*(" . ($type == "FUNCTION" ? "" : $inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$pattern = "$space*(" . ($type == "FUNCTION" ? "" : $inout) . ")?\\s*(?:`((?:[^`]|``)*)`\\s*|\\b(\\S+)\\s+)$type_pattern";
$create = $connection->result("SHOW CREATE $type " . idf_escape($name), 2);
preg_match("~\\(((?:$pattern\\s*,?)*)\\)\\s*" . ($type == "FUNCTION" ? "RETURNS\\s+$type_pattern\\s+" : "") . "(.*)~is", $create, $match);
$fields = array();
@@ -844,10 +851,10 @@ if (!defined("DRIVER")) {
}
/** Get list of routines
* @return array ("ROUTINE_TYPE" => , "ROUTINE_NAME" => , "DTD_IDENTIFIER" => )
* @return array ("SPECIFIC_NAME" => , "ROUTINE_NAME" => , "ROUTINE_TYPE" => , "DTD_IDENTIFIER" => )
*/
function routines() {
return get_rows("SELECT 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 FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = " . q(DB));
}
/** Get list of available routine languages
@@ -857,6 +864,15 @@ if (!defined("DRIVER")) {
return array(); // "SQL" not required
}
/** Get routine signature
* @param string
* @param array result of routine()
* @return string
*/
function routine_id($name, $row) {
return idf_escape($name);
}
/** Get last auto increment ID
* @return string
*/
@@ -871,7 +887,7 @@ if (!defined("DRIVER")) {
* @return Min_Result
*/
function explain($connection, $query) {
return $connection->query("EXPLAIN " . ($connection->server_info >= 5.1 ? "PARTITIONS " : "") . $query);
return $connection->query("EXPLAIN " . (min_version(5.1) ? "PARTITIONS " : "") . $query);
}
/** Get approximate number of rows
@@ -915,9 +931,10 @@ if (!defined("DRIVER")) {
/** Get SQL command to create table
* @param string
* @param bool
* @param string
* @return string
*/
function create_sql($table, $auto_increment) {
function create_sql($table, $auto_increment, $style) {
global $connection;
$return = $connection->result("SHOW CREATE TABLE " . table($table), 1);
if (!$auto_increment) {
@@ -944,14 +961,12 @@ if (!defined("DRIVER")) {
/** Get SQL commands to create triggers
* @param string
* @param string
* @return string
*/
function trigger_sql($table, $style) {
function trigger_sql($table) {
$return = "";
foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_\\")), null, "-- ") as $row) {
$return .= "\n" . ($style == 'CREATE+ALTER' ? "DROP TRIGGER IF EXISTS " . idf_escape($row["Trigger"]) . ";;\n" : "")
. "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
$return .= "\nCREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
}
return $return;
}
@@ -977,14 +992,6 @@ if (!defined("DRIVER")) {
return get_key_vals("SHOW STATUS");
}
/** Get replication status of master or slave
* @param string
* @return array ($name => $value)
*/
function replication_status($type) {
return get_rows("SHOW $type STATUS");
}
/** Convert field in select and edit
* @param array one element from fields()
* @return string
@@ -997,7 +1004,7 @@ if (!defined("DRIVER")) {
return "BIN(" . idf_escape($field["field"]) . " + 0)"; // + 0 is required outside MySQLnd
}
if (preg_match("~geometry|point|linestring|polygon~", $field["type"])) {
return "AsWKT(" . idf_escape($field["field"]) . ")";
return (min_version(8) ? "ST_" : "") . "AsWKT(" . idf_escape($field["field"]) . ")";
}
}
@@ -1024,8 +1031,7 @@ if (!defined("DRIVER")) {
* @return bool
*/
function support($feature) {
global $connection;
return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . ($connection->server_info < 5.1 ? "|event|partitioning" . ($connection->server_info < 5 ? "|routine|trigger|view" : "") : "") . "~", $feature);
return !preg_match("~scheme|sequence|type|view_trigger|materializedview" . (min_version(5.1) ? "" : "|event|partitioning" . (min_version(5) ? "" : "|routine|trigger|view")) . "~", $feature);
}
function kill_process($val) {
@@ -1056,8 +1062,8 @@ if (!defined("DRIVER")) {
$structured_types[$key] = array_keys($val);
}
$unsigned = array("unsigned", "zerofill", "unsigned zerofill"); ///< @var array number variants
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"); ///< @var array operators used in select
$functions = array("char_length", "date", "from_unixtime", "lower", "round", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$operators = array("=", "<", ">", "<=", ">=", "!=", "LIKE", "LIKE %%", "REGEXP", "IN", "FIND_IN_SET", "IS NULL", "NOT LIKE", "NOT REGEXP", "NOT IN", "IS NOT NULL", "SQL"); ///< @var array operators used in select
$functions = array("char_length", "date", "from_unixtime", "lower", "round", "floor", "ceil", "sec_to_time", "time_to_sec", "upper"); ///< @var array functions used in select
$grouping = array("avg", "count", "count distinct", "group_concat", "max", "min", "sum"); ///< @var array grouping functions used in select
$edit_functions = array( ///< @var array of array("$type|$type2" => "$function/$function2") functions used in editing, [0] - edit and insert, [1] - edit only
array(

View File

@@ -175,8 +175,8 @@ if (isset($_GET["oracle"])) {
));
}
function limit1($query, $where) {
return " $query$where";
function limit1($table, $query, $where, $separator = "\n") {
return " $query$where"; //! limit
}
function db_collation($db, $collations) {

View File

@@ -89,6 +89,10 @@ if (isset($_GET["pgsql"])) {
}
return pg_fetch_result($result->_result, 0, $field);
}
function warnings() {
return h(pg_last_notice($this->_link)); // second parameter is available since PHP 7.1.0
}
}
class Min_Result {
@@ -143,6 +147,10 @@ if (isset($_GET["pgsql"])) {
return ($adminer->database() == $database);
}
function warnings() {
return ''; // not implemented in PDO_PgSQL as of PHP 7.2.1
}
function close() {
}
}
@@ -173,6 +181,10 @@ if (isset($_GET["pgsql"])) {
return true;
}
function warnings() {
return $this->_conn->warnings();
}
}
@@ -186,12 +198,20 @@ if (isset($_GET["pgsql"])) {
}
function connect() {
global $adminer;
global $adminer, $types, $structured_types;
$connection = new Min_DB;
$credentials = $adminer->credentials();
if ($connection->connect($credentials[0], $credentials[1], $credentials[2])) {
if ($connection->server_info >= 9) {
if (min_version(9, 0, $connection)) {
$connection->query("SET application_name = 'Adminer'");
if (min_version(9.2, 0, $connection)) {
$structured_types[lang('Strings')][] = "json";
$types["json"] = 4294967295;
if (min_version(9.4, 0, $connection)) {
$structured_types[lang('Strings')][] = "jsonb";
$types["jsonb"] = 4294967295;
}
}
}
return $connection;
}
@@ -206,8 +226,11 @@ if (isset($_GET["pgsql"])) {
return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
}
function limit1($query, $where) {
return " $query$where";
function limit1($table, $query, $where, $separator = "\n") {
return (preg_match('~^INTO~', $query)
? limit($query, $where, 1, 0, $separator)
: " $query WHERE ctid = (SELECT ctid FROM " . table($table) . $where . $separator . "LIMIT 1)"
);
}
function db_collation($db, $collations) {
@@ -244,10 +267,10 @@ ORDER BY 1";
function table_status($name = "") {
$return = array();
foreach (get_rows("SELECT c.relname AS \"Name\", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\", pg_relation_size(c.oid) AS \"Data_length\", pg_indexes_size(c.oid) AS \"Index_length\", obj_description(c.oid, 'pg_class') AS \"Comment\", c.relhasoids::int AS \"Oid\", c.reltuples as \"Rows\", n.nspname
foreach (get_rows("SELECT c.relname AS \"Name\", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'm' THEN 'materialized view' ELSE 'view' END AS \"Engine\", pg_relation_size(c.oid) AS \"Data_length\", pg_total_relation_size(c.oid) - pg_relation_size(c.oid) AS \"Index_length\", obj_description(c.oid, 'pg_class') AS \"Comment\", CASE WHEN c.relhasoids THEN 'oid' ELSE '' END AS \"Oid\", c.reltuples as \"Rows\", n.nspname
FROM pg_class c
JOIN pg_namespace n ON(n.nspname = current_schema() AND n.oid = c.relnamespace)
WHERE relkind IN ('r', 'm', 'v')
WHERE relkind IN ('r', 'm', 'v', 'f')
" . ($name != "" ? "AND relname = " . q($name) : "ORDER BY relname")
) as $row) { //! Index_length, Auto_increment
$return[$row["Name"]] = $row;
@@ -296,7 +319,7 @@ ORDER BY a.attnum"
$row["auto_increment"] = preg_match('~^nextval\\(~i', $row["default"]);
$row["privileges"] = array("insert" => 1, "select" => 1, "update" => 1);
if (preg_match('~(.+)::[^)]+(.*)~', $row["default"], $match)) {
$row["default"] = ($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2];
$row["default"] = ($match[1] == "NULL" ? null : (($match[1][0] == "'" ? idf_unescape($match[1]) : $match[1]) . $match[2]));
}
$return[$row["field"]] = $row;
}
@@ -352,7 +375,9 @@ ORDER BY conkey, conname") as $row) {
function view($name) {
global $connection;
return array("select" => trim($connection->result("SELECT pg_get_viewdef(" . q($name) . ")")));
return array("select" => trim($connection->result("SELECT view_definition
FROM information_schema.views
WHERE table_schema = current_schema() AND table_name = " . q($name))));
}
function collations() {
@@ -533,30 +558,36 @@ ORDER BY conkey, conname") as $row) {
);
}
/*
function routine($name, $type) {
//! there can be more functions with the same name differing only in parameters, it must be also passed to DROP FUNCTION
//! no procedures, only functions
//! different syntax of CREATE FUNCTION
$rows = get_rows('SELECT pg_catalog.format_type(p.prorettype, NULL) AS "returns", p.prosrc AS "definition"
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid
WHERE n.nspname = current_schema() AND p.proname = ' . q($name));
$rows[0]["fields"] = array(); //!
return $rows[0];
$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;
}
*/
function routines() {
return get_rows('SELECT p.proname AS "ROUTINE_NAME", p.proargtypes AS "ROUTINE_TYPE", pg_catalog.format_type(p.prorettype, NULL) AS "DTD_IDENTIFIER"
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid
WHERE n.nspname = current_schema()
ORDER BY p.proname');
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');
}
function routine_languages() {
return get_vals("SELECT langname FROM pg_catalog.pg_language");
return get_vals("SELECT LOWER(lanname) FROM pg_catalog.pg_language");
}
function routine_id($name, $row) {
$return = array();
foreach ($row["fields"] as $field) {
$return[] = $field["type"];
}
return idf_escape($name) . "(" . implode(", ", $return) . ")";
}
function last_id() {
@@ -609,12 +640,7 @@ AND typelem = 0"
return $return;
}
/** Get SQL command to create table
* @param string
* @param bool
* @return string
*/
function create_sql($table, $auto_increment) {
function create_sql($table, $auto_increment, $style) {
global $connection;
$return = '';
$return_parts = array();
@@ -626,7 +652,6 @@ AND typelem = 0"
ksort($indexes);
$fkeys = foreign_keys($table);
ksort($fkeys);
$triggers = triggers($table);
if (!$status || empty($fields)) {
return false;
@@ -638,14 +663,15 @@ AND typelem = 0"
foreach ($fields as $field_name => $field) {
$part = idf_escape($field['field']) . ' ' . $field['full_type']
. (is_null($field['default']) ? "" : " DEFAULT $field[default]")
. ($field['attnotnull'] ? "" : " NOT NULL");
. ($field['attnotnull'] ? " NOT NULL" : "");
$return_parts[] = $part;
// sequences for fields
if (preg_match('~nextval\(\'([^\']+)\'\)~', $field['default'], $matches)) {
$sequence_name = $matches[1];
$sq = reset(get_rows("SELECT * FROM $sequence_name"));
$sequences[] = "CREATE SEQUENCE $sequence_name INCREMENT $sq[increment_by] MINVALUE $sq[min_value] MAXVALUE $sq[max_value] START " . ($auto_increment ? $sq['last_value'] : 1) . " CACHE $sq[cache_value];";
$sequences[] = ($style == "DROP+CREATE" ? "DROP SEQUENCE $sequence_name;\n" : "")
. "CREATE SEQUENCE $sequence_name INCREMENT $sq[increment_by] MINVALUE $sq[min_value] MAXVALUE $sq[max_value] START " . ($auto_increment ? $sq['last_value'] : 1) . " CACHE $sq[cache_value];";
}
}
@@ -687,30 +713,17 @@ AND typelem = 0"
}
}
// triggers
foreach ($triggers as $trg_id => $trg) {
$trigger = trigger($trg_id, $status['Name']);
$return .= "\n\nCREATE TRIGGER " . idf_escape($trigger['Trigger']) . " $trigger[Timing] $trigger[Events] ON " . idf_escape($status["nspname"]) . "." . idf_escape($status['Name']) . " $trigger[Type] $trigger[Statement];";
}
return rtrim($return, ';');
}
/** Get SQL commands to create triggers
* @param string
* @param string
* @return string
*/
//@TODO
function trigger_sql($table, $style) {
function trigger_sql($table) {
$status = table_status($table);
$return = "";
//foreach (get_rows("SHOW TRIGGERS LIKE " . q(addcslashes($table, "%_\\")), null, "-- ") as $row) {
// $return .= "\n" . ($style == 'CREATE+ALTER' ? "DROP TRIGGER IF EXISTS " . idf_escape($row["Trigger"]) . ";;\n" : "")
// . "CREATE TRIGGER " . idf_escape($row["Trigger"]) . " $row[Timing] $row[Event] ON " . table($row["Table"]) . " FOR EACH ROW\n$row[Statement];;\n";
//}
//return $return;
return false;
foreach (triggers($table) as $trg_id => $trg) {
$trigger = trigger($trg_id, $status['Name']);
$return .= "\nCREATE TRIGGER " . idf_escape($trigger['Trigger']) . " $trigger[Timing] $trigger[Events] ON " . idf_escape($status["nspname"]) . "." . idf_escape($status['Name']) . " $trigger[Type] $trigger[Statement];;\n";
}
return $return;
}
@@ -723,8 +736,7 @@ AND typelem = 0"
}
function process_list() {
global $connection;
return get_rows("SELECT * FROM pg_stat_activity ORDER BY " . ($connection->server_info < 9.2 ? "procpid" : "pid"));
return get_rows("SELECT * FROM pg_stat_activity ORDER BY " . (min_version(9.2) ? "pid" : "procpid"));
}
function show_status() {
@@ -738,8 +750,7 @@ AND typelem = 0"
}
function support($feature) {
global $connection;
return preg_match('~^(database|table|columns|sql|indexes|comment|view|' . ($connection->server_info >= 9.3 ? 'materializedview|' : '') . 'scheme|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature); //! routine|
return preg_match('~^(database|table|columns|sql|indexes|comment|view|' . (min_version(9.3) ? 'materializedview|' : '') . 'scheme|routine|processlist|sequence|trigger|type|variables|drop_col|kill|dump)$~', $feature);
}
function kill_process($val) {

View File

@@ -2,10 +2,10 @@
$drivers["simpledb"] = "SimpleDB";
if (isset($_GET["simpledb"])) {
$possible_drivers = array("SimpleXML");
$possible_drivers = array("SimpleXML + allow_url_fopen");
define("DRIVER", "simpledb");
if (class_exists('SimpleXMLElement')) {
if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) {
class Min_DB {
var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_result;

View File

@@ -184,11 +184,13 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function __construct() {
parent::__construct(":memory:");
$this->query("PRAGMA foreign_keys = 1");
}
function select_db($filename) {
if (is_readable($filename) && $this->query("ATTACH " . $this->quote(preg_match("~(^[/\\\\]|:)~", $filename) ? $filename : dirname($_SERVER["SCRIPT_FILENAME"]) . "/$filename") . " AS a")) { // is_readable - SQLite 3
parent::__construct($filename);
$this->query("PRAGMA foreign_keys = 1");
return true;
}
return false;
@@ -240,9 +242,12 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return " $query$where" . ($limit !== null ? $separator . "LIMIT $limit" . ($offset ? " OFFSET $offset" : "") : "");
}
function limit1($query, $where) {
function limit1($table, $query, $where, $separator = "\n") {
global $connection;
return ($connection->result("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')") ? limit($query, $where, 1) : " $query$where");
return (preg_match('~^INTO~', $query) || $connection->result("SELECT sqlite_compileoption_used('ENABLE_UPDATE_DELETE_LIMIT')")
? limit($query, $where, 1, 0, $separator)
: " $query WHERE rowid = (SELECT rowid FROM " . table($table) . $where . $separator . "LIMIT 1)"
);
}
function db_collation($db, $collations) {
@@ -269,9 +274,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function table_status($name = "") {
global $connection;
$return = array();
foreach (get_rows("SELECT name AS Name, type AS Engine FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
$row["Oid"] = 1;
$row["Auto_increment"] = "";
foreach (get_rows("SELECT name AS Name, type AS Engine, 'rowid' AS Oid, '' AS Auto_increment FROM sqlite_master WHERE type IN ('table', 'view') " . ($name != "" ? "AND name = " . q($name) : "ORDER BY name")) as $row) {
$row["Rows"] = $connection->result("SELECT COUNT(*) FROM " . idf_escape($row["Name"]));
$return[$row["Name"]] = $row;
}
@@ -713,7 +716,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
return true;
}
function create_sql($table, $auto_increment) {
function create_sql($table, $auto_increment, $style) {
global $connection;
$return = $connection->result("SELECT sql FROM sqlite_master WHERE type IN ('table', 'view') AND name = " . q($table));
foreach (indexes($table) as $name => $index) {
@@ -732,7 +735,7 @@ if (isset($_GET["sqlite"]) || isset($_GET["sqlite2"])) {
function use_sql($database) {
}
function trigger_sql($table, $style) {
function trigger_sql($table) {
return implode(get_vals("SELECT sql || ';;\n' FROM sqlite_master WHERE type = 'trigger' AND tbl_name = " . q($table)));
}

View File

@@ -92,7 +92,7 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
$fields = fields($name);
$adminer->dumpData($name, $_POST["data_style"], "SELECT *" . convert_fields($fields, $fields) . " FROM " . table($name));
}
if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name, $_POST["table_style"]))) {
if ($is_sql && $_POST["triggers"] && $table && ($triggers = trigger_sql($name))) {
echo "\nDELIMITER ;;\n$triggers\nDELIMITER ;\n";
}
@@ -169,8 +169,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 onclick='formCheck(this, /^tables\\[/);'>" . lang('Tables') . "</label>";
echo "<th style='text-align: right;'><label class='block'>" . lang('Data') . "<input type='checkbox' id='check-data'$checked onclick='formCheck(this, /^data\\[/);'></label>";
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 "</thead>\n";
$views = "";
@@ -178,22 +178,25 @@ if (DB != "") {
foreach ($tables_list as $name => $type) {
$prefix = preg_replace('~_.*~', '', $name);
$checked = ($TABLE == "" || $TABLE == (substr($TABLE, -1) == "%" ? "$prefix%" : $name)); //! % may be part of table name
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "checkboxClick(event, this); formUncheck('check-tables');", "block");
$print = "<tr><td>" . checkbox("tables[]", $name, $checked, $name, "checkboxClick.call(this, event); formUncheck('check-tables');", "block");
if ($type !== null && !preg_match('~table~i', $type)) {
$views .= "$print\n";
} else {
echo "$print<td align='right'><label class='block'><span id='Rows-" . h($name) . "'></span>" . checkbox("data[]", $name, $checked, "", "checkboxClick(event, this); formUncheck('check-data');") . "</label>\n";
echo "$print<td align='right'><label class='block'><span id='Rows-" . h($name) . "'></span>" . checkbox("data[]", $name, $checked, "", "checkboxClick.call(this, event); formUncheck('check-data');") . "</label>\n";
}
$prefixes[$prefix]++;
}
echo $views;
if ($tables_list) {
echo "<script type='text/javascript'>ajaxSetHtml('" . js_escape(ME) . "script=db');</script>\n";
echo script("ajaxSetHtml('" . js_escape(ME) . "script=db');");
}
} else {
echo "<thead><tr><th style='text-align: left;'><label class='block'><input type='checkbox' id='check-databases'" . ($TABLE == "" ? " checked" : "") . " onclick='formCheck(this, /^databases\\[/);'>" . lang('Database') . "</label></thead>\n";
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 "</thead>\n";
$databases = $adminer->databases();
if ($databases) {
foreach ($databases as $db) {

View File

@@ -1,7 +1,7 @@
<?php
$TABLE = $_GET["edit"];
$fields = fields($TABLE);
$where = (isset($_GET["select"]) ? (count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "") : where($_GET, $fields));
$where = (isset($_GET["select"]) ? ($_POST["check"] && count($_POST["check"]) == 1 ? where_check($_POST["check"][0], $fields) : "") : where($_GET, $fields));
$update = (isset($_GET["select"]) ? $_POST["edit"] : $where);
foreach ($fields as $name => $field) {
if (!isset($field["privileges"][$update ? "update" : "insert"]) || $adminer->fieldName($field) == "") {
@@ -82,9 +82,13 @@ if ($_POST["save"]) {
}
if ($select) {
$result = $driver->select($TABLE, $select, array($where), $select, array(), (isset($_GET["select"]) ? 2 : 1));
$row = $result->fetch_assoc();
if (!$row) { // MySQLi returns null
$row = false;
if (!$result) {
$error = error();
} else {
$row = $result->fetch_assoc();
if (!$row) { // MySQLi returns null
$row = false;
}
}
if (isset($_GET["select"]) && (!$row || $result->fetch_assoc())) { // $result->num_rows != 1 isn't available in all drivers
$row = null;

View File

@@ -47,6 +47,6 @@ if (!$row && $EVENT != "") {
<p><?php textarea("EVENT_DEFINITION", $row["EVENT_DEFINITION"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($EVENT != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($EVENT != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $EVENT)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -67,7 +67,7 @@ $referencable = array_keys(array_filter(table_status('', true), 'fk_support'));
$j = 0;
foreach ($row["source"] as $key => $val) {
echo "<tr>";
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow(this);" : 1), "label-source");
echo "<td>" . html_select("source[" . (+$key) . "]", array(-1 => "") + $source, $val, ($j == count($row["source"]) - 1 ? "foreignAddRow.call(this);" : 1), "label-source");
echo "<td>" . html_select("target[" . (+$key) . "]", $target, $row["target"][$key], 1, "label-target");
$j++;
}
@@ -86,6 +86,6 @@ foreach ($row["source"] as $key => $val) {
<input type="submit" value="<?php echo lang('Save'); ?>">
<noscript><p><input type="submit" name="add" value="<?php echo lang('Add column'); ?>"></noscript>
<?php } ?>
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -9,7 +9,7 @@ class Adminer {
* @return string HTML code
*/
function name() {
return "<a href='https://www.adminer.org/' target='_blank' id='h1'>Adminer</a>";
return "<a href='https://www.adminer.org/'" . target_blank() . " id='h1'>Adminer</a>";
}
/** Connection parameters
@@ -65,14 +65,20 @@ class Adminer {
}
/** Headers to send before HTML output
* @return bool true to send security headers
* @return null
*/
function headers() {
return true;
}
/** Get Content Security Policy headers
* @return array of arrays with directive name in key, allowed sources in value
*/
function csp() {
return csp();
}
/** Print HTML code inside <head>
* @return bool true to link adminer.css if exists
* @return bool true to link favicon.ico and adminer.css if exists
*/
function head() {
?>
@@ -81,6 +87,18 @@ class Adminer {
return true;
}
/** Get URLs of the CSS files
* @return array of strings
*/
function css() {
$return = array();
$filename = "adminer.css";
if (file_exists($filename)) {
$return[] = $filename;
}
return $return;
}
/** Print login form
* @return null
*/
@@ -88,16 +106,14 @@ class Adminer {
global $drivers;
?>
<table cellspacing="0">
<tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER); ?>
<tr><th><?php echo lang('System'); ?><td><?php echo html_select("auth[driver]", $drivers, DRIVER) . "\n"; ?>
<tr><th><?php echo lang('Server'); ?><td><input name="auth[server]" value="<?php echo h(SERVER); ?>" title="hostname[:port]" placeholder="localhost" autocapitalize="off">
<tr><th><?php echo lang('Username'); ?><td><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
<tr><th><?php echo lang('Database'); ?><td><input name="auth[db]" value="<?php echo h($_GET["db"]); ?>" autocapitalize="off">
</table>
<script type="text/javascript">
focus(document.getElementById('username'));
</script>
<?php
echo script("focus(qs('#username'));");
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
}
@@ -110,7 +126,7 @@ focus(document.getElementById('username'));
function login($login, $password) {
global $jush;
if ($jush == "sqlite") {
return lang('<a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to use SQLite.', '<code>login()</code>');
return lang('<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.', target_blank(), '<code>login()</code>');
}
return true;
}
@@ -186,14 +202,22 @@ focus(document.getElementById('username'));
/** Query printed in select before execution
* @param string query to be executed
* @param string elapsed time
* @param float start time of the query
* @param bool
* @return string
*/
function selectQuery($query, $time) {
global $jush;
return "<p><code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> <span class='time'>($time)</span>"
function selectQuery($query, $start, $failed = false) {
global $jush, $driver;
$return = "</p>\n"; // required for IE9 inline edit
if (!$failed && ($warnings = $driver->warnings())) {
$id = "warnings";
$return = ", <a href='#$id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "")
. "$return<div id='$id' class='hidden'>\n$warnings</div>\n"
;
}
return "<p><code class='jush-$jush'>" . h(str_replace("\n", " ", $query)) . "</code> <span class='time'>(" . format_time($start) . ")</span>"
. (support("sql") ? " <a href='" . h(ME) . "sql=" . urlencode($query) . "'>" . lang('Edit') . "</a>" : "")
. "</p>" // </p> - required for IE9 inline edit
. $return
;
}
@@ -239,14 +263,14 @@ focus(document.getElementById('username'));
* @return string
*/
function selectVal($val, $link, $field, $original) {
$return = ($val === null ? "<i>NULL</i>" : (preg_match("~char|binary~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>" : $val));
$return = ($val === null ? "<i>NULL</i>" : (preg_match("~char|binary|boolean~", $field["type"]) && !preg_match("~var~", $field["type"]) ? "<code>$val</code>" : $val));
if (preg_match('~blob|bytea|raw|file~', $field["type"]) && !is_utf8($val)) {
$return = "<i>" . lang('%d byte(s)', strlen($original)) . "</i>";
}
if (preg_match('~json~', $field["type"])) {
$return = "<code class='jush-js'>$return</code>";
}
return ($link ? "<a href='" . h($link) . "'" . (is_url($link) ? " rel='noreferrer'" : "") . ">$return</a>" : $return);
return ($link ? "<a href='" . h($link) . "'" . (is_url($link) ? target_blank() : "") . ">$return</a>" : $return);
}
/** Value conversion used in select and edit
@@ -263,7 +287,7 @@ focus(document.getElementById('username'));
* @return null
*/
function tableStructurePrint($fields) {
echo "<table cellspacing='0'>\n";
echo "<table cellspacing='0' class='nowrap'>\n";
echo "<thead><tr><th>" . lang('Column') . "<td>" . lang('Type') . (support("comment") ? "<td>" . lang('Comment') : "") . "</thead>\n";
foreach ($fields as $field) {
echo "<tr" . odd() . "><th>" . h($field["field"]);
@@ -309,9 +333,16 @@ focus(document.getElementById('username'));
$select[""] = array();
foreach ($select as $key => $val) {
$val = $_GET["columns"][$key];
$column = select_input(" name='columns[$i][col]' onchange='" . ($key !== "" ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";'", $columns, $val["col"]);
echo "<div>" . ($functions || $grouping ? "<select name='columns[$i][fun]' onchange='helpClose();" . ($key !== "" ? "" : " this.nextSibling.nextSibling.onchange();") . "'"
. on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1) . ">" . optionlist(array(-1 => "") + array_filter(array(lang('Functions') => $functions, lang('Aggregation') => $grouping)), $val["fun"]) . "</select>"
$column = select_input(
" name='columns[$i][col]'",
$columns,
$val["col"],
($key !== "" ? "selectFieldChange" : "selectAddRow")
);
echo "<div>" . ($functions || $grouping ? "<select name='columns[$i][fun]'>"
. optionlist(array(-1 => "") + array_filter(array(lang('Functions') => $functions, lang('Aggregation') => $grouping)), $val["fun"]) . "</select>"
. on_help("getTarget(event).value && getTarget(event).value.replace(/ |\$/, '(') + ')'", 1)
. script("qsl('select').onchange = function () { helpClose();" . ($key !== "" ? "" : " qsl('select, input', this.parentNode).onchange();") . " };", "")
. "($column)" : $column) . "</div>\n";
$i++;
}
@@ -328,21 +359,30 @@ focus(document.getElementById('username'));
print_fieldset("search", lang('Search'), $where);
foreach ($indexes as $i => $index) {
if ($index["type"] == "FULLTEXT") {
echo "(<i>" . implode("</i>, <i>", array_map('h', $index["columns"])) . "</i>) AGAINST";
echo " <input type='search' name='fulltext[$i]' value='" . h($_GET["fulltext"][$i]) . "' onchange='selectFieldChange(this.form);'>";
echo "<div>(<i>" . implode("</i>, <i>", array_map('h', $index["columns"])) . "</i>) AGAINST";
echo " <input type='search' name='fulltext[$i]' value='" . h($_GET["fulltext"][$i]) . "'>";
echo script("qsl('input').oninput = selectFieldChange;", "");
echo checkbox("boolean[$i]", 1, isset($_GET["boolean"][$i]), "BOOL");
echo "<br>\n";
echo "</div>\n";
}
}
$_GET["where"] = (array) $_GET["where"];
reset($_GET["where"]);
$change_next = "this.nextSibling.onchange();";
$change_next = "this.parentNode.firstChild.onchange();";
for ($i = 0; $i <= count($_GET["where"]); $i++) {
list(, $val) = each($_GET["where"]);
if (!$val || ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators))) {
echo "<div>" . select_input(" name='where[$i][col]' onchange='$change_next'", $columns, $val["col"], "(" . lang('anywhere') . ")");
echo "<div>" . select_input(
" name='where[$i][col]'",
$columns,
$val["col"],
($val ? "selectFieldChange" : "selectAddRow"),
"(" . lang('anywhere') . ")"
);
echo html_select("where[$i][op]", $this->operators, $val["op"], $change_next);
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onchange='" . ($val ? "selectFieldChange(this.form)" : "selectAddRow(this)") . ";' onkeydown='selectSearchKeydown(this, event);' onsearch='selectSearchSearch(this);'></div>\n";
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "'>";
echo script("mixin(qsl('input'), {oninput: function () { $change_next }, onkeydown: selectSearchKeydown, onsearch: selectSearchSearch});", "");
echo "</div>\n";
}
}
echo "</div></fieldset>\n";
@@ -359,12 +399,12 @@ focus(document.getElementById('username'));
$i = 0;
foreach ((array) $_GET["order"] as $key => $val) {
if ($val != "") {
echo "<div>" . select_input(" name='order[$i]' onchange='selectFieldChange(this.form);'", $columns, $val);
echo "<div>" . select_input(" name='order[$i]'", $columns, $val, "selectFieldChange");
echo checkbox("desc[$i]", 1, isset($_GET["desc"][$key]), lang('descending')) . "</div>\n";
$i++;
}
}
echo "<div>" . select_input(" name='order[$i]' onchange='selectAddRow(this);'", $columns);
echo "<div>" . select_input(" name='order[$i]'", $columns, "", "selectAddRow");
echo checkbox("desc[$i]", 1, false, lang('descending')) . "</div>\n";
echo "</div></fieldset>\n";
}
@@ -375,7 +415,8 @@ focus(document.getElementById('username'));
*/
function selectLimitPrint($limit) {
echo "<fieldset><legend>" . lang('Limit') . "</legend><div>"; // <div> for easy styling
echo "<input type='number' name='limit' class='size' value='" . h($limit) . "' onchange='selectFieldChange(this.form);'>";
echo "<input type='number' name='limit' class='size' value='" . h($limit) . "'>";
echo script("qsl('input').oninput = selectFieldChange;", "");
echo "</div></fieldset>\n";
}
@@ -399,7 +440,7 @@ focus(document.getElementById('username'));
echo "<fieldset><legend>" . lang('Action') . "</legend><div>";
echo "<input type='submit' value='" . lang('Select') . "'>";
echo " <span id='noindex' title='" . lang('Full table scan') . "'></span>";
echo "<script type='text/javascript'>\n";
echo "<script" . nonce() . ">\n";
echo "var indexColumns = ";
$columns = array();
foreach ($indexes as $index) {
@@ -413,7 +454,7 @@ focus(document.getElementById('username'));
json_row($key);
}
echo ";\n";
echo "selectFieldChange(document.getElementById('form'));\n";
echo "selectFieldChange.call(qs('#form')['select']);\n";
echo "</script>\n";
echo "</div></fieldset>\n";
}
@@ -474,7 +515,11 @@ focus(document.getElementById('username'));
}
}
foreach ((array) $_GET["where"] as $val) {
if ($val["op"] == "") {
$val["op"] = "LIKE %%";
}
if ("$val[col]$val[val]" != "" && in_array($val["op"], $this->operators)) {
$prefix = "";
$cond = " $val[op]";
if (preg_match('~IN$~', $val["op"])) {
$in = process_length($val["val"]);
@@ -485,11 +530,14 @@ focus(document.getElementById('username'));
$cond = " LIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%");
} elseif ($val["op"] == "ILIKE %%") {
$cond = " ILIKE " . $this->processInput($fields[$val["col"]], "%$val[val]%");
} elseif ($val["op"] == "FIND_IN_SET") {
$prefix = "$val[op](" . q($val["val"]) . ", ";
$cond = ")";
} elseif (!preg_match('~NULL$~', $val["op"])) {
$cond .= " " . $this->processInput($fields[$val["col"]], $val["val"]);
}
if ($val["col"] != "") {
$return[] = idf_escape($val["col"]) . $cond;
$return[] = $prefix . idf_escape($val["col"]) . $cond;
} else {
// find anywhere
$cols = array();
@@ -499,10 +547,10 @@ focus(document.getElementById('username'));
&& (!preg_match("~[\x80-\xFF]~", $val["val"]) || $is_text)
) {
$name = idf_escape($name);
$cols[] = ($jush == "sql" && $is_text && !preg_match("~^utf8_~", $field["collation"]) ? "CONVERT($name USING " . charset($connection) . ")" : $name);
$cols[] = $prefix . ($jush == "sql" && $is_text && !preg_match("~^utf8~", $field["collation"]) ? "CONVERT($name USING " . charset($connection) . ")" : $name) . $cond;
}
}
$return[] = ($cols ? "(" . implode("$cond OR ", $cols) . "$cond)" : "0");
$return[] = ($cols ? "(" . implode(" OR ", $cols) . ")" : "0");
}
}
}
@@ -565,19 +613,28 @@ focus(document.getElementById('username'));
/** Query printed after execution in the message
* @param string executed query
* @param string elapsed time
* @param bool
* @return string
*/
function messageQuery($query, $time) {
global $jush;
function messageQuery($query, $time, $failed = false) {
global $jush, $driver;
restart_session();
$history = &get_session("queries");
$id = "sql-" . count($history[$_GET["db"]]);
if (!$history[$_GET["db"]]) {
$history[$_GET["db"]] = array();
}
if (strlen($query) > 1e6) {
$query = preg_replace('~[\x80-\xFF]+$~', '', substr($query, 0, 1e6)) . "\n..."; // [\x80-\xFF] - valid UTF-8, \n - can end by one-line comment
}
$history[$_GET["db"]][] = array($query, time(), $time); // not DB - $_GET["db"] is changed in database.inc.php //! respect $_GET["ns"]
return " <span class='time'>" . @date("H:i:s") . "</span> <a href='#$id' onclick=\"return !toggle('$id');\">" . lang('SQL command') . "</a>" // @ - time zone may be not set
. "<div id='$id' class='hidden'><pre><code class='jush-$jush'>" . shorten_utf8($query, 1000) . '</code></pre>'
$sql_id = "sql-" . count($history[$_GET["db"]]);
$return = "<a href='#$sql_id' class='toggle'>" . lang('SQL command') . "</a>\n";
if (!$failed && ($warnings = $driver->warnings())) {
$id = "warnings-" . count($history[$_GET["db"]]);
$return = "<a href='#$id' class='toggle'>" . lang('Warnings') . "</a>, $return<div id='$id' class='hidden'>\n$warnings</div>\n";
}
return " <span class='time'>" . @date("H:i:s") . "</span>" // @ - time zone may be not set
. " $return<div id='$sql_id' class='hidden'><pre><code class='jush-$jush'>" . shorten_utf8($query, 1000) . "</code></pre>"
. ($time ? " <span class='time'>($time)</span>" : '')
. (support("sql") ? '<p><a href="' . h(str_replace("db=" . urlencode(DB), "db=" . urlencode($_GET["db"]), ME) . 'sql=&history=' . (count($history[$_GET["db"]]) - 1)) . '">' . lang('Edit') . '</a>' : '')
. '</div>'
@@ -626,6 +683,16 @@ focus(document.getElementById('username'));
return "";
}
/** Get hint for edit field
* @param string table name
* @param array single field from fields()
* @param string
* @return string
*/
function editHint($table, $field, $value) {
return "";
}
/** Process sent input
* @param array single field from fields()
* @param string
@@ -645,7 +712,7 @@ focus(document.getElementById('username'));
} elseif (preg_match('~^([+-]|\\|\\|)$~', $function)) {
$return = idf_escape($name) . " $function $return";
} elseif (preg_match('~^[+-] interval$~', $function)) {
$return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+$~i", $value) ? $value : $return);
$return = idf_escape($name) . " $function " . (preg_match("~^(\\d+|'[0-9.: -]') [A-Z_]+\$~i", $value) ? $value : $return);
} elseif (preg_match('~^(addtime|subtime|concat)$~', $function)) {
$return = "$function(" . idf_escape($name) . ", $return)";
} elseif (preg_match('~^(md5|sha1|password|encrypt)$~', $function)) {
@@ -699,7 +766,7 @@ focus(document.getElementById('username'));
}
$create = "CREATE TABLE " . table($table) . " (" . implode(", ", $fields) . ")";
} else {
$create = create_sql($table, $_POST["auto_increment"]);
$create = create_sql($table, $_POST["auto_increment"], $style);
}
set_utf8mb4($create);
if ($style && $create) {
@@ -812,6 +879,13 @@ focus(document.getElementById('username'));
return $ext;
}
/** Set the path of the file for webserver load
* @return string path of the sql dump file
*/
function importServerPath() {
return "adminer.sql";
}
/** Print homepage
* @return bool whether to print default homepage
*/
@@ -832,7 +906,7 @@ focus(document.getElementById('username'));
?>
<h1>
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
<a href="https://www.adminer.org/#download" target="_blank" id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
<a href="https://www.adminer.org/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
</h1>
<?php
if ($missing == "auth") {
@@ -842,7 +916,7 @@ focus(document.getElementById('username'));
foreach ($usernames as $username => $password) {
if ($password !== null) {
if ($first) {
echo "<p id='logins' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
echo "<p id='logins'>" . script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
$first = false;
}
$dbs = $_SESSION["db"][$vendor][$server][$username];
@@ -858,16 +932,14 @@ focus(document.getElementById('username'));
$connection->select_db(DB);
$tables = table_status('', true);
}
?>
<script type="text/javascript" src="../externals/jush/modules/jush.js"></script>
<script type="text/javascript" src="../externals/jush/modules/jush-textarea.js"></script>
<script type="text/javascript" src="../externals/jush/modules/jush-txt.js"></script>
<script type="text/javascript" src="../externals/jush/modules/jush-js.js"></script>
<?php
echo script_src("../externals/jush/modules/jush.js");
echo script_src("../externals/jush/modules/jush-textarea.js");
echo script_src("../externals/jush/modules/jush-txt.js");
echo script_src("../externals/jush/modules/jush-js.js");
if (support("sql")) {
echo script_src("../externals/jush/modules/jush-$jush.js");
?>
<script type="text/javascript" src="../externals/jush/modules/jush-<?php echo $jush; ?>.js"></script>
<script type="text/javascript">
<script<?php echo nonce(); ?>>
<?php
if ($tables) {
$links = array();
@@ -880,7 +952,7 @@ focus(document.getElementById('username'));
}
}
?>
bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info, 0, 3) : ""); ?>');
bodyLoad('<?php echo (is_object($connection) ? preg_replace('~^(\\d\\.?\\d).*~s', '\\1', $connection->server_info) : ""); ?>');
</script>
<?php
}
@@ -914,15 +986,15 @@ bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info,
<p id="dbs">
<?php
hidden_fields_get();
$db_events = " onmousedown='dbMouseDown(event, this);' onchange='dbChange(this);'";
echo "<span title='" . lang('database') . "'>DB</span>: " . ($databases
? "<select name='db'$db_events>" . optionlist(array("" => "") + $databases, DB) . "</select>"
: '<input name="db" value="' . h(DB) . '" autocapitalize="off">'
$db_events = script("mixin(qsl('select'), {onmousedown: dbMouseDown, onchange: dbChange});");
echo "<span title='" . lang('database') . "'>" . lang('DB') . "</span>: " . ($databases
? "<select name='db'>" . optionlist(array("" => "") + $databases, DB) . "</select>$db_events"
: "<input name='db' value='" . h(DB) . "' autocapitalize='off'>\n"
);
echo "<input type='submit' value='" . lang('Use') . "'" . ($databases ? " class='hidden'" : "") . ">\n";
if ($missing != "db" && DB != "" && $connection->select_db(DB)) {
if (support("scheme")) {
echo "<br>" . lang('Schema') . ": <select name='ns'$db_events>" . optionlist(array("" => "") + $adminer->schemas(), $_GET["ns"]) . "</select>";
echo "<br>" . lang('Schema') . ": <select name='ns'>" . optionlist(array("" => "") + $adminer->schemas(), $_GET["ns"]) . "</select>$db_events";
if ($_GET["ns"] != "") {
set_schema($_GET["ns"]);
}
@@ -941,7 +1013,7 @@ bodyLoad('<?php echo (is_object($connection) ? substr($connection->server_info,
* @return null
*/
function tablesPrint($tables) {
echo "<ul id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
echo "<ul id='tables'>" . script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});");
foreach ($tables as $table => $status) {
echo '<li><a href="' . h(ME) . 'select=' . urlencode($table) . '"' . bold($_GET["select"] == $table || $_GET["edit"] == $table, "select") . ">" . lang('select') . "</a> ";
$name = $this->tableName($status);

View File

@@ -17,15 +17,10 @@ if ($_COOKIE["adminer_permanent"]) {
function add_invalid_login() {
global $adminer;
$filename = get_temp_dir() . "/adminer.invalid";
$fp = @fopen($filename, "r+"); // @ - may not exist
if (!$fp) { // c+ is available since PHP 5.2.6
$fp = @fopen($filename, "w"); // @ - may not be writable
if (!$fp) {
return;
}
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
if (!$fp) {
return;
}
flock($fp, LOCK_EX);
$invalids = unserialize(stream_get_contents($fp));
$time = time();
if ($invalids) {
@@ -40,22 +35,21 @@ function add_invalid_login() {
$invalid = array($time + 30*60, 0); // active for 30 minutes
}
$invalid[1]++;
$serialized = serialize($invalids);
rewind($fp);
fwrite($fp, $serialized);
ftruncate($fp, strlen($serialized));
flock($fp, LOCK_UN);
fclose($fp);
file_write_unlock($fp, serialize($invalids));
}
function check_invalid_login() {
global $adminer;
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
$invalid = $invalids[$adminer->bruteForceKey()];
$next_attempt = ($invalid[1] > 29 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login
auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)));
}
}
$auth = $_POST["auth"];
if ($auth) {
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
$invalid = $invalids[$adminer->bruteForceKey()];
$next_attempt = ($invalid[1] > 30 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login
auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)));
}
session_regenerate_id(); // defense against session fixation
$vendor = $auth["driver"];
$server = $auth["server"];
@@ -89,7 +83,7 @@ if ($auth) {
set_session($key, null);
}
unset_permanent();
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . ' ' . lang('Thanks for using Adminer, consider <a href="%s">donating</a>.', 'https://sourceforge.net/donate/index.php?group_id=264133'));
}
} elseif ($permanent && !$_SESSION["pwds"]) {
@@ -130,7 +124,7 @@ function auth_error($error) {
$password = get_password();
if ($password !== null) {
if ($password === false) {
$error .= '<br>' . lang('Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.', '<code>permanentLogin()</code>');
$error .= '<br>' . lang('Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.', target_blank(), '<code>permanentLogin()</code>');
}
set_password(DRIVER, SERVER, $_GET["username"], null);
}
@@ -161,11 +155,15 @@ if (isset($_GET["username"])) {
page_footer("auth");
exit;
}
list($host, $port) = explode(":", SERVER, 2);
if (is_numeric($port) && $port < 1024) {
auth_error(lang('Connecting to privileged ports is not allowed.'));
}
check_invalid_login();
$connection = connect();
$driver = new Min_Driver($connection);
}
$driver = new Min_Driver($connection);
if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) {
auth_error((is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid credentials.'))));
}

View File

@@ -33,11 +33,14 @@ if (!$_SERVER["REQUEST_URI"]) { // IIS 5 compatibility
if (!strpos($_SERVER["REQUEST_URI"], '?') && $_SERVER["QUERY_STRING"] != "") { // IIS 7 compatibility
$_SERVER["REQUEST_URI"] .= "?$_SERVER[QUERY_STRING]";
}
if ($_SERVER["HTTP_X_FORWARDED_PREFIX"]) {
$_SERVER["REQUEST_URI"] = $_SERVER["HTTP_X_FORWARDED_PREFIX"] . $_SERVER["REQUEST_URI"];
}
$HTTPS = $_SERVER["HTTPS"] && strcasecmp($_SERVER["HTTPS"], "off");
@ini_set("session.use_trans_sid", false); // protect links in export, @ - may be disabled
session_cache_limiter(""); // to allow restarting session and to not send Cache-Control: no-store
if (!defined("SID")) {
session_cache_limiter(""); // to allow restarting session
session_name("adminer_sid"); // use specific session name to get own namespace
$params = array(0, preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"]), "", $HTTPS);
if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
@@ -54,7 +57,7 @@ if (get_magic_quotes_runtime()) {
}
@set_time_limit(0); // @ - can be disabled
@ini_set("zend.ze1_compatibility_mode", false); // @ - deprecated
@ini_set("precision", 20); // @ - can be disabled
@ini_set("precision", 16); // @ - can be disabled, 16 - internal PHP precision
include "../adminer/include/lang.inc.php";
include "../adminer/lang/$LANG.inc.php";

View File

@@ -17,7 +17,6 @@ function connect_error() {
'processlist' => lang('Process list'),
'variables' => lang('Variables'),
'status' => lang('Status'),
'replication' => lang('Replication'),
) as $key => $val) {
if (support($key)) {
echo "<a href='" . h(ME) . "$key='>$val</a>\n";
@@ -30,13 +29,14 @@ function connect_error() {
$scheme = support("scheme");
$collations = collations();
echo "<form action='' method='post'>\n";
echo "<table cellspacing='0' class='checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);'>\n";
echo "<table cellspacing='0' class='checkable'>\n";
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
echo "<thead><tr>"
. (support("database") ? "<td>&nbsp;" : "")
. "<th>" . lang('Database') . " - <a href='" . h(ME) . "refresh=1'>" . lang('Refresh') . "</a>"
. "<td>" . lang('Collation')
. "<td>" . lang('Tables')
. "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1' onclick=\"return !ajaxSetHtml('" . h(js_escape(ME)) . "script=connect');\">" . lang('Compute') . "</a>"
. "<td>" . lang('Size') . " - <a href='" . h(ME) . "dbsize=1'>" . lang('Compute') . "</a>" . script("qsl('a').onclick = partial(ajaxSetHtml, '" . js_escape(ME) . "script=connect');", "")
. "</thead>\n"
;
@@ -57,12 +57,12 @@ function connect_error() {
echo "</table>\n";
echo (support("database")
? "<fieldset><legend>" . lang('Selected') . " <span id='selected'></span></legend><div>\n"
. "<input type='hidden' name='all' value='' onclick=\"selectCount('selected', formChecked(this, /^db/));\">\n" // used by trCheck()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . ">\n"
. "<input type='hidden' name='all' value=''>" . script("qsl('input').onclick = function () { selectCount('selected', formChecked(this, /^db/)); };") // used by trCheck()
. "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm() . "\n"
. "</div></fieldset>\n"
: ""
);
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo script("tableCheck();");
echo "<input type='hidden' name='token' value='$token'>\n";
echo "</form>\n";
}
@@ -78,7 +78,7 @@ if (isset($_GET["import"])) {
$_GET["sql"] = $_GET["import"];
}
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["replication"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (!(DB != "" ? $connection->select_db(DB) : isset($_GET["sql"]) || isset($_GET["dump"]) || isset($_GET["database"]) || isset($_GET["processlist"]) || isset($_GET["privileges"]) || isset($_GET["user"]) || isset($_GET["variables"]) || $_GET["script"] == "connect" || $_GET["script"] == "kill")) {
if (DB != "" || $_GET["refresh"]) {
restart_session();
set_session("dbs", null);

View File

@@ -19,28 +19,49 @@ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") {
<!DOCTYPE html>
<html lang="<?php echo $LANG; ?>" dir="<?php echo lang('ltr'); ?>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta name="robots" content="noindex">
<meta name="referrer" content="origin-when-crossorigin">
<title><?php echo $title_page; ?></title>
<link rel="stylesheet" type="text/css" href="../adminer/static/default.css">
<script type="text/javascript" src="../adminer/static/functions.js"></script>
<script type="text/javascript" src="static/editing.js"></script>
<?php echo script_src("../adminer/static/functions.js"); ?>
<?php echo script_src("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">
<?php if (file_exists("adminer.css")) { ?>
<link rel="stylesheet" type="text/css" href="adminer.css">
<?php foreach ($adminer->css() as $css) { ?>
<link rel="stylesheet" type="text/css" href="<?php echo h($css); ?>">
<?php } ?>
<?php } ?>
<body class="<?php echo lang('ltr'); ?> nojs" onkeydown="bodyKeydown(event);" onclick="bodyClick(event);"<?php echo (isset($_COOKIE["adminer_version"]) ? "" : " onload=\"verifyVersion('$VERSION');\""); ?>>
<script type="text/javascript">
<body class="<?php echo lang('ltr'); ?> nojs">
<?php
$filename = get_temp_dir() . "/adminer.version";
if (!$_COOKIE["adminer_version"] && function_exists('openssl_verify') && file_exists($filename) && filemtime($filename) + 86400 > time()) { // 86400 - 1 day in seconds
$version = unserialize(file_get_contents($filename));
$public = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqWOVuF5uw7/+Z70djoK
RlHIZFZPO0uYRezq90+7Amk+FDNd7KkL5eDve+vHRJBLAszF/7XKXe11xwliIsFs
DFWQlsABVZB3oisKCBEuI71J4kPH8dKGEWR9jDHFw3cWmoH3PmqImX6FISWbG3B8
h7FIx3jEaw5ckVPVTeo5JRm/1DZzJxjyDenXvBQ/6o9DgZKeNDgxwKzH+sw9/YCO
jHnq1cFpOIISzARlrHMa/43YfeNRAm/tsBXjSxembBPo7aQZLAWHmaj5+K19H10B
nCpz9Y++cipkVEiKRGih4ZEvjoFysEOdRLj6WiD/uUNky4xGeA6LaJqh5XpkFkcQ
fQIDAQAB
-----END PUBLIC KEY-----
";
if (openssl_verify($version["version"], base64_decode($version["signature"]), $public) == 1) {
$_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser
}
}
?>
<script<?php echo nonce(); ?>>
mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick<?php
echo (isset($_COOKIE["adminer_version"]) ? "" : ", onload: partial(verifyVersion, '$VERSION', '" . js_escape(ME) . "', '" . get_token() . "')"); // $token may be empty in auth.inc.php
?>});
document.body.className = document.body.className.replace(/ nojs/, ' js');
var offlineMessage = '<?php echo js_escape(lang('You are offline.')); ?>';
</script>
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden" onmouseover="helpOpen = 1;" onmouseout="helpMouseout(this, event);"></div>
<div id="help" class="jush-<?php echo $jush; ?> jsonly hidden"></div>
<?php echo script("mixin(qs('#help'), {onmouseover: function () { helpOpen = 1; }, onmouseout: helpMouseout});"); ?>
<div id="content">
<?php
@@ -89,10 +110,45 @@ function page_headers() {
global $adminer;
header("Content-Type: text/html; charset=utf-8");
header("Cache-Control: no-cache");
if ($adminer->headers()) {
header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9
header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page
header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9
header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: origin-when-cross-origin");
foreach ($adminer->csp() as $csp) {
$header = array();
foreach ($csp as $key => $val) {
$header[] = "$key $val";
}
header("Content-Security-Policy: " . implode("; ", $header));
}
$adminer->headers();
}
/** Get Content Security Policy headers
* @return array of arrays with directive name in key, allowed sources in value
*/
function csp() {
return array(
array(
"script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-'
"connect-src" => "'self'",
"frame-src" => "https://www.adminer.org",
"object-src" => "'none'",
"base-uri" => "'none'",
"form-action" => "'self'",
),
);
}
/** Get a CSP nonce
* @return string Base64 value
*/
function get_nonce() {
static $nonce;
if (!$nonce) {
$nonce = base64_encode(rand_string());
}
return $nonce;
}
/** Print flash and error messages
@@ -103,7 +159,7 @@ function page_messages($error) {
$uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]);
$messages = $_SESSION["messages"][$uri];
if ($messages) {
echo "<div class='message'>" . implode("</div>\n<div class='message'>", $messages) . "</div>\n";
echo "<div class='message'>" . implode("</div>\n<div class='message'>", $messages) . "</div>" . script("messagesPrint();");
unset($_SESSION["messages"][$uri]);
}
if ($error) {
@@ -132,6 +188,6 @@ function page_footer($missing = "") {
<div id="menu">
<?php $adminer->navigation($missing); ?>
</div>
<script type="text/javascript">setupSubmitHighlight(document);</script>
<?php
echo script("setupSubmitHighlight(document);");
}

View File

@@ -27,7 +27,7 @@
$query = $adminer->selectQueryBuild($select, $where, $group, $order, $limit, $page);
if (!$query) {
$query = "SELECT" . limit(
($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table),
($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql" ? "SQL_CALC_FOUND_ROWS " : "") . implode(", ", $select) . "\nFROM " . table($table),
($where ? "\nWHERE " . implode(" AND ", $where) : "") . ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : ""),
($limit != "" ? +$limit : null),
($page ? $limit * $page : 0),
@@ -37,7 +37,7 @@
$start = microtime(true);
$return = $this->_conn->query($query);
if ($print) {
echo $adminer->selectQuery($query, format_time($start));
echo $adminer->selectQuery($query, $start, !$return);
}
return $return;
}
@@ -50,7 +50,7 @@
*/
function delete($table, $queryWhere, $limit = 0) {
$query = "FROM " . table($table);
return queries("DELETE" . ($limit ? limit1($query, $queryWhere) : " $query$queryWhere"));
return queries("DELETE" . ($limit ? limit1($table, $query, $queryWhere) : " $query$queryWhere"));
}
/** Update data in table
@@ -67,7 +67,7 @@
$values[] = "$key = $val";
}
$query = table($table) . " SET$separator" . implode(",$separator", $values);
return queries("UPDATE" . ($limit ? limit1($query, $queryWhere) : " $query$queryWhere"));
return queries("UPDATE" . ($limit ? limit1($table, $query, $queryWhere, $separator) : " $query$queryWhere"));
}
/** Insert data into table
@@ -99,12 +99,25 @@
return queries("BEGIN");
}
/** Commit transaction
* @return bool
*/
function commit() {
return queries("COMMIT");
}
/** Rollback transaction
* @return bool
*/
function rollback() {
return queries("ROLLBACK");
}
/** Get warnings about the last command
* @return string HTML
*/
function warnings() {
return '';
}
}

View File

@@ -135,22 +135,25 @@ function textarea($name, $value, $rows = 10, $cols = 80) {
* @param array
* @param array
* @param array returned by referencable_primary()
* @param array extra types to prepend
* @return null
*/
function edit_type($key, $field, $collations, $foreign_keys = array()) {
function edit_type($key, $field, $collations, $foreign_keys = array(), $extra_types = array()) {
global $structured_types, $types, $unsigned, $on_actions;
$type = $field["type"];
?>
<td><select name="<?php echo h($key); ?>[type]" class="type" onfocus="lastType = selectValue(this);" onchange="editingTypeChange(this);"<?php echo on_help("getTarget(event).value", 1); ?> aria-labelledby="label-type"><?php
if ($type && !isset($types[$type]) && !isset($foreign_keys[$type])) {
array_unshift($structured_types, $type);
<td><select name="<?php echo h($key); ?>[type]" class="type" aria-labelledby="label-type"><?php
if ($type && !isset($types[$type]) && !isset($foreign_keys[$type]) && !in_array($type, $extra_types)) {
$extra_types[] = $type;
}
if ($foreign_keys) {
$structured_types[lang('Foreign keys')] = $foreign_keys;
}
echo optionlist($structured_types, $type);
echo optionlist(array_merge($extra_types, $structured_types), $type);
?></select>
<td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3" onfocus="editingLengthFocus(this);"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); ?> onchange="editingLengthChange(this);" onkeyup="this.onchange();" aria-labelledby="label-length"><td class="options"><?php //! type="number" with enabled JavaScript
<?php echo on_help("getTarget(event).value", 1); ?>
<?php echo script("mixin(qsl('select'), {onfocus: function () { lastType = selectValue(this); }, onchange: editingTypeChange});", ""); ?>
<td><input name="<?php echo h($key); ?>[length]" value="<?php echo h($field["length"]); ?>" size="3"<?php echo (!$field["length"] && preg_match('~var(char|binary)$~', $type) ? " class='required'" : ""); ?> aria-labelledby="label-length"><?php echo script("mixin(qsl('input'), {onfocus: editingLengthFocus, oninput: editingLengthChange});", ""); ?><td class="options"><?php //! type="number" with enabled JavaScript
echo "<select name='" . h($key) . "[collation]'" . (preg_match('~(char|text|enum|set)$~', $type) ? "" : " class='hidden'") . '><option value="">(' . lang('collation') . ')' . optionlist($collations, $field["collation"]) . '</select>';
echo ($unsigned ? "<select name='" . h($key) . "[unsigned]'" . (!$type || preg_match('~((^|[^o])int|float|double|decimal)$~', $type) ? "" : " class='hidden'") . '><option>' . optionlist($unsigned, $field["unsigned"]) . '</select>' : '');
echo (isset($field['on_update']) ? "<select name='" . h($key) . "[on_update]'" . (preg_match('~timestamp|datetime~', $type) ? "" : " class='hidden'") . '>' . optionlist(array("" => "(" . lang('ON UPDATE') . ")", "CURRENT_TIMESTAMP"), $field["on_update"]) . '</select>' : '');
@@ -195,12 +198,7 @@ function process_field($field, $type_field) {
idf_escape(trim($field["field"])),
process_type($type_field),
($field["null"] ? " NULL" : " NOT NULL"), // NULL for timestamp
(isset($default) ? " DEFAULT " . (
(preg_match('~time~', $field["type"]) && preg_match('~^CURRENT_TIMESTAMP$~i', $default))
|| ($jush == "sqlite" && preg_match('~^CURRENT_(TIME|TIMESTAMP|DATE)$~i', $default))
|| ($field["type"] == "bit" && preg_match("~^([0-9]+|b'[0-1]+')\$~", $default))
|| ($jush == "pgsql" && preg_match("~^[a-z]+\\(('[^']*')+\\)\$~", $default))
? $default : q($default)) : ""),
(isset($default) ? " DEFAULT " . (preg_match('~char|binary|text|enum|set~', $field["type"]) || preg_match('~^(?![a-z])~i', $default) ? q($default) : $default) : ""),
(preg_match('~timestamp|datetime~', $field["type"]) && $field["on_update"] ? " ON UPDATE $field[on_update]" : ""),
(support("comment") && $field["comment"] != "" ? " COMMENT " . q($field["comment"]) : ""),
($field["auto_increment"] ? auto_increment() : null),
@@ -233,13 +231,13 @@ function type_class($type) {
* @return null
*/
function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = array(), $comments = false) {
global $connection, $inout;
global $inout;
$fields = array_values($fields);
?>
<thead><tr class="wrap">
<?php if ($type == "PROCEDURE") { ?><td>&nbsp;<?php } ?>
<th id="label-name"><?php echo ($type == "TABLE" ? lang('Column name') : lang('Parameter name')); ?>
<td id="label-type"><?php echo lang('Type'); ?><textarea id="enum-edit" rows="4" cols="12" wrap="off" style="display: none;" onblur="editingLengthBlur(this);"></textarea>
<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 id="label-length"><?php echo lang('Length'); ?>
<td><?php echo lang('Options'); /* no label required, options have their own label */ ?>
<?php if ($type == "TABLE") { ?>
@@ -253,10 +251,11 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
<td id="label-default"><?php echo lang('Default value'); ?>
<?php echo (support("comment") ? "<td id='label-comment'" . ($comments ? "" : " class='hidden'") . ">" . lang('Comment') : ""); ?>
<?php } ?>
<td><?php echo "<input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>"; ?><script type="text/javascript">row_count = <?php echo count($fields); ?>;</script>
<td><?php echo "<input type='image' class='icon' name='add[" . (support("move_col") ? 0 : count($fields)) . "]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>" . script("row_count = " . count($fields) . ";"); ?>
</thead>
<tbody onkeydown="return editingKeydown(event);">
<tbody>
<?php
echo script("qsl('tbody').onkeydown = editingKeydown;");
foreach ($fields as $i => $field) {
$i++;
$orig = $field[($_POST ? "orig" : "field")];
@@ -264,24 +263,23 @@ function edit_fields($fields, $collations, $type = "TABLE", $foreign_keys = arra
?>
<tr<?php echo ($display ? "" : " style='display: none;'"); ?>>
<?php echo ($type == "PROCEDURE" ? "<td>" . html_select("fields[$i][inout]", explode("|", $inout), $field["inout"]) : ""); ?>
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" onchange="editingNameChange(this);<?php echo ($field["field"] != "" || count($fields) > 1 ? '' : ' editingAddRow(this);" onkeyup="if (this.value) editingAddRow(this);'); ?>" maxlength="64" autocapitalize="off" aria-labelledby="label-name"><?php } ?>
<th><?php if ($display) { ?><input name="fields[<?php echo $i; ?>][field]" value="<?php echo h($field["field"]); ?>" maxlength="64" autocapitalize="off" aria-labelledby="label-name"><?php echo script("qsl('input').oninput = function () { editingNameChange.call(this);" . ($field["field"] != "" || count($fields) > 1 ? "" : " editingAddRow.call(this);") . " };", ""); ?><?php } ?>
<input type="hidden" name="fields[<?php echo $i; ?>][orig]" value="<?php echo h($orig); ?>">
<?php edit_type("fields[$i]", $field, $collations, $foreign_keys); ?>
<?php if ($type == "TABLE") { ?>
<td><?php echo checkbox("fields[$i][null]", 1, $field["null"], "", "", "block", "label-null"); ?>
<td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> onclick="var field = this.form['fields[' + this.value + '][field]']; if (!field.value) { field.value = 'id'; field.onchange(); }" aria-labelledby="label-ai"></label><td><?php
echo checkbox("fields[$i][has_default]", 1, $field["has_default"], "", "", "", "label-default"); ?><input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" onkeyup="keyupChange.call(this);" onchange="this.previousSibling.checked = true;" aria-labelledby="label-default">
<?php echo (support("comment") ? "<td" . ($comments ? "" : " class='hidden'") . "><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' maxlength='" . ($connection->server_info >= 5.5 ? 1024 : 255) . "' aria-labelledby='label-comment'>" : ""); ?>
<td><label class="block"><input type="radio" name="auto_increment_col" value="<?php echo $i; ?>"<?php if ($field["auto_increment"]) { ?> checked<?php } ?> aria-labelledby="label-ai"><?php echo script("qsl('input').onclick = function () { var field = this.form['fields[' + this.value + '][field]']; if (!field.value) { field.value = 'id'; field.oninput(); } }"); ?></label><td><?php
echo checkbox("fields[$i][has_default]", 1, $field["has_default"], "", "", "", "label-default"); ?><input name="fields[<?php echo $i; ?>][default]" value="<?php echo h($field["default"]); ?>" aria-labelledby="label-default"><?php echo script("qsl('input').oninput = function () { this.previousSibling.checked = true; }", ""); ?>
<?php echo (support("comment") ? "<td" . ($comments ? "" : " class='hidden'") . "><input name='fields[$i][comment]' value='" . h($field["comment"]) . "' maxlength='" . (min_version(5.5) ? 1024 : 255) . "' aria-labelledby='label-comment'>" : ""); ?>
<?php } ?>
<?php
echo "<td>";
echo (support("move_col") ?
"<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "' onclick='return !editingAddRow(this, 1);'>&nbsp;"
. "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='^' title='" . lang('Move up') . "' onclick='return !editingMoveRow(this, 1);'>&nbsp;"
. "<input type='image' class='icon' name='down[$i]' src='../adminer/static/down.gif' alt='v' title='" . lang('Move down') . "' onclick='return !editingMoveRow(this, 0);'>&nbsp;"
"<input type='image' class='icon' name='add[$i]' src='../adminer/static/plus.gif' alt='+' title='" . lang('Add next') . "'>&nbsp;" . script("qsl('input').onclick = partial(editingAddRow, 1);", "")
. "<input type='image' class='icon' name='up[$i]' src='../adminer/static/up.gif' alt='^' title='" . lang('Move up') . "'>&nbsp;" . script("qsl('input').onclick = partial(editingMoveRow, 1);", "")
. "<input type='image' class='icon' name='down[$i]' src='../adminer/static/down.gif' alt='v' title='" . lang('Move down') . "'>&nbsp;" . script("qsl('input').onclick = partial(editingMoveRow, 0);", "")
: "");
echo ($orig == "" || support("drop_col") ? "<input type='image' class='icon' name='drop_col[$i]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "' onclick=\"return !editingRemoveRow(this, 'fields\$1[field]');\">" : "");
echo "\n";
echo ($orig == "" || support("drop_col") ? "<input type='image' class='icon' name='drop_col[$i]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" . script("qsl('input').onclick = partial(editingRemoveRow, 'fields\$1[field]');") : "");
}
}
@@ -411,7 +409,7 @@ function create_trigger($on, $row) {
* @return string
*/
function create_routine($routine, $row) {
global $inout;
global $inout, $jush;
$set = array();
$fields = (array) $row["fields"];
ksort($fields); // enforce fields order
@@ -420,13 +418,13 @@ function create_routine($routine, $row) {
$set[] = (preg_match("~^($inout)\$~", $field["inout"]) ? "$field[inout] " : "") . idf_escape($field["field"]) . process_type($field, "CHARACTER SET");
}
}
$definition = rtrim("\n$row[definition]", ";");
return "CREATE $routine "
. idf_escape(trim($row["name"]))
. " (" . implode(", ", $set) . ")"
. (isset($_GET["function"]) ? " RETURNS" . process_type($row["returns"], "CHARACTER SET") : "")
. ($row["language"] ? " LANGUAGE $row[language]" : "")
. rtrim("\n$row[definition]", ";")
. ";"
. ($jush == "pgsql" ? " AS " . q($definition) : "$definition;")
;
}
@@ -489,14 +487,15 @@ function ini_bytes($ini) {
*/
function doc_link($paths) {
global $jush, $connection;
$version = preg_replace('~^(\\d\\.?\\d).*~s', '\\1', $connection->server_info);
$urls = array(
'sql' => "http://dev.mysql.com/doc/refman/" . substr($connection->server_info, 0, 3) . "/en/",
'sqlite' => "http://www.sqlite.org/",
'pgsql' => "http://www.postgresql.org/docs/" . substr($connection->server_info, 0, 3) . "/static/",
'mssql' => "http://msdn.microsoft.com/library/",
'oracle' => "http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/",
'sql' => "https://dev.mysql.com/doc/refman/$version/en/",
'sqlite' => "https://www.sqlite.org/",
'pgsql' => "https://www.postgresql.org/docs/$version/static/",
'mssql' => "https://msdn.microsoft.com/library/",
'oracle' => "https://download.oracle.com/docs/cd/B19306_01/server.102/b14200/",
);
return ($paths[$jush] ? "<a href='$urls[$jush]$paths[$jush]' target='_blank' rel='noreferrer'><sup>?</sup></a>" : "");
return ($paths[$jush] ? "<a href='$urls[$jush]$paths[$jush]'" . target_blank() . "><sup>?</sup></a>" : "");
}
/** Wrap gzencode() for usage in ob_start()
@@ -529,7 +528,7 @@ function db_size($db) {
* @return null
*/
function set_utf8mb4($create) {
global $connection;
global $connection;
static $set = false;
if (!$set && preg_match('~\butf8mb4~i', $create)) { // possible false positive
$set = true;

View File

@@ -38,7 +38,7 @@ function escape_string($val) {
* @return string
*/
function number($val) {
return preg_replace('~[^0-9]+~', '', $val);
return preg_replace('~[^0-9]+~', '', $val);
}
/** Disable magic_quotes_gpc
@@ -73,12 +73,62 @@ function bracket_escape($idf, $back = false) {
return strtr($idf, ($back ? array_flip($trans) : $trans));
}
/** Check if connection has at least the given version
* @param string required version
* @param string required MariaDB version
* @param Min_DB defaults to $connection
* @return bool
*/
function min_version($version, $maria_db = "", $connection2 = null) {
global $connection;
if (!$connection2) {
$connection2 = $connection;
}
$server_info = $connection2->server_info;
if ($maria_db && preg_match('~([\d.]+)-MariaDB~', $server_info, $match)) {
$server_info = $match[1];
$version = $maria_db;
}
return (version_compare($server_info, $version) >= 0);
}
/** Get connection charset
* @param Min_DB
* @return string
*/
function charset($connection) {
return (version_compare($connection->server_info, "5.5.3") >= 0 ? "utf8mb4" : "utf8"); // SHOW CHARSET would require an extra query
return (min_version("5.5.3", 0, $connection) ? "utf8mb4" : "utf8"); // SHOW CHARSET would require an extra query
}
/** Return <script> element
* @param string
* @param string
* @return string
*/
function script($source, $trailing = "\n") {
return "<script" . nonce() . ">$source</script>$trailing";
}
/** Return <script src> element
* @param string
* @return string
*/
function script_src($url) {
return "<script src='" . h($url) . "'" . nonce() . "></script>\n";
}
/** Get a nonce="" attribute with CSP nonce
* @return string
*/
function nonce() {
return ' nonce="' . get_nonce() . '"';
}
/** Get a target="_blank" attribute
* @return string
*/
function target_blank() {
return ' target="_blank" rel="noreferrer noopener"';
}
/** Escape for HTML
@@ -119,8 +169,8 @@ function checkbox($name, $value, $checked, $label = "", $onclick = "", $class =
$return = "<input type='checkbox' name='$name' value='" . h($value) . "'"
. ($checked ? " checked" : "")
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ($onclick ? ' onclick="' . h($onclick) . '"' : '')
. ">"
. ($onclick ? script("qsl('input').onclick = function () { $onclick };", "") : "")
;
return ($label != "" || $class ? "<label" . ($class ? " class='$class'" : "") . ">$return" . h($label) . "</label>" : $return);
}
@@ -160,9 +210,10 @@ function optionlist($options, $selected = null, $use_keys = false) {
function html_select($name, $options, $value = "", $onchange = true, $labelled_by = "") {
if ($onchange) {
return "<select name='" . h($name) . "'"
. (is_string($onchange) ? ' onchange="' . h($onchange) . '"' : "")
. ($labelled_by ? " aria-labelledby='$labelled_by'" : "")
. ">" . optionlist($options, $value) . "</select>";
. ">" . optionlist($options, $value) . "</select>"
. (is_string($onchange) ? script("qsl('select').onchange = function () { $onchange };", "") : "")
;
}
$return = "";
foreach ($options as $key => $val) {
@@ -172,35 +223,42 @@ function html_select($name, $options, $value = "", $onchange = true, $labelled_b
}
/** Generate HTML <select> or <input> if $options are empty
* @param string
* @param array
* @param string
* @param string
* @return string
*/
function select_input($attrs, $options, $value = "", $placeholder = "") {
return ($options
? "<select$attrs><option value=''>$placeholder" . optionlist($options, $value, true) . "</select>"
: "<input$attrs size='10' value='" . h($value) . "' placeholder='$placeholder'>"
);
* @param string
* @param array
* @param string
* @param string
* @param string
* @return string
*/
function select_input($attrs, $options, $value = "", $onchange = "", $placeholder = "") {
$tag = ($options ? "select" : "input");
return "<$tag$attrs" . ($options
? "><option value=''>$placeholder" . optionlist($options, $value, true) . "</select>"
: " size='10' value='" . h($value) . "' placeholder='$placeholder'>"
) . ($onchange ? script("qsl('$tag').onchange = $onchange;", "") : ""); //! use oninput for input
}
/** Get onclick confirmation
* @param string
* @param string
* @return string
*/
function confirm() {
return " onclick=\"return confirm('" . lang('Are you sure?') . "');\"";
function confirm($message = "", $selector = "qsl('input')") {
return script("$selector.onclick = function () { return confirm('" . ($message ? js_escape($message) : lang('Are you sure?')) . "'); };", "");
}
/** Print header for hidden fieldset (close by </div></fieldset>)
* @param string
* @param string
* @param bool
* @param string
* @return null
*/
function print_fieldset($id, $legend, $visible = false, $onclick = "") {
echo "<fieldset><legend><a href='#fieldset-$id' onclick=\"" . h($onclick) . "return !toggle('fieldset-$id');\">$legend</a></legend><div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
function print_fieldset($id, $legend, $visible = false) {
echo "<fieldset><legend>";
echo "<a href='#fieldset-$id'>$legend</a>";
echo script("qsl('a').onclick = partial(toggle, 'fieldset-$id');", "");
echo "</legend>";
echo "<div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
}
/** Return class='active' if $bold is true
@@ -329,9 +387,10 @@ function get_vals($query, $column = 0) {
* @param string
* @param Min_DB
* @param float
* @param bool
* @return array
*/
function get_key_vals($query, $connection2 = null, $timeout = 0) {
function get_key_vals($query, $connection2 = null, $timeout = 0, $set_keys = true) {
global $connection;
if (!is_object($connection2)) {
$connection2 = $connection;
@@ -342,7 +401,11 @@ function get_key_vals($query, $connection2 = null, $timeout = 0) {
$connection2->timeout = 0;
if (is_object($result)) {
while ($row = $result->fetch_row()) {
$return[$row[0]] = $row[1];
if ($set_keys) {
$return[$row[0]] = $row[1];
} else {
$return[] = $row[0];
}
}
}
return $return;
@@ -352,7 +415,7 @@ function get_key_vals($query, $connection2 = null, $timeout = 0) {
* @param string
* @param Min_DB
* @param string
* @return array associative
* @return array of associative arrays
*/
function get_rows($query, $connection2 = null, $error = "<p class='error'>") {
global $connection;
@@ -481,8 +544,8 @@ function cookie($name, $value, $lifetime = 2592000) { // 2592000 - 30 days
. ($lifetime ? "; expires=" . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT" : "")
. "; path=" . preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"])
. ($HTTPS ? "; secure" : "")
. "; HttpOnly; SameSite=lax"
);
. "; HttpOnly; SameSite=lax",
false);
}
/** Restart stopped session
@@ -584,10 +647,10 @@ function query_redirect($query, $location, $message, $redirect = true, $execute
}
$sql = "";
if ($query) {
$sql = $adminer->messageQuery($query, $time);
$sql = $adminer->messageQuery($query, $time, $failed);
}
if ($failed) {
$error = error() . $sql;
$error = error() . $sql . script("messagesPrint();");
return false;
}
if ($redirect) {
@@ -755,7 +818,7 @@ function shorten_utf8($string, $length = 80, $suffix = "") {
* @return string
*/
function format_number($val) {
return strtr(number_format($val, 0, ".", lang(',')), preg_split('~~u', lang('0123456789'), -1, PREG_SPLIT_NO_EMPTY));
return strtr(number_format($val, 0, ".", lang(',')), preg_split('~~u', lang('0123456789'), -1, PREG_SPLIT_NO_EMPTY));
}
/** Generate friendly URL
@@ -847,7 +910,7 @@ function enum_input($type, $attrs, $field, $value, $empty = null) {
* @return null
*/
function input($field, $value, $function) {
global $connection, $types, $adminer, $jush;
global $types, $adminer, $jush;
$name = h(bracket_escape($field["field"]));
echo "<td class='function'>";
if (is_array($value) && !$function) {
@@ -867,18 +930,11 @@ function input($field, $value, $function) {
if ($field["type"] == "enum") {
echo nbsp($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
} else {
$first = 0;
foreach ($functions as $key => $val) {
if ($key === "" || !$val) {
break;
}
$first++;
}
$onchange = ($first ? " onchange=\"var f = this.form['function[" . h(js_escape(bracket_escape($field["field"]))) . "]']; if ($first > f.selectedIndex) f.selectedIndex = $first;\" onkeyup='keyupChange.call(this);'" : "");
$attrs .= $onchange;
$has_function = (in_array($function, $functions) || isset($functions[$function]));
echo (count($functions) > 1
? "<select name='function[$name]' onchange='functionChange(this);'" . on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1) . ">" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
? "<select name='function[$name]'>" . optionlist($functions, $function === null || $has_function ? $function : "") . "</select>"
. on_help("getTarget(event).value.replace(/^SQL\$/, '')", 1)
. script("qsl('select').onchange = functionChange;", "")
: nbsp(reset($functions))
) . '<td>';
$input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
@@ -886,16 +942,16 @@ function input($field, $value, $function) {
echo $input;
} elseif (preg_match('~bool~', $field["type"])) {
echo "<input type='hidden'$attrs value='0'>" .
"<input type='checkbox'" . (in_array(strtolower($value), array('1', 't', 'true', 'y', 'yes', 'on')) ? " checked='checked'" : "") . "$attrs value='1'>";
"<input type='checkbox'" . (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? " checked='checked'" : "") . "$attrs value='1'>";
} elseif ($field["type"] == "set") { //! 64 bits
preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
foreach ($matches[1] as $i => $val) {
$val = stripcslashes(str_replace("''", "'", $val));
$checked = (is_int($value) ? ($value >> $i) & 1 : in_array($val, explode(",", $value), true));
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . (1 << $i) . "'" . ($checked ? ' checked' : '') . "$onchange>" . h($adminer->editVal($val, $field)) . '</label>';
echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . (1 << $i) . "'" . ($checked ? ' checked' : '') . ">" . h($adminer->editVal($val, $field)) . '</label>';
}
} elseif (preg_match('~blob|bytea|raw|file~', $field["type"]) && ini_bool("file_uploads")) {
echo "<input type='file' name='fields-$name'$onchange>";
echo "<input type='file' name='fields-$name'>";
} elseif (($text = preg_match('~text|lob~', $field["type"])) || preg_match("~\n~", $value)) {
if ($text && $jush != "sqlite") {
$attrs .= " cols='50' rows='12'";
@@ -909,7 +965,7 @@ function input($field, $value, $function) {
} else {
// int(3) is only a display hint
$maxlength = (!preg_match('~int~', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((preg_match("~binary~", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
if ($jush == 'sql' && $connection->server_info >= 5.6 && preg_match('~time~', $field["type"])) {
if ($jush == 'sql' && min_version(5.6) && preg_match('~time~', $field["type"])) {
$maxlength += 7; // microtime
}
// type='date' and type='time' display localized value which may be confusing, type='datetime' uses 'T' as date and time separator
@@ -920,6 +976,18 @@ function input($field, $value, $function) {
. "$attrs>"
;
}
echo $adminer->editHint($_GET["edit"], $field, $value);
// skip 'original'
$first = 0;
foreach ($functions as $key => $val) {
if ($key === "" || !$val) {
break;
}
$first++;
}
if ($first) {
echo script("mixin(qsl('td'), {onchange: partial(skipOriginal, $first), oninput: function () { this.onchange(); }});");
}
}
}
@@ -1003,7 +1071,6 @@ function fields_from_edit() {
*/
function search_tables() {
global $adminer, $connection;
$_GET["where"][0]["op"] = "LIKE %%";
$_GET["where"][0]["val"] = $_POST["query"];
$found = false;
foreach (table_status('', true) as $table => $table_status) {
@@ -1084,6 +1151,35 @@ function get_temp_dir() {
return $return;
}
/** Open and exclusively lock a file
* @param string
* @return resource or null for error
*/
function file_open_lock($filename) {
$fp = @fopen($filename, "r+"); // @ - may not exist
if (!$fp) { // c+ is available since PHP 5.2.6
$fp = @fopen($filename, "w"); // @ - may not be writable
if (!$fp) {
return;
}
chmod($filename, 0660);
}
flock($fp, LOCK_EX);
return $fp;
}
/** Write and unlock a file
* @param resource
* @param string
*/
function file_write_unlock($fp, $data) {
rewind($fp);
fwrite($fp, $data);
ftruncate($fp, strlen($data));
flock($fp, LOCK_UN);
fclose($fp);
}
/** Read password from file adminer.key in temporary directory or create one
* @param bool
* @return string or false if the file can not be created
@@ -1119,7 +1215,7 @@ function rand_string() {
* @return string HTML
*/
function select_value($val, $link, $field, $text_length) {
global $adminer, $HTTPS;
global $adminer;
if (is_array($val)) {
$return = "";
foreach ($val as $k => $v) {
@@ -1137,11 +1233,8 @@ function select_value($val, $link, $field, $text_length) {
if (is_mail($val)) {
$link = "mailto:$val";
}
if ($protocol = is_url($val)) {
$link = (($protocol == "http" && $HTTPS) || preg_match('~WebKit|Firefox~i', $_SERVER["HTTP_USER_AGENT"]) // WebKit supports noreferrer since 2009, Firefox since version 38
? $val // HTTP links from HTTPS pages don't receive Referer automatically
: "https://www.adminer.org/redirect/?url=" . urlencode($val) // intermediate page to hide Referer
);
if (is_url($val)) {
$link = $val; // IE 11 and all modern browsers hide referrer
}
}
$return = $adminer->editVal($val, $field);
@@ -1172,11 +1265,11 @@ function is_mail($email) {
/** Check whether the string is URL address
* @param string
* @return string "http", "https" or ""
* @return bool
*/
function is_url($string) {
$domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN
return (preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string, $match) ? strtolower($match[1]) : ""); //! restrict path, query and fragment characters
return preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string); //! restrict path, query and fragment characters
}
/** Check if field should be shortened
@@ -1199,7 +1292,7 @@ function count_rows($table, $where, $is_group, $group) {
$query = " FROM " . table($table) . ($where ? " WHERE " . implode(" AND ", $where) : "");
return ($is_group && ($jush == "sql" || count($group) == 1)
? "SELECT COUNT(DISTINCT " . implode(", ", $group) . ")$query"
: "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query$group_by) x" : $query)
: "SELECT COUNT(*)" . ($is_group ? " FROM (SELECT 1$query GROUP BY " . implode(", ", $group) . ") x" : $query)
);
}
@@ -1214,10 +1307,10 @@ function slow_query($query) {
if (support("kill") && is_object($connection2 = connect()) && ($db == "" || $connection2->select_db($db))) {
$kill = $connection2->result(connection_id()); // MySQL and MySQLi can use thread_id but it's not in PDO_MySQL
?>
<script type="text/javascript">
<script<?php echo nonce(); ?>>
var timeout = setTimeout(function () {
ajax('<?php echo js_escape(ME); ?>script=kill', function () {
}, 'token=<?php echo $token; ?>&kill=<?php echo $kill; ?>');
}, 'kill=<?php echo $kill; ?>&token=<?php echo $token; ?>');
}, <?php echo 1000 * $timeout; ?>);
</script>
<?php
@@ -1226,13 +1319,13 @@ var timeout = setTimeout(function () {
}
ob_flush();
flush();
$return = @get_key_vals($query, $connection2, $timeout); // @ - may be killed
$return = @get_key_vals($query, $connection2, $timeout, false); // @ - may be killed
if ($connection2) {
echo "<script type='text/javascript'>clearTimeout(timeout);</script>\n";
echo script("clearTimeout(timeout);");
ob_flush();
flush();
}
return array_keys($return);
return $return;
}
/** Generate BREACH resistant CSRF token
@@ -1295,7 +1388,7 @@ function lzw_decompress($binary) {
* @return string
*/
function on_help($command, $side = 0) {
return " onmouseover='helpMouseover(this, event, " . h($command) . ", $side);' onmouseout='helpMouseout(this, event);'";
return script("mixin(qsl('select, input'), {onmouseover: function (event) { helpMouseover.call(this, event, $command, $side) }, onmouseout: helpMouseout});", "");
}
/** Print edit data form
@@ -1323,7 +1416,7 @@ function edit_form($TABLE, $fields, $row, $update) {
if (!$fields) {
echo "<p class='error'>" . lang('You have no privileges to update this table.') . "\n";
} else {
echo "<table cellspacing='0' onkeydown='return editingKeydown(event);'>\n";
echo "<table cellspacing='0'>" . script("qsl('table').onkeydown = editingKeydown;");
foreach ($fields as $name => $field) {
echo "<tr><th>" . $adminer->fieldName($field);
@@ -1363,7 +1456,8 @@ function edit_form($TABLE, $fields, $row, $update) {
}
if (!support("table")) {
echo "<tr>"
. "<th><input name='field_keys[]' onkeyup='keyupChange.call(this);' onchange='fieldChange(this);' value=''>" // needs empty value for keyupChange()
. "<th><input name='field_keys[]'>"
. script("qsl('input').oninput = fieldChange;")
. "<td class='function'>" . html_select("field_funs[]", $adminer->editFunctions(array("null" => isset($_GET["select"]))))
. "<td><input name='field_vals[]'>"
. "\n"
@@ -1376,13 +1470,14 @@ function edit_form($TABLE, $fields, $row, $update) {
echo "<input type='submit' value='" . lang('Save') . "'>\n";
if (!isset($_GET["select"])) {
echo "<input type='submit' name='insert' value='" . ($update
? lang('Save and continue edit') . "' onclick='return !ajaxForm(this.form, \"" . lang('Saving') . '...", this)'
? lang('Save and continue edit')
: lang('Save and insert next')
) . "' title='Ctrl+Shift+Enter'>\n";
echo ($update ? script("qsl('input').onclick = function () { return !ajaxForm(this.form, '" . lang('Saving') . "...', this); };") : "");
}
}
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'" . confirm() . ">\n"
: ($_POST || !$fields ? "" : "<script type='text/javascript'>focus(document.getElementById('form').getElementsByTagName('td')[1].firstChild);</script>\n")
echo ($update ? "<input type='submit' name='delete' value='" . lang('Delete') . "'>" . confirm() . "\n"
: ($_POST || !$fields ? "" : script("focus(qsa('td', qs('#form'))[1].firstChild);"))
);
if (isset($_GET["select"])) {
hidden_fields(array("check" => (array) $_POST["check"], "clone" => $_POST["clone"], "all" => $_POST["all"]));

View File

@@ -2,13 +2,13 @@
// not used in a single language version
$langs = array(
'en' => 'English', // Jakub Vrána - http://www.vrana.cz
'en' => 'English', // Jakub Vrána - https://www.vrana.cz
'ar' => 'العربية', // Y.M Amine - Algeria - nbr7@live.fr
'bg' => 'Български', // Deyan Delchev
'bn' => 'বাংলা', // Dipak Kumar - dipak.ndc@gmail.com
'bs' => 'Bosanski', // Emir Kurtovic
'ca' => 'Català', // Joan Llosas
'cs' => 'Čeština', // Jakub Vrána - http://www.vrana.cz
'cs' => 'Čeština', // Jakub Vrána - https://www.vrana.cz
'da' => 'Dansk', // Jarne W. Beutnagel - jarne@beutnagel.dk
'de' => 'Deutsch', // Klemens Häckel - http://clickdimension.wordpress.com
'el' => 'Ελληνικά', // Dimitrios T. Tanis - jtanis@tanisfood.gr
@@ -18,24 +18,26 @@ $langs = array(
'fi' => 'Suomi', // Finnish - Kari Eveli - http://www.lexitec.fi/
'fr' => 'Français', // Francis Gagné, Aurélien Royer
'gl' => 'Galego', // Eduardo Penabad Ramos
'he' => 'עברית', // Binyamin Yawitz - https://stuff-group.com/
'hu' => 'Magyar', // Borsos Szilárd (Borsosfi) - http://www.borsosfi.hu, info@borsosfi.hu
'id' => 'Bahasa Indonesia', // Ivan Lanin - http://ivan.lanin.org
'it' => 'Italiano', // Alessandro Fiorotto, Paolo Asperti
'ja' => '日本語', // Hitoshi Ozawa - http://sourceforge.jp/projects/oss-ja-jpn/releases/
'ko' => '한국어', // dalli - skcha67@gmail.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
'pl' => 'Polski', // Radosław Kowalewski - http://srsbiz.pl/
'pt' => 'Português', // André Dias
'pt-br' => 'Português (Brazil)', // Gian Live - gian@live.com, Davi Alexandre davi@davialexandre.com.br, RobertoPC - http://www.robertopc.com.br
'ro' => 'Limba Română', // .nick .messing - dot.nick.dot.messing@gmail.com
'ru' => 'Русский язык', // Maksim Izmaylov
'ru' => 'Русский', // Maksim Izmaylov; Andre Polykanine - https://github.com/Oire/
'sk' => 'Slovenčina', // Ivan Suchy - http://www.ivansuchy.com, Juraj Krivda - http://www.jstudio.cz
'sl' => 'Slovenski', // Matej Ferlan - www.itdinamik.com, matej.ferlan@itdinamik.com
'sr' => 'Српски', // Nikola Radovanović - cobisimo@gmail.com
'ta' => 'த‌மிழ்', // G. Sampath Kumar, Chennai, India, sampathkumar11@gmail.com
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'th' => 'ภาษาไทย', // Panya Saraphi, elect.tu@gmail.com - http://www.opencart2u.com/
'tr' => 'Türkçe', // Bilgehan Korkmaz - turktron.com
'uk' => 'Українська', // Valerii Kryzhov
'vi' => 'Tiếng Việt', // Giang Manh @ manhgd google mail

View File

@@ -1,2 +1,2 @@
<?php
$VERSION = "4.3.0";
$VERSION = "4.6.0";

View File

@@ -3,8 +3,8 @@
* @link https://www.adminer.org/
* @author Jakub Vrana, https://www.vrana.cz/
* @copyright 2007 Jakub Vrana
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
include "./include/bootstrap.inc.php";
@@ -65,8 +65,6 @@ if (isset($_GET["download"])) {
include "./user.inc.php";
} elseif (isset($_GET["processlist"])) {
include "./processlist.inc.php";
} elseif (isset($_GET["replication"])) {
include "./replication.inc.php";
} elseif (isset($_GET["select"])) {
include "./select.inc.php";
} elseif (isset($_GET["variables"])) {

View File

@@ -2,10 +2,10 @@
$TABLE = $_GET["indexes"];
$index_types = array("PRIMARY", "UNIQUE", "INDEX");
$table_status = table_status($TABLE, true);
if (preg_match('~MyISAM|M?aria' . ($connection->server_info >= 5.6 ? '|InnoDB' : '') . '~i', $table_status["Engine"])) {
if (preg_match('~MyISAM|M?aria' . (min_version(5.6, '10.0.5') ? '|InnoDB' : '') . '~i', $table_status["Engine"])) {
$index_types[] = "FULLTEXT";
}
if (preg_match('~MyISAM|M?aria' . ($connection->server_info >= 5.7 ? '|InnoDB' : '') . '~i', $table_status["Engine"])) {
if (preg_match('~MyISAM|M?aria' . (min_version(5.7, '10.2.2') ? '|InnoDB' : '') . '~i', $table_status["Engine"])) {
$index_types[] = "SPATIAL";
}
$indexes = indexes($TABLE);
@@ -113,16 +113,17 @@ if ($primary) {
$j = 1;
foreach ($row["indexes"] as $index) {
if (!$_POST["drop_col"] || $j != key($_POST["drop_col"])) {
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow(this);" : 1), "label-type");
echo "<tr><td>" . html_select("indexes[$j][type]", array(-1 => "") + $index_types, $index["type"], ($j == count($row["indexes"]) ? "indexesAddRow.call(this);" : 1), "label-type");
echo "<td>";
ksort($index["columns"]);
$i = 1;
foreach ($index["columns"] as $key => $column) {
echo "<span>" . select_input(
" name='indexes[$j][columns][$i]' onchange=\"" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . "(this, '" . h(js_escape($jush == "sql" ? "" : $_GET["indexes"] . "_")) . "');\" title='" . lang('Column') . "'",
" name='indexes[$j][columns][$i]' title='" . lang('Column') . "'",
($fields ? array_combine($fields, $fields) : $fields),
$column
$column,
"partial(" . ($i == count($index["columns"]) ? "indexesAddColumn" : "indexesChangeColumn") . ", '" . js_escape($jush == "sql" ? "" : $_GET["indexes"] . "_") . "')"
);
echo ($jush == "sql" || $jush == "mssql" ? "<input type='number' name='indexes[$j][lengths][$i]' class='size' value='" . h($index["lengths"][$key]) . "' title='" . lang('Length') . "'>" : "");
echo ($jush != "sql" ? checkbox("indexes[$j][descs][$i]", 1, $index["descs"][$key], lang('descending')) : "");
@@ -131,7 +132,7 @@ foreach ($row["indexes"] as $index) {
}
echo "<td><input name='indexes[$j][name]' value='" . h($index["name"]) . "' autocapitalize='off' aria-labelledby='label-name'>\n";
echo "<td><input type='image' class='icon' name='drop_col[$j]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "' onclick=\"return !editingRemoveRow(this, 'indexes\$1[type]');\">\n";
echo "<td><input type='image' class='icon' name='drop_col[$j]' src='../adminer/static/cross.gif' alt='x' title='" . lang('Remove') . "'>" . script("qsl('input').onclick = partial(editingRemoveRow, 'indexes\$1[type]');");
}
$j++;
}

View File

@@ -12,7 +12,7 @@ $translations = array(
'Logout successful.' => 'Излизането е успешно.',
'Invalid credentials.' => 'Невалидни потребителски данни.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %d минути.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Главната парола вече е невалидна. <a href="https://www.adminer.org/en/extension/" target="_blank">Изберете</a> %s метод, за да я направите постоянна.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Главната парола вече е невалидна. <a href="https://www.adminer.org/en/extension/"%s>Изберете</a> %s метод, за да я направите постоянна.',
'Language' => 'Език',
'Invalid CSRF token. Send the form again.' => 'Невалиден шифроващ ключ. Попълнете и изпратете формуляра отново.',
'If you did not send this request from Adminer then close this page.' => 'Ако не сте изпратили тази заявка през Adminer, затворете тази страница.',

View File

@@ -10,15 +10,17 @@ $translations = array(
'Logout' => 'Odhlásit',
'Logged as: %s' => 'Přihlášen jako: %s',
'Logout successful.' => 'Odhlášení proběhlo v pořádku.',
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Díky za použití Admineru, zvažte <a href="%s">příspěvek</a>.',
'Invalid credentials.' => 'Neplatné přihlašovací údaje.',
'<a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to use SQLite.' => 'Pro přihlášení k SQLite <a href="https://www.adminer.org/cs/extension/" target="_blank">implementujte</a> metodu %s.',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => 'Pro přihlášení k SQLite <a href="https://www.adminer.org/cs/extension/"%s>implementujte</a> metodu %s.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minutu.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minuty.', 'Příliš mnoho pokusů o přihlášení, zkuste to znovu za %d minut.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Platnost hlavního hesla vypršela. <a href="https://www.adminer.org/cs/extension/" target="_blank">Implementujte</a> metodu %s, aby platilo stále.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Platnost hlavního hesla vypršela. <a href="https://www.adminer.org/cs/extension/"%s>Implementujte</a> metodu %s, aby platilo stále.',
'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 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.',
'Session support must be enabled.' => 'Session proměnné musí být povolené.',
'Session expired, please login again.' => 'Session vypršela, přihlašte se prosím znovu.',
'%s version: %s through PHP extension %s' => 'Verze %s: %s přes PHP rozšíření %s',
@@ -45,15 +47,12 @@ $translations = array(
'Variables' => 'Proměnné',
'Status' => 'Stav',
'Replication' => 'Replikace',
'Master status' => 'Master status',
'Slave status' => 'Slave status',
'SQL command' => 'SQL příkaz',
'%d query(s) executed OK.' => array('%d příkaz proběhl v pořádku.', '%d příkazy proběhly v pořádku.', '%d příkazů proběhlo v pořádku.'),
'Query executed OK, %d row(s) affected.' => array('Příkaz proběhl v pořádku, byl změněn %d záznam.', 'Příkaz proběhl v pořádku, byly změněny %d záznamy.', 'Příkaz proběhl v pořádku, bylo změněno %d záznamů.'),
'No commands to execute.' => 'Žádné příkazy k vykonání.',
'Error in query' => 'Chyba v dotazu',
'Warnings' => 'Varování',
'ATTACH queries are not supported.' => 'Dotazy ATTACH nejsou podporované.',
'Execute' => 'Provést',
'Stop on error' => 'Zastavit při chybě',
@@ -85,6 +84,7 @@ $translations = array(
'Database' => 'Databáze',
'database' => 'databáze',
'DB' => 'DB',
'Use' => 'Vybrat',
'Select database' => 'Vybrat databázi',
'Invalid database.' => 'Nesprávná databáze.',
@@ -173,6 +173,7 @@ $translations = array(
'Default value' => 'Výchozí hodnota',
'Default values' => 'Výchozí hodnoty',
'Drop' => 'Odstranit',
'Drop %s?' => 'Odstranit %s?',
'Are you sure?' => 'Opravdu?',
'Size' => 'Velikost',
'Compute' => 'Spočítat',
@@ -339,8 +340,4 @@ $translations = array(
'Type has been dropped.' => 'Typ byl odstraněn.',
'Type has been created.' => 'Typ byl vytvořen.',
'Alter type' => 'Pozměnit typ',
'Replication' => null,
'Master status' => null,
'Slave status' => null,
);

View File

@@ -10,7 +10,7 @@ $translations = array(
'Logged as: %s' => 'Logget ind som: %s',
'Logout successful.' => 'Log af vellykket.',
'Invalid credentials.' => 'Ugyldige log ind oplysninger.',
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/" target="_blank">Implementer</a> en metode for %s for at gøre det permanent.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-kodeordet er udløbet. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for at gøre det permanent.',
'Language' => 'Sprog',
'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.',
'No extension' => 'Ingen udvidelse',

View File

@@ -283,6 +283,6 @@ $translations = array(
'Saving' => 'Speichere',
'yes' => 'ja',
'no' => 'nein',
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/" target="_blank">Implementieren</a> Sie die %s Methode, um es permanent zu machen.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Das Master-Passwort ist abgelaufen. <a href="https://www.adminer.org/de/extension/"%s>Implementieren</a> Sie die %s Methode, um es permanent zu machen.',
'%d / ' => '%d / ',
);

View File

@@ -12,7 +12,7 @@ $translations = array(
'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.',
'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανηλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανηλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Έλειξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/" target="_blank">Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Έλειξε ο Κύριος Κωδικός. <a href="https://www.adminer.org/en/extension/"%s>Ενεργοποιήστε</a> τη μέθοδο %s για να τον κάνετε μόνιμο.',
'Language' => 'Γλώσσα',
'Invalid CSRF token. Send the form again.' => 'Άκυρο κουπόνι CSRF. Στείλτε τη φόρμα ξανά.',
'If you did not send this request from Adminer then close this page.' => 'Αν δε στείλατε αυτό το αίτημα από το Adminer, τότε κλείστε αυτή τη σελίδα.',
@@ -149,7 +149,7 @@ $translations = array(
'Table' => 'Πίνακας',
'No tables.' => 'Χωρίς πίνακες.',
'Alter table' => 'Τροποποίηση πίνακα',
'Create table' => 'Δημιουργία πίνακα',
'Create table' => 'Δημιουργία πίνακα',
'Table has been dropped.' => 'Ο πίνακας διαγράφηκε.',
'Tables have been dropped.' => 'Οι πινακες διαγράφηκαν.',
'Tables have been optimized.' => 'Οι πίνακες βελτιστοποιήθηκαν.',

View File

@@ -44,9 +44,9 @@ $translations = array(
'Delete' => 'Eliminar',
'Database' => 'Base de datos',
'Routines' => 'Procedimientos',
'Indexes have been altered.' => 'Indices actualizados.',
'Indexes' => 'Indices',
'Alter indexes' => 'Modificar indices',
'Indexes have been altered.' => 'Índices actualizados.',
'Indexes' => 'Índices',
'Alter indexes' => 'Modificar índices',
'Add next' => 'Agregar',
'Language' => 'Idioma',
'Select' => 'Mostrar',
@@ -77,7 +77,7 @@ $translations = array(
'File uploads are disabled.' => 'Importación de archivos deshablilitada.',
'Routine has been called, %d row(s) affected.' => array('Consulta ejecutada, %d registro afectado.', 'Consulta ejecutada, %d registros afectados.'),
'Call' => 'Llamar',
'No extension' => 'No hay extension',
'No extension' => 'No hay extensión',
'None of the supported PHP extensions (%s) are available.' => 'Ninguna de las extensiones PHP soportadas (%s) está disponible.',
'Session support must be enabled.' => 'Deben estar habilitadas las sesiones.',
'Session expired, please login again.' => 'Sesión caducada, por favor escriba su clave de nuevo.',
@@ -113,7 +113,7 @@ $translations = array(
'Routine has been dropped.' => 'Procedimiento eliminado.',
'Routine has been altered.' => 'Procedimiento modificado.',
'Routine has been created.' => 'Procedimiento creado.',
'Alter function' => 'Modificar Función',
'Alter function' => 'Modificar función',
'Alter procedure' => 'Modificar procedimiento',
'Return type' => 'Tipo de valor de vuelta',
'Add trigger' => 'Agregar disparador',
@@ -127,7 +127,7 @@ $translations = array(
'%s version: %s through PHP extension %s' => 'Versión %s: %s a través de la extensión de PHP %s',
'%d row(s)' => array('%d registro', '%d registros'),
'Remove' => 'Eliminar',
'Are you sure?' => 'Está seguro?',
'Are you sure?' => '¿Está seguro?',
'Privileges' => 'Privilegios',
'Create user' => 'Crear Usuario',
'User has been dropped.' => 'Usuario eliminado.',
@@ -139,7 +139,7 @@ $translations = array(
'Grant' => 'Conceder',
'Revoke' => 'Impedir',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'POST data demasiado grande. Reduzca el tamaño o aumente la directiva de configuración %s.',
'Logged as: %s' => 'Logeado como: %s',
'Logged as: %s' => 'Logueado como: %s',
'Move up' => 'Mover arriba',
'Move down' => 'Mover abajo',
'Functions' => 'Funciones',
@@ -191,7 +191,7 @@ $translations = array(
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Excedida la cantidad máxima de campos permitidos. Por favor aumente %s.',
'Partition by' => 'Particionar por',
'Partitions' => 'Particiones',
'Partition name' => 'Nombre de Partición',
'Partition name' => 'Nombre de partición',
'Values' => 'Valores',
'%d row(s) have been imported.' => array('%d registro importado.', '%d registros importados.'),
'anywhere' => 'donde sea',
@@ -248,16 +248,16 @@ $translations = array(
'System' => 'Motor de base de datos',
'Select data' => 'Visualizar contenido',
'Show structure' => 'Mostrar estructura',
'empty' => 'ningúno',
'empty' => 'ninguno',
'Network' => 'Red',
'Geometry' => 'Geometría',
'File exists.' => 'Ese archivo ya existe.',
'Attachments' => 'Adjuntos',
'%d query(s) executed OK.' => array('%d sentencia sql ejecutada correctamente.', '%d sentencias sql ejecutadas correctamente.'),
'%d query(s) executed OK.' => array('%d sentencia SQL ejecutada correctamente.', '%d sentencias SQL ejecutadas correctamente.'),
'Show only errors' => 'Mostrar solamente errores',
'Refresh' => 'Refrescar',
'Invalid schema.' => 'Esquema inválido.',
'Please use one of the extensions %s.' => 'Por favor use una de las extensiones %s.',
'Please use one of the extensions %s.' => 'Por favor, use una de las extensiones %s.',
'now' => 'ahora',
'ltr' => 'ltr',
'Tables have been copied.' => 'Tablas copiadas.',

View File

@@ -12,7 +12,7 @@ $translations = array(
'Logout successful.' => 'با موفقیت خارج شدید.',
'Invalid credentials.' => 'اعتبار سنجی نامعتبر.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/" target="_blank">پیاده سازی</a> کرده تا آن را دائمی سازید.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را <a href="https://www.adminer.org/en/extension/"%s>پیاده سازی</a> کرده تا آن را دائمی سازید.',
'Language' => 'زبان',
'Invalid CSRF token. Send the form again.' => 'CSRF token نامعتبر است. دوباره سعی کنید.',
'No extension' => 'پسوند نامعتبر',

View File

@@ -12,7 +12,7 @@ $translations = array(
'Logout successful.' => 'Uloskirjautuminen onnistui.',
'Invalid credentials.' => 'Virheelliset kirjautumistiedot.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/" target="_blank">Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. <a href="https://www.adminer.org/en/extension/"%s>Toteuta</a> %s-metodi sen tekemiseksi pysyväksi.',
'Language' => 'Kieli',
'Invalid CSRF token. Send the form again.' => 'Virheellinen CSRF-vastamerkki. Lähetä lomake uudelleen.',
'If you did not send this request from Adminer then close this page.' => 'Jollet lähettänyt tämä pyyntö Adminerista, sulje tämä sivu.',

View File

@@ -274,7 +274,7 @@ $translations = array(
'File must be in UTF-8 encoding.' => 'Les fichiers doivent être encodés en UTF-8.',
'Full table scan' => 'Scan de toute la table',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Trop de connexions échouées, essayez à nouveau dans %d minute.', 'Trop de connexions échouées, essayez à nouveau dans %d minutes.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Le mot de passe a expiré. <a href="https://www.adminer.org/en/extension/" target="_blank">Implémentez</a> la méthode %s afin de le rendre permanent.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Le mot de passe a expiré. <a href="https://www.adminer.org/en/extension/"%s>Implémentez</a> la méthode %s afin de le rendre permanent.',
'You can upload a big SQL file via FTP and import it from server.' => 'Vous pouvez uploader un gros fichier SQL par FTP et ensuite l\'importer depuis le serveur.',
'Size' => 'Taille',
'Compute' => 'Calcul',

View File

@@ -278,7 +278,7 @@ $translations = array(
'Default value' => 'Valor por defecto',
'Full table scan' => 'Escaneo completo da táboa',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Demasiados intentos de conexión, intentao de novo en %d minuto', 'Demasiados intentos de conexión, intentao de novo en %d minutos'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/" target="_blank">Implementa</a> o método %s para facelo permanente.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'O contrasinal principal caducou. <a href="https://www.adminer.org/en/extension/"%s>Implementa</a> o método %s para facelo permanente.',
'If you did not send this request from Adminer then close this page.' => 'Se non enviaches esta petición dende o Adminer entón pecha esta páxina',
'You can upload a big SQL file via FTP and import it from server.' => 'Podes subir un ficheiro SQL de gran tamaño vía FTP e importalo dende o servidor',
'Size' => 'Tamaño',

294
adminer/lang/he.inc.php Normal file
View File

@@ -0,0 +1,294 @@
<?php
$translations = array(
'Login' => 'התחברות',
'Logout successful.' => 'ההתחברות הצליחה',
'Invalid credentials.' => 'פרטי התחברות שגויים',
'Server' => 'שרת',
'Username' => 'שם משתמש',
'Password' => 'סיסמה',
'Select database' => 'בחר מסד נתונים',
'Invalid database.' => 'מסד נתונים שגוי',
'Table has been dropped.' => 'הטבלה הושלכה',
'Table has been altered.' => 'הטבלה שונתה',
'Table has been created.' => 'הטבלה נוצרה',
'Alter table' => 'שנה טבלה',
'Create table' => 'צור טבלה',
'Table name' => 'שם הטבלה',
'engine' => 'מנוע',
'collation' => 'קולקציה',
'Column name' => 'שם עמודה',
'Type' => 'סוג',
'Length' => 'אורך',
'Auto Increment' => 'הגדלה אוטומטית',
'Options' => 'אפשרויות',
'Save' => 'שמור',
'Drop' => 'השלך',
'Database has been created.' => 'מסד הנתונים נוצר',
'Database has been renamed.' => 'שם מסד הנתונים שונה',
'Database has been altered.' => 'מסד הנתונים שונה',
'Alter database' => 'שנה מסד נתונים',
'Create database' => 'צור מסד נתונים',
'SQL command' => 'שאילתת SQL',
'Logout' => 'התנתק',
'database' => 'מסד נתונים',
'Use' => 'השתמש',
'No tables.' => 'אין טבלאות',
'select' => 'בחר',
'Item has been deleted.' => 'הפריט נמחק',
'Item has been updated.' => 'הפריט עודכן',
'Edit' => 'ערוך',
'Insert' => 'הכנס',
'Save and insert next' => 'שמור והמשך להכניס',
'Delete' => 'מחק',
'Database' => 'מסד נתונים',
'Routines' => 'רוטינות',
'Indexes have been altered.' => 'האינדקסים שונו',
'Indexes' => 'אינדקסים',
'Alter indexes' => 'שנה אינדקסים',
'Add next' => 'הוסף הבא',
'Language' => 'שפה',
'Select' => 'בחר',
'New item' => 'פריט חדש',
'Search' => 'חפש',
'Sort' => 'מיין',
'descending' => 'סדר הפוך',
'Limit' => 'הגבל',
'No rows.' => 'אין שורות',
'Action' => 'פעולות',
'edit' => 'ערוך',
'Page' => 'עמוד',
'Query executed OK, %d row(s) affected.' => 'השאילתה בוצעה כהלכה, %d שורות הושפעו',
'Error in query' => 'שגיאה בשאילתה',
'Execute' => 'הרץ',
'Table' => 'טבלה',
'Foreign keys' => 'מפתחות זרים',
'Triggers' => 'מפעילים',
'View' => 'הצג',
'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.' => 'העלאת הקובץ נכשלה',
'File upload' => 'העלה קובץ',
'File uploads are disabled.' => 'העלאת קבצים מבוטלת',
'Routine has been called, %d row(s) affected.' => 'הרוטינה נקראה, %d שורות הושפעו',
'Call' => 'קרא',
'No extension' => 'אין תוסף',
'None of the supported PHP extensions (%s) are available.' => 'שום תוסף PHP (%s) זמין',
'Session support must be enabled.' => 'חובה להפעיל תמיכה בסשן',
'Session expired, please login again.' => 'תם זמן ההפעלה, אנא התחבר שוב',
'Text length' => 'אורך הטקסט',
'Foreign key has been dropped.' => 'המפתח הזר הושלך',
'Foreign key has been altered.' => 'המפתח הזר שונה',
'Foreign key has been created.' => 'המפתח הזר נוצר',
'Foreign key' => 'מפתח זר',
'Target table' => 'טבלת יעד',
'Change' => 'שנה',
'Source' => 'מקור',
'Target' => 'יעד',
'Add column' => 'הוסף עמודה',
'Alter' => 'שנה',
'Add foreign key' => 'הוסף מפתח זר',
'ON DELETE' => 'בעת מחיקה',
'ON UPDATE' => 'בעת עידכון',
'Index Type' => 'סוג אינדקס',
'Column (length)' => 'עמודה (אורך)',
'View has been dropped.' => 'התצוגה הושלכה',
'View has been altered.' => 'התצוגה שונתה',
'View has been created.' => 'התצוגה נוצרה',
'Alter view' => 'שנה תצוגה',
'Create view' => 'צור תצוגה',
'Name' => 'שם',
'Process list' => 'רשימת תהליכים',
'%d process(es) have been killed.' => '%d תהליכים חוסלו',
'Kill' => 'חסל',
'Parameter name' => 'שם הפרמטר',
'Database schema' => 'סכמת מסד נתונים',
'Create procedure' => 'צור פרוצדורה',
'Create function' => 'צור פונקציה',
'Routine has been dropped.' => 'הרוטינה הושלכה',
'Routine has been altered.' => 'הרוטינה שונתה',
'Routine has been created.' => 'הרוטינה נוצרה',
'Alter function' => 'שנה פונקציה',
'Alter procedure' => 'שנה פרוצדורה',
'Return type' => 'סוג ערך מוחזר',
'Add trigger' => 'הוסף טריגר',
'Trigger has been dropped.' => 'הטריגר הושלך',
'Trigger has been altered.' => 'הטריגר שונה',
'Trigger has been created.' => 'הטריגר נוצר',
'Alter trigger' => 'שנה טריגר',
'Create trigger' => 'צור טריגר',
'Time' => 'זמן',
'Event' => 'אירוע',
'%d row(s)' => '%d שורות',
'Remove' => 'הסר',
'Are you sure?' => 'האם אתה בטוח?',
'Privileges' => 'פריווילגיות',
'Create user' => 'צור משתמש',
'User has been dropped.' => 'המשתמש הושלך',
'User has been altered.' => 'המשתמש שונה',
'User has been created.' => 'המשתמש נוצר',
'Hashed' => 'הצפנה',
'Column' => 'עמודה',
'Routine' => 'רוטינה',
'Grant' => 'הענק',
'Revoke' => 'שלול',
'%s version: %s through PHP extension %s' => '%s גרסה: %s דרך תוסף PHP %s',
'Logged as: %s' => 'מחובר כ: %s',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'מידע גדול מידי נשלח ב-POST. הקטן את את המידע הוא הגדלת את הגדרות ה-%s',
'Move up' => 'הזז למעלה',
'Move down' => 'הזז למטה',
'Export' => 'יצא',
'Tables' => 'טבלאות',
'Data' => 'נתונים',
'Output' => 'פלט',
'open' => 'פתח',
'save' => 'שמור',
'Format' => 'פורמט',
'Functions' => 'פונקציות',
'Aggregation' => 'צבירה',
'Event has been dropped.' => 'האירוע הושלך',
'Event has been altered.' => 'האירוע שונה',
'Event has been created.' => 'האירוע נוצר',
'Alter event' => 'שנה אירוע',
'Create event' => 'צור אירוע',
'Start' => 'התחלה',
'End' => 'סיום',
'Every' => 'כל',
'Status' => 'סטטוס',
'On completion preserve' => 'בעת סיום שמור',
'Events' => 'אירועים',
'Schedule' => 'תזמן',
'At given time' => 'לפי זמן נתון',
'Save and continue edit' => 'שמור והמשך לערוך',
'original' => 'מקורי',
'Tables have been truncated.' => 'הטבלה קוצרה',
'Tables have been moved.' => 'הטבלה הועברה',
'Tables have been dropped.' => 'הטבלה הושלכה',
'Tables and views' => 'טבלאות ותצוגות',
'Engine' => 'מנוע',
'Collation' => 'קולקציה',
'Data Length' => 'אורך נתונים',
'Index Length' => 'אורך אינדקס',
'Data Free' => 'נתונים משוחררים',
'Rows' => 'שורות',
',' => ',',
'0123456789' => '0123456789',
'Analyze' => 'נתח',
'Optimize' => 'יעל',
'Check' => 'בדוק',
'Repair' => 'תקן',
'Truncate' => 'קצר',
'Move to other database' => 'העבר למסד נתונים אחר',
'Move' => 'העבר',
'%d item(s) have been affected.' => '%d פריטים הושפעו',
'whole result' => 'כל התוצאות',
'Clone' => 'שכפל',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'הגעת למספר השדות המרבי. בבקשה הגדל את %s',
'Partition by' => 'מחיצות ע"י',
'Partitions' => 'מחיצות',
'Partition name' => 'שם מחיצה',
'Values' => 'ערכים',
'%d row(s) have been imported.' => '%d שורות יובאו',
'anywhere' => 'בכל מקום',
'Import' => 'יבא',
'Stop on error' => 'עצור בעת שגיאה',
'%.3f s' => '%.3f s',
'$1-$3-$5' => '$1-$3-$5',
'[yyyy]-mm-dd' => '[yyyy]-mm-dd',
'History' => 'היסטוריה',
'Variables' => 'משתנים',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'על עמודות המקור והיעד להיות מאותו טיפוס נתונים, חובה שיהיה אינדקס בעמודת היעד ושהמידע המתאים יהיה קיים',
'Relations' => 'הקשרים',
'Run file' => 'הרץ קובץ',
'Clear' => 'נקה',
'Maximum allowed file size is %sB.' => 'גודל מקסימלאי להעלאה: %sB',
'Numbers' => 'מספרים',
'Date and time' => 'תאריך ושעה',
'Strings' => 'מחרוזות',
'Binary' => 'בינארי',
'Lists' => 'רשימות',
'Editor' => 'עורך',
'E-mail' => 'דוא"ל',
'From' => 'מ:',
'Subject' => 'נושא',
'Send' => 'שלח',
'%d e-mail(s) have been sent.' => '%d הודעות דוא"ל נשלחו',
'Webserver file %s' => 'קובץ השרת %s',
'File does not exist.' => 'הקובץ אינו קיים',
'%d in total' => '%d בסך הכל',
'Permanent login' => 'התחבר לצמיתות',
'Databases have been dropped.' => 'מסד הנתונים הושלך',
'Database has been dropped.' => 'מסד הנתונים הושלך',
'Search data in tables' => 'חפש מידע בטבלאות',
'Schema' => 'סכמה',
'Alter schema' => 'שנה סכמה',
'Create schema' => 'צור סכמה',
'Schema has been dropped.' => 'הסכמה הושלכה',
'Schema has been created.' => 'הסכמה נוצרה',
'Schema has been altered.' => 'הסכמה שונתה',
'Sequences' => 'סדרות',
'Create sequence' => 'צור סדרה',
'Alter sequence' => 'שנה סדרה',
'Sequence has been dropped.' => 'הסדרה הושלכה',
'Sequence has been created.' => 'הסדרה נוצרה',
'Sequence has been altered.' => 'הסדרה שונתה',
'User types' => 'סוגי משתמשים',
'Create type' => 'צור סוג',
'Alter type' => 'שנה סוג',
'Type has been dropped.' => 'הסוג הושלך',
'Type has been created.' => 'הסוג נוצר',
'Use edit link to modify this value.' => 'השתמש בקישור העריכה בשביל לשנות את הערך',
'last' => 'אחרון',
'From server' => 'משרת',
'System' => 'מערכת',
'Select data' => 'בחר נתונים',
'Show structure' => 'הראה מבנה',
'empty' => 'ריק',
'Network' => 'רשת',
'Geometry' => 'גיאומטריה',
'File exists.' => 'קובץ קיים',
'Attachments' => 'קבצים מצורפים',
'Item%s has been inserted.' => 'הפריט %s הוזן בהצלחה',
'now' => 'כעת',
'%d query(s) executed OK.' => '%d שאילתות בוצעו בהצלחה',
'Show only errors' => 'הראה שגיאות בלבד',
'Refresh' => 'רענן',
'Invalid schema.' => 'סכמה שגויה',
'Please use one of the extensions %s.' => 'בבקשה השתמש באחד מהתוספים %s',
'ltr' => 'rtl',
'Tables have been copied.' => 'הטבלה הועתקה',
'Copy' => 'העתק',
'Permanent link' => 'קישור סופי',
'Edit all' => 'ערוך הכל',
'HH:MM:SS' => 'HH:MM:SS',
'Tables have been optimized.' => 'הטבלאות עברו אופטימיזציה',
'Materialized view' => 'תצוגת מימוש ',
'Vacuum' => 'וואקום',
'Selected' => 'נבחרים',
'Ctrl+click on a value to modify it.' => 'לחץ ctrl + לחיצת עכבר לערוך ערך זה',
'File must be in UTF-8 encoding.' => 'על הקובץ להיות בקידוד utf-8',
'Modify' => 'ערוך',
'Loading' => 'טוען',
'Load more data' => 'טען נתונים נוספים',
'ATTACH queries are not supported.' => 'שאילתת ATTACH אינה נתמכת',
'%d / ' => '%d / ',
'Limit rows' => 'הגבל שורות',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>התקן</a> את תוסף SQLite בשביל להתחבר',
'Default value' => 'ערך ברירת מחדל',
'Full table scan' => 'סריקה טבלה מלאה',
'Too many unsuccessful logins, try again in %d minute(s).' => 'יותר מידי נסיונות כניסה נכשלו, אנא נסה עוד %d דקות',
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'תודה שהשתמש ב-adminer אנא שקול <a href="%s">לתרום</a>.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'סיסמת המאסטר פגה <a href="https://www.adminer.org/en/extension/"%s>התקן תוסף</a> על מנת להפוך את זה לתמידי',
'If you did not send this request from Adminer then close this page.' => 'אם לא אתה שלחת בקשה ל-Adminer הינך יכול לסגור חלון זה',
'You can upload a big SQL file via FTP and import it from server.' => 'ניתן לעלות קבצים ב-FTP ואז למשוך אותם מהשרת',
'Size' => 'גודל',
'Compute' => 'חישוב',
'You are offline.' => 'הינך לא מקוון',
'You have no privileges to update this table.' => 'אין לך ההרשאות המתאימות לעדכן טבלה זו',
'Saving' => 'שומר',
'yes' => 'כן',
'no' => 'לא',
);

341
adminer/lang/ms.inc.php Normal file
View File

@@ -0,0 +1,341 @@
<?php
$translations = array(
// label for database system selection (MySQL, SQLite, ...)
'System' => 'Sistem',
'Server' => 'Pelayan',
'Username' => 'Nama pengguna',
'Password' => 'Kata laluan',
'Permanent login' => 'Log masuk kekal',
'Login' => 'Log masuk',
'Logout' => 'Log keluar',
'Logged as: %s' => 'Log masuk sebagai: %s',
'Logout successful.' => 'Log keluar berjaya.',
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Terima kasih kerana menggunakan Adminer, pertimbangkan untuk <a href="%s">menderma</a>.',
'Invalid credentials.' => 'Akses tidak sah.',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk menggunakan SQLite.',
'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Kata laluan utama telah luput. <a href="https://www.adminer.org/en/extension/"%s>Gunakan</a> cara %s untuk mengekalkannya.',
'Language' => 'Bahasa',
'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Sila hantar borang sekali lagi.',
'If you did not send this request from Adminer then close this page.' => 'Jika anda tidak menghantar permintaan ini dari Adminer sila tutup halaman ini.',
'No extension' => 'Tiada sambungan',
'None of the supported PHP extensions (%s) are available.' => 'Sambungan PHP yang (%s) disokong tidak wujud.',
'Connecting to privileged ports is not allowed.' => 'Penyambungan ke port yang istimewa tidak dibenarkan.',
'Session support must be enabled.' => 'Sokongan sesi perlu diaktifkan.',
'Session expired, please login again.' => 'Sesi telah luput, sila log masuk kembali.',
'%s version: %s through PHP extension %s' => 'Versi %s: %s melalui sambungan PHP %s',
'Refresh' => 'Segar kembali',
// text direction - 'ltr' or 'rtl'
'ltr' => 'ltr',
'Privileges' => 'Keistimewaan',
'Create user' => 'Bina pengguna',
'User has been dropped.' => 'Pengguna telah dijatuhkan.',
'User has been altered.' => 'Pengguna telah diubah.',
'User has been created.' => 'Pengguna telah dibuat.',
'Hashed' => 'Hashed',
'Column' => 'Kolum',
'Routine' => 'Rutin',
'Grant' => 'Beri',
'Revoke' => 'Batal',
'Process list' => 'Senarai proses',
'%d process(es) have been killed.' => '%d proses telah dihentikan.',
'Kill' => 'Henti',
'Variables' => 'Pembolehubah',
'Status' => 'Status',
'SQL command' => 'Arahan SQL',
'%d query(s) executed OK.' => '%d query berjaya dilaksanakan.',
'Query executed OK, %d row(s) affected.' => 'Query berjaya dilaksanakan, %d baris terjejas.',
'No commands to execute.' => 'Tiada arahan untuk dilaksanakan.',
'Error in query' => 'Ralat pada query',
'ATTACH queries are not supported.' => 'Query berikut tidak disokong.',
'Execute' => 'Laksana',
'Stop on error' => 'Berhenti jika ralat',
'Show only errors' => 'Paparkan jika ralat',
// sprintf() format for time of the command
'%.3f s' => '%.3f s',
'History' => 'Sejarah',
'Clear' => 'Bersih',
'Edit all' => 'Ubah semua',
'File upload' => 'Muat naik fail',
'From server' => 'Dari pelayan',
'Webserver file %s' => 'Fail pelayan sesawang %s',
'Run file' => 'Jalankan fail',
'File does not exist.' => 'Fail tidak wujud.',
'File uploads are disabled.' => 'Muat naik fail dihalang.',
'Unable to upload a file.' => 'Muat naik fail gagal.',
'Maximum allowed file size is %sB.' => 'Saiz fail maksimum yang dibenarkan adalah %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Data POST terlalu besar. Kecilkan data atau tingkatkan tetapan %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Anda boleh muat naik fail SQL yang besar melalui FTP dan import melalui pelayan.',
'You are offline.' => 'Anda sedang offline.',
'Export' => 'Eksport',
'Output' => 'Pengeluaran',
'open' => 'buka',
'save' => 'simpan',
'Saving' => 'Menyimpan',
'Format' => 'Format',
'Data' => 'Data',
'Database' => 'Pangkalan data',
'database' => 'pangkalan data',
'Use' => 'Guna',
'Select database' => 'Pilih pangkalan data',
'Invalid database.' => 'Pangkalan data tidak sah.',
'Database has been dropped.' => 'Pangkalan data telah dijatuhkan.',
'Databases have been dropped.' => 'Pangkalan data telah dijatuhkan.',
'Database has been created.' => 'Pangkalan data telah dibuat.',
'Database has been renamed.' => 'Pangkalan data telah ditukar nama.',
'Database has been altered.' => 'Pangkalan data telah diubah.',
'Alter database' => 'Ubah pangkalan data',
'Create database' => 'Bina pangkalan data',
'Database schema' => 'Skema pangkalan data',
// link to current database schema layout
'Permanent link' => 'Pautan kekal',
// thousands separator - must contain single byte
',' => ',',
'0123456789' => '0123456789',
'Engine' => 'Enjin',
'Collation' => 'Collation',
'Data Length' => 'Panjang Data',
'Index Length' => 'Panjang Indeks',
'Data Free' => 'Data Free',
'Rows' => 'Baris',
'%d in total' => '%d secara keseluruhan',
'Analyze' => 'Menganalisis',
'Optimize' => 'Mengoptimum',
'Vacuum' => 'Vacuum',
'Check' => 'Periksa',
'Repair' => 'Baiki',
'Truncate' => 'Memangkas',
'Tables have been truncated.' => 'Jadual telah dimangkaskan.',
'Move to other database' => 'Pindahkan ke pangkalan data yang lain',
'Move' => 'Pindah',
'Tables have been moved.' => 'Jadual telah dipindahkan.',
'Copy' => 'Salin',
'Tables have been copied.' => 'Jadual telah disalin.',
'Routines' => 'Rutin',
'Routine has been called, %d row(s) affected.' => 'Rutin telah dipanggil, %d baris terjejas.',
'Call' => 'Panggil',
'Parameter name' => 'Nama pembolehubah',
'Create procedure' => 'Bina prosedur',
'Create function' => 'Bina fungsi',
'Routine has been dropped.' => 'Rutin telah dijatuhkan.',
'Routine has been altered.' => 'Rutin telah diubah.',
'Routine has been created.' => 'Rutin telah dibuat.',
'Alter function' => 'Ubah fungsi',
'Alter procedure' => 'Ubah prosedur',
'Return type' => 'Jenis Return',
'Events' => 'Peristiwa',
'Event has been dropped.' => 'Peristiwa telah dijatuhkan.',
'Event has been altered.' => 'Peristiwa telah diubah.',
'Event has been created.' => 'Peristiwa telah dibuat.',
'Alter event' => 'Ubah peristiwa',
'Create event' => 'Bina peristiwa',
'At given time' => 'Pada masa tersebut',
'Every' => 'Setiap',
'Schedule' => 'Jadual',
'Start' => 'Mula',
'End' => 'Habis',
'On completion preserve' => 'Dalam melestarikan penyelesaian',
'Tables' => 'Jadual',
'Tables and views' => 'Jadual dan pandangan',
'Table' => 'Jadual',
'No tables.' => 'Tiada jadual.',
'Alter table' => 'Ubah jadual',
'Create table' => 'Bina jadual',
'Table has been dropped.' => 'Jadual telah dijatuhkan.',
'Tables have been dropped.' => 'Jadual telah dijatuhkan.',
'Tables have been optimized.' => 'Jadual telah dioptimumkan.',
'Table has been altered.' => 'Jadual telah diubah.',
'Table has been created.' => 'Jadual telah dibuat.',
'Table name' => 'Nama jadual',
'Show structure' => 'Paparkan struktur',
'engine' => 'enjin',
'collation' => 'collation',
'Column name' => 'Nama kolum',
'Type' => 'Jenis',
'Length' => 'Kepanjangan',
'Auto Increment' => 'Kenaikan Auto',
'Options' => 'Pilihan',
'Comment' => 'Komen',
'Default value' => 'Nilai lalai',
'Default values' => 'Nilai lalai',
'Drop' => 'Jatuh',
'Drop %s?' => 'Jatuhkan %s?',
'Are you sure?' => 'Anda pasti?',
'Size' => 'Saiz',
'Compute' => 'Kira',
'Move up' => 'Gerak ke atas',
'Move down' => 'Gerak ke bawah',
'Remove' => 'Buang',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Bilangan medan telah melebihi had yang dibenarkan. Sila tingkatkan %s.',
'Partition by' => 'Partition mengikut',
'Partitions' => 'Partition',
'Partition name' => 'Nama partition',
'Values' => 'Nilai',
'View' => 'Papar',
'Materialized view' => 'Paparan yang menjadi kenyataan',
'View has been dropped.' => 'Paparan telah dijatuhkan.',
'View has been altered.' => 'Paparan telah diubah.',
'View has been created.' => 'Paparan telah dibuat.',
'Alter view' => 'Ubah paparan',
'Create view' => 'Bina paparan',
'Indexes' => 'Indeks',
'Indexes have been altered.' => 'Indeks telah diubah.',
'Alter indexes' => 'Ubah indeks',
'Add next' => 'Tambah yang seterusnya',
'Index Type' => 'Jenis Indeks',
'Column (length)' => 'Kolum (kepanjangan)',
'Foreign keys' => 'Kunci asing',
'Foreign key' => 'Kunci asing',
'Foreign key has been dropped.' => 'Kunci asing telah dijatuhkan.',
'Foreign key has been altered.' => 'Kunci asing telah diubah.',
'Foreign key has been created.' => 'Kunci asing telah dibuat.',
'Target table' => 'Jadual sasaran',
'Change' => 'Tukar',
'Source' => 'Sumber',
'Target' => 'Sasaran',
'Add column' => 'Tambah kolum',
'Alter' => 'Ubah',
'Add foreign key' => 'Tambah kunci asing',
'ON DELETE' => 'ON DELETE',
'ON UPDATE' => 'ON UPDATE',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Kolum sumber dan sasaran perlu mempunyai jenis data yang sama, indeks diperlukan pada kolum sasaran dan data yang dirujuk wujud.',
'Triggers' => ' Pencetus',
'Add trigger' => 'Tambah pencetus',
'Trigger has been dropped.' => 'Pencetus telah dijatuhkan.',
'Trigger has been altered.' => 'Pencetus telah diubah.',
'Trigger has been created.' => 'Pencetus telah dibuat.',
'Alter trigger' => 'Ubah pencetus',
'Create trigger' => 'Buat pencetus',
'Time' => 'Masa',
'Event' => 'Peristiwa',
'Name' => 'Nama',
'select' => 'pilih',
'Select' => 'Pilih',
'Select data' => 'Pilih data',
'Functions' => 'Fungsi',
'Aggregation' => 'Pengagregatan',
'Search' => 'Cari',
'anywhere' => 'di mana-mana',
'Search data in tables' => 'Cari data dalam jadual',
'Sort' => 'Susun',
'descending' => 'menurun',
'Limit' => 'Had',
'Limit rows' => 'Had baris',
'Text length' => 'Kepanjangan teks',
'Action' => 'Aksi',
'Full table scan' => 'Imbasan penuh jadual',
'Unable to select the table' => 'Pemilihan jadual tidak berjaya',
'No rows.' => 'Tiada baris.',
'%d / ' => '%d / ',
'%d row(s)' => '%d baris',
'Page' => 'Halaman',
'last' => 'akhir',
'Load more data' => 'Load lebih data',
'Loading' => 'Loading',
'whole result' => 'keputusan keseluruhan',
'%d byte(s)' => array('%d byte', '%d bytes'),
'Import' => 'Import',
'%d row(s) have been imported.' => '%d baris telah diimport.',
'File must be in UTF-8 encoding.' => 'Fail mesti dalam pengekodan UTF-8.',
// in-place editing in select
'Modify' => 'Pinda',
'Ctrl+click on a value to modify it.' => 'Ctrl+click pada nilai untuk meminda.',
'Use edit link to modify this value.' => 'Guna pautan ubah untuk meminda nilai ini.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Item%s telah dimasukkan.',
'Item has been deleted.' => 'Item telah dipadamkan.',
'Item has been updated.' => 'Item telah dikemaskini.',
'%d item(s) have been affected.' => '%d item telah terjejas.',
'New item' => 'Item baru',
'original' => 'asli',
// label for value '' in enum data type
'empty' => 'kosong',
'edit' => 'ubah',
'Edit' => 'Ubah',
'Insert' => 'Masukkan',
'Save' => 'Simpan',
'Save and continue edit' => 'Simpan dan sambung ubah',
'Save and insert next' => 'Simpan dan masukkan seterusnya',
'Selected' => 'Terpilih',
'Clone' => 'Klon',
'Delete' => 'Padam',
'You have no privileges to update this table.' => 'Anda tidak mempunyai keistimewaan untuk mengemaskini jadual ini.',
'E-mail' => 'Emel',
'From' => 'Dari',
'Subject' => 'Subjek',
'Attachments' => 'Lampiran',
'Send' => 'Hantar',
'%d e-mail(s) have been sent.' => '%d emel telah dihantar.',
// data type descriptions
'Numbers' => 'Nombor',
'Date and time' => 'Tarikh dan masa',
'Strings' => 'String',
'Binary' => 'Binari',
'Lists' => 'Senarai',
'Network' => 'Rangkaian',
'Geometry' => 'Geometri',
'Relations' => 'Hubungan',
'Editor' => 'Editor',
// date format in Editor: $1 yyyy, $2 yy, $3 mm, $4 m, $5 dd, $6 d
'$1-$3-$5' => '$1-$3-$5',
// hint for date format - use language equivalents for day, month and year shortcuts
'[yyyy]-mm-dd' => '[yyyy]-mm-dd',
// hint for time format - use language equivalents for hour, minute and second shortcuts
'HH:MM:SS' => 'HH:MM:SS',
'now' => 'sekarang',
'yes' => 'ya',
'no' => 'tidak',
// general SQLite error in create, drop or rename database
'File exists.' => 'Fail wujud.',
'Please use one of the extensions %s.' => 'Sila guna salah satu sambungan %s.',
// PostgreSQL and MS SQL schema support
'Alter schema' => 'Ubah skema',
'Create schema' => 'Buat skema',
'Schema has been dropped.' => 'Skema telah dijatuhkan.',
'Schema has been created.' => 'Skema telah dibuat.',
'Schema has been altered.' => 'Skema telah diubah.',
'Schema' => 'Skema',
'Invalid schema.' => 'Skema tidak sah.',
// PostgreSQL sequences support
'Sequences' => 'Turutan',
'Create sequence' => 'Buat turutan',
'Sequence has been dropped.' => 'Turutan telah dijatuhkan.',
'Sequence has been created.' => 'Turutan telah dibuat.',
'Sequence has been altered.' => 'Turutan telah diubah.',
'Alter sequence' => 'Ubah turutan',
// PostgreSQL user types support
'User types' => 'Jenis pengguna',
'Create type' => 'Buat jenis',
'Type has been dropped.' => 'Jenis telah dijatuhkan.',
'Type has been created.' => 'Jenis telah dibuat.',
'Alter type' => 'Ubah jenis',
);

View File

@@ -10,7 +10,7 @@ $translations = array(
'Logged as: %s' => 'Logget inn som: %s',
'Logout successful.' => 'Utlogging vellykket.',
'Invalid credentials.' => 'Ugylding innloggingsinformasjon.',
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/" target="_blank">Implementer</a> en metode for %s for å gjøre det permanent.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Master-passord er utløpt. <a href="https://www.adminer.org/en/extension/"%s>Implementer</a> en metode for %s for å gjøre det permanent.',
'Language' => 'Språk',
'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.',
'No extension' => 'Ingen utvidelse',

View File

@@ -10,14 +10,17 @@ $translations = array(
'Logout' => 'Wyloguj',
'Logged as: %s' => 'Zalogowany jako: %s',
'Logout successful.' => 'Wylogowano pomyślnie.',
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Dziękujemy za używanie Adminera, rozważ proszę <a href="%s">dotację</a>.',
'Invalid credentials.' => 'Nieprawidłowe dane logowania.',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> metodę %s aby użyć SQLite.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/" target="_blank">Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Ważność hasła głównego wygasła. <a href="https://www.adminer.org/pl/extension/"%s>Zaimplementuj</a> własną metodę %s, aby ustawić je na stałe.',
'Language' => 'Język',
'Invalid CSRF token. Send the form again.' => 'Nieprawidłowy token CSRF. Spróbuj wysłać formularz ponownie.',
'If you did not send this request from Adminer then close this page.' => 'Jeżeli nie wywołałeś tej strony z Adminera, zamknij to okno.',
'No extension' => 'Brak rozszerzenia',
'None of the supported PHP extensions (%s) are available.' => 'Żadne z rozszerzeń PHP umożliwiających połączenie się z bazą danych (%s) nie jest dostępne.',
'Connecting to privileged ports is not allowed.' => 'Łączenie do portów uprzywilejowanych jest niedozwolone.',
'Session support must be enabled.' => 'Wymagana jest obsługa sesji w PHP.',
'Session expired, please login again.' => 'Sesja wygasła, zaloguj się ponownie.',
'%s version: %s through PHP extension %s' => 'Wersja %s: %s za pomocą %s',
@@ -49,6 +52,7 @@ $translations = array(
'Query executed OK, %d row(s) affected.' => array('Zapytanie wykonane pomyślnie, zmieniono %d rekord.', 'Zapytanie wykonane pomyślnie, zmieniono %d rekordy.', 'Zapytanie wykonane pomyślnie, zmieniono %d rekordów.'),
'No commands to execute.' => 'Nic do wykonania.',
'Error in query' => 'Błąd w zapytaniu',
'ATTACH queries are not supported.' => 'Zapytania ATTACH są niewspierane.',
'Execute' => 'Wykonaj',
'Stop on error' => 'Zatrzymaj w przypadku błędu',
'Show only errors' => 'Pokaż tylko błędy',
@@ -167,6 +171,7 @@ $translations = array(
'Default value' => 'Wartość domyślna',
'Default values' => 'Wartości domyślne',
'Drop' => 'Usuń',
'Drop %s?' => 'Usunąć %s?',
'Are you sure?' => 'Czy jesteś pewien?',
'Size' => 'Wielkość',
'Compute' => 'Oblicz',
@@ -233,11 +238,13 @@ $translations = array(
'Sort' => 'Sortuj',
'descending' => 'malejąco',
'Limit' => 'Limit',
'Limit rows' => 'Limit rekordów',
'Text length' => 'Długość tekstu',
'Action' => 'Czynność',
'Full table scan' => 'Wymaga pełnego przeskanowania tabeli',
'Unable to select the table' => 'Nie udało się pobrać danych z tabeli',
'No rows.' => 'Brak rekordów.',
'%d / ' => '%d / ',
'%d row(s)' => array('%d rekord', '%d rekordy', '%d rekordów'),
'Page' => 'Strona',
'last' => 'ostatni',

View File

@@ -7,14 +7,14 @@ $translations = array(
'Username' => 'Имя пользователя',
'Password' => 'Пароль',
'Select database' => 'Выбрать базу данных',
'Invalid database.' => 'Плохая база данных.',
'Invalid database.' => 'Неверная база данных.',
'Table has been dropped.' => 'Таблица была удалена.',
'Table has been altered.' => 'Таблица была изменена.',
'Table has been created.' => 'Таблица была создана.',
'Alter table' => 'Изменить таблицу',
'Create table' => 'Создать таблицу',
'Table name' => 'Название таблицы',
'engine' => 'тип',
'engine' => 'Тип таблицы',
'collation' => 'режим сопоставления',
'Column name' => 'Название поля',
'Type' => 'Тип',
@@ -29,7 +29,7 @@ $translations = array(
'Database has been altered.' => 'База данных была изменена.',
'Alter database' => 'Изменить базу данных',
'Create database' => 'Создать базу данных',
'SQL command' => 'SQL запрос',
'SQL command' => 'SQL-запрос',
'Logout' => 'Выйти',
'database' => 'база данных',
'Use' => 'Выбрать',
@@ -67,7 +67,7 @@ $translations = array(
'Triggers' => 'Триггеры',
'View' => 'Представление',
'Unable to select the table' => 'Не удалось получить данные из таблицы',
'Invalid CSRF token. Send the form again.' => 'Недействительный CSRF токен. Отправите форму ещё раз.',
'Invalid CSRF token. Send the form again.' => 'Недействительный CSRF-токен. Отправите форму ещё раз.',
'Comment' => 'Комментарий',
'Default values' => 'Значения по умолчанию',
'%d byte(s)' => array('%d байт', '%d байта', '%d байтов'),
@@ -90,13 +90,13 @@ $translations = array(
'Change' => 'Изменить',
'Source' => 'Источник',
'Target' => 'Цель',
'Add column' => 'Добавить колонку',
'Add column' => 'Добавить поле',
'Alter' => 'Изменить',
'Add foreign key' => 'Добавить внешний ключ',
'ON DELETE' => 'При стирании',
'ON UPDATE' => 'При обновлении',
'Index Type' => 'Тип индекса',
'Column (length)' => 'Колонка (длина)',
'Column (length)' => 'Поле (длина)',
'View has been dropped.' => 'Представление было удалено.',
'View has been altered.' => 'Представление было изменено.',
'View has been created.' => 'Представление было создано.',
@@ -134,11 +134,11 @@ $translations = array(
'User has been altered.' => 'Пользователь был изменён.',
'User has been created.' => 'Пользователь был создан.',
'Hashed' => 'Хешировано',
'Column' => 'Колонка',
'Column' => 'поле',
'Routine' => 'Процедура',
'Grant' => 'Позволить',
'Revoke' => 'Запретить',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Слишком большой объем POST-данных. Пошлите меньший объем данных или увеличьте параметр конфигурационной директивы %s.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Слишком большой объем POST-данных. Пошлите меньший объём данных или увеличьте параметр конфигурационной директивы %s.',
'Logged as: %s' => 'Вы вошли как: %s',
'Move up' => 'Переместить вверх',
'Move down' => 'Переместить вниз',
@@ -181,7 +181,7 @@ $translations = array(
'Tables have been moved.' => 'Таблицы были перемещены.',
'Move to other database' => 'Переместить в другую базу данных',
'Move' => 'Переместить',
'Engine' => 'Тип',
'Engine' => 'Тип таблиц',
'Save and continue edit' => 'Сохранить и продолжить редактирование',
'original' => 'исходный',
'%d item(s) have been affected.' => array('Была изменена %d запись.', 'Были изменены %d записи.', 'Было изменено %d записей.'),
@@ -202,20 +202,20 @@ $translations = array(
'[yyyy]-mm-dd' => 'дд.мм.[гггг]',
'History' => 'История',
'Variables' => 'Переменные',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Колонки должны иметь одинаковые типы данных, в результирующей колонке должен быть индекс, данные для импорта должны существовать.',
'Relations' => 'Реляции',
'Source and target columns must have the same data type, there must be an index on the target columns and referenced data must exist.' => 'Поля должны иметь одинаковые типы данных, в результирующем поле должен быть индекс, данные для импорта должны существовать.',
'Relations' => 'Отношения',
'Run file' => 'Запустить файл',
'Clear' => 'Очистить',
'Maximum allowed file size is %sB.' => 'Максимальный разрешённый размер файла - %sB.',
'Numbers' => 'Число',
'Maximum allowed file size is %sB.' => 'Максимальный разрешённый размер файла %sB.',
'Numbers' => 'Числа',
'Date and time' => 'Дата и время',
'Strings' => 'Строки',
'Binary' => 'Двоичный тип',
'Lists' => 'Списки',
'Editor' => 'Редактор',
'E-mail' => 'Электропочта',
'E-mail' => 'Эл. почта',
'From' => 'От',
'Subject' => 'Кому',
'Subject' => 'Тема',
'Send' => 'Послать',
'%d e-mail(s) have been sent.' => array('Было отправлено %d письмо.', 'Было отправлено %d письма.', 'Было отправлено %d писем.'),
'Webserver file %s' => 'Файл %s на вебсервере',
@@ -241,7 +241,7 @@ $translations = array(
'Alter type' => 'Изменить тип',
'Type has been dropped.' => 'Тип удален.',
'Type has been created.' => 'Создан новый тип.',
'Ctrl+click on a value to modify it.' => 'Ctrl+кликни по значению, чтобы его изменить.',
'Ctrl+click on a value to modify it.' => 'Выполните Ctrl+Щелчок мышью по значению, чтобы его изменить.',
'Use edit link to modify this value.' => 'Изменить это значение можно с помощью ссылки «изменить».',
'last' => 'последняя',
'From server' => 'С сервера',
@@ -265,4 +265,29 @@ $translations = array(
'Permanent link' => 'Постоянная ссылка',
'Edit all' => 'Редактировать всё',
'HH:MM:SS' => 'ЧЧ:ММ:СС',
'Tables have been optimized.' => 'Таблицы оптимизированы.',
'Materialized view' => 'Материализованное представление',
'Vacuum' => 'Вакуум',
'Selected' => 'Выбранные',
'File must be in UTF-8 encoding.' => 'Файл должен быть в кодировке UTF-8.',
'Modify' => 'Изменить',
'Loading' => 'Загрузка',
'Load more data' => 'Загрузить ещё данные',
'ATTACH queries are not supported.' => 'ATTACH-запросы не поддерживаются.',
'%d / ' => '%d / ',
'Limit rows' => 'Лимит строк',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Реализуйте</a> метод %s, чтобы использовать SQLite.',
'Default value' => 'Значение по умолчанию',
'Full table scan' => 'Анализ полной таблицы',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Слишком много неудачных попыток входа. Попробуйте снова через %d минуту.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минуты.', 'Слишком много неудачных попыток входа. Попробуйте снова через %d минут.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Мастер-пароль истёк. <a href="https://www.adminer.org/en/extension/"%s>Реализуйте</a> метод %s, чтобы сделать его постоянным.',
'If you did not send this request from Adminer then close this page.' => 'Если вы не посылали этот запрос из Adminer, закройте эту страницу.',
'You can upload a big SQL file via FTP and import it from server.' => 'Вы можете закачать большой SQL-файл по FTP и затем импортировать его с сервера.',
'Size' => 'Размер',
'Compute' => 'Вычислить',
'You are offline.' => 'Вы не выполнили вход.',
'You have no privileges to update this table.' => 'У вас нет прав на обновление этой таблицы.',
'Saving' => 'Сохранение',
'yes' => 'Да',
'no' => 'Нет',
);

View File

@@ -231,8 +231,8 @@ $translations = array(
'%d row(s)' => array('%d ред', '%d реда', '%d редова'),
'Page' => 'Страна',
'last' => 'последња',
'Loading' => 'Учитавам',
'Load more data' => 'Учитавам још података',
'Loading' => 'Учитавам',
'Load more data' => 'Учитавам још података',
'whole result' => 'цео резултат',
'%d byte(s)' => array('%d бајт', '%d бајта', '%d бајтова'),

View File

@@ -12,7 +12,7 @@ $translations = array(
'Logout successful.' => 'Đã thoát xong.',
'Invalid credentials.' => 'Tài khoản sai.',
'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.',
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/" target="_blank">Thử cách làm</a> để giữ cố định.',
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => 'Mật khẩu đã hết hạn. <a href="https://www.adminer.org/en/extension/"%s>Thử cách làm</a> để giữ cố định.',
'Language' => 'Ngôn ngữ',
'Invalid CSRF token. Send the form again.' => 'Mã kiểm tra CSRF sai, hãy nhập lại biểu mẫu.',
'No extension' => 'Không có phần mở rộng',

View File

@@ -8,20 +8,22 @@ $translations = array(
'Permanent login' => 'Xx',
'Login' => 'Xx',
'Logout' => 'Xx',
'Logged as: %s' => 'Xx',
'Logged as: %s' => 'Xx: %s',
'Logout successful.' => 'Xx.',
'Thanks for using Adminer, consider <a href="%s">donating</a>.' => 'Xx <a href="%s">xx</a>.',
'Invalid credentials.' => 'Xx.',
'<a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to use SQLite.' => 'Xx.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx.', 'Xx.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.' => 'Xx.',
'<a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to use SQLite.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
'Too many unsuccessful logins, try again in %d minute(s).' => array('Xx %d.', 'Xx %d.'),
'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' => '<a href="https://www.adminer.org/en/extension/"%s>Xx</a> %s xx.',
'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 extension' => 'Xx',
'None of the supported PHP extensions (%s) are available.' => 'Xx.',
'None of the supported PHP extensions (%s) are available.' => 'Xx (%s).',
'Connecting to privileged ports is not allowed.' => 'Xx.',
'Session support must be enabled.' => 'Xx.',
'Session expired, please login again.' => 'Xx.',
'%s version: %s through PHP extension %s' => 'Xx',
'%s version: %s through PHP extension %s' => '%s xx: %s xx %s',
'Refresh' => 'Xx',
// text direction - 'ltr' or 'rtl'
@@ -39,40 +41,37 @@ $translations = array(
'Revoke' => 'Xx',
'Process list' => 'Xx',
'%d process(es) have been killed.' => array('Xx.', 'Xx.'),
'%d process(es) have been killed.' => array('%d xx.', '%d xx.'),
'Kill' => 'Xx',
'Variables' => 'Xx',
'Status' => 'Xx',
'Replication' => 'Xx',
'Master status' => 'Xx',
'Slave status' => 'Xx',
'SQL command' => 'Xx',
'%d query(s) executed OK.' => array('Xx.', 'Xx.'),
'Query executed OK, %d row(s) affected.' => array('Xx.', 'Xx.'),
'%d query(s) executed OK.' => array('%d xx.', '%d xx.'),
'Query executed OK, %d row(s) affected.' => array('Xx, %d.', 'Xx, %d.'),
'No commands to execute.' => 'Xx.',
'Error in query' => 'Xx',
'Warnings' => 'Xx',
'ATTACH queries are not supported.' => 'Xx.',
'Execute' => 'Xx',
'Stop on error' => 'Xx',
'Show only errors' => 'Xx',
// sprintf() format for time of the command
'%.3f s' => 'xx',
'%.3f s' => '%.3f xx',
'History' => 'Xx',
'Clear' => 'Xx',
'Edit all' => 'Xx',
'File upload' => 'Xx',
'From server' => 'Xx',
'Webserver file %s' => 'Xx',
'Webserver file %s' => 'Xx %s',
'Run file' => 'Xx',
'File does not exist.' => 'Xx.',
'File uploads are disabled.' => 'Xx.',
'Unable to upload a file.' => 'Xx.',
'Maximum allowed file size is %sB.' => 'Xx.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Xx.',
'Maximum allowed file size is %sB.' => 'Xx %sB.',
'Too big POST data. Reduce the data or increase the %s configuration directive.' => 'Xx %s.',
'You can upload a big SQL file via FTP and import it from server.' => 'Xx.',
'You are offline.' => 'Xx.',
@@ -86,6 +85,7 @@ $translations = array(
'Database' => 'Xx',
'database' => 'xx',
'DB' => 'XX',
'Use' => 'Xx',
'Select database' => 'Xx',
'Invalid database.' => 'Xx.',
@@ -110,7 +110,7 @@ $translations = array(
'Index Length' => 'Xx',
'Data Free' => 'Xx',
'Rows' => 'Xx',
'%d in total' => 'xx',
'%d in total' => '%d xx',
'Analyze' => 'Xx',
'Optimize' => 'Xx',
'Vacuum' => 'Xx',
@@ -125,7 +125,7 @@ $translations = array(
'Tables have been copied.' => 'Xx.',
'Routines' => 'Xx',
'Routine has been called, %d row(s) affected.' => array('Xx.', 'Xx.'),
'Routine has been called, %d row(s) affected.' => array('Xx, %d.', 'Xx, %d.'),
'Call' => 'Xx',
'Parameter name' => 'Xx',
'Create procedure' => 'Xx',
@@ -174,13 +174,14 @@ $translations = array(
'Default value' => 'Xx',
'Default values' => 'Xx',
'Drop' => 'Xx',
'Are you sure?' => 'Xx',
'Drop %s?' => 'Xx %s?',
'Are you sure?' => 'Xx?',
'Size' => 'Xx',
'Compute' => 'Xx',
'Move up' => 'Xx',
'Move down' => 'Xx',
'Remove' => 'Xx',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Xx.',
'Maximum number of allowed fields exceeded. Please increase %s.' => 'Xx %s.',
'Partition by' => 'Xx',
'Partitions' => 'Xx',
@@ -246,17 +247,17 @@ $translations = array(
'Full table scan' => 'Xx',
'Unable to select the table' => 'Xx',
'No rows.' => 'Xx.',
'%d / ' => 'xx',
'%d row(s)' => array('xx', 'xx'),
'%d / ' => '%d / ',
'%d row(s)' => array('%d xx', '%d xx'),
'Page' => 'Xx',
'last' => 'xx',
'Load more data' => 'Xx',
'Loading' => 'Xx',
'whole result' => 'xx',
'%d byte(s)' => array('xx', 'xx'),
'%d byte(s)' => array('%d xx', '%d xx'),
'Import' => 'Xx',
'%d row(s) have been imported.' => array('Xx.', 'Xx.'),
'%d row(s) have been imported.' => array('%d xx.', '%d xx.'),
'File must be in UTF-8 encoding.' => 'Xx.',
// in-place editing in select
@@ -265,10 +266,10 @@ $translations = array(
'Use edit link to modify this value.' => 'Xx.',
// %s can contain auto-increment value
'Item%s has been inserted.' => 'Xx.',
'Item%s has been inserted.' => 'Xx%s.',
'Item has been deleted.' => 'Xx.',
'Item has been updated.' => 'Xx.',
'%d item(s) have been affected.' => array('Xx.', 'Xx.'),
'%d item(s) have been affected.' => array('%d xx.', '%d xx.'),
'New item' => 'Xx',
'original' => 'xx',
// label for value '' in enum data type
@@ -289,7 +290,7 @@ $translations = array(
'Subject' => 'Xx',
'Attachments' => 'Xx',
'Send' => 'Xx',
'%d e-mail(s) have been sent.' => array('Xx.', 'Xx.'),
'%d e-mail(s) have been sent.' => array('%d xx.', '%d xx.'),
// data type descriptions
'Numbers' => 'Xx',
@@ -314,7 +315,7 @@ $translations = array(
// general SQLite error in create, drop or rename database
'File exists.' => 'Xx.',
'Please use one of the extensions %s.' => 'Xx.',
'Please use one of the extensions %s.' => 'Xx %s.',
// PostgreSQL and MS SQL schema support
'Alter schema' => 'Xx',

View File

@@ -17,7 +17,7 @@ function adminer_object() {
new AdminerDumpXml,
new AdminerDumpAlter,
//~ new AdminerSqlLog("past-" . rtrim(`git describe --tags --abbrev=0`) . ".sql"),
//~ new AdminerEditCalendar("<script type='text/javascript' src='../externals/jquery-ui/jquery-1.4.4.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.core.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.widget.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.datepicker.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.mouse.js'></script>\n<script type='text/javascript' src='../externals/jquery-ui/ui/jquery.ui.slider.js'></script>\n<script type='text/javascript' src='../externals/jquery-timepicker/jquery-ui-timepicker-addon.js'></script>\n<link rel='stylesheet' href='../externals/jquery-ui/themes/base/jquery.ui.all.css'>\n<style type='text/css'>\n.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }\n.ui-timepicker-div dl { text-align: left; }\n.ui-timepicker-div dl dt { height: 25px; }\n.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }\n.ui-timepicker-div td { font-size: 90%; }\n</style>\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"),
//~ new AdminerEditCalendar(script_src("../externals/jquery-ui/jquery-1.4.4.js") . script_src("../externals/jquery-ui/ui/jquery.ui.core.js") . script_src("../externals/jquery-ui/ui/jquery.ui.widget.js") . script_src("../externals/jquery-ui/ui/jquery.ui.datepicker.js") . script_src("../externals/jquery-ui/ui/jquery.ui.mouse.js") . script_src("../externals/jquery-ui/ui/jquery.ui.slider.js") . script_src("../externals/jquery-timepicker/jquery-ui-timepicker-addon.js") . "<link rel='stylesheet' href='../externals/jquery-ui/themes/base/jquery.ui.all.css'>\n<style>\n.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }\n.ui-timepicker-div dl { text-align: left; }\n.ui-timepicker-div dl dt { height: 25px; }\n.ui-timepicker-div dl dd { margin: -25px 0 10px 65px; }\n.ui-timepicker-div td { font-size: 90%; }\n</style>\n", "../externals/jquery-ui/ui/i18n/jquery.ui.datepicker-%s.js"),
//~ new AdminerTinymce("../externals/tinymce/jscripts/tiny_mce/tiny_mce_dev.js"),
//~ new AdminerWymeditor(array("../externals/wymeditor/src/jquery/jquery.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.explorer.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.mozilla.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.opera.js", "../externals/wymeditor/src/wymeditor/jquery.wymeditor.safari.js")),
new AdminerFileUpload(""),

View File

@@ -1,17 +1,18 @@
<?php
$PROCEDURE = $_GET["procedure"];
$PROCEDURE = ($_GET["name"] ? $_GET["name"] : $_GET["procedure"]);
$routine = (isset($_GET["function"]) ? "FUNCTION" : "PROCEDURE");
$row = $_POST;
$row["fields"] = (array) $row["fields"];
if ($_POST && !process_fields($row["fields"]) && !$error) {
$orig = routine($_GET["procedure"], $routine);
$temp_name = "$row[name]_adminer_" . uniqid();
drop_create(
"DROP $routine " . idf_escape($PROCEDURE),
"DROP $routine " . routine_id($PROCEDURE, $orig),
create_routine($routine, $row),
"DROP $routine " . idf_escape($row["name"]),
"DROP $routine " . routine_id($row["name"], $row),
create_routine($routine, array("name" => $temp_name) + $row),
"DROP $routine " . idf_escape($temp_name),
"DROP $routine " . routine_id($temp_name, $row),
substr(ME, 0, -1),
lang('Routine has been dropped.'),
lang('Routine has been altered.'),
@@ -24,7 +25,7 @@ if ($_POST && !process_fields($row["fields"]) && !$error) {
page_header(($PROCEDURE != "" ? (isset($_GET["function"]) ? lang('Alter function') : lang('Alter procedure')) . ": " . h($PROCEDURE) : (isset($_GET["function"]) ? lang('Create function') : lang('Create procedure'))), $error);
if (!$_POST && $PROCEDURE != "") {
$row = routine($PROCEDURE, $routine);
$row = routine($_GET["procedure"], $routine);
$row["name"] = $PROCEDURE;
}
@@ -35,20 +36,20 @@ $routine_languages = routine_languages();
<form action="" method="post" id="form">
<p><?php echo lang('Name'); ?>: <input name="name" value="<?php echo h($row["name"]); ?>" maxlength="64" autocapitalize="off">
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) : ""); ?>
<?php echo ($routine_languages ? lang('Language') . ": " . html_select("language", $routine_languages, $row["language"]) . "\n" : ""); ?>
<input type="submit" value="<?php echo lang('Save'); ?>">
<table cellspacing="0" class="nowrap">
<?php
edit_fields($row["fields"], $collations, $routine);
if (isset($_GET["function"])) {
echo "<tr><td>" . lang('Return type');
edit_type("returns", $row["returns"], $collations);
edit_type("returns", $row["returns"], $collations, array(), ($jush == "pgsql" ? array("void", "trigger") : array()));
}
?>
</table>
<p><?php textarea("definition", $row["definition"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($PROCEDURE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($PROCEDURE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $PROCEDURE)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -13,8 +13,9 @@ page_header(lang('Process list'), $error);
?>
<form action="" method="post">
<table cellspacing="0" onclick="tableClick(event);" ondblclick="tableClick(event, true);" class="nowrap checkable">
<table cellspacing="0" class="nowrap checkable">
<?php
echo script("mixin(qsl('table'), {onclick: tableClick, ondblclick: partialArg(tableClick, true)});");
// HTML valid because there is always at least one process
$i = -1;
foreach (process_list() as $i => $row) {
@@ -44,7 +45,7 @@ foreach (process_list() as $i => $row) {
}
?>
</table>
<script type='text/javascript'>tableCheck();</script>
<?php echo script("tableCheck();"); ?>
<p>
<?php
if (support("kill")) {

View File

@@ -1,30 +0,0 @@
<?php
page_header(lang('Replication'));
echo "<h3>" . lang('Master status') . doc_link(array("sql" => "show-master-status.html")) . "</h3>\n";
$master_replication_status = replication_status("MASTER");
if (!$master_replication_status) {
echo "<p class='message'>" . lang('No rows.') . "\n";
} else {
echo "<table cellspacing='0'>\n";
foreach ($master_replication_status[0] as $key => $val) {
echo "<tr>";
echo "<th>" . h($key);
echo "<td>" . nbsp($val);
}
echo "</table>\n";
}
$slave_replication_status = replication_status("SLAVE");
if ($slave_replication_status) {
echo "<h3>" . lang('Slave status') . doc_link(array("sql" => "show-slave-status.html")) . "</h3>\n";
foreach ($slave_replication_status[0] as $slave) {
echo "<table cellspacing='0'>\n";
foreach ($slave as $key => $val) {
echo "<tr>";
echo "<th>" . h($key);
echo "<td>" . nbsp($val);
}
echo "</table>\n";
}
}

View File

@@ -48,19 +48,19 @@ foreach (table_status('', true) as $table => $table_status) {
}
?>
<div id="schema" style="height: <?php echo $top; ?>em;" onselectstart="return false;">
<script type="text/javascript">
<div id="schema" style="height: <?php echo $top; ?>em;">
<script<?php echo nonce(); ?>>
qs('#schema').onselectstart = function () { return false; };
var tablePos = {<?php echo implode(",", $table_pos_js) . "\n"; ?>};
var em = document.getElementById('schema').offsetHeight / <?php echo $top; ?>;
var em = qs('#schema').offsetHeight / <?php echo $top; ?>;
document.onmousemove = schemaMousemove;
document.onmouseup = function (ev) {
schemaMouseup(ev, '<?php echo js_escape(DB); ?>');
};
document.onmouseup = partialArg(schemaMouseup, '<?php echo js_escape(DB); ?>');
</script>
<?php
foreach ($schema as $name => $table) {
echo "<div class='table' style='top: " . $table["pos"][0] . "em; left: " . $table["pos"][1] . "em;' onmousedown='schemaMousedown(this, event);'>";
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>';

View File

@@ -27,11 +27,11 @@ if (!$row) {
<form action="" method="post">
<p><input name="name" id="name" value="<?php echo h($row["name"]); ?>" autocapitalize="off">
<script type='text/javascript'>focus(document.getElementById('name'));</script>
<?php echo script("focus(qs('#name'));"); ?>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php
if ($_GET["ns"] != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . ">\n";
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', $_GET["ns"])) . "\n";
}
?>
<input type="hidden" name="token" value="<?php echo $token; ?>">

View File

@@ -34,6 +34,12 @@ if ($_GET["script"] == "db") {
} elseif ($_GET["script"] == "kill") {
$connection->query("KILL " . number($_POST["kill"]));
} elseif ($_GET["script"] == "version") {
$fp = file_open_lock(get_temp_dir() . "/adminer.version");
if ($fp) {
file_write_unlock($fp, serialize(array("signature" => $_POST["signature"], "version" => $_POST["version"])));
}
} else { // connect
foreach (count_tables($adminer->databases()) as $db => $val) {
json_row("tables-$db", $val);

View File

@@ -4,11 +4,7 @@ $table_status = table_status1($TABLE);
$indexes = indexes($TABLE);
$fields = fields($TABLE);
$foreign_keys = column_foreign_keys($TABLE);
$oid = "";
if ($table_status["Oid"]) {
$oid = ($jush == "sqlite" ? "rowid" : "oid");
$indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
}
$oid = $table_status["Oid"];
parse_str($_COOKIE["adminer_import"], $adminer_import);
$rights = array(); // privilege => 0
@@ -30,10 +26,6 @@ $is_group = count($group) < count($select);
$where = $adminer->selectSearchProcess($fields, $indexes);
$order = $adminer->selectOrderProcess($fields, $indexes);
$limit = $adminer->selectLimitProcess();
$from = ($select ? implode(", ", $select) : "*" . ($oid ? ", $oid" : ""))
. convert_fields($columns, $fields, $select)
. "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if ($_GET["val"] && is_ajax()) {
header("Content-Type: text/plain; charset=utf-8");
@@ -49,6 +41,24 @@ if ($_GET["val"] && is_ajax()) {
exit;
}
$primary = $unselected = null;
foreach ($indexes as $index) {
if ($index["type"] == "PRIMARY") {
$primary = array_flip($index["columns"]);
$unselected = ($select ? $primary : array());
foreach ($unselected as $key => $val) {
if (in_array(idf_escape($key), $select)) {
unset($unselected[$key]);
}
}
break;
}
}
if ($oid && $unselected === null) {
$primary = $unselected = array($oid => 0);
$indexes[] = array("type" => "PRIMARY", "columns" => array($oid));
}
if ($_POST && !$error) {
$where_check = $where;
if (!$_POST["all"] && is_array($_POST["check"])) {
@@ -59,24 +69,14 @@ if ($_POST && !$error) {
$where_check[] = "((" . implode(") OR (", $checks) . "))";
}
$where_check = ($where_check ? "\nWHERE " . implode(" AND ", $where_check) : "");
$primary = $unselected = null;
foreach ($indexes as $index) {
if ($index["type"] == "PRIMARY") {
$primary = array_flip($index["columns"]);
$unselected = ($select ? $primary : array());
break;
}
}
foreach ((array) $unselected as $key => $val) {
if (in_array(idf_escape($key), $select)) {
unset($unselected[$key]);
}
}
if ($_POST["export"]) {
cookie("adminer_import", "output=" . urlencode($_POST["output"]) . "&format=" . urlencode($_POST["format"]));
dump_headers($TABLE);
$adminer->dumpTable($TABLE, "");
$from = ($select ? implode(", ", $select) : "*")
. convert_fields($columns, $fields, $select)
. "\nFROM " . table($TABLE);
$group_by = ($group && $is_group ? "\nGROUP BY " . implode(", ", $group) : "") . ($order ? "\nORDER BY " . implode(", ", $order) : "");
if (!is_array($_POST["check"]) || $unselected === array()) {
$query = "SELECT $from$where_check$group_by";
} else {
@@ -124,8 +124,8 @@ if ($_POST && !$error) {
$result = ($_POST["delete"]
? $driver->delete($TABLE, $where2, 1)
: ($_POST["clone"]
? queries("INSERT" . limit1($query, $where2))
: $driver->update($TABLE, $set, $where2)
? queries("INSERT" . limit1($TABLE, $query, $where2))
: $driver->update($TABLE, $set, $where2, 1)
)
);
if (!$result) {
@@ -226,7 +226,7 @@ $set = null;
if (isset($rights["insert"]) || !support("table")) {
$set = "";
foreach ((array) $_GET["where"] as $val) {
if (count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "="
if ($foreign_keys[$val["col"]] && count($foreign_keys[$val["col"]]) == 1 && ($val["op"] == "="
|| (!$val["op"] && !preg_match('~[_%]~', $val["val"])) // LIKE in Editor
)) {
$set .= "&set" . urlencode("[" . bracket_escape($val["col"]) . "]") . "=" . urlencode($val["val"]);
@@ -259,17 +259,29 @@ if (!$columns && support("table")) {
}
$select2 = $select;
$group2 = $group;
if (!$select2) {
$select2[] = "*";
if ($oid) {
$select2[] = $oid;
$convert_fields = convert_fields($columns, $fields, $select);
if ($convert_fields) {
$select2[] = substr($convert_fields, 2);
}
}
$convert_fields = convert_fields($columns, $fields, $select);
if ($convert_fields) {
$select2[] = substr($convert_fields, 2);
foreach ($select as $key => $val) {
$field = $fields[idf_unescape($val)];
if ($field && ($as = convert_field($field))) {
$select2[$key] = "$as AS $val";
}
}
$result = $driver->select($TABLE, $select2, $where, $group, $order, $limit, $page, true);
if (!$is_group && $unselected) {
foreach ($unselected as $key => $val) {
$select2[] = idf_escape($key);
if ($group2) {
$group2[] = idf_escape($key);
}
}
}
$result = $driver->select($TABLE, $select2, $where, $group2, $order, $limit, $page, true);
if (!$result) {
echo "<p class='error'>" . error() . "\n";
@@ -288,7 +300,7 @@ if (!$columns && support("table")) {
}
// use count($rows) without LIMIT, COUNT(*) without grouping, FOUND_ROWS otherwise (slowest)
if ($_GET["page"] != "last" && +$limit && $group && $is_group && $jush == "sql") {
if ($_GET["page"] != "last" && $limit != "" && $group && $is_group && $jush == "sql") {
$found_rows = $connection->result(" SELECT FOUND_ROWS()"); // space to allow mysql.trace_mode
}
@@ -297,14 +309,18 @@ if (!$columns && support("table")) {
} else {
$backward_keys = $adminer->backwardKeys($TABLE, $table_name);
echo "<table id='table' cellspacing='0' class='nowrap checkable' onclick='tableClick(event);' ondblclick='tableClick(event, true);' onkeydown='return editingKeydown(event);'>\n";
echo "<thead><tr>" . (!$group && $select ? "" : "<td><input type='checkbox' id='all-page' onclick='formCheck(this, /check/);' class='jsonly'> <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('Modify') . "</a>");
echo "<table id='table' cellspacing='0' class='nowrap checkable'>";
echo script("mixin(qs('#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/);", "")
. " <a href='" . h($_GET["modify"] ? remove_from_uri("modify") : $_SERVER["REQUEST_URI"] . "&modify=1") . "'>" . lang('Modify') . "</a>");
$names = array();
$functions = array();
reset($select);
$rank = 1;
foreach ($rows[0] as $key => $val) {
if ($key != $oid) {
if (!isset($unselected[$key])) {
$val = $_GET["columns"][key($select)];
$field = $fields[$select ? ($val ? $val["col"] : current($select)) : $key];
$name = ($field ? $adminer->fieldName($field, $rank) : ($val["fun"] ? "*" : $key));
@@ -314,13 +330,14 @@ if (!$columns && support("table")) {
$column = idf_escape($key);
$href = remove_from_uri('(order|desc)[^=]*|page') . '&order%5B0%5D=' . urlencode($key);
$desc = "&desc%5B0%5D=1";
echo '<th onmouseover="columnMouse(this);" onmouseout="columnMouse(this, \' hidden\');">';
echo "<th>" . script("mixin(qsl('th'), {onmouseover: partial(columnMouse), onmouseout: partial(columnMouse, ' hidden')});", "");
echo '<a href="' . h($href . ($order[0] == $column || $order[0] == $key || (!$order && $is_group && $group[0] == $column) ? $desc : '')) . '">'; // $order[0] == $key - COUNT(*)
echo apply_sql_function($val["fun"], $name) . "</a>"; //! columns looking like functions
echo "<span class='column hidden'>";
echo "<a href='" . h($href . $desc) . "' title='" . lang('descending') . "' class='text'> ↓</a>";
if (!$val["fun"]) {
echo '<a href="#fieldset-search" onclick="selectSearch(\'' . h(js_escape($key)) . '\'); return false;" 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>";
}
@@ -359,9 +376,9 @@ if (!$columns && support("table")) {
}
$unique_idf = "";
foreach ($unique_array as $key => $val) {
if (($jush == "sql" || $jush == "pgsql") && strlen($val) > 64) {
if (($jush == "sql" || $jush == "pgsql") && preg_match('~char|text|enum|set~', $fields[$key]["type"]) && strlen($val) > 64) {
$key = (strpos($key, '(') ? $key : idf_escape($key)); //! columns looking like functions
$key = "MD5(" . ($jush == 'sql' && preg_match("~^utf8_~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")";
$key = "MD5(" . ($jush != 'sql' || preg_match("~^utf8~", $fields[$key]["collation"]) ? $key : "CONVERT($key USING " . charset($connection) . ")") . ")";
$val = md5($val);
}
$unique_idf .= "&" . ($val !== null ? urlencode("where[" . bracket_escape($key) . "]") . "=" . urlencode($val) : "null%5B%5D=" . urlencode($key));
@@ -419,7 +436,8 @@ if (!$columns && support("table")) {
echo "<td>" . ($text ? "<textarea name='$id' cols='30' rows='" . (substr_count($row[$key], "\n") + 1) . "'>$h_value</textarea>" : "<input name='$id' value='$h_value' size='$lengths[$key]'>");
} else {
$long = strpos($val, "<i>...</i>");
echo "<td id='$id' onclick=\"selectClick(this, event, " . ($long ? 2 : ($text ? 1 : 0)) . ($editable ? "" : ", '" . h(lang('Use edit link to modify this value.')) . "'") . ");\">$val";
echo "<td id='$id'>$val</td>";
echo script("qsl('td').onclick = partialArg(selectClick, " . ($long ? 2 : ($text ? 1 : 0)) . ($editable ? "" : ", '" . h(lang('Use edit link to modify this value.')) . "'") . ");", "");
}
}
}
@@ -440,8 +458,8 @@ if (!$columns && support("table")) {
if (($rows || $page) && !is_ajax()) {
$exact_count = true;
if ($_GET["page"] != "last") {
if (!+$limit) {
$found_rows = count($rows);
if ($limit == "" || (count($rows) < $limit && ($rows || !$page))) {
$found_rows = ($page ? $page * $limit : 0) + count($rows);
} elseif ($jush != "sql" || !$is_group) {
$found_rows = ($is_group ? false : found_rows($table_status, $where));
if ($found_rows < max(1e4, 2 * ($page + 1) * $limit)) {
@@ -453,7 +471,7 @@ if (!$columns && support("table")) {
}
}
if (+$limit && ($found_rows === false || $found_rows > $limit || $page)) {
if ($limit != "" && ($found_rows === false || $found_rows > $limit || $page)) {
echo "<p class='pages'>";
// display first, previous 4, next 4 and last page
$max_page = ($found_rows === false
@@ -461,7 +479,8 @@ if (!$columns && support("table")) {
: floor(($found_rows - 1) / $limit)
);
if ($jush != "simpledb") {
echo '<a href="' . h(remove_from_uri("page")) . "\" onclick=\"pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "'), event); return false;\">" . lang('Page') . "</a>:";
echo '<a href="' . h(remove_from_uri("page")) . '">' . lang('Page') . "</a>:";
echo script("qsl('a').onclick = function () { pageClick(this.href, +prompt('" . lang('Page') . "', '" . ($page + 1) . "')); return false; };");
echo pagination(0, $page) . ($page > 5 ? " ..." : "");
for ($i = max(1, $page - 4); $i < min($max_page, $page + 5); $i++) {
echo pagination($i, $page);
@@ -474,7 +493,8 @@ if (!$columns && support("table")) {
);
}
echo (($found_rows === false ? count($rows) + 1 : $found_rows - $page * $limit) > $limit
? ' <a href="' . h(remove_from_uri("page") . "&page=" . ($page + 1)) . '" onclick="return !selectLoadMore(this, ' . (+$limit) . ', \'' . lang('Loading') . '...\');" class="loadmore">' . lang('Load more data') . '</a>'
? ' <a href="' . h(remove_from_uri("page") . "&page=" . ($page + 1)) . '" class="loadmore">' . lang('Load more data') . '</a>'
. script("qsl('a').onclick = partial(selectLoadMore, " . (+$limit) . ", '" . lang('Loading') . "...');", "")
: ''
);
} else {
@@ -498,7 +518,7 @@ if (!$columns && support("table")) {
<fieldset><legend><?php echo lang('Selected'); ?> <span id="selected"></span></legend><div>
<input type="submit" name="edit" value="<?php echo lang('Edit'); ?>">
<input type="submit" name="clone" value="<?php echo lang('Clone'); ?>">
<input type="submit" name="delete" value="<?php echo lang('Delete'); ?>"<?php echo confirm(); ?>>
<input type="submit" name="delete" value="<?php echo lang('Delete'); ?>"><?php echo confirm(); ?>
</div></fieldset>
<?php
}
@@ -519,7 +539,6 @@ if (!$columns && support("table")) {
echo "</div></fieldset>\n";
}
echo (!$group && $select ? "" : "<script type='text/javascript'>tableCheck();</script>\n");
}
if ($adminer->selectImportPrint()) {
@@ -534,6 +553,7 @@ if (!$columns && support("table")) {
echo "<p><input type='hidden' name='token' value='$token'></p>\n";
echo "</form>\n";
echo (!$group && $select ? "" : script("tableCheck();"));
}
}

View File

@@ -28,7 +28,7 @@ if (!$row) {
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php
if ($SEQUENCE != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . ">\n";
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', $SEQUENCE)) . "\n";
}
?>
<input type="hidden" name="token" value="<?php echo $token; ?>">

View File

@@ -21,9 +21,10 @@ if (!$error && $_POST) {
if (!isset($_GET["import"])) {
$query = $_POST["query"];
} elseif ($_POST["webfile"]) {
$fp = @fopen((file_exists("adminer.sql")
? "adminer.sql"
: "compress.zlib://adminer.sql.gz"
$sql_file_path = $adminer->importServerPath();
$fp = @fopen((file_exists($sql_file_path)
? $sql_file_path
: "compress.zlib://$sql_file_path.gz"
), "rb");
$query = ($fp ? fread($fp, 1e6) : false);
} else {
@@ -116,9 +117,6 @@ if (!$error && $_POST) {
do {
$result = $connection->store_result();
$time = " <span class='time'>(" . format_time($start) . ")</span>"
. (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters
;
if ($connection->error) {
echo ($_POST["only_errors"] ? $print : "");
@@ -128,41 +126,54 @@ if (!$error && $_POST) {
break 2;
}
} elseif (is_object($result)) {
$limit = $_POST["limit"];
$orgtables = select($result, $connection2, array(), $limit);
if (!$_POST["only_errors"]) {
echo "<form action='' method='post'>\n";
$num_rows = $result->num_rows;
echo "<p>" . ($num_rows ? ($limit && $num_rows > $limit ? lang('%d / ', $limit) : "") . lang('%d row(s)', $num_rows) : "");
echo $time;
$id = "export-$commands";
$export = ", <a href='#$id' onclick=\"return !toggle('$id');\">" . lang('Export') . "</a><span id='$id' class='hidden'>: "
. html_select("output", $adminer->dumpOutput(), $adminer_export["output"]) . " "
. html_select("format", $dump_format, $adminer_export["format"])
. "<input type='hidden' name='query' value='" . h($q) . "'>"
. " <input type='submit' name='export' value='" . lang('Export') . "'><input type='hidden' name='token' value='$token'></span>\n"
;
if ($connection2 && preg_match("~^($space|\\()*+SELECT\\b~i", $q) && ($explain = explain($connection2, $q))) {
$id = "explain-$commands";
echo ", <a href='#$id' onclick=\"return !toggle('$id');\">EXPLAIN</a>$export";
echo "<div id='$id' class='hidden'>\n";
select($explain, $connection2, $orgtables);
echo "</div>\n";
} else {
echo $export;
}
echo "</form>\n";
}
} else {
if (preg_match("~^$space*+(CREATE|DROP|ALTER)$space++(DATABASE|SCHEMA)\\b~i", $q)) {
restart_session();
set_session("dbs", null); // clear cache
stop_session();
$time = " <span class='time'>(" . format_time($start) . ")</span>"
. (strlen($q) < 1000 ? " <a href='" . h(ME) . "sql=" . urlencode(trim($q)) . "'>" . lang('Edit') . "</a>" : "") // 1000 - maximum length of encoded URL in IE is 2083 characters
;
$affected = $connection->affected_rows; // getting warnigns overwrites this
$warnings = ($_POST["only_errors"] ? "" : $driver->warnings());
$warnings_id = "warnings-$commands";
if ($warnings) {
$time .= ", <a href='#$warnings_id'>" . lang('Warnings') . "</a>" . script("qsl('a').onclick = partial(toggle, '$warnings_id');", "");
}
if (!$_POST["only_errors"]) {
echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $connection->affected_rows) . "$time\n";
$explain = null;
$explain_id = "explain-$commands";
if (is_object($result)) {
$limit = $_POST["limit"];
$orgtables = select($result, $connection2, array(), $limit);
if (!$_POST["only_errors"]) {
echo "<form action='' method='post'>\n";
$num_rows = $result->num_rows;
echo "<p>" . ($num_rows ? ($limit && $num_rows > $limit ? lang('%d / ', $limit) : "") . lang('%d row(s)', $num_rows) : "");
echo $time;
if ($connection2 && preg_match("~^($space|\\()*+SELECT\\b~i", $q) && ($explain = explain($connection2, $q))) {
echo ", <a href='#$explain_id'>Explain</a>" . script("qsl('a').onclick = partial(toggle, '$explain_id');", "");
}
$id = "export-$commands";
echo ", <a href='#$id'>" . lang('Export') . "</a>" . script("qsl('a').onclick = partial(toggle, '$id');", "") . "<span id='$id' class='hidden'>: "
. html_select("output", $adminer->dumpOutput(), $adminer_export["output"]) . " "
. html_select("format", $dump_format, $adminer_export["format"])
. "<input type='hidden' name='query' value='" . h($q) . "'>"
. " <input type='submit' name='export' value='" . lang('Export') . "'><input type='hidden' name='token' value='$token'></span>\n"
. "</form>\n"
;
}
} else {
if (preg_match("~^$space*+(CREATE|DROP|ALTER)$space++(DATABASE|SCHEMA)\\b~i", $q)) {
restart_session();
set_session("dbs", null); // clear cache
stop_session();
}
if (!$_POST["only_errors"]) {
echo "<p class='message' title='" . h($connection->info) . "'>" . lang('Query executed OK, %d row(s) affected.', $affected) . "$time\n";
}
}
echo ($warnings ? "<div id='$warnings_id' class='hidden'>\n$warnings</div>\n" : "");
if ($explain) {
echo "<div id='$explain_id' class='hidden'>\n";
select($explain, $connection2, $orgtables);
echo "</div>\n";
}
}
@@ -208,7 +219,7 @@ if (!isset($_GET["import"])) {
}
echo "<p>";
textarea("query", $q, 20);
echo ($_POST ? "" : "<script type='text/javascript'>focus(document.getElementsByTagName('textarea')[0]);</script>\n");
echo ($_POST ? "" : script("qs('textarea').focus();"));
echo "<p>$execute\n";
echo lang('Limit rows') . ": <input type='number' name='limit' class='size' value='" . h($_POST ? $_POST["limit"] : $_GET["limit"]) . "'>\n";
@@ -220,7 +231,7 @@ if (!isset($_GET["import"])) {
);
echo "</div></fieldset>\n";
echo "<fieldset><legend>" . lang('From server') . "</legend><div>";
echo lang('Webserver file %s', "<code>adminer.sql" . (extension_loaded("zlib") ? "[.gz]" : "") . "</code>");
echo lang('Webserver file %s', "<code>" . h($adminer->importServerPath()) . (extension_loaded("zlib") ? "[.gz]" : "") . "</code>");
echo ' <input type="submit" name="webfile" value="' . lang('Run file') . '">';
echo "</div></fieldset>\n";
echo "<p>";

View File

@@ -2,7 +2,7 @@
function adminer_object() {
include_once "../plugins/plugin.php";
include_once "../plugins/login-sqlite.php";
return new AdminerPlugin(array(new AdminerLoginSqlite));
return new AdminerPlugin(array(new AdminerLoginSqlite("admin", password_hash("", PASSWORD_DEFAULT))));
}
include "./index.php";

View File

@@ -10,8 +10,8 @@ h2 { font-size: 150%; margin: 0 0 20px -18px; padding: .8em 1em; border-bottom:
h3 { font-weight: normal; font-size: 130%; margin: 1em 0 0; }
form { margin: 0; }
td table { width: 100%; margin: 0; }
table { margin: 1em 20px 0 0; border: 0; border-top: 1px solid #999; border-left: 1px solid #999; font-size: 90%; }
td, th { border: 0; border-right: 1px solid #999; border-bottom: 1px solid #999; padding: .2em .3em; }
table { margin: 1em 20px 0 0; border-collapse: collapse; font-size: 90%; }
td, th { border: 1px solid #999; padding: .2em .3em; }
th { background: #eee; text-align: left; }
thead th { text-align: center; padding: .2em .5em; }
thead td, thead th { background: #ddf; }
@@ -32,11 +32,12 @@ input.wayoff { left: -1000px; position: absolute; }
.version { color: #777; font-size: 67%; }
.js .hidden, .nojs .jsonly { display: none; }
.js .column { position: absolute; background: #ddf; padding: .27em 1ex .3em 0; margin-top: -.27em; }
.nowrap td, .nowrap th, td.nowrap { white-space: pre; }
.nowrap td, .nowrap th, td.nowrap, p.nowrap { white-space: pre; }
.wrap td { white-space: normal; }
.error { color: red; background: #fee; }
.error b { background: #fff; font-weight: normal; }
.message { color: green; background: #efe; }
.message table { color: #000; background: #fff; }
.error, .message { padding: .5em .8em; margin: 1em 20px 0 0; }
.char { color: #007F00; }
.date { color: #7F007F; }

View File

@@ -5,7 +5,7 @@
*/
function bodyLoad(version) {
if (window.jush) {
jush.create_links = ' target="_blank" rel="noreferrer"';
jush.create_links = ' target="_blank" rel="noreferrer noopener"';
if (version) {
for (var key in jush.urls) {
var obj = jush.urls;
@@ -23,7 +23,7 @@ function bodyLoad(version) {
jush.custom_links = jushLinks;
}
jush.highlight_tag('code', 0);
var tags = document.getElementsByTagName('textarea');
var tags = qsa('textarea', document);
for (var i = 0; i < tags.length; i++) {
if (/(^|\s)jush-/.test(tags[i].className)) {
var pre = jush.textarea(tags[i]);
@@ -60,6 +60,15 @@ function typePassword(el, disable) {
}
}
/** Install toggle handler
*/
function messagesPrint() {
var els = qsa('.toggle', document);
for (var i = 0; i < els.length; i++) {
els[i].onclick = partial(toggle, els[i].getAttribute('href').substr(1));
}
}
var dbCtrl;
@@ -67,45 +76,46 @@ var dbPrevious = {};
/** Check if database should be opened to a new window
* @param MouseEvent
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function dbMouseDown(event, el) {
function dbMouseDown(event) {
dbCtrl = isCtrl(event);
if (dbPrevious[el.name] == undefined) {
dbPrevious[el.name] = el.value;
if (dbPrevious[this.name] == undefined) {
dbPrevious[this.name] = this.value;
}
}
/** Load database after selecting it
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function dbChange(el) {
function dbChange() {
if (dbCtrl) {
el.form.target = '_blank';
this.form.target = '_blank';
}
el.form.submit();
el.form.target = '';
if (dbCtrl && dbPrevious[el.name] != undefined) {
el.value = dbPrevious[el.name];
dbPrevious[el.name] = undefined;
this.form.submit();
this.form.target = '';
if (dbCtrl && dbPrevious[this.name] != undefined) {
this.value = dbPrevious[this.name];
dbPrevious[this.name] = undefined;
}
}
/** Check whether the query will be executed with index
* @param HTMLFormElement
* @this HTMLElement
*/
function selectFieldChange(form) {
function selectFieldChange() {
var form = this.form;
var ok = (function () {
var inputs = form.getElementsByTagName('input');
var inputs = qsa('input', form);
for (var i=0; i < inputs.length; i++) {
if (inputs[i].value && /^fulltext/.test(inputs[i].name)) {
return true;
}
}
var ok = form.limit.value;
var selects = form.getElementsByTagName('select');
var selects = qsa('select', form);
var group = false;
var columns = {};
for (var i=0; i < selects.length; i++) {
@@ -172,14 +182,14 @@ function idfEscape(s) {
}
/** Detect foreign key
* @param HTMLInputElement
* @this HTMLInputElement
*/
function editingNameChange(field) {
var name = field.name.substr(0, field.name.length - 7);
var type = formField(field.form, name + '[type]');
function editingNameChange() {
var name = this.name.substr(0, this.name.length - 7);
var type = formField(this.form, name + '[type]');
var opts = type.options;
var candidate; // don't select anything with ambiguous match (like column `id`)
var val = field.value;
var val = this.value;
for (var i = opts.length; i--; ) {
var match = /(.+)`(.+)/.exec(opts[i].value);
if (!match) { // common type
@@ -209,23 +219,23 @@ function editingNameChange(field) {
}
/** Add table row for next field
* @param HTMLInputElement
* @param boolean
* @return boolean
* @return boolean false
* @this HTMLInputElement
*/
function editingAddRow(button, focus) {
var match = /(\d+)(\.\d+)?/.exec(button.name);
function editingAddRow(focus) {
var match = /(\d+)(\.\d+)?/.exec(this.name);
var x = match[0] + (match[2] ? added.substr(match[2].length) : added) + '1';
var row = parentTag(button, 'tr');
var row = parentTag(this, 'tr');
var row2 = cloneNode(row);
var tags = row.getElementsByTagName('select');
var tags2 = row2.getElementsByTagName('select');
var tags = qsa('select', row);
var tags2 = qsa('select', row2);
for (var i=0; i < tags.length; i++) {
tags2[i].name = tags[i].name.replace(/[0-9.]+/, x);
tags2[i].selectedIndex = tags[i].selectedIndex;
}
tags = row.getElementsByTagName('input');
tags2 = row2.getElementsByTagName('input');
tags = qsa('input', row);
tags2 = qsa('input', row2);
var input = tags2[0]; // IE loose tags2 after insertBefore()
for (var i=0; i < tags.length; i++) {
if (tags[i].name == 'auto_increment_col') {
@@ -240,59 +250,52 @@ function editingAddRow(button, focus) {
tags2[i].checked = false;
}
}
tags[0].onchange = function () {
editingNameChange(tags[0]);
};
tags[0].onkeyup = function () {
};
tags[0].oninput = editingNameChange;
row.parentNode.insertBefore(row2, row.nextSibling);
if (focus) {
input.onchange = function () {
editingNameChange(input);
};
input.onkeyup = function () {
};
input.oninput = editingNameChange;
input.focus();
}
added += '0';
rowCount++;
return true;
return false;
}
/** Remove table row for field
* @param HTMLInputElement
* @param string
* @return boolean
* @return boolean false
* @this HTMLInputElement
*/
function editingRemoveRow(button, name) {
var field = formField(button.form, button.name.replace(/[^\[]+(.+)/, name));
function editingRemoveRow(name) {
var field = formField(this.form, this.name.replace(/[^\[]+(.+)/, name));
field.parentNode.removeChild(field);
parentTag(button, 'tr').style.display = 'none';
return true;
parentTag(this, 'tr').style.display = 'none';
return false;
}
/** Move table row for field
* @param HTMLInputElement
* @param boolean direction to move row, true for up or false for down
* @return boolean
* @return boolean false for success
* @this HTMLInputElement
*/
function editingMoveRow(button, dir){
var row = parentTag(button, 'tr');
function editingMoveRow(dir){
var row = parentTag(this, 'tr');
if (!('nextElementSibling' in row)) {
return false;
return true;
}
row.parentNode.insertBefore(row, dir
? row.previousElementSibling
: row.nextElementSibling ? row.nextElementSibling.nextElementSibling : row.parentNode.firstChild);
return true;
return false;
}
var lastType = '';
/** Clear length and hide collation or unsigned
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function editingTypeChange(type) {
function editingTypeChange() {
var type = this;
var name = type.name.substr(0, type.name.length - 6);
var text = selectValue(type);
for (var i=0; i < type.form.elements.length; i++) {
@@ -304,7 +307,7 @@ function editingTypeChange(type) {
)) {
el.value = '';
}
el.onchange.apply(el);
el.oninput.apply(el);
}
if (lastType == 'timestamp' && el.name == name + '[has_default]' && /timestamp/i.test(formField(type.form, name + '[default]').value)) {
el.checked = false;
@@ -326,37 +329,37 @@ function editingTypeChange(type) {
}
/** Mark length as required
* @param HTMLInputElement
* @this HTMLInputElement
*/
function editingLengthChange(el) {
alterClass(el, 'required', !el.value.length && /var(char|binary)$/.test(selectValue(el.parentNode.previousSibling.firstChild)));
function editingLengthChange() {
alterClass(this, 'required', !this.value.length && /var(char|binary)$/.test(selectValue(this.parentNode.previousSibling.firstChild)));
}
/** Edit enum or set
* @param HTMLInputElement
* @this HTMLInputElement
*/
function editingLengthFocus(field) {
var td = field.parentNode;
function editingLengthFocus() {
var td = this.parentNode;
if (/(enum|set)$/.test(selectValue(td.previousSibling.firstChild))) {
var edit = document.getElementById('enum-edit');
var val = field.value;
var edit = qs('#enum-edit');
var val = this.value;
edit.value = (/^'.+'$/.test(val) ? val.substr(1, val.length - 2).replace(/','/g, "\n").replace(/''/g, "'") : val); //! doesn't handle 'a'',''b' correctly
td.appendChild(edit);
field.style.display = 'none';
this.style.display = 'none';
edit.style.display = 'inline';
edit.focus();
}
}
/** Finish editing of enum or set
* @param HTMLTextAreaElement
* @this HTMLTextAreaElement
*/
function editingLengthBlur(edit) {
var field = edit.parentNode.firstChild;
var val = edit.value;
field.value = (/^'[^\n]+'$/.test(val) ? val : "'" + val.replace(/\n+$/, '').replace(/'/g, "''").replace(/\n/g, "','") + "'");
function editingLengthBlur() {
var field = this.parentNode.firstChild;
var val = this.value;
field.value = (/^'[^\n]+'$/.test(val) ? val : val && "'" + val.replace(/\n+$/, '').replace(/'/g, "''").replace(/\n/g, "','") + "'");
field.style.display = 'inline';
edit.style.display = 'none';
this.style.display = 'none';
}
/** Show or hide selected table column
@@ -364,9 +367,9 @@ function editingLengthBlur(edit) {
* @param number
*/
function columnShow(checked, column) {
var trs = document.getElementById('edit-fields').getElementsByTagName('tr');
var trs = qsa('tr', qs('#edit-fields'));
for (var i=0; i < trs.length; i++) {
alterClass(trs[i].getElementsByTagName('td')[column], 'hidden', !checked);
alterClass(qsa('td', trs[i])[column], 'hidden', !checked);
}
}
@@ -374,76 +377,76 @@ function columnShow(checked, column) {
*/
function editingHideDefaults() {
if (innerWidth < document.documentElement.scrollWidth) {
document.getElementById('form')['defaults'].checked = false;
qs('#form')['defaults'].checked = false;
columnShow(false, 5);
}
}
/** Display partition options
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function partitionByChange(el) {
var partitionTable = /RANGE|LIST/.test(selectValue(el));
alterClass(el.form['partitions'], 'hidden', partitionTable || !el.selectedIndex);
alterClass(document.getElementById('partition-table'), 'hidden', !partitionTable);
function partitionByChange() {
var partitionTable = /RANGE|LIST/.test(selectValue(this));
alterClass(this.form['partitions'], 'hidden', partitionTable || !this.selectedIndex);
alterClass(qs('#partition-table'), 'hidden', !partitionTable);
helpClose();
}
/** Add next partition row
* @param HTMLInputElement
* @this HTMLInputElement
*/
function partitionNameChange(el) {
var row = cloneNode(parentTag(el, 'tr'));
function partitionNameChange() {
var row = cloneNode(parentTag(this, 'tr'));
row.firstChild.firstChild.value = '';
parentTag(el, 'table').appendChild(row);
el.onchange = function () {};
parentTag(this, 'table').appendChild(row);
this.oninput = function () {};
}
/** Add row for foreign key
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function foreignAddRow(field) {
field.onchange = function () { };
var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select');
function foreignAddRow() {
this.onchange = function () { };
var row = cloneNode(parentTag(this, 'tr'));
var selects = qsa('select', row);
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/\]/, '1$&');
selects[i].selectedIndex = 0;
}
parentTag(field, 'table').appendChild(row);
parentTag(this, 'table').appendChild(row);
}
/** Add row for indexes
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function indexesAddRow(field) {
field.onchange = function () { };
var row = cloneNode(parentTag(field, 'tr'));
var selects = row.getElementsByTagName('select');
function indexesAddRow() {
this.onchange = function () { };
var row = cloneNode(parentTag(this, 'tr'));
var selects = qsa('select', row);
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/indexes\[\d+/, '$&1');
selects[i].selectedIndex = 0;
}
var inputs = row.getElementsByTagName('input');
var inputs = qsa('input', row);
for (var i=0; i < inputs.length; i++) {
inputs[i].name = inputs[i].name.replace(/indexes\[\d+/, '$&1');
inputs[i].value = '';
}
parentTag(field, 'table').appendChild(row);
parentTag(this, 'table').appendChild(row);
}
/** Change column in index
* @param HTMLSelectElement
* @param string name prefix
* @this HTMLSelectElement
*/
function indexesChangeColumn(field, prefix) {
function indexesChangeColumn(prefix) {
var names = [];
for (var tag in { 'select': 1, 'input': 1 }) {
var columns = parentTag(field, 'td').getElementsByTagName(tag);
var columns = qsa(tag, parentTag(this, 'td'));
for (var i=0; i < columns.length; i++) {
if (/\[columns\]/.test(columns[i].name)) {
var value = selectValue(columns[i]);
@@ -453,17 +456,15 @@ function indexesChangeColumn(field, prefix) {
}
}
}
field.form[field.name.replace(/\].*/, '][name]')].value = prefix + names.join('_');
this.form[this.name.replace(/\].*/, '][name]')].value = prefix + names.join('_');
}
/** Add column for index
* @param HTMLSelectElement
* @param string name prefix
* @this HTMLSelectElement
*/
function indexesAddColumn(field, prefix) {
field.onchange = function () {
indexesChangeColumn(field, prefix);
};
function indexesAddColumn(prefix) {
var field = this;
var select = field.form[field.name.replace(/\].*/, '][type]')];
if (!select.selectedIndex) {
while (selectValue(select) != "INDEX" && select.selectedIndex < select.options.length) {
@@ -472,13 +473,14 @@ function indexesAddColumn(field, prefix) {
select.onchange();
}
var column = cloneNode(field.parentNode);
var selects = column.getElementsByTagName('select');
var selects = qsa('select', column);
for (var i = 0; i < selects.length; i++) {
select = selects[i];
select.name = select.name.replace(/\]\[\d+/, '$&1');
select.selectedIndex = 0;
}
var inputs = column.getElementsByTagName('input');
field.onchange = partial(indexesChangeColumn, prefix);
var inputs = qsa('input', column);
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
input.name = input.name.replace(/\]\[\d+/, '$&1');
@@ -510,48 +512,47 @@ function triggerChange(tableRe, table, form) {
var that, x, y; // em and tablePos defined in schema.inc.php
/** Get mouse position
* @param HTMLElement
* @param MouseEvent
* @this HTMLElement
*/
function schemaMousedown(el, event) {
function schemaMousedown(event) {
if ((event.which ? event.which : event.button) == 1) {
that = el;
x = event.clientX - el.offsetLeft;
y = event.clientY - el.offsetTop;
that = this;
x = event.clientX - this.offsetLeft;
y = event.clientY - this.offsetTop;
}
}
/** Move object
* @param MouseEvent
*/
function schemaMousemove(ev) {
function schemaMousemove(event) {
if (that !== undefined) {
ev = ev || event;
var left = (ev.clientX - x) / em;
var top = (ev.clientY - y) / em;
var divs = that.getElementsByTagName('div');
var left = (event.clientX - x) / em;
var top = (event.clientY - y) / em;
var divs = qsa('div', that);
var lineSet = { };
for (var i=0; i < divs.length; i++) {
if (divs[i].className == 'references') {
var div2 = document.getElementById((/^refs/.test(divs[i].id) ? 'refd' : 'refs') + divs[i].id.substr(4));
var div2 = qs('[id="' + (/^refs/.test(divs[i].id) ? 'refd' : 'refs') + divs[i].id.substr(4) + '"]');
var ref = (tablePos[divs[i].title] ? tablePos[divs[i].title] : [ div2.parentNode.offsetTop / em, 0 ]);
var left1 = -1;
var id = divs[i].id.replace(/^ref.(.+)-.+/, '$1');
if (divs[i].parentNode != div2.parentNode) {
left1 = Math.min(0, ref[1] - left) - 1;
divs[i].style.left = left1 + 'em';
divs[i].getElementsByTagName('div')[0].style.width = -left1 + 'em';
divs[i].querySelector('div').style.width = -left1 + 'em';
var left2 = Math.min(0, left - ref[1]) - 1;
div2.style.left = left2 + 'em';
div2.getElementsByTagName('div')[0].style.width = -left2 + 'em';
div2.querySelector('div').style.width = -left2 + 'em';
}
if (!lineSet[id]) {
var line = document.getElementById(divs[i].id.replace(/^....(.+)-.+$/, 'refl$1'));
var line = qs('[id="' + divs[i].id.replace(/^....(.+)-.+$/, 'refl$1') + '"]');
var top1 = top + divs[i].offsetTop / em;
var top2 = top + div2.offsetTop / em;
if (divs[i].parentNode != div2.parentNode) {
top2 += ref[0] - top;
line.getElementsByTagName('div')[0].style.height = Math.abs(top1 - top2) + 'em';
line.querySelector('div').style.height = Math.abs(top1 - top2) + 'em';
}
line.style.left = (left + left1) + 'em';
line.style.top = Math.min(top1, top2) + 'em';
@@ -568,17 +569,16 @@ function schemaMousemove(ev) {
* @param MouseEvent
* @param string
*/
function schemaMouseup(ev, db) {
function schemaMouseup(event, db) {
if (that !== undefined) {
ev = ev || event;
tablePos[that.firstChild.firstChild.firstChild.data] = [ (ev.clientY - y) / em, (ev.clientX - x) / em ];
tablePos[that.firstChild.firstChild.firstChild.data] = [ (event.clientY - y) / em, (event.clientX - x) / em ];
that = undefined;
var s = '';
for (var key in tablePos) {
s += '_' + key + ':' + Math.round(tablePos[key][0] * 10000) / 10000 + 'x' + Math.round(tablePos[key][1] * 10000) / 10000;
}
s = encodeURIComponent(s.substr(1));
var link = document.getElementById('schema-link');
var link = qs('#schema-link');
link.href = link.href.replace(/[^=]+$/, '') + s;
cookie('adminer_schema-' + db + '=' + s, 30); //! special chars in db
}
@@ -589,18 +589,18 @@ function schemaMouseup(ev, db) {
var helpOpen, helpIgnore; // when mouse outs <option> then it mouse overs border of <select> - ignore it
/** Display help
* @param HTMLElement
* @param MouseEvent
* @param string
* @param bool display on left side (otherwise on top)
* @this HTMLElement
*/
function helpMouseover(el, event, text, side) {
function helpMouseover(event, text, side) {
var target = getTarget(event);
if (!text) {
helpClose();
} else if (window.jush && (!helpIgnore || el != target)) {
} else if (window.jush && (!helpIgnore || this != target)) {
helpOpen = 1;
var help = document.getElementById('help');
var help = qs('#help');
help.innerHTML = text;
jush.highlight_tag([ help ]);
alterClass(help, 'hidden');
@@ -612,12 +612,12 @@ function helpMouseover(el, event, text, side) {
}
/** Close help after timeout
* @param HTMLElement
* @param MouseEvent
* @this HTMLElement
*/
function helpMouseout(el, event) {
function helpMouseout(event) {
helpOpen = 0;
helpIgnore = (el != getTarget(event));
helpIgnore = (this != getTarget(event));
setTimeout(function () {
if (!helpOpen) {
helpClose();
@@ -628,5 +628,5 @@ function helpMouseout(el, event) {
/** Close help
*/
function helpClose() {
alterClass(document.getElementById('help'), 'hidden', true);
alterClass(qs('#help'), 'hidden', true);
}

View File

@@ -1,4 +1,67 @@
/** Get first element by selector
* @param string
* @param [HTMLElement] defaults to document
* @return HTMLElement
*/
function qs(selector, context) {
return (context || document).querySelector(selector);
}
/** Get last element by selector
* @param string
* @param [HTMLElement] defaults to document
* @return HTMLElement
*/
function qsl(selector, context) {
var els = qsa(selector, context || document);
return els[els.length - 1];
}
/** Get all elements by selector
* @param string
* @param HTMLElement
* @return NodeList
*/
function qsa(selector, context) {
return context.querySelectorAll(selector);
}
/** Return a function calling fn with the next arguments
* @param function
* @param ...
* @return function with preserved this
*/
function partial(fn) {
var args = Array.apply(null, arguments).slice(1);
return function () {
return fn.apply(this, args);
};
}
/** Return a function calling fn with the first parameter and then the next arguments
* @param function
* @param ...
* @return function with preserved this
*/
function partialArg(fn) {
var args = Array.apply(null, arguments);
return function (arg) {
args[0] = arg;
return fn.apply(this, args);
};
}
/** Assign values from source to target
* @param Object
* @param Object
*/
function mixin(target, source) {
for (var key in source) {
target[key] = source[key];
}
}
/** Add or remove CSS class
* @param HTMLElement
* @param string
@@ -12,12 +75,12 @@ function alterClass(el, className, enable) {
/** Toggle visibility
* @param string
* @return boolean
* @return boolean false
*/
function toggle(id) {
var el = document.getElementById(id);
var el = qs('#' + id);
el.className = (el.className == 'hidden' ? '' : 'hidden');
return true;
return false;
}
/** Set permanent cookie
@@ -33,8 +96,10 @@ function cookie(assign, days) {
/** Verify current Adminer version
* @param string
* @param string own URL base
* @param string
*/
function verifyVersion(current) {
function verifyVersion(current, url, token) {
cookie('adminer_version=0', 1);
var iframe = document.createElement('iframe');
iframe.src = 'https://www.adminer.org/version/?current=' + current;
@@ -50,11 +115,13 @@ function verifyVersion(current) {
var match = /version=(.+)/.exec(event.data);
if (match) {
cookie('adminer_version=' + match[1], 1);
ajax(url + 'script=version', function () {
}, event.data + '&token=' + token);
}
}
}, false);
}
document.getElementById('version').appendChild(iframe);
qs('#version').appendChild(iframe);
}
/** Get value of select
@@ -70,20 +137,20 @@ function selectValue(select) {
}
/** Verify if element has a specified tag name
* @param HTMLElement
* @param string regular expression
* @return bool
*/
* @param HTMLElement
* @param string regular expression
* @return bool
*/
function isTag(el, tag) {
var re = new RegExp('^(' + tag + ')$', 'i');
return re.test(el.tagName);
}
/** Get parent node with specified tag name
* @param HTMLElement
* @param string regular expression
* @return HTMLElement
*/
* @param HTMLElement
* @param string regular expression
* @return HTMLElement
*/
function parentTag(el, tag) {
while (el && !isTag(el, tag)) {
el = el.parentNode;
@@ -108,24 +175,27 @@ function trCheck(el) {
*/
function selectCount(id, count) {
setHtml(id, (count === '' ? '' : '(' + (count + '').replace(/\B(?=(\d{3})+$)/g, ' ') + ')'));
var inputs = document.getElementById(id).parentNode.parentNode.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.type == 'submit') {
input.disabled = (count == '0');
var el = qs('#' + id);
if (el) {
var inputs = qsa('input', el.parentNode.parentNode);
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if (input.type == 'submit') {
input.disabled = (count == '0');
}
}
}
}
/** Check all elements matching given name
* @param HTMLInputElement
* @param RegExp
* @this HTMLInputElement
*/
function formCheck(el, name) {
var elems = el.form.elements;
function formCheck(name) {
var elems = this.form.elements;
for (var i=0; i < elems.length; i++) {
if (name.test(elems[i].name)) {
elems[i].checked = el.checked;
elems[i].checked = this.checked;
trCheck(elems[i]);
}
}
@@ -134,10 +204,10 @@ function formCheck(el, name) {
/** Check all rows in <table class="checkable">
*/
function tableCheck() {
var tables = document.getElementsByTagName('table');
var tables = qsa('table', document);
for (var i=0; i < tables.length; i++) {
if (/(^|\s)checkable(\s|$)/.test(tables[i].className)) {
var trs = tables[i].getElementsByTagName('tr');
var trs = qsa('tr', tables[i]);
for (var j=0; j < trs.length; j++) {
trCheck(trs[j].firstChild.firstChild);
}
@@ -149,7 +219,7 @@ function tableCheck() {
* @param string
*/
function formUncheck(id) {
var el = document.getElementById(id);
var el = qs('#' + id);
el.checked = false;
trCheck(el);
}
@@ -182,7 +252,7 @@ function tableClick(event, click) {
if (el.type != 'checkbox') {
return;
}
checkboxClick(event, el);
checkboxClick.call(el, event);
click = false;
}
el = el.parentNode;
@@ -201,25 +271,25 @@ function tableClick(event, click) {
var lastChecked;
/** Shift-click on checkbox for multiple selection.
* @param MouseEvent
* @param HTMLInputElement
*/
function checkboxClick(event, el) {
if (!el.name) {
* @param MouseEvent
* @this HTMLInputElement
*/
function checkboxClick(event) {
if (!this.name) {
return;
}
if (event.shiftKey && (!lastChecked || lastChecked.name == el.name)) {
if (event.shiftKey && (!lastChecked || lastChecked.name == this.name)) {
var checked = (lastChecked ? lastChecked.checked : true);
var inputs = parentTag(el, 'table').getElementsByTagName('input');
var inputs = qsa('input', parentTag(this, 'table'));
var checking = !lastChecked;
for (var i=0; i < inputs.length; i++) {
var input = inputs[i];
if (input.name === el.name) {
if (input.name === this.name) {
if (checking) {
input.checked = checked;
trCheck(input);
}
if (input === el || input === lastChecked) {
if (input === this || input === lastChecked) {
if (checking) {
break;
}
@@ -228,7 +298,7 @@ function checkboxClick(event, el) {
}
}
} else {
lastChecked = el;
lastChecked = this;
}
}
@@ -237,7 +307,7 @@ function checkboxClick(event, el) {
* @param string undefined to set parentNode to &nbsp;
*/
function setHtml(id, html) {
var el = document.getElementById(id);
var el = qs('#' + id);
if (el) {
if (html == null) {
el.parentNode.innerHTML = '&nbsp;';
@@ -262,52 +332,49 @@ function nodePosition(el) {
/** Go to the specified page
* @param string
* @param string
* @param [MouseEvent]
*/
function pageClick(href, page, event) {
function pageClick(href, page) {
if (!isNaN(page) && page) {
href += (page != 1 ? '&page=' + (page - 1) : '');
location.href = href;
location.href = href + (page != 1 ? '&page=' + (page - 1) : '');
}
}
/** Display items in menu
* @param HTMLElement
* @param MouseEvent
* @this HTMLElement
*/
function menuOver(el, event) {
function menuOver(event) {
var a = getTarget(event);
if (isTag(a, 'a|span') && a.offsetLeft + a.offsetWidth > a.parentNode.offsetWidth - 15) { // 15 - ellipsis
el.style.overflow = 'visible';
this.style.overflow = 'visible';
}
}
/** Hide items in menu
* @param HTMLElement
* @this HTMLElement
*/
function menuOut(el) {
el.style.overflow = 'auto';
function menuOut() {
this.style.overflow = 'auto';
}
/** Add row in select fieldset
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function selectAddRow(field) {
field.onchange = function () {
selectFieldChange(field.form);
};
field.onchange();
function selectAddRow() {
var field = this;
var row = cloneNode(field.parentNode);
var selects = row.getElementsByTagName('select');
field.onchange = selectFieldChange;
field.onchange();
var selects = qsa('select', row);
for (var i=0; i < selects.length; i++) {
selects[i].name = selects[i].name.replace(/[a-z]\[\d+/, '$&1');
selects[i].selectedIndex = 0;
}
var inputs = row.getElementsByTagName('input');
var inputs = qsa('input', row);
for (var i=0; i < inputs.length; i++) {
inputs[i].name = inputs[i].name.replace(/[a-z]\[\d+/, '$&1');
inputs[i].className = '';
@@ -321,33 +388,33 @@ function selectAddRow(field) {
}
/** Prevent onsearch handler on Enter
* @param HTMLInputElement
* @param KeyboardEvent
* @this HTMLInputElement
*/
function selectSearchKeydown(el, event) {
function selectSearchKeydown(event) {
if (event.keyCode == 13 || event.keyCode == 10) {
el.onsearch = function () {
this.onsearch = function () {
};
}
}
/** Clear column name after resetting search
* @param HTMLInputElement
* @this HTMLInputElement
*/
function selectSearchSearch(el) {
if (!el.value) {
el.parentNode.firstChild.selectedIndex = 0;
function selectSearchSearch() {
if (!this.value) {
this.parentNode.firstChild.selectedIndex = 0;
}
}
/** Toggles column context menu
* @param HTMLElement
* @param [string] extra class name
*/
function columnMouse(el, className) {
var spans = el.getElementsByTagName('span');
* @param [string] extra class name
* @this HTMLElement
*/
function columnMouse(className) {
var spans = qsa('span', this);
for (var i=0; i < spans.length; i++) {
if (/column/.test(spans[i].className)) {
spans[i].className = 'column' + (className || '');
@@ -358,12 +425,13 @@ function columnMouse(el, className) {
/** Fill column in search field
* @param string
*/
* @param string
* @return boolean false
*/
function selectSearch(name) {
var el = document.getElementById('fieldset-search');
var el = qs('#fieldset-search');
el.className = '';
var divs = el.getElementsByTagName('div');
var divs = qsa('div', el);
for (var i=0; i < divs.length; i++) {
var div = divs[i];
if (isTag(div.firstChild, 'select') && selectValue(div.firstChild) == name) {
@@ -374,7 +442,8 @@ function selectSearch(name) {
div.firstChild.value = name;
div.firstChild.onchange();
}
div.lastChild.focus();
qs('[name$="[val]"]', div).focus();
return false;
}
@@ -402,6 +471,7 @@ function getTarget(event) {
* @return boolean
*/
function bodyKeydown(event, button) {
eventStop(event);
var target = getTarget(event);
if (target.jushTextarea) {
target = target.jushTextarea;
@@ -450,18 +520,17 @@ function editingKeydown(event) {
return false;
}
if (event.shiftKey && !bodyKeydown(event, 'insert')) {
eventStop(event);
return false;
}
return true;
}
/** Disable maxlength for functions
* @param HTMLSelectElement
* @this HTMLSelectElement
*/
function functionChange(select) {
var input = select.form[select.name.replace(/^function/, 'fields')];
if (selectValue(select)) {
function functionChange() {
var input = this.form[this.name.replace(/^function/, 'fields')];
if (selectValue(this)) {
if (input.origType === undefined) {
input.origType = input.type;
input.origMaxLength = input.getAttribute('data-maxlength');
@@ -478,28 +547,29 @@ function functionChange(select) {
helpClose();
}
/** Call this.onchange() if value changes
* @this HTMLInputElement
/** Skip 'original' when typing
* @param number
* @this HTMLTableCellElement
*/
function keyupChange() {
if (this.value != this.getAttribute('value')) {
this.onchange();
this.setAttribute('value', this.value);
function skipOriginal(first) {
var fnSelect = this.previousSibling.firstChild;
if (fnSelect.selectedIndex < first) {
fnSelect.selectedIndex = first;
}
}
/** Add new field in schema-less edit
* @param HTMLInputElement
* @this HTMLInputElement
*/
function fieldChange(field) {
var row = cloneNode(parentTag(field, 'tr'));
var inputs = row.getElementsByTagName('input');
function fieldChange() {
var row = cloneNode(parentTag(this, 'tr'));
var inputs = qsa('input', row);
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
// keep value in <select> (function)
parentTag(field, 'table').appendChild(row);
field.onchange = function () { };
parentTag(this, 'table').appendChild(row);
this.oninput = function () { };
}
@@ -514,7 +584,7 @@ function fieldChange(field) {
function ajax(url, callback, data, message) {
var request = (window.XMLHttpRequest ? new XMLHttpRequest() : (window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : false));
if (request) {
var ajaxStatus = document.getElementById('ajaxstatus');
var ajaxStatus = qs('#ajaxstatus');
if (message) {
ajaxStatus.innerHTML = '<div class="message">' + message + '</div>';
ajaxStatus.className = ajaxStatus.className.replace(/ hidden/g, '');
@@ -543,11 +613,11 @@ function ajax(url, callback, data, message) {
/** Use setHtml(key, value) for JSON response
* @param string
* @return XMLHttpRequest or false in case of an error
* @return boolean false for success
*/
function ajaxSetHtml(url) {
return ajax(url, function (request) {
var data = eval('(' + request.responseText + ')');
return !ajax(url, function (request) {
var data = window.JSON ? JSON.parse(request.responseText) : eval('(' + request.responseText + ')');
for (var key in data) {
setHtml(key, data[key]);
}
@@ -584,7 +654,7 @@ function ajaxForm(form, message, button) {
return ajax(url, function (request) {
setHtml('ajaxstatus', request.responseText);
if (window.jush) {
jush.highlight_tag(document.getElementById('ajaxstatus').getElementsByTagName('code'), 0);
jush.highlight_tag(qsa('code', qs('#ajaxstatus')), 0);
}
}, data, message);
}
@@ -592,12 +662,13 @@ function ajaxForm(form, message, button) {
/** Display edit field
* @param HTMLElement
* @param MouseEvent
* @param number display textarea instead of input, 2 - load long text
* @param string warning to display
* @this HTMLElement
*/
function selectClick(td, event, text, warning) {
function selectClick(event, text, warning) {
var td = this;
var target = getTarget(event);
if (!isCtrl(event) || isTag(td.firstChild, 'input|textarea') || isTag(target, 'a')) {
return;
@@ -627,7 +698,7 @@ function selectClick(td, event, text, warning) {
});
input.rows = rows;
}
if (value == '\u00A0' || td.getElementsByTagName('i').length) { // &nbsp; or i - NULL
if (value == '\u00A0' || qsa('i', td).length) { // &nbsp; or i - NULL
value = '';
}
if (document.selection) {
@@ -664,21 +735,22 @@ function selectClick(td, event, text, warning) {
/** Load and display next page in select
* @param HTMLLinkElement
* @param number
* @param string
* @return boolean
* @return boolean false for success
* @this HTMLLinkElement
*/
function selectLoadMore(a, limit, loading) {
function selectLoadMore(limit, loading) {
var a = this;
var title = a.innerHTML;
var href = a.href;
a.innerHTML = loading;
if (href) {
a.removeAttribute('href');
return ajax(href, function (request) {
return !ajax(href, function (request) {
var tbody = document.createElement('tbody');
tbody.innerHTML = request.responseText;
document.getElementById('table').appendChild(tbody);
qs('#table').appendChild(tbody);
if (tbody.children.length < limit) {
a.parentNode.removeChild(a);
} else {
@@ -711,7 +783,7 @@ function eventStop(event) {
*/
function setupSubmitHighlight(parent) {
for (var key in { input: 1, select: 1, textarea: 1 }) {
var inputs = parent.getElementsByTagName(key);
var inputs = qsa(key, parent);
for (var i = 0; i < inputs.length; i++) {
setupSubmitHighlightInput(inputs[i])
}
@@ -756,7 +828,10 @@ function findDefaultSubmit(el) {
if (el.jushTextarea) {
el = el.jushTextarea;
}
var inputs = el.form.getElementsByTagName('input');
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) {
@@ -795,6 +870,17 @@ function focus(el) {
*/
function cloneNode(el) {
var el2 = el.cloneNode(true);
var selector = 'input, select';
var origEls = qsa(selector, el);
var cloneEls = qsa(selector, el2);
for (var i=0; i < origEls.length; i++) {
var origEl = origEls[i];
for (var key in origEl) {
if (/^on/.test(key) && origEl[key]) {
cloneEls[i][key] = origEl[key];
}
}
}
setupSubmitHighlight(el2);
return el2;
}

View File

@@ -11,7 +11,7 @@ page_header(($fields && is_view($table_status) ? $table_status['Engine'] == 'mat
$adminer->selectLinks($table_status);
$comment = $table_status["Comment"];
if ($comment != "") {
echo "<p>" . lang('Comment') . ": " . h($comment) . "\n";
echo "<p class='nowrap'>" . lang('Comment') . ": " . h($comment) . "\n";
}
if ($fields) {

View File

@@ -40,10 +40,10 @@ 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"]); ?>" maxlength="64" autocapitalize="off">
<script type="text/javascript">document.getElementById('form')['Timing'].onchange();</script>
<?php echo script("qs('#form')['Timing'].onchange();"); ?>
<p><?php textarea("Statement", $row["Statement"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($name != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $name)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -22,7 +22,7 @@ if (!$row) {
<p>
<?php
if ($TYPE != "") {
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'" . confirm() . ">\n";
echo "<input type='submit' name='drop' value='" . lang('Drop') . "'>" . confirm(lang('Drop %s?', $TYPE)) . "\n";
} else {
echo "<input name='name' value='" . h($row['name']) . "' autocapitalize='off'>\n";
textarea("as", $row["as"]);

View File

@@ -61,7 +61,7 @@ if ($_POST && !$error) {
$created = false;
if (!$error) {
if ($old_user != $new_user) {
$created = queries(($connection->server_info < 5 ? "GRANT USAGE ON *.* TO" : "CREATE USER") . " $new_user IDENTIFIED BY PASSWORD " . q($pass));
$created = queries((min_version(5) ? "CREATE USER" : "GRANT USAGE ON *.* TO") . " $new_user IDENTIFIED BY PASSWORD " . q($pass));
$error = !$created;
} elseif ($pass != $old_pass) {
queries("SET PASSWORD FOR $new_user = " . q($pass));
@@ -134,8 +134,8 @@ if ($_POST) {
<table cellspacing="0">
<tr><th><?php echo lang('Server'); ?><td><input name="host" maxlength="60" value="<?php echo h($row["host"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Username'); ?><td><input name="user" maxlength="16" 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"]); ?>">
<?php if (!$row["hashed"]) { ?><script type="text/javascript">typePassword(document.getElementById('pass'));</script><?php } ?>
<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 echo checkbox("hashed", 1, $row["hashed"], lang('Hashed'), "typePassword(this.form['pass'], this.checked);"); ?>
</table>
@@ -169,7 +169,11 @@ foreach (array(
} elseif (isset($_GET["grant"])) {
echo "<td><select name=$name><option><option value='1'" . ($value ? " selected" : "") . ">" . lang('Grant') . "<option value='0'" . ($value == "0" ? " selected" : "") . ">" . lang('Revoke') . "</select>";
} else {
echo "<td align='center'><label class='block'><input type='checkbox' name=$name value='1'" . ($value ? " checked" : "") . ($privilege == "All privileges" ? " id='grants-$i-all'" : ($privilege == "Grant option" ? "" : " onclick=\"if (this.checked) formUncheck('grants-$i-all');\"")) . "></label>"; //! uncheck all except grant if all is checked
echo "<td align='center'><label class='block'>";
echo "<input type='checkbox' name=$name value='1'" . ($value ? " checked" : "") . ($privilege == "All privileges"
? " id='grants-$i-all'>" //! uncheck all except grant if all is checked
: ">" . ($privilege == "Grant option" ? "" : script("qsl('input').onclick = function () { if (this.checked) formUncheck('grants-$i-all'); };")));
echo "</label>";
}
$i++;
}
@@ -180,6 +184,6 @@ echo "</table>\n";
?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if (isset($_GET["host"])) { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if (isset($_GET["host"])) { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', "$USER@$_GET[host]")); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -53,6 +53,6 @@ page_header(($TABLE != "" ? lang('Alter view') : lang('Create view')), $error, a
<p><?php textarea("select", $row["select"]); ?>
<p>
<input type="submit" value="<?php echo lang('Save'); ?>">
<?php if ($_GET["view"] != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"<?php echo confirm(); ?>><?php } ?>
<?php if ($TABLE != "") { ?><input type="submit" name="drop" value="<?php echo lang('Drop'); ?>"><?php echo confirm(lang('Drop %s?', $TABLE)); ?><?php } ?>
<input type="hidden" name="token" value="<?php echo $token; ?>">
</form>

View File

@@ -1,3 +1,71 @@
Adminer 4.6.0 (released 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
Stop redirecting links via adminer.org
Support X-Forwarded-Prefix
Display options for timestamp columns when creating a new table
Disable autocompleting password on create user page
Use primary key to edit rows even if not selected
MySQL, PostgreSQL: Display warnings
MySQL: Add floor and ceil select functions
MySQL: Add FIND_IN_SET search operator
MariaDB: Support JSON since MariaDB 10.2
SQLite, PostgreSQL: Limit rows in data manipulation without unique key
PostgreSQL: Support routines
PostgreSQL: Allow editing views with uppercase letters (bug #467)
PostgreSQL: Allow now() as default value (bug #525)
SimpleDB: Document that allow_url_fopen is required
Malay translation
Adminer 4.5.0 (released 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)
Hide window.opener from pages opened in a new window (bug #561)
Display error when getting row to edit
Store current Adminer version server-side to avoid excessive requests
Adminer: Fix Search data in tables (regression from 4.4.0)
CSP: Allow any styles, images, media and fonts, disallow base-uri
MySQL: Support geometry in MySQL 8 (bug #574)
MySQL: Support routines with comments in parameters (bug #460)
MariaDB: Support fulltext and spatial indexes in InnoDB (bug #583)
SQLite: Enable foreign key checks
PostgreSQL: Respect NULL default value
PostgreSQL: Display foreign tables (bug #576)
PostgreSQL: Do not export triggers if not requested
PostgreSQL: Export DROP SEQUENCE if dropping table
PostgreSQL: Display boolean values as code (bug #562)
MS SQL: Support freetds
non-MySQL: Avoid CONVERT() (bug #509)
Elasticsearch: Insert, update, delete
MongoDB: Support mongodb PHP extension
Editor: Fix displaying of false values in PostgreSQL (bug #568)
Adminer 4.4.0 (released 2018-01-17):
Add Content Security Policy
Disallow scripts without nonce
Rate limit password-less login attempts from the same IP address
Disallow connecting to privileged ports
Add nosniff header
PHP 7.1: Prevent warning when using empty limit
PHP 7.2: Prevent warning when searching in select
MySQL: Remove dedicated view for replication status (added in 4.3.0)
PostgreSQL: Sort table names (regression from 4.3.1)
Editor: Don't set time zone from PHP, fixes DST
Editor: Display field comment's text inside [] only in edit form
Editor: Fix doubleclick on database page
Editor: Fix Search data in tables
Customization: Always send security headers
Hebrew translation
Adminer 4.3.1 (released 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 (released 2017-03-15):
Make maxlength in edit fields a soft limit
Add accessibility labels

View File

@@ -300,6 +300,10 @@ function compile_file($match) {
return '"' . add_quo_slashes($file) . '"';
}
function min_version() {
return true;
}
$project = "adminer";
if ($_SERVER["argv"][1] == "editor") {
$project = "editor";
@@ -327,10 +331,12 @@ if ($_SERVER["argv"][1]) {
}
// check function definition in drivers
$filename = dirname(__FILE__) . "/adminer/drivers/mysql.inc.php";
preg_match_all('~\\bfunction ([^(]+)~', file_get_contents($filename), $matches); //! respect context (extension, class)
$file = file_get_contents(dirname(__FILE__) . "/adminer/drivers/mysql.inc.php");
$file = preg_replace('~( *)class Min_Driver.*}~sU', '', $file);
preg_match_all('~\\bfunction ([^(]+)~', $file, $matches); //! respect context (extension, class)
$functions = array_combine($matches[1], $matches[0]);
unset($functions["__destruct"], $functions["Min_DB"], $functions["Min_Result"], $functions["Min_Driver"]);
//! 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);
@@ -344,11 +350,10 @@ foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*"
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", "replication", "variables", "view");
$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
$file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
if ($driver) {
$connection = (object) array("server_info" => 5.1); // MySQL support is version specific
$_GET[$driver] = true; // to load the driver
include_once dirname(__FILE__) . "/adminer/drivers/$driver.inc.php";
foreach ($features as $key => $feature) {
@@ -376,7 +381,7 @@ if ($driver) {
}
}
if (count($drivers) == 1) {
$file = str_replace('<?php echo html_select("auth[driver]", $drivers, DRIVER); ?>', "<input type='hidden' name='auth[driver]' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers), $file);
$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('(;../externals/jush/modules/jush-(?!textarea\.|txt\.|js\.|' . preg_quote($driver == "mysql" ? "sql" : $driver) . '\.)[^.]+.js)', '', $file);
}
@@ -393,17 +398,15 @@ if ($_SESSION["lang"]) {
$file = str_replace("<?php switch_lang(); ?>\n", "", $file);
$file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
}
$file = str_replace('<script type="text/javascript" src="static/editing.js"></script>' . "\n", "", $file);
$file = str_replace('<script type="text/javascript" src="../externals/jush/modules/jush-textarea.js"></script>' . "\n", "", $file);
$file = str_replace('<script type="text/javascript" src="../externals/jush/modules/jush-txt.js"></script>' . "\n", "", $file);
$file = str_replace('<script type="text/javascript" src="../externals/jush/modules/jush-js.js"></script>' . "\n", "", $file);
$file = str_replace('<script type="text/javascript" src="../externals/jush/modules/jush-<?php echo $jush; ?>.js"></script>' . "\n", "", $file);
$file = str_replace('<?php echo script_src("static/editing.js"); ?>' . "\n", "", $file);
$file = preg_replace('~\\s+echo script_src\\("\\.\\./externals/jush/modules/jush-(textarea|txt|js|\\$jush)\\.js"\\);~', '', $file);
$file = str_replace('<link rel="stylesheet" type="text/css" href="../externals/jush/jush.css">' . "\n", "", $file);
$file = preg_replace_callback("~compile_file\\('([^']+)'(?:, '([^']*)')?\\)~", 'compile_file', $file); // integrate static files
$replace = 'h(preg_replace("~\\\\\\\\?.*~", "", ME)) . "?file=\\1&amp;version=' . $VERSION . ($driver ? '&amp;driver=' . $driver : '');
$file = preg_replace('~\\.\\./adminer/static/(default\\.css|functions\\.js|favicon\\.ico)~', '<?php echo ' . $replace . '"; ?>', $file);
$file = preg_replace('~\\.\\./adminer/static/([^\'"]*)~', '" . ' . $replace, $file);
$file = preg_replace('~\\.\\./externals/jush/modules/(jush\\.js)~', '<?php echo ' . $replace . '"; ?>', $file);
$replace = 'preg_replace("~\\\\\\\\?.*~", "", ME) . "?file=\\1&version=' . $VERSION . ($driver ? '&driver=' . $driver : '') . '"';
$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/([^\'"]*)~', '" . h(' . $replace . ') . "', $file);
$file = preg_replace('~"\\.\\./externals/jush/modules/(jush\\.js)"~', $replace, $file);
$file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
$file = php_shrink($file);

View File

@@ -23,7 +23,7 @@
},
"license": [
"Apache-2.0",
"GPL-2.0"
"GPL-2.0-only"
],
"scripts": {
"compile": "php compile.php"

261
designs/esterka/adminer.css Normal file
View File

@@ -0,0 +1,261 @@
* {
font: 11px/1.25 Verdana, 'Geneva CE', lucida, sans-serif;
color:#333333;
margin:0px;
padding:0px;
}
a,a:visited {
color:#0033ff;
text-decoration:none;
padding:3px 1px;
}
#content table thead span, #content table thead a {
font-weight:bold;
color:black;
}
#content table thead a:hover {
background:none;
text-decoration:underline;
color:black;
}
a:hover {
color:white;
background:#0033ff;
}
h1 {
font-size:1.5em;
line-height: 2em;
font-weight:bold;
background:white;
color:#1e5eb6;
border-bottom:1px solid #f4f4f4;
padding:20px;
margin:0px;
}
#menu h1 {
padding:0px 0px 5px 20px;
background:none;
}
h2,h3 {
font-size:1.5em;
font-weight:normal;
background:white;
color:#A0522D;
border-bottom:1px solid #f4f4f4;
padding:5px 0px;
margin:0px;
}
fieldset {
padding:5px;
border:1px solid #d0cdc4;
background:#fcfaf5;
}
input,select,textarea {
border:1px solid #e5e5e5;
margin:1px;
padding:3px;
}
input[type=submit] {
color:white;
background:#A0522D;
padding:3px 10px;
cursor:pointer;
border:0px solid;
}
input[type=submit]:hover{
background:blue;
}
input[type=checkbox]{
margin-right:5px;
}
input[type=image] {
border:1px solid #d0cdc4;
}
input[type=checkbox],input[type=radio]{
border:1px solid #e5e5e5;
padding:2px 5px;
}
code{
background:#f0ffe1;
border:1px dashed #d5f1b9;
padding:2px 4px;
font-family:"Courier New";
}
code a:hover{background:transparent}
table{
margin:10px 0px;
border:1px solid #d0cdc4;
border-collapse:collapse;
}
tbody tr:hover td,tbody tr:hover th{
background:#edf4ff
}
thead th, thead td {
text-align:center;
vertical-align:middle;
font-weight:bold;
white-space:nowrap;
background:#f2eee1;
color:#808080;
}
th,td{
border:1px solid #d0cdc4;
padding:1px 4px;
vertical-align:middle;
}
th a {
font-weight:bold;
padding-bottom:0px;
}
th {
background:white;
}
tr.odd td {
background:#fcfaf5;
}
#content tbody tr.checked td, tr.checked.odd td {
background:#fbe2e2;
color:red;
}
.hidden{
display:none
}
.error,.message{
padding:0px;
background:transparent;
font-weight:bold
}
.error{
color:#c00
}
.message{
color:#090
}
#content{
margin:0px 0px 0px 255px;
padding:50px 20px 40px 0px;
height:100%;
}
#lang {
background:#f2eee1;
color:#808080;
position:fixed;
top:0px;
left:0px;
width:100%;
padding:10px 20px;
z-index:1;
}
#breadcrumb {
position:fixed;
top:0px;
left:260px;
background:#f2eee1;
z-index:2;
width:100%;
padding:10px;
}
#menu {
background:#fcfaf5;
position:fixed;
top:-10px;
padding:0px;
padding-top:10px;
bottom:0px;
overflow:auto;
left:0px;
width:240px;
border-right:5px solid #f2eee1;
}
#schema .table {
padding:5px;
background:#fcfaf5;
border:1px solid #d0cdc4;
}
#schema .table b {
color:#0033ff;
font-weight:bold;
text-decoration:underline;
}
#schema .table b:hover {
color:white;
}
input[name=logout] {
color:#fce2e2;
background:#d73e3e;
}
input[name=logout]:hover {
background:#ea0202;
}
#logins a, #tables a {
background:none;
}
#logins a:hover, #tables a:hover {
background:#A0522D;
color:white;
}
#logout {
color:#0033ff;
text-decoration:none;
}
#logout:hover {
color:white;
background:#0033ff;
}
.js .column {
background:#f2eee1;
}
#content table thead a.text:hover {
text-decoration:none;
}
#version, .version {
font-size:50%;
}
#h1:hover {
color:white;
}

View File

@@ -3,7 +3,8 @@
*
* Klemens Häckel [http://clickdimension.wordpress.com/]
*
* update 2014-01
* update 2017-03
* adapted for adminer 4.3.0
*
* new remaster based on style for WT-NMP 13.12
*
@@ -77,7 +78,7 @@ html>/**/body input[name="logout"], #logout {
right: 8px;
text-indent: 8px;
top: 6px;
width: 80px;
width: 120px;
position:fixed;
z-index: 10;
}
@@ -154,10 +155,10 @@ html>/**/body form>table a[href*="&edit="][href*="&where"] {
}
/* Select data */
html>/**/body #tables li a[href*="&select="], html>/**/body .links a[href*="&select="] {
html>/**/body #menu li a[href*="&select="], html>/**/body .links a[href*="&select="] {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdVJREFUeNqck8tO21AQhn8bB8ehRe0SUEBOlIsSVFGqqlK3oey6K+9A96wTKU/RFU/AG7CrKhAg7gmKiJKIplFWqItWIQEfuzOT2LmsSo408j+2/5lvjo+1rULhM4AFTLfahuu6i3vF4rdp3F/y+W3DVUrzKNk8BTzPC4IKS3h8Hc0Hz49zr8BeXSml8wu8PsU1uW7EhjpHOmd7wX1fs4e9hnIcTUkBDfs1DzGjS5N1pPOGRR3bLjR6ztoNNJm9ebDXcBxnjMD99YCdzGvJT25v8T6ZFH1QLuNjNiv6++UlESyDvSMEEIKcCZzX6zLvXDiMo0pFZn5hWfhxfS2aF3sCAkUvDwmA1ZUVyS9qNawnEn0aKvQhkxF9WCqBPUIgBSYISnd3QmCZJs6qVekaYZqbmzGCfoGnp2AEnyAdjUpeajTwJh4XfU778S6d7tNQISlA3rFN9AkqzaYQmLOzuKIxuGuYaE4H++F/RvbqVEVXE+cgsbSEFFH0Hh+RtW2sxmLo9npYoy/yNpUajkBeo9ftzkwSVFstIeBVpjH8rhc0xigBe43f9/dmKBTCburv4ISb//VvsYe9mmXbX/VIZHman8ntdH7y0BbFSwrjmX6H4s8/AQYAQChL+KIinhAAAAAASUVORK5CYII=") no-repeat left bottom
}
html>/**/body #tables li a[href*="&select="] {
html>/**/body #menu li a[href*="&select="] {
clear: left;
display: block;
float: left;
@@ -305,8 +306,12 @@ a, a:visited {
box-shadow: 0px 0px 3px rgba(0,0,0,0.30) !important;
margin: 0;
padding-bottom: 0;
padding-top: 30px;
top: 0;
}
#menu > h1:first-child {
margin-top: -30px;
}
/*** Forms ***/
fieldset {
border-radius: 1px !important
@@ -316,7 +321,7 @@ fieldset {
background: transparent;
font-size: .9em;
left: auto;
right: 90px;
right: 120px;
position:fixed;
z-index: 10;
padding-top: 2px;
@@ -333,10 +338,6 @@ p {
margin: 0.8em 0 0 0
}
#menu form {
padding-top: 30px;
}
.view {
background-color: #FFFFAA !important;
}

View File

@@ -73,9 +73,12 @@ input[type="button"] {
margin-right: 0;
color: #fff;
}
.error {
.error, .error b {
background: #ae1010;
}
.error b {
font-weight: bold;
}
.message {
background: #379f17;
}
@@ -259,7 +262,7 @@ th {
}
td:last-child,
th:last-child {
border-style: none;
border-right-style: none;
}
thead th,
thead td {

1189
designs/mancave/adminer.css Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED <20>AS IS<49>, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
@@ -29,8 +29,8 @@ html/*\*/>/*/*/body a[href$="dump="] {background:url("data:image/png;base64,iVBO
html/*\*/>/*/*/body select[name="db"] {background:white url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:16px;}
html/*\*/>/*/*/body select[name="db"] option {padding-left:18px;}
html/*\*/>/*/*/body a[href$="&create="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIpSURBVDjLpZNPSFRRFMZ/749/Kt3IqFTSRoSMmrGIYTTbpEJtjBCCok1Em9JVG1dRC8FFEES5aGFEgRRZWq1iLKKxBiNqLDcltQgmHR9hY6LOu+feFm+YGVsZXbh8nHO53/nud8+xjDH8z3IB7r5avGgMZ8XoBq01okFpjYhGtEGJLtmCKINo/XbgVFPUBdDG9PVEq0P/UvnSvdlwQYFoHQIY/3obpRVKFL5W+OIXUVThrL91AN+XihKCwIeTu85sqPryqsJXUvRARAMwkshsiKB7fw25UgKVJwA40V7H/cl5jh+oL+RGk/P0xIqxl11dr8AXjTYG14HRNxkcx+ZhMoNlg52/ND6VAWMoc6F5+2Zy/l9PMIDrWByL1jI+tcDRaN06BaXxbDqLUnq9AqPBteHpuwUcJ0AIcgBXH93h+/wEyyuLrPk5cmv7gNY8gdIYYyhz4PDeWuIpj85IsS2ujQ2zJAk6DkZpqGnixcwYyU+PifUOX7Eh6DoAx7aIpzwA4imPeMrj+bTH+88PaNkZQWwhsrULsXxie9oAzgcESgUe2NAZCeE6AXZGQhwKh/Cyc5RZVXQ39wFwoeMmjXVhgMqiB8awe0cVP36u0Fi/iW9zvwuzkF3+xUz6Nal0gv6uWww+O02lUwGwmv8FM3l55EtLTvQWXwm+EkRpfNEoUZRXHCE5PUFbuJ0nH4cot1wSH14C3LA2Os6x3m2DwDmgGlgChpLX0/1/AIu8MA7WsWBMAAAAAElFTkSuQmCC") no-repeat scroll left bottom; padding-left:22px;}
html/*\*/>/*/*/body #tables a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; clear:left; display:block; float:left; height:16px; margin-right:8px; padding:1px 0 0 16px; overflow:hidden; width:0; text-decoration:none; }
html/*\*/>/*/*/body #tables a[href*="&table="], html/*\*/>/*/*/body #tables a[href*="&view="] {margin:0; line-height:18px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #menu p a[href*="&select="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; clear:left; display:block; float:left; height:16px; margin-right:8px; padding:1px 0 0 16px; overflow:hidden; width:0; text-decoration:none; }
html/*\*/>/*/*/body #menu p a[href*="&table="], html/*\*/>/*/*/body #menu p a[href*="&view="] {margin:0; line-height:18px; padding-bottom:1px; text-decoration:none;}
html/*\*/>/*/*/body #content p a[href*="&create="] {padding-left:22px;}
html/*\*/>/*/*/body #content p a[href$="?database="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIkSURBVDjLpVNNiFJRFP7eU1E0KSLTMpAwYSxyaidDtChm0WYQ3NSutv2s2kwwm2igNgMtooUQEQhhA9GqhSDTQsZZFDbNDBgVg5bSw9J8rzFF33udc+HGg0ladOHj3nPe+b7zc99VbNvG/yy30yiVSl4SnCNcsixrivYEgY7WJu0faX9EKGUyGVNyFFkBkY/T+WkoFEpFIhEEAgH4/X7w916vB8Mw0Gg00G63y+S7mM1mm4LIAYxisbhSr9c5nT1pjUYju1qt2oVC4YnkqbIUMk6Ew+F/9hyNRkFJLuyaATmFoqZp8Pl88Hq98Hg8wtfv99HpdNBsNhGPx0XsRAG3241ut4vBYCDs8XgMXdcxHA7FN/b9VUD25HK5RAUczKC+hYgcNpNN05xcAQdLkqIoIlj6VFWdXIEUkAQGV8M2k2vaG3z6sYGfVR39XzsHlm/dX3h5d31xlwAHM5goBd5+LuO75z3OnU3jyP4EVrZeKGub2p309cP7VKcAQ2Znoiz3deMVTk1Nw1RNTB+ahamMkD45w7RrfwSYwFdFf6K4Quf6pmvwKHswl7wh7Jvnc4gfTPHR52zhcqVSeZZMJgOxWEyI8BC5CmOnh63WKtZbZczPPsa94hX4XCLJQHG+xnw+f5SEFghZmvhefgvcTqn2HN3gBmZSZ5CInMaHr1Wsvivjy3ZvSZn0nHO5XJDIxwgWDbW2vL10m9xXCUGCQXi49qA1/xvyq6BCh7yZeQAAAABJRU5ErkJggg==") no-repeat scroll 2px bottom; padding-left:22px;}
html/*\*/>/*/*/body #content a[href*="&database="] {background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKRSURBVDjLhVNLTBNRFD3TTju1FCcBaxuaQEr94ydiZIHGpcFISBOi0YREZWHCVoyRxKUxxq0LXcACQyLsjO6KjSEiDfHDz0S0CLSxlFKd2g7MTDudGd+bMAQCxJucuXfuu+fcO/PeYwzDALVoNMqRuI3guq7rR4g/SEBC/Svxc8T3EUTD4bCGTcZQAUI+RvxLr9d70u/3o6KiAm63G3Qtn89DFEUkk0lks9lRkrvW3t6e2lCgRZFI5F0ikaDtjN1MVVVjYmLCGBoa6qccC7Z1kQafz4f/WSAQAGlyaXOOpQ+SNNUymQxcLhc4joPD4TBzkiRBEASkUimEQiGzdlcBlmWRy+WgKIr5Xi6XUSgUUCwWzTVN+IAzeOOde71orP0eAaOkbrDWf6Cw2+3mBLSYgny3KULXPOUY2BUB/hMd4IOn8XfhMGYjvU+2TECLLRLDMNA0zYw5JYa6Ghke/hyEn9/gZEqo3OuHp7qW3yJgESjoNPSdlb8gWCOCr29BMT0Ip5tBYnIWqlL6o8irzVsEaHcKSqQCen4cweok+FAblNRz2JxlODx1cEkzGWmVbTl7Z/jHhgCF1Z3GYjIKf+U8+ANhQn4Gm6OMUiGI9MhHg5Gl1sbu8UnKNc8B7Ui3ipxEcwvlpVFw6hz2N1xGabkXdqeBYqEOmfefEZWac4e6xz9Z22hbn+BmLBZbi8fjEBdG4NF/QdUDSM88hQ4FawKJR6cxLDZl86qzZdtdoDYwMBAkQg/2LL/ovNLVh++Dd7G0OAau9hTkrKgnnE39GW3f/Z6enpUdBSx7ePu4eq+zi4VNw+TbV0gsxFd5b9X5i4+mpnY63tsErl6okhvrfWzT0SAMR3FMXsnean08Pb/b/fgHqpjCspi90kkAAAAASUVORK5CYII=") no-repeat scroll 2px bottom; padding-left:22px;}
@@ -46,7 +46,7 @@ html/*\*/>/*/*/body input[name="delete"], html/*\*/>/*/*/body input[name="drop"]
html/*\*/>/*/*/body input[name="delete"]:hover, html/*\*/>/*/*/body input[name="drop"]:hover {color:red; background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJdSURBVDjLpZP7S1NhGMf9W7YfogSJboSEUVCY8zJ31trcps6zTI9bLGJpjp1hmkGNxVz4Q6ildtXKXzJNbJRaRmrXoeWx8tJOTWptnrNryre5YCYuI3rh+8vL+/m8PA/PkwIg5X+y5mJWrxfOUBXm91QZM6UluUmthntHqplxUml2lciF6wrmdHriI0Wx3xw2hAediLwZRWRkCPzdDswaSvGqkGCfq8VEUsEyPF1O8Qu3O7A09RbRvjuIttsRbT6HHzebsDjcB4/JgFFlNv9MnkmsEszodIIY7Oaut2OJcSF68Qx8dgv8tmqEL1gQaaARtp5A+N4NzB0lMXxon/uxbI8gIYjB9HytGYuusfiPIQcN71kjgnW6VeFOkgh3XcHLvAwMSDPohOADdYQJdF1FtLMZPmslvhZJk2ahkgRvq4HHUoWHRDqTEDDl2mDkfheiDgt8pw340/EocuClCuFvboQzb0cwIZgki4KhzlaE6w0InipbVzBfqoK/qRH94i0rgokSFeO11iBkp8EdV8cfJo0yD75aE2ZNRvSJ0lZKcBXLaUYmQrCzDT6tDN5SyRqYlWeDLZAg0H4JQ+Jt6M3atNLE10VSwQsN4Z6r0CBwqzXesHmV+BeoyAUri8EyMfi2FowXS5dhd7doo2DVII0V5BAjigP89GEVAtda8b2ehodU4rNaAW+dGfzlFkyo89GTlcrHYCLpKD+V7yeeHNzLjkp24Uu1Ed6G8/F8qjqGRzlbl2H2dzjpMg1KdwsHxOlmJ7GTeZC/nesXbeZ6c9OYnuxUc3fmBuFft/Ff8xMd0s65SXIb/gAAAABJRU5ErkJggg==")}
body{background-color:#eee}
form{margin:0;overflow:auto}
#breadcrumb{position:absolute;top:0;left:0;height:2.6em;margin:0;padding:5px 5px 0 22em;width:-moz-available!important;width:100%;line-height:1.6em;border:1px solid #444;white-space:nowrap;color:#fff;background:#7abcff;background:-moz-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#7abcff),color-stop(44%,#60abf8),color-stop(100%,#4096ee));background:-webkit-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-o-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-ms-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:linear-gradient(to bottom,#7abcff 0,#60abf8 44%,#4096ee 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7abcff',endColorstr='#4096ee',GradientType=0)}
#breadcrumb{position:absolute;top:0;left:0;height:2.6em;margin:0;padding:5px 5px 0 22em;width:-moz-available!important;width: -webkit-fill-available !important;width:100%;line-height:1.6em;border:1px solid #444;white-space:nowrap;color:#fff;background:#7abcff;background:-moz-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#7abcff),color-stop(44%,#60abf8),color-stop(100%,#4096ee));background:-webkit-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-o-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:-ms-linear-gradient(top,#7abcff 0,#60abf8 44%,#4096ee 100%);background:linear-gradient(to bottom,#7abcff 0,#60abf8 44%,#4096ee 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7abcff',endColorstr='#4096ee',GradientType=0)}
#menu,#content{background-color:#fff;border-radius:10px;border:1px solid #444;box-shadow:0 0 5px #999;margin:5em 1em 2em 0}
#menu{position:absolute;top:0;left:0;margin-left:1em;padding:0 0 30px;width:19em}
#content{border:1px solid #444;margin-left:21.5em;padding:10px 10px 30px 30px}

447
designs/rmsoft/adminer.css Normal file
View File

@@ -0,0 +1,447 @@
/**
* @package Adminer.css - Theme CSS for Adminer - gray
* @version 4.5.0.2
* @date Mon, 30 Jan 2018 20:59:32 +0100, Slovakia
* @author Robert Mesaros
* @copyright Copyright © 2018 Robert Mesaros, rmSOFT
* @web http://www.rmsoft.sk
* @link http://www.rmsoft.sk/en/portfolio/programming-work/web-services/theme-for-adminer
*
* @donate https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BB4D8Y28YZDH6
*
* @license MIT: http://mit-license.org/
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @code text/css; charset=UTF-8
*
* Default Silk icon set 1.3 by Mark James - http://www.famfamfam.com/lab/icons/silk
* Modified icons by Robert Mesaros
*/
/* Alternative 1 */
body { background: #f0f0f0; }
h1 { padding: .6em 1em; background: #cc6600; border: 1px solid #894501; }
h2 { padding: .63em 1em; background: #b8b8b8; }
.ltr h2 { margin: 0 0 20px -18px; }
.rtl h2 { margin: 0 -18px 20px 0; }
#h1 { color: #fff; }
.version { color: #ddd; margin-left: 20px; }
fieldset { font-size: 90%; background: #dcdcdc; border-top: 1px solid #ffffff; border-bottom: 1px solid #999999; }
.ltr fieldset { margin: 1.6em .5em .5em 0; border-right: 1px solid #999999; border-left: 1px solid #ffffff; }
.rtl fieldset { margin: 1.6em 0 .5em .5em; border-right: 1px solid #999999; border-left: 1px solid #ffffff; }
fieldset legend { background: #dcdcdc; border-top: 1px solid #ffffff; padding: 0 .5em; }
.ltr fieldset legend { border-right: 1px solid #999999; border-left: 1px solid #ffffff; }
.rtl fieldset legend { border-right: 1px solid #999999; border-left: 1px solid #ffffff; }
fieldset legend span { font-size: 80%; color: #777777; }
.ltr fieldset legend span { margin: 0 0 0 1em; }
.rtl fieldset legend span { margin: .2em 1em 0 0; }
.ltr fieldset select { font-size: 95%; margin: 0 3px 2px 0; }
.rtl fieldset select { font-size: 95%; margin: 0 0 2px 3px; }
fieldset label { vertical-align: -15%; margin: 0; }
fieldset input { font-size: 95%; }
a { color: #cc6600; text-decoration: none; }
a:visited { color: #844200; }
a:link:hover,
a:visited:hover { color: #d00808; text-decoration: underline; }
a sup { margin-left: .2em; }
#help { background: #feeec7; }
#help a { color: #844200; }
#help a:visited { color: #844200; }
.icon { width: 18px; height: 18px; background-color: #cc6600; }
.icon:hover { background-color: #844200; }
#tables a { background: #f0f0f0; }
tbody a { color: #cc6600; }
tbody a:visited { color: #844200; }
#menu p,
#menu ul { padding: .8em 1em; margin: 0; border-bottom: 1px solid #b3b3b3; }
#menu .links a { display: block; margin: 0; font-size: 93%; }
#menu p.message { margin: 10px 0; border-bottom: 1px solid #7fbd7f; }
.ltr p.links { margin: .8em 20px 8px 0; }
.rtl p.links { margin: .8em 0 8px 20px; }
.links a { margin: 0; }
.ltr .links a { margin-right: 20px; }
.rtl .links a { margin-left: 20px; }
.ltr form { margin: 0 20px 0 0; }
.rtl form { margin: 0 0 0 20px; }
code { background: #f0e8d6; padding: .2em .5em; white-space: normal; }
.ltr code { margin: 0 13px 0 0; }
.rtl code { margin: 0 0 0 13px; }
table code { font-size: 120%; background: #f0e8d6; padding: .1em .3em; }
code.jush-sql { background: #f0e8d6; }
pre { background: #e0e0e0; }
textarea { font-size: 120%; }
table,
td,
th { border: 0; border-collapse: separate; }
.ltr table { margin: 1.5em 2px 0 0; }
.rtl table { margin: 1.5em 0 0 20px; }
.rtl table tbody td,
.rtl table tbody th { text-align: right; }
.ltr table thead td:first-child,
.ltr table thead th:first-child { border-left: 1px solid #999999; }
.rtl table thead td:first-child,
.rtl table thead th:first-child { border-right: 1px solid #999999; }
table thead td,
table thead th { border-top: 1px solid #999999; border-bottom: 1px solid #999999; }
.ltr table thead td,
.ltr table thead th { border-right: 1px solid #999999; }
.rtl table thead td,
.rtl table thead th { border-left: 1px solid #999999; }
table tbody tr:first-child td,
table tbody tr:first-child th { border-top: 1px solid #999999; }
.ltr table tbody td:first-child,
.ltr table tbody th:first-child { border-left: 1px solid #999999; }
.rtl table tbody td:first-child,
.rtl table tbody th:first-child { border-right: 1px solid #999999; }
table tbody td,
table tbody th { border-bottom: 1px solid #bebebe; }
.ltr table tbody td,
.ltr table tbody th { border-right: 1px solid #bebebe; }
.rtl table tbody td,
.rtl table tbody th { border-left: 1px solid #bebebe; }
.ltr table tbody td:last-of-type,
.ltr table tbody th:last-of-type { border-right: 1px solid #999999; }
.rtl table tbody td:last-of-type,
.rtl table tbody th:last-of-type { border-left: 1px solid #999999; }
table tbody tr:last-child td,
table tbody tr:last-child th { border-bottom: 1px solid #999999; }
thead th a { color: #b35900; }
thead th,
thead td { color: #b35900; }
.ltr p.count { font-size: 90%; margin: .8em 20px 8px 0; }
.rtl p.count { font-size: 90%; margin: .8em 0 8px 20px; }
#breadcrumb { font-size: 90%; background: #e0e0e0; }
.ltr #breadcrumb { left: 23em; margin: 0 0 0 -12px; }
.rtl #breadcrumb { right: 23em; margin: 0 -12px 0 0; }
#breadcrumb a { color: #cc6600; }
#breadcrumb a:visited { color: #844200; }
#breadcrumb a:link:hover,
#breadcrumb a:visited:hover { color: #d00808; text-decoration: underline; }
#logins { font-size: 90%; }
#logins a { color: #cc6600; background: #f0f0f0; }
#logins a:visited { color: #844200; }
#logins a:link:hover,
#logins a:visited:hover { color: #d00808; text-decoration: underline; }
#lang,
#dbs { font-size: 90%; }
td { background: #f0f0f0; }
.odd td { background: #e6e6e6; }
tbody { font-size: 90%; }
tbody td { padding: .15em .3em; }
thead td,
thead th { background: #c2c2c2; }
.rtl thead td,
.rtl thead th { text-align: center; }
.js .checkable thead .checked td,
.js .checkable thead .checked th { background: #c2c2c2; }
.js .checkable .checked td,
.js .checkable .checked th { background: #f5e1ce; }
.js .checkable .odd.checked td,
.js .checkable .odd.checked th { background: #efd6bf; }
tbody tr:hover td,
tbody tr:hover th { background: #fff9eb !important; }
tbody tr.checked:hover td,
tbody tr.checked:hover th { background: #f5edd9 !important; }
.js .column { position: absolute; background: #dcdcdc; opacity: .9; margin-top: -.27em; }
.ltr .column { padding: .27em 1ex .3em 0; margin-left: .3em; }
.rtl .column { padding: .27em 0 .3em 1ex; margin-right: .3em; }
a.text:hover { text-decoration: none; }
#schema { font-size: 85%; }
#schema .table { background: #dcdcdc; border: 1px solid #b46b0f; padding: 0 3px 3px; cursor: move; position: absolute; }
.binary { color: #aa0000; }
span.jush {font-size: 120%; }
span.jush-bac { color: #d22929; }
span.jush a:visited { color: #844200; }
.message { font-size: 90%; border: 1px solid #7fbd7f; }
.message .time { color: #a6a6a6; }
.message a { color: #844200; }
.message a:visited { color: #844200; }
.message a:link:hover,
.message a:visited:hover { color: #d00808; text-decoration: underline; }
.error { font-size: 90%; border: 1px solid #e76f6f; }
.error .time { color: #cc6633; }
.error a { color: #844200; }
.error a:visited { color: #844200; }
.error a:link:hover,
.error a:visited:hover { color: #d00808; text-decoration: underline; }
p label { font-size: 90%; }
.ltr label { margin: 0 0 0 10px; }
.rtl label { margin: 0 10px 0 0; }
label.block { margin: 0; }
#fieldset-history input { margin: 10px 0 0 0; }
.pages { left: auto; background: #fff7e5; }
.ltr .pages { font-size: 90%; left: 22.5em; }
.rtl .pages { font-size: 90%; right: 22.5em; }
.ltr .pages .loadmore { margin: 0 0 0 .5em; }
.rtl .pages .loadmore { margin: 0 .5em 0 0; }
.pages a { color: #d48d00; }
.pages a:visited { color: #844200; }
.pages a:link:hover,
.pages a:visited:hover { color: #d00808; text-decoration: underline; }
#menu #tables { font-size: 75%; }
#menu #tables a.view { margin: 0 10px; }
.rtl p.logout { margin: 0 0 0 20px; }
.ltr #logout { margin-top: .15em; }
.rtl #logout { margin-top: .7em; }
#sum-Data_length { color: #894806; background: #dcdcdc; }
#sum-Index_length { color: #894806; background: #dcdcdc; }
#sum-Data_free { color: #894806; background: #dcdcdc; }
.ltr #fieldset-history a[href*="&sql=&history=all"] { padding: 0 0 0 18px; }
.rtl #fieldset-history a[href*="&sql=&history=all"] { padding: 0 18px 0 0; }
#version { color: yellow; margin-left: 8px; }
div#ajaxstatus + .message a:first-child { color: red; }
table.checkable thead a[href*="&refresh="],
table.checkable thead a[href*="&dbsize="] { color: #990000; }
/*select (tables)*/
#menu li a[href*="&select="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAFKSURBVHjapJJNK8RRFIefmfmLyEZeFmNjIZEkaSI+A2lKkZ0s7a3EwgdRShQ1+QiI+AQiFgozpPGWae55saCZ/8iC3Drdzrnd5/zOr5Nwd/5zIoCN/eKyOwvq1mlmqIGYoWqoOaIWC0XFUbPTtbnuTARg7ovZTHPrXzqvbF0MVBSoWStA7nIdMUFUCCYEDdVbpfK2NLpGCFofA3z6MNs3/6vubyUhiFY9UDUANg8KvwJMDLdQjgPkCwAwM97O9mGe6bGOSm3nOE92pJo/PJdqFQQ1zJ0oBTtHBVKpJLvHBRJJSH59yp0UwJ26CHrTjZTDtxEciFIJpjJt5E7umcy01yiI5xc3z4hYFZAvviLSxnhPM7eP7wx1NXJ191rZg/50A2fXTzU+NERuMQV+uLp5PlhWawqiBFFUjKCGqPxoZPGltAeQ+O8qfwwAxOXQjeCbPgEAAAAASUVORK5CYII=") no-repeat scroll right bottom; height: 12px; width: 0; display: block; overflow: hidden; text-decoration: none; }
.ltr #menu li a[href*="&select="] { clear: left; float: left; margin: 0 8px 0 0; padding: 1px 0 0 20px; }
.rtl #menu li a[href*="&select="] { clear: right; float: right; margin: 0 0 0 6px; padding: 1px 20px 0 0; }
/*Modify (table)*/
table thead #all-page ~ a { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKhSURBVDjLpZNZSJRRFMd/937fN58zqWPpjBWamYmtlG0YLW+RVEQPLQ9JVNBCENR7UEhFJPUSZZAR0UsLCEE9VGQLLVCG5kJm2CZajjg2rjPfzHdvD4NTRj31h/NwDvf++Z17zxFaa/5HJkDFkVtn3ITYHh5x04ZifzmlxqdeGzK9XKmt2nbYBHCVqDi+b3EgGAgIIUw0oFP3BFqD1mO5xk047K68txNIGoSHXDuQExAHzl5jan4WtqFwtQ3SjxQkQwoMKfja1syJw/uJu0KkWhiJgZQmxUXTmVe2EkMaaO2CMEEIpBAIIZFSYhkSpf54g7E2bTuNNG96kvcvyuivY5NzmcGnL6la+MTfdOHYjnEGcSdKPDoKQqC1QmkXpSQCyB68S3GkAe/8CvyFpfz4VELb/ZrTKQOtoTfSTV8oQlwlUNplINaD4+ZRqB4xL6+DzOIVhDve4REOGZmTSc+e5h9n8L3Hh9UZ/VXQAQrMZ6yb1U7WjLXEvl3H4xN8aWwjMqy1dPoXyDF8rUEaHqRhJ8NMo8DTSEXJW7KK1hHtvoSw+rHSM/CqPi5+WDK89GBtu/yd4HcFBx6wJf8V/pkbiXZVI604zsB0OuveYJQdpcvJcQEkgFYKAYQ+t9LZ+hLZWk355BaCc9fjfK/B8GhiAwV0Pa7nWHMpMrsk9ZVmctaSE3b+5BF6Gm4S0IoEeXxrPsfEoIdoOJ++122I8stUbp4COClSCZDplRGViDLF5xBqqmHOyr3Ync9ov/2cxnth3j9sxL/mBLnBbHJ9cSzpYFtCpwgm2PLGnpMPl4/E9fxV0ZDfab1D4YJVRHr76Kh/r+/4Dg33VLW40AKAbYHX5CqA+HOdt66eNLpoRq65bHYh2oq9GA317tpwqunjv9b5J0pAFDVe4XHbAAAAAElFTkSuQmCC") no-repeat scroll right bottom; height: 16px; width: 0; display: inline-block; overflow: hidden; text-decoration: none; margin: 0 0 -2px 0; }
.ltr table thead #all-page ~ a { padding: 0 0 0 18px; }
.rtl table thead #all-page ~ a { padding: 0 18px 0 0; }
/*Edit (row)*/
/*Edit (row - History)*/
table a[href*="&edit="][href*="&where"],
#fieldset-history a[href*="&sql=&history"]:not([href*="&sql=&history=all"]) { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAFOSURBVHjapNIxSAIBGAVg19bCoEVcchJEsMlFjoZoSKElB8NosCJpCNxaahKhjCMw0C1LjSTIBgWDtOjOE65CIjktrguLsAY7uVOS1yYEegc2vO3/+OHxNAA0g0T14DVjGuIS9o8C6ehQwRncR0zPTwcTY6qwHHPgMboCiachCwwKewRym+ak2jeIpSPI/DVaQhEtoQiJy4IO2juKSP7MQ36JoZpchchGIbJRSFwWDDkrKaIf8QzN8hK+2TXcRpyoHq+D3rWjZzl/UMUN8WES7a9t1FIulHes6Nlq2m9Ao3ahirowtKjXp/0G8MwpqLhHFXUh6dWhwVNov93hfMOC/L4ZlSsv2PA0brYs6DsA0qtDS2BQTyzgPWRDzqNFwj2KlM8IxeU4iWGUwi402UPU2TguA1OKqAvnbCOYJ7QIL48j5TMiE7Ce/Hur/fI7AMEYQUPA30tTAAAAAElFTkSuQmCC") no-repeat scroll right bottom; display: inline-block; overflow: hidden; }
.ltr table a[href*="&edit="][href*="&where"] { background-position: right; padding: 0 20px 0 8px; }
.rtl table a[href*="&edit="][href*="&where"] { background-position: left; padding: 0 8px 0 20px; }
.ltr table input[type="checkbox"] ~ a[href*="&edit="][href*="&where"],
.ltr #fieldset-history a[href*="&sql=&history"]:not([href*="&sql=&history=all"]) { height: 14px; width: 0; text-decoration: none; padding: 0 0 0 16px; }
.rtl table input[type="checkbox"] ~ a[href*="&edit="][href*="&where"],
.rtl #fieldset-history a[href*="&sql=&history"]:not([href*="&sql=&history=all"]) { height: 14px; width: 0; text-decoration: none; padding: 0 16px 0 0; }
/*Edit (user)*/
td a[href*="&user="] { line-height: 19px; }
/* Alternative 2 - Added Icons */
/*DB*/
#menu #dbs span { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr #menu #dbs span { padding-left: 22px; }
.rtl #menu #dbs span { background-position: right bottom; padding: 0 20px 0 0; }
/*SQL command*/
#menu p a[href$="&sql="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAGxSURBVHjapJO9a1VBEMV/73JBVFAMSZ5apjeghaCFYvAjARVBm6CIsbCx8H+wsLcQbAQRxCAIIiha+AEWloGANoKIhSYxIAqRvLs7cyxm38uTvFRZWHbZ3TPnzMzZliQ2M+pbD7/JTKTsNFl0ktNpnNUkmuS4C3NwldWFufByVruLiQO7Atw4q42TTJiJbAGyPlA/+PmHZapsIuVga3KA4iG4gtGdMmMvCSmCVCmXAFmcPTzEhaPDhVlcPjnKzFQbl3CJK5NtJOGlbO5QJxNNds4cGuLxu2WyiX1j2xgf2869F4uYi2und3Pn6Q+2bql6YAglVcpOk+I08hNzn1cKQ0iOx+s74IKqk0R2MfvmJ9MTI1w6MYoVGi95xl4DA9QpO1aq/eDVEubi6lR7TZE2ViApFLjg4vERrPR6/stKD3RkfMeGJnInfGAm7r9cYmYymO8+W+D9/B+un9uzDnTj/F4Abj/5jiRa0zc/6tTB4ZKGsP7el34f27+TxV+JT1///hfs0esFatea0waBAd7O/R6YggS1eViyWzAz9XyvPv93Xdl1oBT3rc3+xopNjn8DAEzJiOP473VxAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr #menu p a[href$="&sql="] { padding-left: 22px; }
.rtl #menu p a[href$="&sql="] { background-position: right bottom; padding-right: 24px; }
/*Import*/
#menu p a[href$="&import="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAJ9SURBVHjapNPPT9NwGAZwEg+cvMrB/8CL8eC/4NEYFHGAooboRb0QvMlRCPsRyZQdwJA5BLvgBqVtvtCVlZWiLpGwLOkC2WjaEr6wLVBDOzIGPN7EZRAPPsl7ePImn9vTBKDpf66uSJLULElSmyiKsfn5eY0QUiOEVAVB+MlxHMOy7K2ZmZlL5wKSJF1LJBKZTCaD3d1dHBwc4OTkBMfHx9jb24NhGFAUBfF4XInFYlcbAFEUk6Zp4vT0FBelVqthbW0N0Wg0fB5QrFar/wRKpRIYhik2AISQ4uHhISilsG0blUoFtVoNR0dHsG0buq5jeXkZlFJMTk42AoIgFCuVCsrlMnRdRy6Xg6ZpyGazUFUVi4uLWFpawvb2NiYmJs4HXNfF/v4+KKWwLAuUUhiGgdXVVSiKAkVRYFkWwuFwI8BxXNFxHJRKJZimic3NTWxtbUHXdaTTaSSTSciyDNM0MT4+3giwLFt0HAc7OzsoFArY2NiAYRjI5/NQVRULCwtIJBIwTRNjY2P1wDOhCz1cJ56yHjyOP8Cjr/ehaRoKhQLW19eRSqXA8zwIITAMA6FQqB7o4TpbnnPdeP/djw8/AuiK3kM2m0U+n0cul4Msy2BZFjzPQ9d1DA8PnwE9cx0tT2c9v/ql13gr9+OdOoSOL611QCqVQjqdBqUUKysr8Pl8Z8CTWU/5jdSH4DcfeoWX8Ey1ov3zHbiuC9d14TgObNuGZVkQRRFer5cODAzc/AN0x9rn+sgr9PIv8HCqnUQikY9tn24jEolgenoaDMMgFAohEAhQr9c7NDg4eKVhTJ3MXeKZao39/RgdHb08MjJyIxgMXvf7/c0Xzfn3ACuyH7V6hJHQAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr #menu p a[href$="&import="] { padding-left: 22px; }
.rtl #menu p a[href$="&import="] { background-position: right bottom; padding-right: 24px; }
/*Export*/
#menu p a[href*="&dump="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAKMSURBVHjajNPPT9NwGAbw3Th59e7Vi/HgP+HBGCLiDyLGqFzARAnGiyReANkPJVN2GErm5mQLU6xdLXRlZcumLhGyLOsy0vFNW0KhkFHSdjgGPJ4Ul0Himzy35/ncXgcAx//mPtOFu/RN3KGu4/ana7gVu9pc4Hm+jef5Do7jPs7OzoosyzZYlq0zDPOTpunI2y/+zh66G6++u/H6hwdd0StN47OJRCKfz+exsbEB0zRxcHCA/f19VKtViJUieqhuDPKPMSQM4mVmFDem2o8AjuOSiqLg8PAQx13f13t4yg/A+82FfqYP1z+0o/P95SZAr9frJwIvss8xwD5Af7wXD6d6fwFwdLy7dASwLKvv7u5C0zQYhoFarYZGo4G9vT0YhgFCCJ58foQh7hnC4bD+Z/cXYBhGr9Vq2NraAiEEpVIJoiiiUCggk8lgfn4eCwsLWFtbQygUOh6wbRvb29vQNA2qqkLTNMiyjMXFRaTTaaTTaaiqikAg0ArQNK1bloXNzU0oioKVlRWsrq6CEIJcLodkMglBEKAoCiYnJ1sBiqJ0y7Kwvr6OSqWC5eVlyLIMSZKQyWQwNzeHRCIBRVEwMTHRCszMzOimaUJVVZTLZYiiiEqlgnK5jFQqhXg8DpZlIcsyfD5fKxCLxfSdnR0QQlAsFlEoFCBJEkqlEgRBAEVRiMfjIIRgbGysFYhGozohBKZpQpKkJiCVSiGXy0HTNGSzWbhcrlYgEolcDIfD1tLSEqrVKmzbhm3bsCwLhmFAVVVwHAen06kNDw9faAEAOEKh0JlgMPgmEAgYwWAQ09PTiEQi8Pl88Hg8mtPpHB0ZGTn97+bE1/X7/afGx8fPe73ec263u+2k3u8BANRmJnJM+MxYAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr #menu p a[href*="&dump="] { padding-left: 22px; }
.rtl #menu p a[href*="&dump="] { background-position: right bottom; padding-right: 24px; }
/*Create new database*/
p a[href$="&database="]:not([href*="&db="]) { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIkSURBVDjLpVNNiFJRFP7eU1E0KSLTMpAwYSxyaidDtChm0WYQ3NSutv2s2kwwm2igNgMtooUQEQhhA9GqhSDTQsZZFDbNDBgVg5bSw9J8rzFF33udc+HGg0ladOHj3nPe+b7zc99VbNvG/yy30yiVSl4SnCNcsixrivYEgY7WJu0faX9EKGUyGVNyFFkBkY/T+WkoFEpFIhEEAgH4/X7w916vB8Mw0Gg00G63y+S7mM1mm4LIAYxisbhSr9c5nT1pjUYju1qt2oVC4YnkqbIUMk6Ew+F/9hyNRkFJLuyaATmFoqZp8Pl88Hq98Hg8wtfv99HpdNBsNhGPx0XsRAG3241ut4vBYCDs8XgMXdcxHA7FN/b9VUD25HK5RAUczKC+hYgcNpNN05xcAQdLkqIoIlj6VFWdXIEUkAQGV8M2k2vaG3z6sYGfVR39XzsHlm/dX3h5d31xlwAHM5goBd5+LuO75z3OnU3jyP4EVrZeKGub2p309cP7VKcAQ2Znoiz3deMVTk1Nw1RNTB+ahamMkD45w7RrfwSYwFdFf6K4Quf6pmvwKHswl7wh7Jvnc4gfTPHR52zhcqVSeZZMJgOxWEyI8BC5CmOnh63WKtZbZczPPsa94hX4XCLJQHG+xnw+f5SEFghZmvhefgvcTqn2HN3gBmZSZ5CInMaHr1Wsvivjy3ZvSZn0nHO5XJDIxwgWDbW2vL10m9xXCUGCQXi49qA1/xvyq6BCh7yZeQAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href$="&database="]:not([href*="&db="]) { padding-left: 22px; }
.rtl p a[href$="&database="]:not([href*="&db="]) { background-position: right bottom; padding-right: 22px; }
/*Privileges*/
p a[href$="&privileges="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAK/SURBVDjLjdJZSNMBHAfw1UMPhfTUQ5bgkfWQSodmYplroiAkXkvXcnOVipqsWhLKXEvnUEHUOecU72tec8vEVgQamUfeUzzThcc2QUqd+09b+u0pMxTz4fv04/d5+PIlASAdFG6wJWsk3351ofoMZstszKVs22I/V9tjf+4HPrN9z1I0lTZbizWnsTsFsXbZhwKKmadEi03O0KoiQHRnQit3x6LMCqP5dj8OBUiCT2bqhlRY/SyBeagchk4JFgZb0ZZyWXMoIND3buRY1bPtteFGbI03wTiqhK5dhGSGp3xfIJJsz8pj3V4VhZEhCaeYo0Mc+0QvYn/q5BzMv34FXXMSOqSP4RRxsdUl3uHEPwDT/Rwlj+W1lU0nY3dKstjILRAgQ8yFMtcf4y001CjC4ci7UHaJc/74DpAVcqWjMNofTfyHGKvhoppDhSiMAmmUF0qHuGh5Q8VyDxtmQw/mP9xHRhUNbtEukh1AHGLXMN0m21OYLJEMueoelj6GwbxSiZVRPpa7eJioCMBQmsf/C0tPCUanwg+b3+uwoeVhQ1+IlWEeiDk+pqSef4GjV3MSxAlxewpzoD5HRYkP1mfSQXyLgWmOA0LDBDFFRT/fzUQCQDriXvsokNNvaNcDwno5kkpkiBeVobZtAL3VUVDLQw1rkwwQ034wzdBhnKCin+9kqgi1ppFsfKVUKrvF2Dy+BcEYEPEFYLQDwvoWfCoLBzFXAOPXIBCT3ujLdl0fTHHRqwXX9DKGdRAAEkktcP7V15gLjkIHpgpgKrdBl22jqy4GG9pyrKmvgxjzwYD4Bgrodg9UQZYW7Qwri50haXJuaRtTn4LG60bke4D1FmAogS4FG5tLQhgn76A7xwO9wpvYb62kycoot9bkwERXapXS+UkvyDw1yLwRpKW+RHdRAN4Jvc1FcV4Ns6U0+n7Ab/dSu26WPRQHAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href$="&privileges="] { padding-left: 22px; }
.rtl p a[href$="&privileges="] { background-position: right bottom; padding-right: 22px; }
#breadcrumb a[href$="&privileges="] { background-image: none; padding-left: 0; }
/*Edit (user) Alternative 3*/
td a[href*="&user="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKjSURBVDjLjZJbSNNhGMZXF912FZEVpOaVFFSCmhe2/iNqhYVsmo1tDXUiJjNnrC0RMxVFxTm3ecJDeSrblorpSFAJzxptOrfFzJnuUJDplG2ZrqchtaSGePFcffx+vN/zviQApL2STQvgzFaFOCytx7HQFLjVyAuqjwkPOvTnfU+YRz1BmJsDPda2Y9idmrRg8b4E9ewjEqsqDDZ1MlzjZbApo2BtPwldVfDqvgRy2uEyu0YNx4gcW5qn2BiVw/K+F4NPzpn3JYilxnH1LZk/17UKeAwqOHWdsA9JkMe6pPQr4JJDODLOZYeESYb8LrGVGn9mWiJI+2FX8rHc9RiWrmQYW2/D1FUATf0VaGWhLB/MjjpNyDgUj5hBxu40lPNQWZOPF01M2AcEWJvpATasWJ1RYLT06hefoDz+/HBt6i2ochOhb8tGK58OCZNAdQoFr8dY+DqXg83lbu8XSuCaVWF7cRiahuRtn0AaH/zSNNj+X2Hqkkis6LLhcQ3D9fEeVibTYWhOxGQdEyZZzN6FWfoz8W1WCI97DM55NtxLDKzrRZiroyCjPA62uht/BQcvVAilwnRfYYZnDNinBL9hFtyf7sChewS9nACn8KLtATc3d6ExgbEDH4h6nhTLf7cx9Bko7FBCLBNC15flHfst3OZEfF9iYs07iUlGuIylEad2b44USK2m03k9zm6DB/l6QNTSjrleEbR9Ylgm6HCaGVjRPIRWTHEZyyKC/r0V0kx+2Pa0ohL8V3aw1UBHMQGsL8JYS8OAKAAj1dcwUEDGvJQKf8dGMldE2xQF95GQMw7uGyCPexabY1JsTlRgwgu2cUNQnCXYKcyv4ENzSmRvXqwonN7SGZYxBVr0URSyQ9FfdB0NRUmIuFm1XJmVtFOYP8EvH33H/9EvkWcAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&user="] { padding-left: 22px; }
.rtl td a[href*="&user="] { background-position: 80% bottom; padding-right: 22px; }
/*Create user*/
p a[href$="&user="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAK5SURBVDjLjZBbSNNxHMVXDz3UQ0892AVSs4Q0shQRA5uzCFGL5Rxqc1u5mZpNnWNN533eaDr976blZeFllc7mMLMl6IOGqdOpS4vAPaRbb6FiQjpPm5QahvmFw5cfP87nezgkAKS9JI4+zp5Wey3Ot57AnMZ9rYnn0RAV6HHoz/+eZl74SYq12d2x0OaGnapL9azeF6CBeYxY6PSHrZeDH8OVsOmCsaA9BYva8/u+AKroo5V2cy8Wh1RYMz/D8nsV5id60F/sZ90XgBoew51pydxYmuyAY7YTKxY97AMEihKu6v4J4JK92Ep26CLBIEPFoqwl033HCGHqT7uOj69dhbAbcjFY+wAXOOd7AgQ+R/4CMIPPUJTsMEd1PBk71SjjQV4nQYUiF/lSAbo+tqCkvwi+eec0F/lnD28BZPRLg0+Sb6Gz4B5m2sRo5dNAMCioTQpDk1kM9bgQVaYMlJsy0f6pAen6NAQlB6i2AAq6Z/uXfu2uwrTZZMjGH6HCJEDxaDpyRlMg+pACtoqFOVXU/wurKI6GYkKEfMN9pKvjwK26ibjSUFAl12B7GrENOHi5RqQQpe0qzIeWBW5dDArb2ei2KGG2GSF7lwK6zBcMoffrTfOB4OeJVL5peeAbUPpSh9xGLQSEBvUjqxAo5hFfcn29a7oaXTMEXCPt40DWl4TAVLdVknt4LY3G614xzDogmQE4I0DCABDTDdC1ADEEROT4ocdSj51jmFK6ACBNSfzXxzrk4L+yg9kLMPUbiNdugKZxIFINRModuPLwNB4b76LMyNo0l71lbSew1oTYOkoyEJs3DK4RYL9xJtADDANwx5WifA6xvCjclnqj0pi4edm1XW8nQEr63JwU1FNEzQ6ktej900dBzptyahpk8SRCsk3wvPHCKs9KLEgQehuchiVX7N+73NXfL+Zkqi9OGtlWAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href$="&user="] { padding-left: 22px; }
.rtl p a[href$="&user="] { background-position: right bottom; padding-right: 22px; }
/*Process list*/
p a[href$="&processlist="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGQSURBVBgZpcG9alRhFIbR5/tRA0Fbbe0tp4tFsHFKLSaNjSIGJlapDIq12BgIxJRaCGIK8QaUNN6BmEJBLNIGCcko55z9bs8WpxlECLNWcnfmkW6uv7l/dXnw9HDii+6AhEuYDJcjF26G3HEzTOLC2fZkf//gwdtnK9t1sDTYOrOwmC8ucBqLJxPbArbrpPU8OTzmtH62ngkPX33xf3n0+qv/z90n771HdRdhvAcjfaBpGobDIVOHx7+wzrHOMReNOZcvncdkhIo7YWeZ3jVm1VJJyUjFKcrUzgnqjFBNRhjvwfUf72jbltFoxFTJkFOhJrDkWBZBJkJ1OWFnmd4NZpUESuAJyImiQpCMUCUjLL2Ae+klTdOwurrKVKqZKiGHDCjxhyRC7dqW8PEOvdvMyvRypgDmTk5O6NqOUN1EuLIJa+eec3R0xMbGBlM5JYKAkhIuEVwiVEmET+v01phVUiIU/iqFIHdCPfj2fXe82a7IDJkwMyRhbcutx5+ROy7DzZELl5AIu/SSuzOPzJx+AwKoFtIrwFHLAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href$="&processlist="] { padding-left: 22px; }
.rtl p a[href$="&processlist="] { background-position: right bottom; padding-right: 22px; }
/*Clone*/
td code.jush-sql + a[href*="&sql="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJFSURBVDjLpZPNS1RhFMZ/5733zkzjR/ZBCUpoJdUiBCkll4m0CUKJIGpVSLjyL2gntDFop6shAolWbcSNIW0ircHBUHCloo3VjNY0jjP3831bWA5ai8Bnfc7vPOfhHDHGcBjZAENji7N1cSj7IcdqY2zkKoiC2qSFNsKPYoXpTPbBynj/4j8BlbLL9c4L3OqoZWLmM4/vXdpX9OJtHq0lBXQdBIgxhvtPZmZ7ui+yspZrjwKfWExxtMbh66YLAgj4geZnyd2YzmT7Vsb75/c5UEqwDLgVl55r57hxuYY3c18Y6mtDgO1KSBBETMwV0VpeA2f3ARKOwvUCcgWX9bzH0NhqvC4Okx9zBzNpPdGQ4OHIrJnOZLtWxvs/2AChNnhRiFIKy8j/ZjILiALYLgc4YnO8zsJSIWUv4Pt2CMBU+tteoxtC0YN8wUdEV1eItMHCIdSagru5l0kQaZ4OdqC1wQAWhqQNnudR3PGrANu2aGmE9FJATSxJwinhegHDr1ZRAmGk0ZHGAMYYMJB0dh0ogOVs6VNqcoGtosYv1+9lYikHERvBQsQCozBGCMIQ3w+rDtKjvQMAd4bfL59vFqYzQasjNoM36wi1vzvHgBFNwo4x8nKNreJOFfBHy9nSXGpyoSPSYOGgqZCae8TJ5BkERb68zsDVZygSlD3/b0B6tPf2byempRFO127T095JQ6wJFBTcJk7VhCRjYItUT/mgrgxOvWtrPtLdEG8gYdcT6gDRGjERWsosrS2TKwbMP78rcth3/gX/0SEvLZFG1QAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr td code.jush-sql + a[href*="&sql="] { padding-left: 22px; }
.rtl td code.jush-sql + a[href*="&sql="] { background-position: 70% bottom; padding-right: 22px; }
/*Variables*/
p a[href$="&variables="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIbSURBVDjLjVPPaxNREJ79Qena1EO6u/GQ9CiFouCp5FQQET0KQvBQbA/tqf+BCEXoyauCl7KFHkoOvYimUpToRTyISVtsliImpCwkLUGqxvzY3bfOvO2+bOgljx32vdn5Zr4336wUBAGUy+V7f96/3PVaDnjNKty17DkYbZ1KpVLppu/7n5nbnVDAh7NXK3Bn4/tIaFVV59R8Pm9ns9nV8aOClZhCbwDguu5QIGMMiGn8rGlamCSXy80ggxfMXAAFPPj9qXipkizLHBQtSZJEQsFg7KBgTZroZGEArWc7TSAchXIA4w+sPdQH1xAMDGQgeXD+4aNIQODZjHaRILT9Wpt/Q8wwA3X/rXVVD3glkQD3h7V/vGrA8Bvz0Rf2AK/F7zRQoY8qIAPn+TLczx/xRPF709nzPOFHayeTyfkBg29vrEkj5BkFPdlu4NtHugH4wYUSqNBaziQGE5hXifXgMVfh115RdHr90TUOIkPNBZtutwvVahUURZFlYuA4zmqzsAl/v24BFhQSRXJFDYvAlUoFUqkU+VmMwSLIyKC1W4ypwISRr9PpgG3bkMlkQNf1YRXkL6+thIlN8y9PIDGgygROp9NgGMZgqOIqEIPa0yV4sPeDgwlIne/1etBoNHhV0zTjExn+Cxh041bl3c8rSY0PCzWIgGQRCxpnSlKv1/m+3++HSaKGLV2fmp9OjN122u7JxnHrYNTf+T+76nzVPsi2lQAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href$="&variables="] { padding-left: 22px; }
.rtl p a[href$="&variables="] { background-position: right bottom; padding-right: 22px; }
/*Status*/
p a[href$="&status="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAH2SURBVBgZpcE/SJRxHMfx9+/uuT8qlgR6mvTHqyGwKMWpbmhvskFa2spFRJxaGlprKBQcKmhqcWloaQ2ixcFaDhUKLDDJSFHvT+fzfD/ffJC2Go5er+Du/I8wPrs4Vbk+9nC74V3ugIRLmAyXIxduhtxxM0ziWD6ur6xs3Hv1eGIhGrs2Np8rdmVKRdrRVW/YPLAQNWLPNLZrtKsZe4ZDkZtz/+Yg7Zqe+0IqchfujpNycCAEPiwv8y+jIyOYjFSEO2bG5Nw6fzyfOUuqUqnwN7VaDSVGKjIZcufp9BkIDh6QO0ecd9UNtvaa1FoFCrmI4x3i6lABmUhFLkcmQgAXhxyCMzw8zNuP69TVxeWhE0S5LFu7B+zst1j6XEMyUhnJkIzEDJMhGUpEtVrlR7NIudTJTiuwuWckIctgXzfbzYAkUlESx5gZM8++88fcZIlUrXlAPp8jaSXIoZU4xShL4hFJnJCK3IQkntzpA5yUJFKdhRwHsREbJHJSHqBRr+MSqUgSkgMiAM6RcvkcvzZj9ptGd0eeljlRJrC5HeM/1zifXSMVxmcXF0unTk7IDJkwMyRhcUwuH9Hf18PoxdPIYbfWwrZWqPR+Y/fT++Tr6tLt4O604/WDG3f7B/of9Q5d6VldetMI7k67Xk5duDVQvvRCSjp+A5XMMGcdZp9aAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href$="&status="] { padding-left: 22px; }
.rtl p a[href$="&status="] { background-position: right bottom; padding-right: 22px; }
/*Replication*/
p a[href$="&replication="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAI3SURBVDjLfZM7aFRBGIW/mXt3swmuaMjGBwqCBlQsRPCB2GknCIpgJSKKkNZGxM7CQrSw0Ngp2vsoLBS0srERUSMiKkFRYkLMO7t778x/LO7VxFdOMWc4//xn5j8wThL/wqnz9w6BrgIrhQNBuSzEQMp/odtnjm7t6m00cC5FQG4OK2rEkHHuyuP+/xpIdDV6GvRfvsWGvr5feuIdn96+4sLpfkxikReA9yl969exZecuEp/gkwreeyqJxwzMFjEwCQM6OmrUOpfAH1kJEU2k7x5sf1Fbunmzc/73sg4QDJ6/HmZUQ4UaiwQ+v/nKsb0QzEid/Ma1e25UnFuQtHPEh3eQwCdVfNJRBlBSpYaAEIyUoBaWdbSHB4hZAn4pztUJ0UAwMjT413gjQ4Og/eTRSMmdl2XErIpMWPMT+ew3zm4bofnsETePGDBUZmBYFsl2V5vgOkM0UpxqFppkc6Bslnx6ivrGY1Qbq1ixehnOuWIsqeCkzucnJ5KKz2KMmkzJPWlnL8s2nQQMJISxJP/I+8EHxDCLxRkUZpA1qfYe58uHMS7dvT8uOJySS4otbO4lipMoTqMwQbfGWd49CWGi1KdQnKVzTUqlNmwPrx1tAKS0kSxg+SgKk8XhMFHux1GYKpsLAylAez7QlExyRBS+l43ljb/MpuebrVWMGRYYKLPxMDfWlc9U61jdSxWwOqgHxTaQIV+w85HYakmZtecNWu2LH68f3IHYh6O+2N9AgHuaYbr9U/oB0sFcUlVzMrwAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr p a[href$="&replication="] { padding-left: 22px; }
.rtl p a[href$="&replication="] { background-position: right bottom; padding-right: 22px; }
/*Refresh*/
p a[href*="&refresh="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAI/SURBVDjLjZPbS9NhHMYH+zNidtCSQrqwQtY5y2QtT2QGrTZf13TkoYFlzsWa/tzcoR3cSc2xYUlGJfzAaIRltY0N12H5I+jaOxG8De+evhtdOP1hu3hv3sPzPO/z4SsBIPnfuvG8cbBlWiEVO5OUItA0VS8oxi9EdhXo+6yV3V3UGHRvVXHNfNv6zRfNuBZVoiFcB/3LdnQ8U+Gk+bhPVKB3qUOuf6/muaQR/qwDkZ9BRFdCmMr5EPz6BN7lMYylLGgNNaKqt3K0SKDnQ7us690t3rNsxeyvaUz+8OJpzo/QNzd8WTtcaQ7WlBmPvxhx1V2Pg7oDziIBimwwf3qAGWESkVwQ7owNujk1ztvk+cg4NnAUTT4FrrjqUKHdF9jxBfXr1rgjaSk4OlMcLrnOrJ7latxbL1V2lgvlbG9MtMTrMw1r1PImtfyn1n5q47TlBLf90n5NmalMtUdKZoyQMkLKlIGLjMyYhFpmlz3nGEVmFJlRZNaf7pIaEndM24XIjCOzjX9mm2S2JsqdkMYIqbB1j5C6yWzVk7YRFTsGFu7l+4nveExIA9aMCcOJh6DIoMigyOh+o4UryRWQOtIjaJtoziM1FD0mpE4uZcTc72gBaUyYKEI6khgqINXO3saR7kM8IZUVCRDS0Ucf+xFbCReQhr97MZ51wpWxYnhpCD3zOrT4lTisr+AJqVx0Fiiyr4/vhP4VyyMFIUWNqRrV96vWKXKckBoIqWzXYcoPDrUslDJoopuEVEpIB0sR+AuErIiZ6OqMKAAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href*="&refresh="] { padding-left: 22px; }
.rtl p a[href*="&refresh="] { background-position: right bottom; padding-right: 22px; }
/*Create table*/
p a[href$="&create="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIpSURBVDjLpZNPSFRRFMZ/749/Kt3IqFTSRoSMmrGIYTTbpEJtjBCCok1Em9JVG1dRC8FFEES5aGFEgRRZWq1iLKKxBiNqLDcltQgmHR9hY6LOu+feFm+YGVsZXbh8nHO53/nud8+xjDH8z3IB7r5avGgMZ8XoBq01okFpjYhGtEGJLtmCKINo/XbgVFPUBdDG9PVEq0P/UvnSvdlwQYFoHQIY/3obpRVKFL5W+OIXUVThrL91AN+XihKCwIeTu85sqPryqsJXUvRARAMwkshsiKB7fw25UgKVJwA40V7H/cl5jh+oL+RGk/P0xIqxl11dr8AXjTYG14HRNxkcx+ZhMoNlg52/ND6VAWMoc6F5+2Zy/l9PMIDrWByL1jI+tcDRaN06BaXxbDqLUnq9AqPBteHpuwUcJ0AIcgBXH93h+/wEyyuLrPk5cmv7gNY8gdIYYyhz4PDeWuIpj85IsS2ujQ2zJAk6DkZpqGnixcwYyU+PifUOX7Eh6DoAx7aIpzwA4imPeMrj+bTH+88PaNkZQWwhsrULsXxie9oAzgcESgUe2NAZCeE6AXZGQhwKh/Cyc5RZVXQ39wFwoeMmjXVhgMqiB8awe0cVP36u0Fi/iW9zvwuzkF3+xUz6Nal0gv6uWww+O02lUwGwmv8FM3l55EtLTvQWXwm+EkRpfNEoUZRXHCE5PUFbuJ0nH4cot1wSH14C3LA2Os6x3m2DwDmgGlgChpLX0/1/AIu8MA7WsWBMAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href$="&create="] { padding-left: 22px; }
.rtl p a[href$="&create="] { background-position: right bottom; padding-right: 22px; }
.rtl #media p a[href$="&create="] { background-position: right bottom; padding-right: 24px; }
/*Alter database*/
p a[href*="&db="][href$="&database="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKRSURBVDjLhVNLTBNRFD3TTju1FCcBaxuaQEr94ydiZIHGpcFISBOi0YREZWHCVoyRxKUxxq0LXcACQyLsjO6KjSEiDfHDz0S0CLSxlFKd2g7MTDudGd+bMAQCxJucuXfuu+fcO/PeYwzDALVoNMqRuI3guq7rR4g/SEBC/Svxc8T3EUTD4bCGTcZQAUI+RvxLr9d70u/3o6KiAm63G3Qtn89DFEUkk0lks9lRkrvW3t6e2lCgRZFI5F0ikaDtjN1MVVVjYmLCGBoa6qccC7Z1kQafz4f/WSAQAGlyaXOOpQ+SNNUymQxcLhc4joPD4TBzkiRBEASkUimEQiGzdlcBlmWRy+WgKIr5Xi6XUSgUUCwWzTVN+IAzeOOde71orP0eAaOkbrDWf6Cw2+3mBLSYgny3KULXPOUY2BUB/hMd4IOn8XfhMGYjvU+2TECLLRLDMNA0zYw5JYa6Ghke/hyEn9/gZEqo3OuHp7qW3yJgESjoNPSdlb8gWCOCr29BMT0Ip5tBYnIWqlL6o8irzVsEaHcKSqQCen4cweok+FAblNRz2JxlODx1cEkzGWmVbTl7Z/jHhgCF1Z3GYjIKf+U8+ANhQn4Gm6OMUiGI9MhHg5Gl1sbu8UnKNc8B7Ui3ipxEcwvlpVFw6hz2N1xGabkXdqeBYqEOmfefEZWac4e6xz9Z22hbn+BmLBZbi8fjEBdG4NF/QdUDSM88hQ4FawKJR6cxLDZl86qzZdtdoDYwMBAkQg/2LL/ovNLVh++Dd7G0OAau9hTkrKgnnE39GW3f/Z6enpUdBSx7ePu4eq+zi4VNw+TbV0gsxFd5b9X5i4+mpnY63tsErl6okhvrfWzT0SAMR3FMXsnean08Pb/b/fgHqpjCspi90kkAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr p a[href*="&db="][href$="&database="] { padding-left: 20px; }
.rtl p a[href*="&db="][href$="&database="] { background-position: right bottom; padding-right: 22px; }
/*Database schema*/
p a[href*="&schema="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAFOSURBVDjLtVK7SgNRED0b9iuM2lr4QK1DQIyk0FZsJAj+gH+ilRZb2NjaRHTLmA9QFKz9huzm7t37Hu+u7IJgQjR6YLjDzOXMmcMERIR5EE5qXA4z4sqACYWEC5wfLQXf/WtMIuDSoL0A7DZDjBj/uYI0l8jzEEJYJMkvCEZM4PqZIxlzpGk+kSCY18TGtGYcx9Tv96dOqBUMBgNyzsFaC621312Ac+59yJFlGRhj5VvVoigKvniglEK32w1mkd3r9ejPPAjOhqdknYX18p1/rzo3pYqTh0OSRkJI5UMgPn4s61sX66SkhtEGcISGsQad5gH2FvehfV5BaIF2cwet5RZyKeu68pe5ubKG7dUNP5AQGltMN57Mosgr5EIiVQmYGvtc1PVicqHY+dXpk8Dg7v22XKFo1ARe9v1bDOlXKKKCs4Sn1xdU1v3vIc2CD3bN4xJjfJWvAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href*="&schema="] { padding-left: 22px; }
.rtl p a[href*="&schema="] { background-position: right bottom; padding-right: 22px; }
/*Create view*/
p a[href$="&view="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHTSURBVDjLY/j//z8DJRhMxE8+VwjEE4D4DBD/j5989l/8pLP/4yec+Z8IpJMnn/2fOPH0//i+0+9TJp063b3uxv/uNdf/Ixsw+z+JoHPVNRQDboB4c468hePZeDAIJPYc+4EwYOLZDzADDt76AsaHbmPHMAMiWg7+gxsQN+HML5DgbAI2I7sgvHEfwguxfaf/kRoGoXV7EAbE9JwCC4bU7/nvU7vrv1fNLjD/3tMPWDFYbc1OhAHRXSfAgg5l2/83L7v436J4G9yA1++/oWCYAcEV2xAGRHUcBwsa5235X7f0wn+9nE0oBjx78/X/moMr/5fMTPif1uf/P7HL679veRGSC9qOgjXopK//X7rg7H/tlLUoBizfu/h/4+rE/1uuTP1/4dmu//27s/6H9+v+N8+W7IG4oO0I3ICS+ZgGgGzceHnC/43XJoHFe/ak/u/fkw4y4DvYgIimQ/9gBoA0IxsAwj7Vhv+3XZmDEgubLk0FGQDJEKENB+7hizL7QqX/3buS/rfvSgDz23cmoLogtHZff0jN3q3B1XveBVfu+h9Yvu1/YNmW/wElG//7F63975wX/z+4R+N/764UsM0gGsSHhwExGKi4A4g/gZwNpTtA4gDRWxxGCQ/RXQAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href$="&view="] { padding-left: 22px; }
.rtl p a[href$="&view="] { background-position: right bottom; padding-right: 22px; }
/*Create procedure*/
p a[href$="&procedure="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ1SURBVBgZBcFNiJVVGADg5z3fmTujY5NZBANBIVkZ2J9IKkZFGKRuglq1KaqVtoqoVbSKFi1LoY2QEVSbcqiFWWJqPxL044wUGESQVqJOKerce7/z9jyRmba++tXTy2YmnyphPaYQIJBBNuPWfls8l1/EfxdeOrJnxxAgMtO2148d2ffC+rWlxMqkkwBkQjp7aeT97xf99cfS5ZPzv6w6umfHElQoXdw+qN3KhX90JYIgG30243G6Muo9tOYa999WfdfOLs92x4UHd3163eG3ti8ViIgVmdkNumKiUIOu0AURFIFmdmZgx4ZZt9w6uazOTO+FAklAQQlKhBKhRCgRShfOnL/i5hUjd64Kz2+6XjfRPQkVIJPaEUJGaH1SQu0YZHHqXBq2sdaGHlg9KWoZQ4VMEjWKlBJRQiAb2RUGlBZa66RCFFAh0RBBCIlENiY6QBTRhyypIROo0MZk0hDITFAKWqhdkkGSQt/oG1ChtZSZJCkBSCCEE79+Yv7UnIuXLxiNR8rwnsomFfpGn2SjAUjQkuPzHzp98XMPb9ngplVrHFr42OX5ubpx1943K7Rxaple+2EopBZkBo2MNL3wnie2P6ovvbtntzp48iMb1232+6n9OyuMx72+Z3Zmwn03Fi3pkz5oyWffnjERKzy29lnw4iPvmDuxG/unKoyXWhu3lsNefPNnr0VKAVpy/tK/Fk5/7afTR72yda83DjxjqpuEqxVGV/u/pwfdDS+vG05nZpE0wLXLqn2Lzzn287s237XF3IndBlEd/fEwvB2ZacPOgzvHo3w8Iu5NuRxAkkhpovug1u5Q5SoGfWurDxzf/eW2/wEnITFm/fHryQAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href$="&procedure="] { padding-left: 22px; }
.rtl p a[href$="&procedure="] { background-position: right bottom; padding-right: 22px; }
/*Create function*/
p a[href$="&function="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAK9SURBVBgZBcHLi1VlAADw3/edc+fRmOP4YEzERxQYZGaQaQ8qRDCK+gPcGC1rYbjRWtqiTaAULWrRItwVVAaFBUIvhqjAyixIE41JB8fxzsy9c+855ztfv1/IOYPDH1/bg5N3rxnb169b/bpVt62Vpu1iCTeRsIB5fIizJUDbNI/s2rhq39EnNwCAXtVO9qt2cmGQNlc1S8Pkys1lX1zqHcCREqBtmunVIwFcu510QlAGipLRTrRlNCpi1CnYvXncpsmJte//OPtWBEh1vXqipGlZqoJuze0h3QHdAfMrzC0ncPz0Vfu2T7h/fWdDCZDqeu2dI1FvSG+QxBiUKApiQSEoAi1CWjRzecEvV7uzJUCqqunJ8UJ3pdEfZjFmRSSmoIgUsqJALtxYHDr11d+LOFwCNFW1dXp1R3eQNZApUhAzEoWszFGbSZ2kqZrtn7762K0IkKrh1o2To3pVFiJFCCIiAiBkcqYZDqVqmKCEgye+HC+LODLaiaqURBlZRhJAQIzUKVnu9RssQgnNsNowMTEmBlrIhEAU5EwIXLx0xl+XP7fUXzAV+0V3+cbrHHyjhFQN7ygnRpSRIgapDeSsRQj8+udH5vtfe/rxh21ee69zFz4JM79fP7H3lU1r4hNHTq9vqurEnh1bXF/MrtxIbi0lvYqUsxCyny6c9uCOXVJMdt11QAq1vTsfhZfLVFX78ezPF/+xsFJaHmZ1yoZ1UDWtJrWWuv/phFWeue8lcHT/e8789i4+GytTXT/0wlMPjL92aC8ASJk6ZVXD88e7Lsz+4Pzsd44d+MCbZ180VozCoNi48+A9U5MTz80v1a7O9cwtDiz2a3WTFTEa6QQpDX3zxxnbpre52f9Xtzfn+/PfWrw9PBV2Hzq5HkewFeuwDlOYwuTYSKczNtYRRs5ZSTPaPEDok9+eeWf22P/PLlOL9Py8xgAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href$="&function="] { padding-left: 22px; }
.rtl p a[href$="&function="] { background-position: right bottom; padding-right: 22px; }
/*Create event*/
p a[href$="&event="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAITSURBVDjLpZNNSJRBGMd/s7q50ZoWISZSRAgF5VpELFJ0CK9RneokEl1qO3URpFNCXqIO0aFLEF0iiAj6JBB0WYwOoikRJiXUYqbsumv7zvu+M/N02BV30YPgc5h5GPh/zMz/USLCVirCFqt+tZGfb8UUFxEJEBMiNkRMgBgfsT6EGms0YjwINU0Xn6haAmuIHrm0TkEEFFQWQCD3/PJ6B37+N9tFEOeVDxSIOEAhrDGoSAMSehtcwRhcMI8pfgLnIxKUdxeA04jTiPPYtucCLixtQGB9wCBOg4QVUDVYI64EYpBgAwdmZalsuUbZwzldIfHAeWUR8289gbMaPTOK8b+DDUAMVheI7W8pKzuNWA/E1byBWg3S4oteibZ0EO86DzhcMEdx/BkN+3aBlBie1YzMOZY9j6CU489K/tabOxOD9VVMhAuT5D6m2dl9FaUUTkKQEu+/FZny45w5fYL23R0MT79kbGr0djLV1hyp/u/Gk72E+b/kR+5VwBqxmtdfc3QdSmAjlsTeHqwKSR7tBri+FmWjUXURdhy/gphmiplX1MUSxFr7WCgsEVVxzh2+AcDNs4842NIJEKvKgSb37j5iNBJ6BN4XmM1Q+vyUQiFgOpthIpumv+cxQx/6iNU1AGi1mWlMptoG2w80DXR3nqKj9Rgz8+NkJtP8+rF8V212nJOptiHgGtAIFIGHYw+y/f8B3ntD1Kp2NbQAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr p a[href$="&event="] { padding-left: 22px; }
.rtl p a[href$="&event="] { background-position: right bottom; padding-right: 22px; }
/*Alter procedure Alternative 3*/
td a[href*="&procedure="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAK5SURBVBgZBcFPaJZ1HADwz+95n3e6uTnREGdljRKtGCYiHTLxkIUmQeeCOnXzVnQIoi5BQV08TMo6GIiHiKI6ZEWgszzEmtpqSDP7s9ycm9NN977vnuf37fNJEWH/G6df6l676vki2YXVSCAhEpFVOU8uzMX36daNV88MH+oApIhw8O2zZz45vOuhokjrgoYAIALC7NKKEz8vmP67fee3XyfWjwwfakMJRSNt6yob68avaRQpkYhMHVlVheWV2r6tffYPjNi4eLyncWCodf7jI1Jr6sUSUkq9EdHoajQkIZALZOpEIWlPf27r4jndQy/oH9xp4c9tJk4de7eEIEGBlAgJREqKRP/yKXVcsH7r4+Ynf9eVOvrWbtK7YUt/CRBB2SBJIiW5Doqkd3nEllWj+gef1r56UldP8tfYhJt3UhTtuR0FRBAoU6FISYFGkaxePG1LfKv/gYNa/30oNW9o9vbpzvOOXj+wsvvwZ5cKCGSkRJGSIiWtK19af/uU/gef1ZoaVjRXdG7db+bMed173zJVD2QoIFdEkBG4fflrPYs/2vjIMzrTxzS6QvvWfWZGRs3tGZY2bFdnoICcQ0QQTI+e1L3wk5W82dWLR2Qtt+fvNnNuwuLeo1LvgNXNpK4CFFBn6iAysxc/8vCel636Z8SlL84a+2be+Hdjlh57R9WzWaDZKFSdCpSQq5AjvPlLx9DkrM74VwZ3POHm7JzJsUk/7PvU9Sv3yipwYlPTSjuDEqqqVtcMrG0a/+Oa9z8Ytnv7oOXNOyw9edyjffeIIIIL1yqRw0qrAiVU7ZyrnKNTS+te/9flFCYlkJdIS5UcRJEUOSnLlKs6V1DCSqueWdPVuOu1oc6aiCgEGdDfXYIIuptJSnKzkRbrKk9BCSnFe0+9cvq5lNLOED0AgkAIIEAr5zxaFk7A/5IUWNTkV3l/AAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr td a[href*="&procedure="] { padding: 0 6px 0 22px; }
.rtl td a[href*="&procedure="] { background-position: 80% bottom; padding: 0 34px 0 6px; }
/*Alter function Alternative 3*/
td a[href*="&function="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAMCSURBVDjLTdBNaFxVGMbx/zn33plOZjIT8zmGOnFM1VoNJYFWYi2CtVSMdKUbK+LKhSAGXYhd2m6FQkEXLbiwETcWiq3WpiiSBLRqTa122pEmMZPmw8lkMt93zrnnXhdJbB54l++Ph0cEQQDAm1/l9gOnHmnbMVzXPnXto32fhueXgAqwChigCBSAz4ErNpvxPe/pvcnY8PvPdbE9NeUn6spPFF2zU2moNA1zq1W+vVs7DIxuB3riIQFAbt3gCIEtwLIh7EhSYYklJY4Fgzsj9Cai7WeuLX4stwCjdTxqg+dDRQlKGtabUHI3rtCAf6sGgA/H5hlOR3mq0+mytwHtrSFJrQk11yClwAYsC6QFFgJLgA8IU+anmSLX50uL9wGlehIRi1LDo94MkDLAkiCNwJJgEbCj/AN/j3/G250D1CZ/5BWdHPsf8JTq64k7lNwADyAAywhksLF9vPI17WvXiAy8TiI9yPrs4zSunH1jW4NmXzIRJrNiEBIkG88SaKlcJuX8SezRA6zdzRASitZ4klhHKmEDvHjicsS2ZCjsSJQxSAIgIADCtSnS9i8k0kdoLn1JqEXwz/RttKsKbqP6jATwmqorLEBujkQAAohUJtglrpLofwl38QzCKeLEWtHVRV+Xl17Y9875rNys32LjY0uwpAAhMfOXSJmrJHYdxb33KdLRqPLDrEzc4PTC4dtD741PA8iDo2OdnlIn9u9OsVwOmFsxlLKXSOqf6X5yBLV8FisU0Cz3kZ/8ndzAR2Sq3TNb29lGqUPAyG+ZWYoNG2fhG14dyOP5vSzdPM0D3SHctYfITd1CHvqEhZyLUSq/BUij9dDLB56IfHF8hJOvPcYeLrLn2bcI5ybJXphi+rs17nx/g4n2D4i09VKp1jFaF+430Hp2ebXEufEMbbEI2Zk86q+LpPcepJQvcO/mDM8fv8CDoX7CNuTXKhitF7YAMXjsVCcwCvQBHf25k0eG0l1i3+60mFPR4HxuSLhOB/FohLZ4C3/cyWWBY9fPvfsrwH+7HFmMUqkOrwAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr td a[href*="&function="] { padding: 0 6px 0 22px; }
.rtl td a[href*="&function="] { background-position: 80% bottom; padding: 0 34px 0 6px; }
/*Select data - table id:Rows- Alternative 3*/
/*Select data*/
td a[href*="&select="],
h2 ~ p a[href*="&select="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHkm9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1zztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wGhGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUHYJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWluUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhNTWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7nHADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGFrwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&select="] { background-position: right bottom; padding: 0 20px 0 8px; }
.rtl td a[href*="&select="] { padding: 0 8px 0 30px; }
.ltr h2 ~ p a[href*="&select="] { padding-left: 22px; }
.rtl h2 ~ p a[href*="&select="] { background-position: right bottom; padding-right: 22px; }
/*Show structure - table id:... Alternative 3*/
/*Show structure*/
th a[href*="&table="],
#content h2 ~ p a[href*="&table="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJcSURBVDjLpZPtT5JhFMafrW997I9rscA+FFu2QRurtlw5cQ4InLpwBogIPNFSiNJ4C+JVkj0QTBHQKFPQlJfwlanY1tXz3ARkn2jd27Wz++yc33XOvd0UAOp/RNGR/X5zeH9rOlTDVKAK3fsqJrxlqN27GHPuYHh+G4rXRQzZNjEws47Hli/oo/PxNsAU3qvWT3/gX3TPuHrWBhiC30nSktXDtKLB1NI4NKkxqBMqjDByPFkcxNBCPwbCfXgUeEBq705m0AZM+qsk2e3hau88W+4ANOy+XPLFQrkrcbW31KkOYJx9rBaAOzPR0gVHW6x593q9cDgcqB6e4sZoogMYdXzD0ck5ZhfLsHGKVfAqVoadKcMdzcLr82PuwwZCoRACgQCWVzdhoK2gaVpDAMNzWzhkAXamQpze/I4t13w+j2AwiFwuh7W1NXg8HmQyGSgUCshkssuU3F7AQf0c84kK3n68KFc4hXQ6DavVCqlUCqVSSdaIx+NQq9UGMsHg7Ab2jxtwp5rOvqUqia3CUqnEObWn0mp1KBaLcLlckMvloPpfrhOAl230/SGLxQK3241CoQC9Xg9nskKk1emQzWZZkBZCoRBU3/NP2GMBgXTTObjSjI1GA8lkEgzDwO/3E4iObXY6nYhEIhCJRHoWcIW6b1pF7egMlYNT7NROUKzU8XX3GJ+3D2E0GgmAm4Zbh2s0mUyIRqMcAGKx+BIlMeSiYu1K/fbEMm4+TaFnJIHrSgZX5TFIZNPo7e1Fj9QOs9kMlUqFaw9pCASCnzwe7x15xG6/rUQiAZ/Px9/5XyhZOMVGKlOdAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr th a[href*="&table="] { padding-left: 22px; }
.rtl th a[href*="&table="] { padding-left: 30px; }
.ltr #content h2 ~ p a[href*="&table="] { padding-left: 22px; }
.rtl #content h2 ~ p a[href*="&table="] { background-position: right bottom; padding-right: 22px; }
/*Alter table - table id:Auto_increment- Alternative 3*/
/*Alter table*/
td a[href*="&create="],
#content h2 ~ p a[href*="&create="]:not([href$="&create="]) { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJ6SURBVDjLpZNZSNRRGMV//2XGsjFrMg2z0so2K21xIFpepYUiAsGIICLffI8eWiBBeg3qQV+KwBYKLB8qpHUmrahcKLc0QsxldNSxdPz/79LD1ChBUXTh8sG93POdc75zDa01/7NsgGvPR09rzQmpVZZSCqlAKIWUCqk0QqoZWyKFRir1uvxIbsAGUFqXHQqkpP1L57M3Pm5MMJBKpQHUdF9BKIGQAlcJXOlOVykSdye3leO6MmkGQNyHw+uO/1X3bzGBK+S0B1IqAKqDg3986HeCZPffwvJtoNT7lOZLvUdtAPEDAKBkRzo3QwMUb89InN1uGGD3spdE214xe8MRUnM2MfppNW0Pqy7YAK5UKK2xLbhdP4hlmdxpGMQwwQT8ziNiI534c7cT6WrFazikzF2Eb8HS1IQEDdiWwcHAQmpehTkQSAcgNvSMiYFW5uUUMdV3HW+ywefGNqITJsbUUL75k4FWYJtQ+yaMZcXrk1ANk/33mbdiD7EvlRieETy+FJLkMFcjRRSW3emIAwiF1hqPBfu2LGSWbbA1uZ41SfWkrtxPrPcypsfFiWYzFGzGKTjFV28WEJeIUHETLdOgrmkI1VdHpCdEet5enP4qLK9mKrqMgedv6cyrAP+qxOTiUxAi7oEJi8frELoFoTLpa7nI/HQvscgSRt+0kV1SSW7qYtp7xrBMphm4Mi5h/VIfTcEq1u0oJaknSEdNiMYHET7UvcMpPEN31Ed7zxgASmk1I0g6dK66s8CRak5mVxjnfS05+TsZCw/T9baTx1nnGb47DrQksjE6HrsHYPz6nYt3+Sc3L8+wA2tz0J6pF5OD4WP7Kpq7f5fO79DfSxjdtCtDAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr td a[href*="&create="] { background-position: right bottom; padding: 0 20px 0 8px; }
.rtl td a[href*="&create="] { padding: 0 8px 0 30px; }
.ltr #content h2 ~ p a[href*="&create="]:not([href$="&create="]) { padding-left: 22px; }
.rtl #content h2 ~ p a[href*="&create="]:not([href$="&create="]) { background-position: right bottom; padding-right: 22px; }
/*Alter view - table id:... Alternative 3*/
/*Alter view*/
td a[href*="&view="],
#content h2 ~ p a[href*="&view="]:not([href$="&view="]) { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJeSURBVDjLpZNLSNRRFIe/O81o+WjISM0epuarEHuDqIFEDyoqEFtFD4gWQVDQoo0QhFARbowKNNpKi0DJRYVGqRmY5oPUBs3S1GnMcdR0/v8Z554WM44RGURne7nf+X6cc5SI8D9lBTh79/0VIBkoAHaCCIJCCxaLwqJAa40O4LFZpT9z/cpdaOFqcZZCRDhT0V4p/1i3HveIiAQNgEKAh83usNrfgp3Pj6NvyGOGI6AlceExPT4SAKX+/PnjNxMAr+GPCANEJGqhq8NlLtk53myk0FlN/0QO19a+Ul33Lp4OArRYF9SWqrmxWqb7WliRcwp7ynY8g5n0Pa+6vQBQACXX6zG0RgvU3djP4OhUMI7nBXZ6iEvPxz3QS4TyEbsykZjVG+0hgAbgu9fPvm1J1LWNhDtH+1qxSRf21IOYY9VERCm+dPQxPatQvolcS8gAgBkjgF+EOXM+OImpZmw/GrCnHcYYrUTZJrHFxBItbh4N5bH70hOHBUCFDEzTj9cfIGD4cfbWEjX7GvvmYxgj97HY/PimN+Fq7GTNgTKchh2AoMEvUxeBnKgOPF+bid96BJ+zimURgjmdzHhTO6qonOUJ2YjMLwL0vA4ThluqKT0UwBdIYqy7Ao3BrHsdrre9qKJyVHQCodgSBgS0/gzQ/eAExWntbCm4QORwE46aZjqeuXG87GTD8TukZmSRkmQPmcrk4iYGdE1JaUOGiOTlulyrfB+ekpJbyNT4BANtDupjLzNe9g6R1lBIPQOWXgD1+zmf3Bvn3ZGaYN2TnYLYzDde1/i5oze7Pi21YD8BVSdMJ0n4cQkAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&view="] { background-position: right bottom; padding: 0 20px 0 8px; }
.rtl td a[href*="&view="] { padding: 0 8px 0 30px; }
.ltr #content h2 ~ p a[href*="&view="]:not([href$="&view="]) { padding-left: 22px; }
.rtl #content h2 ~ p a[href*="&view="]:not([href$="&view="]) { background-position: right bottom; padding-right: 22px; }
/*New item - table id:Data_free- Alternative 3*/
/*New item*/
td a[href*="&edit="][id^="Data_free-"],
p a[href*="&edit="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGSSURBVDjLlZO7S8NQGMVb/weRgoI4iIuCVuoiuBfBwUFwaosPqJODk5OLBVutSlMsuDg4OVWkYO3o4Cha/BNS+qLP9K3HnEtT07f94HATcs8v33eSawBgUGtSlVmVZYimVY3Ro8nQBJgrlUq2Xq9/NxoN9JL6HD6f76oTogEsNBeLRSiK0lIul0Mmk0E8HheQWCwGSZLaICwjAdxQLpdRrVbFShUKBWSzWSQSCQEolUrgSwKBgIB0AWjWRAAN+XweyWSya6RmJsY2gDpGawOvObc2SiqVEp3Istwf0Ck9hJ0wj3Q6/X+AHsJxmAlBIwGoWq0mciGEGhnALkJvDzgK2LB3sQH7mRWrjtmbgQCaNAVf73HyYMdTVMK7HIb3xYkt7zxWDkyeoQC273BbEfy8RPDrGixPZBfeyD4B5aFfgVo/XkQoegt9PX5IBEAP+OmXwdrhDNxhB1xhmzC7nm1/HTR/x2U1ZUXd3PMw+YOn2PTM4Ty8I97MlfcigyZgipBBR3lhe/zO4jQpbJvrkn3CT+8vh7avwsYhJlIAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&edit="][id^="Data_free-"] { background-position: right bottom; padding: 0 20px 0 8px; }
.rtl td a[href*="&edit="][id^="Data_free-"] { padding: 0 8px 0 30px; }
.ltr p a[href*="&edit="] { padding-left: 22px; }
.rtl p a[href*="&edit="] { background-position: right bottom; padding-right: 22px; }
/*Alter indexes - table id:Index_length- Alternative 3*/
/*Alter indexes*/
td a[href*="&indexes="],
p a[href*="&indexes="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKRSURBVDjLhZHfT1JhHMb9F7ptXXXR2lw/Llp3blnNZauLtmwtp15oWsu6oJZ5bKyFQiGIEIRIKoEsJtikWM1JmiQhtpieo3ISUoEINiJNE2SgT5x3ZiVZ3+15v3t/PJ89+755APJ4PJ64s7MzZDKZYDabYbFY0NvbSzq35867u7uh1WpjfD5fwXl+iixqtXoi2xfw/0ppNJrPOQC9Xp/O9vXTvCf4l7jKJkUOgIvH1bmGPlQ1D6Na+gY1Micut77FFcUoapVj5I4rnU6XCzAYDJuAmqz50hbzNdUvQJfu8d8BmUwGMzMz8Hq9oGkaHo8HbrcbTqcTDocDQ0ND+B62gzWeh8/ahPGOIkyo8ssJYCMWmXxLSwtYloXRaIRYLCag6I3rmKUKERmswyJtA5bDWKAtcElORAmgo4MMBqFQCIFAAH6/Hz6fj6RhGAasuw3xqTtIhZ4h8roZCeYpMvMjYLqqkwSgaW8nAKvVCrlcjmAwSNLIZDLM0ibEJ29jLTGCxMdaxMeuwmuoBK0t+zKmOLOHAFQqFQFEo1FEIhGEw2GSZp4x4ytTj7WkCyv+CiSDpViapjCnORJ9Lz1+cHOIcrmCAGw2G5RKJYHY9HxE3tVtmMuRDFzAt8kGsKoifJAcPvTHLzRLJAQQi8WI2FEjpvtvZmM7kJyrxGqwDIvZJH7NSTyUCnK/USgUpocdjnW73Y6+R3xMvaAw8bIVn9wlWJkrRXz8FrzqUxgZ6FsXikSJHABFUYxA0LgiFIrQc/8YsDQPtv0sBqmdcLYVY0BQgAfCetwVNK5m37pyAL9LcDE/nXIpkXLL4W4qRE/VruX++v0Htr7bFlBSsCMpqtibfnWvOG2XHh1+Xrdv93ZmTj8Aff0H4WdEl0kAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&indexes="] { background-position: right bottom; padding: 0 20px 0 8px; }
.rtl td a[href*="&indexes="] { padding: 0 8px 0 30px; }
.ltr p a[href*="&indexes="] { padding-left: 22px; }
.rtl p a[href*="&indexes="] { background-position: right bottom; padding-right: 22px; }
/*Add foreign key*/
p a[href*="&foreign="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJRSURBVDjLjZLta5JRGMZH/0X0DzhG0Wy1PdVG6aIGtYI+9CVhRSt6gT4Vgavl2vI9LVIWrWL0KZTYpBqpFMUMZ03aMpXVMttLpPX47qPT7eqck2NWzjpwcXjOc67ffZ37nBoANdU0M9RqJkJJ5j///5e5mPvEVAnyb3PGi3z0LgrJZ2R5iUFCFslAVUC5OfdVj/z3weXqoCM0yMFt4p5XA7DI1CzMXkLu200i5y+IVYKlIo/pfjGDrAqgkamZaU7BIIWEE6kpLTLTbVjMvcCUcSNWTyC8JwnUKxAG6kHSvxtxbxM53kP4u2ormtfQHkRGzxLDZSQmmpH5IEM2dBKpwAHExhtQiPXB310L+9WG4N/3bduFiOs8FngrqcYR8z5SvRNJ73bExsTMHFDUwaHa7PutidS8VEyQczqQnZUjPilCxteI7OcrmHnQghHXRZy7dRjHr+2HrHfHYtuFDV0MUP7S8hELUsF2UqkOKX8zhLAGHo2Y16ulvMJyBI98Jrydt8PgOIVDhvVoPL1WV6ocJ5GHkA5KwbtFSAd2Qviixmut+IdN1XRfpmwVht8ZMey/wd6BztkJg/MEBQgUkFyIOUizOPAuEbIf24m5Dx6tmH+s5W7TmHvl9XjiG0D5sE2aKKB05+lXSPilpGF7kAn3wK2qj4/ouf7l/nBn1gla+1Eo7R3MrHzasZIgbJWMC9FRZMPdEObvYUwjjtmNW6+XXy3Z2HtQJ4LefoxVpjP9Zj3w3GmRT5i3zL0xborSM780bVNWelxks4ooSWOXZhVd/wllWOl+7RbUkgAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr p a[href*="&foreign="] { padding-left: 22px; }
.rtl p a[href*="&foreign="] { background-position: right bottom; padding-right: 22px; }
/*Edit (foreign key)*/
td a[href*="&foreign="][href*="&name="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAKsSURBVHjahJJZSJRRGIaf/3f+UZomK21UzMxWDSuiTaKgZZQugjLaLiLqQknvjK6im67aCIrMCZEuWqBIaypNSNBpMyqUSKKyXHAc3EdHnfnHf5nThQtGWQc+OB+87/u933uOJITgX6fzSXYJUDDRuhburSn8DSCEmLG8bmeJ1+0URrhVGOFW4XU7hdftLJmO+T852CjG+m4JfbhWCBERXrdTtD3cWTaJk/62wqTtpOxLGMN1SEo8vW/uALBwbw3tt7fQM4pnc2H9jpkERNLuUozBxwgzgKQ4gHT63l0AI0LyvnLaypz0mdEeeabwhNaOMAPjd2MA+Ia0/CTBMQctVS5GlHjmGaHtMwpISgJSlG1CzUTXkxn6WEXi6qMs23mc1I35BMLxyH+xLwMuf0MpIqKiDdQRCK6i42Uly3flovq/ora/xz4nkZgFiyNTGUy9tywRHbeOuRmbCHdfIWI/h+/VA9JzTzDWdR91QKL3e4jQaFBXVXW2ZdrwguQ9FZjBD+gjHkKdZ5HjbuDz3CN9fx5h301kq4EyOxWb6KT42eeVN563aJbpP033v0Dz38EItBCynWew9i4ZB/IJ+1zIioE2nEZ//SeW5FVKx7rXU1wlsIxPLscY9qD1Xkcf8mGNTaL//VMyD51A6y4jyioIB1Lpf9tIYk4KHy6vn7JtAUaMkY921XsRc3SQmIQVtDVnQoKDrqbrzHNYCftTGGr4RlJOCpgd0vTQLYBdUmygzCLaEUtlRZCDBfl8v3+a5tf1RC9aixwaIKuoWhJmALXtCJm5DmYtqwZAjhiRRkONoNi2ItsO86O1D+1LJWlrt2GzraSnqYWsomoJoLF4F8AUGcDSEzAeDT08lahrplXoQv7ys3f+1VIXGzPSsC9dQ+6ZWgmg4dqGP8gAvwYAN7Z8lOPI6HwAAAAASUVORK5CYII=") no-repeat scroll left bottom; }
.ltr td a[href*="&foreign="][href*="&name="] { padding-left: 22px; }
.rtl td a[href*="&foreign="][href*="&name="] { background-position: 80% bottom; padding-right: 22px; }
/*Add trigger*/
p a[href*="&trigger="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJlSURBVDjLpZNbaM9hGMc/v8NsTqF2yMhZKIexmpFyRZIiblwouZDauLYoTVEryg2uXIoIOUU5zJkh4e9QDmtJbWxrbUzz/72/9/m6+P3HLslbT9/3ufm+n/f7Pm8gif9ZMcDxe717JLZ62UQzwxukZnhveBOptyHl8anwZk/3b5pZEwOYtGNDzejSfzm58dTH+b8JvFkpwMizdSCBT8E8OJftkzy4BPIOnONHQzPO+eIhBoM5CCrLwNKslBZM8uDykCbwtgMAl/o/GXhvBYMA2rtAlpGYZSR+UIGKCgCSggGSOHy1Q/0DTifufZUknbr/RZJ0+mHWn3mU9edbMu3qG9DmQ08lKSNw3jCJOIKzjzqJopBzLZ3EEVx40smDr/u4e96QGUXPGpkzYQSJywjCwSsIiKOADUvKiUNYX1tOUQhra8oJg4hZ02cQhhGrqyuyp03tTwbOGzKIQ7j8rIsn3Qd4fEVIIn6+kzAMaH35Fn37wbZD68gnCUl+EbAkI3CpIYmiCNZUlwEwbfIUgiBg1cIyJqbzGFPiWbl8GXUb66mqnkrJ2IvUbq88GEI2dQBRGHDjZTcAbZ8+ERDQnOvm+fszVM1egA89C8avwAeO2nlLAeqRxK7j79TzPa/mXJck6darTG8XdM3uhbry+piGrou5I1pcP17h7wwk5k4aRUfPANMrhtP2pZ8J44bx7nMfff29vGl/SNP1LQA0XdtCa2cO4GdhkPRg78kPVYm3kS71uNTjU8N5I/UpxSWracndZOn8ZVx6dZRhQcz9F3cAjgR/+51rt1c2AXXAaOA7cLTlcHvDL6y6kIpO9lqsAAAAAElFTkSuQmCC") no-repeat scroll left bottom; }
.ltr p a[href*="&trigger="] { padding-left: 22px; }
.rtl p a[href*="&trigger="] { background-position: right bottom; padding-right: 22px; }
/*Edit (SQL)*/
#content p a[href*="&sql="] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAJ+SURBVHjapJPLS1RRHMc/M86M5GtoSMcKMq2ITI0kgh5USJmGhYsIogh1IUgrIfoLwtq1iDBQS3qAtJLoCRGFYGTgq0WWpBiYjk6ao6Mz995zfi3O9UG468DhHA6/7+P3OB4R4X+Wr+nJT1FKsB2N5QhJW5O0NAlbsGyN1oLSoMU9taC0oN03n9ZCWelGA7Y0CUtjK0EpwVEGpNaA1oJffIzidZRgO0bNcgzIBIIWo6g17jZ3EUHEkHhtxyVwhHOHQ5w/vslVFq6U51BbGUaLoEWoqQgjImi3bFqDz1aC5WjOHgrx9H0URwnFBWmUFKTT9jKC0kJ9VS53OyfYkOqlurCPxd7HpGQUc6LoAz7b0Vi2oTT5CX3DcUoK0lcsA4iAnZzFP9FFbvFlgvn7+TO6G1/SFhwtdLyb5mJZNgD3X0WMRTdPgJzMJRZGWgjtOsLMj68EPBaZWbnGgXKr/fDNFEoLdZXhVUcCyp7n1OZ2gttPk5zoIJDmYax/iNgieJO2Cbp0Mhvl9npwJL5iO5S2ROzbTYI7zpD41YLHP4s/I5N0maFx8KqZA6WE9tdT1FYY5XvPJukajJEVWKAs1EZwZzWJ8Wa8fgcrlk+0u59Pec2ITBuC5X63PJ9EuXkHA3EO+FvJ2VuFNdlKSkBIzOUR7e6jJ7+FqZipkVfL6qQplyjdO0+p5wGW2sLElztoEsRntvK7Z4jPLng5RZ/SZiRXCqaEmlAjhQ1tfOu4xveublK37WMuMs4juc1YbwTtTqKI4FnvN96oL7Kv1zX48Cr633YyNjq8EMwOHS1vGhj4N3ZdggvHQkulBWHfwT35iD/ZvTQ1XVt1a3Bkve/8dwDixMULwcWPDAAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr #content p a[href*="&sql="] { padding-left: 22px; }
.rtl #content p a[href*="&sql="] { background-position: right bottom; padding-right: 22px; }
/*Edit all (History) Alternative 3*/
#fieldset-history a[href*="&history=all"] { background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJRSURBVBgZpcHda81xHMDx9+d3fudYzuYw2RaZ5yTWolEiuZpCSjGJFEktUUr8A6ZxQZGHmDtqdrGUXHgoeZqSp1F2bLFWjtkOB8PZzvmd7+djv5XaBRfL6yVmxv+QjQeu7l25uuZYJmtxM0AVU8Wpw9RQU8w51AxzDqfKhFjwq6Mjdbj1RN0Zv2ZFzaloUdwrL2Is4r+y7hRwxs8G5mUzPxmrwcA8hvnmjIZtcxmr3Y09hHwzJZQvOAwwNZyCYqgaThVXMFzBCD7fJfv8MpHiKvaV3ePV2f07fMwIiSeIGeYJJoao4HmCiIeIQzPXifY+paJqO4lZi/nWPZ/krabjvlNHyANMBAQiBiqgakQMCunbxHJviM9bQeZdBzHJUzKhguLJlQnf1BghAmZ4gImAgAjk++8jP56QmL2GXG8zsfFCz8skA1mQXKbaU3X8ISIgQsgDcun7FL7cJjFnLUMfLyLRr0SLS4hbhiup5Szd19rpFYKAESKICCERoS95neyHmyTmbmAodQ4vGpAfmEn6YTtTahv4ODiRkGdOCUUAAUSE/uQNfqTaKFu4jvynJiIxIzcwg/SjF1RsOk9R+QJMlZCvqvwhQFdbM4XvrynIVHpfn2ZSWYyhzHS+PUtSueUC0cQ0QmpGyE9197TUnwzq1DnUKbXSxOb6S7xtPkjngzbGVVbzvS/FjaGt9DU8xlRRJdTCMDEzRjuyZ1FwaFe9j+d4eecaPd1dPxNTSlfWHm1v5y/EzBitblXp4JLZ5f6yBbOwaK5tsD+9c33jq/f8w2+mRSjOllPhkAAAAABJRU5ErkJggg==") no-repeat scroll left bottom; }
.ltr #fieldset-history a[href*="&history=all"] { padding-left: 22px; }
.rtl #fieldset-history a[href*="&history=all"] { background-position: right bottom; padding-right: 22px; }
/*Error*/
.error { background: #efdada url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAIcKAACMCgABCaAAAHkXAABTlgABDrYAADr6AAATiGV4+hEAAAIySURBVHjapNNPSJNxGMDx77t/7zbdu02dUzJKpX+6JOzfUrNgeegghB08RKcuURBBERQRQUF2bpJ0ESGCDkKeU4gOVlB0ik4WhWQ69842bbq97+/pMBOiWYLP5ffwex4+D88PfpqIsJnQJhKJsoVot+2JVs1mbcuxMmdWR1KT7kK5Psd6suHPvQvsbdKDsQbD686PrNdXFqg7Wmw2Ks1WT3wYd+wGNb5Uf+RQvnnDQKgyM+ltO67hdOIIb8G3v0OrcGXHNgTUdy/3G96FWv3wIGr6Kmouid5xn7Aj3Rppz/b/F6gOzI94us4hBRNz6AXm4BiyPIW/5yxBzEf/BLYeyyUD22t0T9s1ih96EQERsD5exnPwEuGdNUZtLJUsC0Q7C9HqitQFd/sVpDANNqAElCC2QhZfo3depKqYOh9sMaN/AYa+8Na/74DmrG/H/noPEFx17tWqYE/dxb0thhHf4/Qu5Z79AUSP5BNBPdOgdw0huVfIj/cABE6EqOw2QADbwp55gL83STg9G/c3fEusAVW++TE93gd2BpUeLS0OZB6nWHyZBUqrqJk34MwQ6EsQyKSfADivn4ncjjS6e3wnh1GZUeT789WJgr5bx7tLR3NpaCKAIOlxvD3DyMTTikXHvKbN3Wm0QqdvOV07ToFaLk0DcGilU7F6p9beA4eP/PhDvgwMFLTPN1umQprZJJYgRQFL8TuXFUEt2aifCsnbKFuhLIUohSjBNEKftM1+518DAEJB6cbyeH5EAAAAAElFTkSuQmCC") no-repeat scroll 0.8em center; }
.ltr .error { padding-left: 40px; }
.rtl .error { background-position: 99%; padding-right: 40px; }
/*Message*/
.message { background: #efe url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLvZPZLkNhFIV75zjvYm7VGFNCqoZUJ+roKUUpjRuqp61Wq0NKDMelGGqOxBSUIBKXWtWGZxAvobr8lWjChRgSF//dv9be+9trCwAI/vIE/26gXmviW5bqnb8yUK028qZjPfoPWEj4Ku5HBspgAz941IXZeze8N1bottSo8BTZviVWrEh546EO03EXpuJOdG63otJbjBKHkEp/Ml6yNYYzpuezWL4s5VMtT8acCMQcb5XL3eJE8VgBlR7BeMGW9Z4yT9y1CeyucuhdTGDxfftaBO7G4L+zg91UocxVmCiy51NpiP3n2treUPujL8xhOjYOzZYsQWANyRYlU4Y9Br6oHd5bDh0bCpSOixJiWx71YY09J5pM/WEbzFcDmHvwwBu2wnikg+lEj4mwBe5bC5h1OUqcwpdC60dxegRmR06TyjCF9G9z+qM2uCJmuMJmaNZaUrCSIi6X+jJIBBYtW5Cge7cd7sgoHDfDaAvKQGAlRZYc6ltJlMxX03UzlaRlBdQrzSCwksLRbOpHUSb7pcsnxCCwngvM2Rm/ugUCi84fycr4l2t8Bb6iqTxSCgNIAAAAAElFTkSuQmCC") no-repeat scroll 0.8em center; }
.ltr .message { padding-left: 40px; }
.rtl .message { background-position: 99%; padding-right: 40px; }
.ltr #menu .message { padding-left: 40px; }
.rtl #menu .message { background-position: 95%; padding-right: 40px; }

View File

@@ -7,8 +7,13 @@ if ($adminer->homepage()) {
if ($_POST["query"] != "") {
search_tables();
}
echo "<table cellspacing='0' class='nowrap checkable' onclick='tableClick(event);'>\n";
echo '<thead><tr class="wrap"><td><input id="check-all" type="checkbox" onclick="formCheck(this, /^tables\[/);" class="jsonly"><th>' . lang('Table') . '<td>' . lang('Rows') . "</thead>\n";
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 '<th>' . lang('Table');
echo '<td>' . lang('Rows');
echo "</thead>\n";
foreach (table_status() as $table => $row) {
$name = $adminer->tableName($row);
@@ -21,6 +26,6 @@ if ($adminer->homepage()) {
}
echo "</table>\n";
echo "<script type='text/javascript'>tableCheck();</script>\n";
echo script("tableCheck();");
echo "</form>\n";
}

View File

@@ -4,7 +4,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 href='https://www.adminer.org/editor/'" . target_blank() . " id='h1'>" . lang('Editor') . "</a>";
}
//! driver, ns
@@ -45,30 +45,38 @@ class Adminer {
}
function headers() {
return true;
}
function csp() {
return csp();
}
function head() {
return true;
}
function css() {
$return = array();
$filename = "adminer.css";
if (file_exists($filename)) {
$return[] = $filename;
}
return $return;
}
function loginForm() {
?>
<table cellspacing="0">
<tr><th><?php echo lang('Username'); ?><td><input type="hidden" name="auth[driver]" value="server"><input name="auth[username]" id="username" value="<?php echo h($_GET["username"]); ?>" autocapitalize="off">
<tr><th><?php echo lang('Password'); ?><td><input type="password" name="auth[password]">
</table>
<script type="text/javascript">
focus(document.getElementById('username'));
</script>
<?php
echo script("focus(qs('#username'));");
echo "<p><input type='submit' value='" . lang('Login') . "'>\n";
echo checkbox("auth[permanent]", 1, $_COOKIE["adminer_permanent"], lang('Permanent login')) . "\n";
}
function login($login, $password) {
global $connection;
$connection->query("SET time_zone = " . q(substr_replace(@date("O"), ":", -2, 0))); // date("P") available since PHP 5.1.3, @ - requires date.timezone since PHP 5.3.0
return true;
}
@@ -77,7 +85,7 @@ focus(document.getElementById('username'));
}
function fieldName($field, $order = 0) {
return h($field["comment"] != "" ? $field["comment"] : $field["field"]);
return h(preg_replace('~\s+\[.*\]$~', '', ($field["comment"] != "" ? $field["comment"] : $field["field"])));
}
function selectLinks($tableStatus, $set = "") {
@@ -132,8 +140,8 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
}
}
function selectQuery($query, $time) {
return "<!--\n" . str_replace("--", "--><!-- ", $query) . "\n($time)\n-->\n";
function selectQuery($query, $start, $failed = false) {
return "<!--\n" . str_replace("--", "--><!-- ", $query) . "\n(" . format_time($start) . ")\n-->\n";
}
function rowDescription($table) {
@@ -184,10 +192,10 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
}
}
if (like_bool($field) && $return != "&nbsp;") { // bool
$return = ($val ? lang('yes') : lang('no'));
$return = (preg_match('~^(1|t|true|y|yes|on)$~i', $value) ? lang('yes') : lang('no'));
}
if ($link) {
$return = "<a href='$link'" . (is_url($link) ? " rel='noreferrer'" : "") . ">$return</a>";
$return = "<a href='$link'" . (is_url($link) ? target_blank() : "") . ">$return</a>";
}
if (!$link && !like_bool($field) && preg_match('~int|float|double|decimal~', $field["type"])) {
$return = "<div class='number'>$return</div>"; // Firefox doesn't support <colgroup>
@@ -244,13 +252,15 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if (($val["col"] == "" || $columns[$val["col"]]) && "$val[col]$val[val]" != "") {
echo "<div><select name='where[$i][col]'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, $val["col"], true) . "</select>";
echo html_select("where[$i][op]", array(-1 => "") + $this->operators, $val["op"]);
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "' onkeydown='selectSearchKeydown(this, event);' onsearch='selectSearchSearch(this);'></div>\n";
echo "<input type='search' name='where[$i][val]' value='" . h($val["val"]) . "'>" . script("mixin(qsl('input'), {onkeydown: selectSearchKeydown, onsearch: selectSearchSearch});", "") . "</div>\n";
$i++;
}
}
echo "<div><select name='where[$i][col]' onchange='this.nextSibling.nextSibling.onchange();'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, null, true) . "</select>";
echo "<div><select name='where[$i][col]'><option value=''>(" . lang('anywhere') . ")" . optionlist($columns, null, true) . "</select>";
echo script("qsl('select').onchange = selectAddRow;", "");
echo html_select("where[$i][op]", array(-1 => "") + $this->operators);
echo "<input type='search' name='where[$i][val]' onchange='selectAddRow(this);' onsearch='selectSearch(this);'></div>\n";
echo "<input type='search' name='where[$i][val]'></div>";
echo script("mixin(qsl('input'), {onchange: function () { this.parentNode.firstChild.onchange(); }, onsearch: selectSearchSearch});");
echo "</div></fieldset>\n";
}
@@ -305,14 +315,15 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
function selectEmailPrint($emailFields, $columns) {
if ($emailFields) {
print_fieldset("email", lang('E-mail'), $_POST["email_append"]);
echo "<div onkeydown=\"eventStop(event); return bodyKeydown(event, 'email');\">\n";
echo "<div>";
echo script("qsl('div').onkeydown = partialArg(bodyKeydown, 'email');");
echo "<p>" . lang('From') . ": <input name='email_from' value='" . h($_POST ? $_POST["email_from"] : $_COOKIE["adminer_email"]) . "'>\n";
echo lang('Subject') . ": <input name='email_subject' value='" . h($_POST["email_subject"]) . "'>\n";
echo "<p><textarea name='email_message' rows='15' cols='75'>" . h($_POST["email_message"] . ($_POST["email_append"] ? '{$' . "$_POST[email_addition]}" : "")) . "</textarea>\n";
echo "<p onkeydown=\"eventStop(event); return bodyKeydown(event, 'email_append');\">" . html_select("email_addition", $columns, $_POST["email_addition"]) . "<input type='submit' name='email_append' value='" . lang('Insert') . "'>\n"; //! JavaScript
echo "<p>" . lang('Attachments') . ": <input type='file' name='email_files[]' onchange=\"this.onchange = function () { }; var el = this.cloneNode(true); el.value = ''; this.parentNode.appendChild(el);\">";
echo "<p>" . script("qsl('p').onkeydown = partialArg(bodyKeydown, 'email_append');", "") . html_select("email_addition", $columns, $_POST["email_addition"]) . "<input type='submit' name='email_append' value='" . lang('Insert') . "'>\n"; //! JavaScript
echo "<p>" . lang('Attachments') . ": <input type='file' name='email_files[]'>" . script("qsl('input').onchange = emailFileChange;");
echo "<p>" . (count($emailFields) == 1 ? '<input type="hidden" name="email_field" value="' . h(key($emailFields)) . '">' : html_select("email_field", $emailFields));
echo "<input type='submit' name='email' value='" . lang('Send') . "' onclick=\"return this.form['delete'].onclick();\">\n";
echo "<input type='submit' name='email' value='" . lang('Send') . "'>" . confirm();
echo "</div>\n";
echo "</div></fieldset>\n";
}
@@ -429,7 +440,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return "";
}
function messageQuery($query, $time) {
function messageQuery($query, $time, $failed = false) {
return " <span class='time'>" . @date("H:i:s") . "</span><!--\n" . str_replace("--", "--><!-- ", $query) . "\n" . ($time ? "($time)\n" : "") . "-->";
}
@@ -459,7 +470,11 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
if ($options !== null) {
return (is_array($options)
? "<select$attrs>" . optionlist($options, $value, true) . "</select>"
: "<input value='" . h($value) . "'$attrs class='hidden'><input value='" . h($options) . "' class='jsonly' onkeyup=\"whisper('" . h(ME . "script=complete&source=" . urlencode($table) . "&field=" . urlencode($field["field"])) . "&value=', this);\"><div onclick='return whisperClick(event, this.previousSibling);'></div>"
: "<input value='" . h($value) . "'$attrs class='hidden'>"
. "<input value='" . h($options) . "' class='jsonly'>"
. "<div></div>"
. script("qsl('input').oninput = partial(whisper, '" . ME . "script=complete&source=" . urlencode($table) . "&field=" . urlencode($field["field"]) . "&value=');
qsl('div').onclick = whisperClick;", "")
);
}
if (like_bool($field)) {
@@ -481,6 +496,10 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return '';
}
function editHint($table, $field, $value) {
return (preg_match('~\s+(\[.*\])$~', ($field["comment"] != "" ? $field["comment"] : $field["field"]), $match) ? h(" $match[1]") : '');
}
function processInput($field, $value, $function = "") {
if ($function == "now") {
return "$function()";
@@ -539,6 +558,9 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
return $ext;
}
function importServerPath() {
}
function homepage() {
return true;
}
@@ -548,7 +570,7 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
?>
<h1>
<?php echo $this->name(); ?> <span class="version"><?php echo $VERSION; ?></span>
<a href="https://www.adminer.org/editor/#download" target="_blank" id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
<a href="https://www.adminer.org/editor/#download"<?php echo target_blank(); ?> id="version"><?php echo (version_compare($VERSION, $_COOKIE["adminer_version"]) < 0 ? h($_COOKIE["adminer_version"]) : ""); ?></a>
</h1>
<?php
if ($missing == "auth") {
@@ -557,7 +579,8 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
foreach ($servers[""] as $username => $password) {
if ($password !== null) {
if ($first) {
echo "<p id='logins' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
echo "<p id='logins'>";
echo script("mixin(qs('#logins'), {onmouseover: menuOver, onmouseout: menuOut});");
$first = false;
}
echo "<a href='" . h(auth_url($vendor, "", $username)) . "'>" . ($username != "" ? h($username) : "<i>" . lang('empty') . "</i>") . "</a><br>\n";
@@ -581,16 +604,19 @@ ORDER BY ORDINAL_POSITION", null, "") as $row) { //! requires MySQL 5
}
function tablesPrint($tables) {
echo "<p id='tables' onmouseover='menuOver(this, event);' onmouseout='menuOut(this);'>\n";
echo "<ul id='tables'>";
echo script("mixin(qs('#tables'), {onmouseover: menuOver, onmouseout: menuOut});");
foreach ($tables as $row) {
echo '<li>';
$name = $this->tableName($row);
if (isset($row["Engine"]) && $name != "") { // ignore views and tables without name
echo "<a href='" . h(ME) . 'select=' . urlencode($row["Name"]) . "'"
. bold($_GET["select"] == $row["Name"] || $_GET["edit"] == $row["Name"], "select")
. " title='" . lang('Select data') . "'>$name</a><br>\n"
. " title='" . lang('Select data') . "'>$name</a>\n"
;
}
}
echo "</ul>\n";
}
function _foreignColumn($foreignKeys, $column) {

View File

@@ -3,8 +3,8 @@
* @link https://www.adminer.org/
* @author Jakub Vrana, https://www.vrana.cz/
* @copyright 2009 Jakub Vrana
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
include "../adminer/include/bootstrap.inc.php";

View File

@@ -1,5 +1,8 @@
// Editor specific functions
function messagesPrint() {
}
function selectFieldChange() {
}
@@ -11,7 +14,34 @@ function helpMouseover() {
function helpMouseout() {
}
function whisperClick(event, field) {
/** Display typeahead
* @param string
* @this HTMLInputElement
*/
function whisper(url) {
var field = this;
field.orig = field.value;
field.previousSibling.value = field.value; // accept number, reject string
return ajax(url + encodeURIComponent(field.value), function (xmlhttp) {
if (xmlhttp.status && field.orig == field.value) { // ignore old responses
field.nextSibling.innerHTML = xmlhttp.responseText;
field.nextSibling.style.display = '';
var a = field.nextSibling.firstChild;
if (a && a.firstChild.data == field.value) {
field.previousSibling.value = decodeURIComponent(a.href.replace(/.*=/, ''));
a.className = 'active';
}
}
});
}
/** Select typeahead value
* @param MouseEvent
* @return boolean false for success
* @this HTMLDivElement
*/
function whisperClick(event) {
var field = this.previousSibling;
var el = getTarget(event);
if (isTag(el, 'a') && !(event.button || event.shiftKey || event.altKey || isCtrl(event))) {
field.value = el.firstChild.data;
@@ -21,20 +51,12 @@ function whisperClick(event, field) {
}
}
function whisper(url, field) {
if (field.orig != field.value) { // ignore arrows, Shift, ...
field.orig = field.value;
field.previousSibling.value = field.value; // accept number, reject string
return ajax(url + encodeURIComponent(field.value), function (xmlhttp) {
if (xmlhttp.status && field.orig == field.value) { // ignore old responses
field.nextSibling.innerHTML = xmlhttp.responseText;
field.nextSibling.style.display = '';
var a = field.nextSibling.firstChild;
if (a && a.firstChild.data == field.value) {
field.previousSibling.value = decodeURIComponent(a.href.replace(/.*=/, ''));
a.className = 'active';
}
}
});
}
/** Add new attachment field
* @this HTMLInputElement
*/
function emailFileChange() {
this.onchange = function () { };
var el = this.cloneNode(true);
el.value = '';
this.parentNode.appendChild(el);
}

2
externals/jush vendored

View File

@@ -3,8 +3,8 @@
/** Hide some databases from the interface - just to improve design, not a security plugin
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDatabaseHide {
protected $disabled;

43
plugins/designs.php Normal file
View File

@@ -0,0 +1,43 @@
<?php
/** Allow switching designs
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @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)
*/
class AdminerDesigns {
/** @access protected */
var $designs;
/**
* @param array URL in key, name in value
*/
function __construct($designs) {
$this->designs = $designs;
}
function headers() {
if (isset($_POST["design"]) && verify_token()) {
restart_session();
$_SESSION["design"] = $_POST["design"];
redirect($_SERVER["REQUEST_URI"]);
}
}
function css() {
$return = array();
if (array_key_exists($_SESSION["design"], $this->designs)) {
$return[] = $_SESSION["design"];
}
return $return;
}
function navigation($missing) {
echo "<form action='' method='post' style='position: fixed; bottom: .5em; right: .5em;'>";
echo html_select("design", array("" => "(design)") + $this->designs, $_SESSION["design"], "this.form.submit();");
echo '<input type="hidden" name="token" value="' . get_token() . '">';
echo "</form>\n";
}
}

View File

@@ -3,8 +3,8 @@
/** Exports one database (e.g. development) so that it can be synced with other database (e.g. production)
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpAlter {

View File

@@ -4,8 +4,8 @@
* @link https://www.adminer.org/plugins/#use
* @uses bzopen(), tempnam("")
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpBz2 {
/** @access protected */

View File

@@ -3,8 +3,8 @@
/** Include current date and time in export filename
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpDate {

View File

@@ -3,8 +3,8 @@
/** Dump to JSON format
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpJson {
/** @access protected */

View File

@@ -2,8 +2,8 @@
/** Dump to PHP format
* @author Martin Zeman (Zemistr), http://www.zemistr.eu/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpPhp {
var $output = array();

View File

@@ -3,8 +3,8 @@
/** Dump to XML format in structure <database name=""><table name=""><column name="">value
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpXml {
/** @access protected */

View File

@@ -4,8 +4,8 @@
* @link https://www.adminer.org/plugins/#use
* @uses ZipArchive, tempnam("")
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerDumpZip {
/** @access protected */

View File

@@ -5,8 +5,8 @@
* @uses jQuery-Timepicker, http://trentrichardson.com/examples/timepicker/
* @uses jQuery UI: core, widget, mouse, slider, datepicker
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEditCalendar {
/** @access protected */
@@ -16,7 +16,14 @@ class AdminerEditCalendar {
* @param string text to append before first calendar usage
* @param string path to language file, %s stands for language code
*/
function __construct($prepend = "<script type='text/javascript' src='jquery-ui/jquery.js'></script>\n<script type='text/javascript' src='jquery-ui/jquery-ui.js'></script>\n<script type='text/javascript' src='jquery-ui/jquery-ui-timepicker-addon.js'></script>\n<link rel='stylesheet' type='text/css' href='jquery-ui/jquery-ui.css'>\n", $langPath = "jquery-ui/i18n/jquery.ui.datepicker-%s.js") {
function __construct($prepend = null, $langPath = "jquery-ui/i18n/jquery.ui.datepicker-%s.js") {
if ($prepend === null) {
$prepend = "<link rel='stylesheet' type='text/css' href='jquery-ui/jquery-ui.css'>\n"
. script_src("jquery-ui/jquery.js")
. script_src("jquery-ui/jquery-ui.js")
. script_src("jquery-ui/jquery-ui-timepicker-addon.js")
;
}
$this->prepend = $prepend;
$this->langPath = $langPath;
}
@@ -27,8 +34,8 @@ class AdminerEditCalendar {
$lang = get_lang();
$lang = ($lang == "zh" ? "zh-CN" : ($lang == "zh-tw" ? "zh-TW" : $lang));
if ($lang != "en" && file_exists(sprintf($this->langPath, $lang))) {
printf("<script type='text/javascript' src='$this->langPath'></script>\n", $lang);
echo "<script type='text/javascript'>jQuery(function () { jQuery.timepicker.setDefaults(jQuery.datepicker.regional['$lang']); });</script>\n";
echo script_src(sprintf($this->langPath, $lang));
echo script("jQuery(function () { jQuery.timepicker.setDefaults(jQuery.datepicker.regional['$lang']); });");
}
}
}
@@ -37,11 +44,12 @@ class AdminerEditCalendar {
if (preg_match("~date|time~", $field["type"])) {
$dateFormat = "changeYear: true, dateFormat: 'yy-mm-dd'"; //! yy-mm-dd regional
$timeFormat = "showSecond: true, timeFormat: 'HH:mm:ss.lcZ', timeInput: true";
return "<input id='fields-" . h($field["field"]) . "' value='" . h($value) . "'" . (@+$field["length"] ? " maxlength='" . (+$field["length"]) . "'" : "") . "$attrs><script type='text/javascript'>jQuery('#fields-" . js_escape($field["field"]) . "')."
return "<input id='fields-" . h($field["field"]) . "' value='" . h($value) . "'" . (@+$field["length"] ? " maxlength='" . (+$field["length"]) . "'" : "") . "$attrs>" . script(
"jQuery('#fields-" . js_escape($field["field"]) . "')."
. ($field["type"] == "time" ? "timepicker({ $timeFormat })"
: (preg_match("~time~", $field["type"]) ? "datetimepicker({ $dateFormat, $timeFormat })"
: "datepicker({ $dateFormat })"
)) . ";</script>";
: (preg_match("~time~", $field["type"]) ? "datetimepicker({ $dateFormat, $timeFormat })"
: "datepicker({ $dateFormat })"
)) . ";");
}
}

View File

@@ -3,8 +3,8 @@
/** Select foreign key in edit form
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEditForeign {
var $_limit;

View File

@@ -3,8 +3,8 @@
/** Use <textarea> for char and varchar
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEditTextarea {

View File

@@ -3,8 +3,8 @@
/** Get e-mail subject and message from database (Adminer Editor)
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEmailTable {
/** @access protected */
@@ -28,12 +28,19 @@ class AdminerEmailTable {
function selectEmailPrint($emailFields, $columns) {
if ($emailFields) {
print_fieldset("email", ('E-mail'));
echo "<div onkeydown=\"eventStop(event); return bodyKeydown(event, 'email');\">\n";
echo "<div>\n";
echo script("qsl('div').onkeydown = partial(bodyKeydown, 'email');");
echo "<p>" . ('From') . ": <input name='email_from' value='" . h($_POST ? $_POST["email_from"] : $_COOKIE["adminer_email"]) . "'>\n";
echo ('Subject') . ": <select name='email_id'><option>" . optionlist(get_key_vals("SELECT $this->id, $this->title FROM $this->table ORDER BY $this->title"), $_POST["email_id"], true) . "</select>\n";
echo "<p>" . ('Attachments') . ": <input type='file' name='email_files[]' onchange=\"this.onchange = function () { }; var el = this.cloneNode(true); el.value = ''; this.parentNode.appendChild(el);\">";
echo "<p>" . ('Attachments') . ": <input type='file' name='email_files[]'>";
echo script("qsl('input').onchange = function () {
this.onchange = function () { };
var el = this.cloneNode(true);
el.value = '';
this.parentNode.appendChild(el);
};");
echo "<p>" . (count($emailFields) == 1 ? '<input type="hidden" name="email_field" value="' . h(key($emailFields)) . '">' : html_select("email_field", $emailFields));
echo "<input type='submit' name='email' value='" . ('Send') . "' onclick=\"return this.form['delete'].onclick();\">\n";
echo "<input type='submit' name='email' value='" . ('Send') . "'>" . confirm();
echo "</div>\n";
echo "</div></fieldset>\n";
return true;

View File

@@ -3,8 +3,8 @@
/** Use <select><option> for enum edit instead of <input type="radio">
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEnumOption {

View File

@@ -3,8 +3,8 @@
/** Use <select><option> for enum edit instead of regular input text on enum type in PostgreSQL
* @link https://www.adminer.org/plugins/#use
* @author Adam Kuśmierz, http://kusmierz.be/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerEnumTypes {
var $_types = null;

View File

@@ -4,8 +4,8 @@
/** Edit fields ending with "_path" by <input type="file"> and link to the uploaded files from select
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerFileUpload {
/** @access protected */

View File

@@ -3,8 +3,8 @@
/** Link system tables (in mysql and information_schema databases) by foreign keys
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerForeignSystem {

View File

@@ -3,8 +3,8 @@
/** Allow using Adminer inside a frame (disables ClickJacking protection)
* @link https://www.adminer.org/plugins/#use
* @author Jakub Vrana, https://www.vrana.cz/
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
* @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)
*/
class AdminerFrames {
/** @access protected */
@@ -20,9 +20,9 @@ class AdminerFrames {
function headers() {
if ($this->sameOrigin) {
header("X-Frame-Options: SameOrigin");
} elseif (function_exists('header_remove')) {
header_remove("X-Frame-Options");
}
header("X-XSS-Protection: 0");
return false;
}
}

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