From: Jakub Vrana Date: Mon, 17 Mar 2025 18:25:57 +0000 (+0100) Subject: Plugins: Autoload plugins in adminer-plugins/ X-Git-Tag: v5.1.0~119 X-Git-Url: https://git.joonet.de/?a=commitdiff_plain;h=41dabfb4f272ae89dea14a67fa5e010480889b3c;p=adminer.git Plugins: Autoload plugins in adminer-plugins/ --- diff --git a/.gitignore b/.gitignore index 2afb1ac5..946395f2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ /adminer/adminer.css +/adminer/adminer-dark.css +/editor/adminer.css +/editor/adminer-dark.css /adminer*.php /editor*.php /vendor/ +adminer-plugins/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 306273a1..56a77204 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - CSS: Sticky table headers (bug #918) - CSS: Allow more custom styles with dark mode (bug #925) - IMAP: New plugin driver created for fun +- Plugins: autoload plugins from adminer-plugins/ +- Plugins: configure plugins with adminer-plugins/config.php ## Adminer 5.0.6 (released 2025-03-17) - Align numbers right (bug #912) diff --git a/README.md b/README.md index 62f31c6b..b70f40d0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Adminer -**Adminer** is a full-featured database management tool written in PHP. It consists of a single file ready to deploy -to the target server. **Adminer Editor** offers data manipulation for end-users. +**Adminer** is a full-featured database management tool written in PHP. +It consists of a single file ready to deploy to the target server. +**Adminer Editor** offers data manipulation for end-users. https://www.adminer.org/ @@ -18,11 +19,32 @@ If downloaded from Git then run: `git submodule update --init` - `adminer/index.php` - Run development version of Adminer - `editor/index.php` - Run development version of Adminer Editor - `editor/example.php` - Example customization -- `plugins/readme.txt` - Plugins for Adminer and Adminer Editor -- `adminer/plugin.php` - Plugin demo - `adminer/sqlite.php` - Development version of Adminer with SQLite allowed - `editor/sqlite.php` - Development version of Editor with SQLite allowed - `adminer/designs.php` - Development version of Adminer with `adminer.css` switcher - `compile.php` - Create a single file version - `lang.php` - Update translations - `tests/*.html` - Katalon Recorder test suites + +## Plugins +There are [several plugins](plugins/) distributed with Adminer and there are also many user-contributed plugins linked from https://www.adminer.org/plugins/. +To use a plugin, simply upload it to `adminer-plugins/` next to `adminer.php`. + +``` +- adminer.php +- adminer-plugins + - config.php + - dump-xml.php + - login-password-less.php +``` + +Some plugins require configuration. To use them, you need to create another file in `adminer-plugins/`: + +```php +plugins = $plugins; + } + + private function callParent($function, $args) { + return call_user_func_array(array('parent', $function), $args); + } + + private function applyPlugin($function, $args) { + foreach ($this->plugins as $plugin) { + if (method_exists($plugin, $function)) { + switch (count($args)) { // call_user_func_array() doesn't work well with references + case 0: + $return = $plugin->$function(); + break; + case 1: + $return = $plugin->$function($args[0]); + break; + case 2: + $return = $plugin->$function($args[0], $args[1]); + break; + case 3: + $return = $plugin->$function($args[0], $args[1], $args[2]); + break; + case 4: + $return = $plugin->$function($args[0], $args[1], $args[2], $args[3]); + break; + case 5: + $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4]); + break; + case 6: + $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); + break; + default: + trigger_error('Too many parameters.', E_USER_WARNING); + } + if ($return !== null) { + return $return; + } + } + } + return $this->callParent($function, $args); + } + + private function appendPlugin($function, $args) { + $return = $this->callParent($function, $args); + foreach ($this->plugins as $plugin) { + if (method_exists($plugin, $function)) { + $value = call_user_func_array(array($plugin, $function), $args); + if ($value) { + $return += $value; + } + } + } + return $return; + } + + // appendPlugin + + function dumpFormat() { + $args = func_get_args(); + return $this->appendPlugin(__FUNCTION__, $args); + } + + function dumpOutput() { + $args = func_get_args(); + return $this->appendPlugin(__FUNCTION__, $args); + } + + function editRowPrint($table, $fields, $row, $update) { + $args = func_get_args(); + return $this->appendPlugin(__FUNCTION__, $args); + } + + function editFunctions($field) { + $args = func_get_args(); + return $this->appendPlugin(__FUNCTION__, $args); + } + + // applyPlugin + + function name() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function credentials() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function connectSsl() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function permanentLogin($create = false) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function bruteForceKey() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function serverName($server) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function database() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function schemas() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function databases($flush = true) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function queryTimeout() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function headers() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function csp() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function head($dark = null) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function css() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function loginForm() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function loginFormField($name, $heading, $value) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function login($login, $password) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function tableName($tableStatus) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function fieldName($field, $order = 0) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLinks($tableStatus, $set = "") { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function foreignKeys($table) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function backwardKeys($table, $tableName) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function backwardKeysPrint($backwardKeys, $row) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectQuery($query, $start, $failed = false) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function sqlCommandQuery($query) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function rowDescription($table) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function rowDescriptions($rows, $foreignKeys) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLink($val, $field) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectVal($val, $link, $field, $original) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function editVal($val, $field) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function tableStructurePrint($fields) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function tableIndexesPrint($indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectColumnsPrint($select, $columns) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectSearchPrint($where, $columns, $indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectOrderPrint($order, $columns, $indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLimitPrint($limit) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLengthPrint($text_length) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectActionPrint($indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectCommandPrint() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectImportPrint() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectEmailPrint($emailFields, $columns) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectColumnsProcess($columns, $indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectSearchProcess($fields, $indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectOrderProcess($fields, $indexes) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLimitProcess() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectLengthProcess() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectEmailProcess($where, $foreignKeys) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function selectQueryBuild($select, $where, $group, $order, $limit, $page) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function messageQuery($query, $time, $failed = false) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function editInput($table, $field, $attrs, $value) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function editHint($table, $field, $value) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function processInput($field, $value, $function = "") { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpDatabase($db) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpTable($table, $style, $is_view = 0) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpData($table, $style, $query) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpFilename($identifier) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpHeaders($identifier, $multi_table = false) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function dumpFooter() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function importServerPath() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function homepage() { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function navigation($missing) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function syntaxHighlighting($tables) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function databasesPrint($missing) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } + + function tablesPrint($tables) { + $args = func_get_args(); + return $this->applyPlugin(__FUNCTION__, $args); + } +} diff --git a/adminer/include/version.inc.php b/adminer/include/version.inc.php index 06e2b335..8f8811d6 100644 --- a/adminer/include/version.inc.php +++ b/adminer/include/version.inc.php @@ -1,4 +1,4 @@ plugins = $plugins; - } - - private function callParent($function, $args) { - return call_user_func_array(array('parent', $function), $args); - } - - private function applyPlugin($function, $args) { - foreach ($this->plugins as $plugin) { - if (method_exists($plugin, $function)) { - switch (count($args)) { // call_user_func_array() doesn't work well with references - case 0: - $return = $plugin->$function(); - break; - case 1: - $return = $plugin->$function($args[0]); - break; - case 2: - $return = $plugin->$function($args[0], $args[1]); - break; - case 3: - $return = $plugin->$function($args[0], $args[1], $args[2]); - break; - case 4: - $return = $plugin->$function($args[0], $args[1], $args[2], $args[3]); - break; - case 5: - $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4]); - break; - case 6: - $return = $plugin->$function($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); - break; - default: - trigger_error('Too many parameters.', E_USER_WARNING); - } - if ($return !== null) { - return $return; - } - } - } - return $this->callParent($function, $args); - } - - private function appendPlugin($function, $args) { - $return = $this->callParent($function, $args); - foreach ($this->plugins as $plugin) { - if (method_exists($plugin, $function)) { - $value = call_user_func_array(array($plugin, $function), $args); - if ($value) { - $return += $value; - } - } - } - return $return; - } - - // appendPlugin - - function dumpFormat() { - $args = func_get_args(); - return $this->appendPlugin(__FUNCTION__, $args); - } - - function dumpOutput() { - $args = func_get_args(); - return $this->appendPlugin(__FUNCTION__, $args); - } - - function editRowPrint($table, $fields, $row, $update) { - $args = func_get_args(); - return $this->appendPlugin(__FUNCTION__, $args); - } - - function editFunctions($field) { - $args = func_get_args(); - return $this->appendPlugin(__FUNCTION__, $args); - } - - // applyPlugin - - function name() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function credentials() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function connectSsl() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function permanentLogin($create = false) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function bruteForceKey() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function serverName($server) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function database() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function schemas() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function databases($flush = true) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function queryTimeout() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function headers() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function csp() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function head($dark = null) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function css() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function loginForm() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function loginFormField($name, $heading, $value) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function login($login, $password) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function tableName($tableStatus) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function fieldName($field, $order = 0) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLinks($tableStatus, $set = "") { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function foreignKeys($table) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function backwardKeys($table, $tableName) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function backwardKeysPrint($backwardKeys, $row) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectQuery($query, $start, $failed = false) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function sqlCommandQuery($query) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function rowDescription($table) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function rowDescriptions($rows, $foreignKeys) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLink($val, $field) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectVal($val, $link, $field, $original) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function editVal($val, $field) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function tableStructurePrint($fields) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function tableIndexesPrint($indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectColumnsPrint($select, $columns) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectSearchPrint($where, $columns, $indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectOrderPrint($order, $columns, $indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLimitPrint($limit) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLengthPrint($text_length) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectActionPrint($indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectCommandPrint() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectImportPrint() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectEmailPrint($emailFields, $columns) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectColumnsProcess($columns, $indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectSearchProcess($fields, $indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectOrderProcess($fields, $indexes) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLimitProcess() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectLengthProcess() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectEmailProcess($where, $foreignKeys) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function selectQueryBuild($select, $where, $group, $order, $limit, $page) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function messageQuery($query, $time, $failed = false) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function editInput($table, $field, $attrs, $value) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function editHint($table, $field, $value) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function processInput($field, $value, $function = "") { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpDatabase($db) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpTable($table, $style, $is_view = 0) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpData($table, $style, $query) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpFilename($identifier) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpHeaders($identifier, $multi_table = false) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function dumpFooter() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function importServerPath() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function homepage() { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function navigation($missing) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function syntaxHighlighting($tables) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function databasesPrint($missing) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } - - function tablesPrint($tables) { - $args = func_get_args(); - return $this->applyPlugin(__FUNCTION__, $args); - } -} diff --git a/plugins/readme.txt b/plugins/readme.txt deleted file mode 100644 index 0f690b61..00000000 --- a/plugins/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -../adminer/plugin.php - demo usage -https://www.adminer.org/plugins/ - documentation diff --git a/todo.txt b/todo.txt index d8419c72..4f685003 100644 --- a/todo.txt +++ b/todo.txt @@ -8,7 +8,6 @@ Draggable columns in alter table (thanks to Michal Manak)