diff --git a/files/docker/index/adminer-theme-switcher.php b/files/docker/index/adminer-theme-switcher.php new file mode 100644 index 0000000..11b6a60 --- /dev/null +++ b/files/docker/index/adminer-theme-switcher.php @@ -0,0 +1,191 @@ + + * @link https://github.com/felladrin/adminer-theme-switcher + * @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) + */ +class AdminerThemeSwitcher +{ + protected static $themeList; + + protected static $option; + + public static $prompt = 'Type the number of the theme you want to use: '; + + public static function run() + { + if (static::isRunningFromCommandLine()) { + static::printListAvailableThemes(); + static::readOptionFromCommandLine(); + static::switchTheme(); + return; + } + + if (static::hasNotSelectedAnOptionFromBrowserYet()) { + static::printListAvailableThemes(); + static::printJavascriptPrompt(); + } else { + static::readOptionFromBrowser(); + static::switchTheme(); + } + } + + public static function isRunningFromCommandLine() + { + return (php_sapi_name() === 'cli'); + } + + public static function isRunningOnWindows() + { + return (PHP_OS == 'WINNT'); + } + + public static function getLineEnding() + { + return (static::isRunningFromCommandLine() ? PHP_EOL : '
'); + } + + public static function getThemeList() + { + if (!empty(static::$themeList)) { + return static::$themeList; + } + + $context = stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'header' => [ + 'User-Agent: PHP' + ] + ], + 'ssl' => [ + "verify_peer" => false, + "verify_peer_name" => false + ] + ]); + + $urlOfThemesDirFromGithubRepo = 'https://api.github.com/repos/vrana/adminer/contents/designs'; + + $jsonThemeList = file_get_contents($urlOfThemesDirFromGithubRepo, false, $context); + + static::$themeList = ($jsonThemeList ? json_decode($jsonThemeList) : false); + + return static::$themeList; + } + + public static function downloadTheme($themeIndex = null) + { + if (is_null($themeIndex)) { + $themeIndex = static::$option; + } + + $themeName = static::getThemeList()[$themeIndex]->name; + $urlOfCssFileFromGithubRepo = "https://raw.githubusercontent.com/vrana/adminer/master/designs/{$themeName}/adminer.css"; + $cssContent = file_get_contents($urlOfCssFileFromGithubRepo); + $filePath = __DIR__ . '/adminer.css'; + $fileExists = file_exists('adminer.css'); + if (file_put_contents($filePath, $cssContent) !== false) { + if (!$fileExists) { + chmod($filePath, 0777); + } + + return true; + } + + return false; + } + + public static function printListAvailableThemes() + { + echo "List of available Adminer Themes:" . static::getLineEnding() . static::getLineEnding(); + + if (static::getThemeList()) { + foreach (static::getThemeList() as $index => $theme) { + if ($theme->type !== 'dir') { + continue; + } + + echo "[{$index}] {$theme->name}" . static::getLineEnding(); + } + } + + echo static::getLineEnding(); + } + + public static function readOptionFromCommandLine() + { + if (static::isRunningOnWindows()) { + echo static::$prompt; + static::$option = stream_get_line(STDIN, 1024, static::getLineEnding()); + } else { + static::$option = readline(static::$prompt); + } + + return static::$option; + } + + public static function printResultOf($download) + { + if ($download) { + echo 'Theme switched successfully!' . static::getLineEnding(); + } else { + echo 'Something went wrong with the download. Try again!' . static::getLineEnding(); + } + } + + public static function printJavascriptPrompt() + { + echo ''; + } + + public static function readOptionFromBrowser() + { + if (isset($_GET['option'])) { + static::$option = $_GET['option']; + } + + return static::$option; + } + + public static function hasNotSelectedAnOptionFromBrowserYet() + { + return !isset($_GET['option']); + } + + public static function hasSelectedAValidOption() + { + return is_numeric(static::$option) && static::$option < count(static::getThemeList()); + } + + public static function printInvalidOptionErrorMessage() + { + $errorMessage = static::$option . " is not a number from the options! Try again!"; + + if (static::isRunningFromCommandLine()) { + echo $errorMessage . static::getLineEnding(); + static::run(); + } else { + echo ''; + echo ''; + } + } + + public static function switchTheme() + { + if (static::hasSelectedAValidOption()) { + static::printResultOf(static::downloadTheme()); + } else { + static::printInvalidOptionErrorMessage(); + } + } +} + +AdminerThemeSwitcher::run(); diff --git a/files/docker/index/docker-stack.yaml b/files/docker/index/docker-stack.yaml new file mode 100644 index 0000000..a7a9e42 --- /dev/null +++ b/files/docker/index/docker-stack.yaml @@ -0,0 +1,65 @@ +secrets: + index_db_pass: + external: true + +networks: + reverse_proxy: + external: true + +volumes: + index_db: + adminer_plugins: + +services: + adminer: + image: ghcr.io/shyim/adminerevo:latest + restart: unless-stopped + networks: + - default + - reverse_proxy + volumes: + - adminer_plugins:/var/www/html/plugins-custom + environment: + ADMINER_DEFAULT_DRIVER: pgsql + ADMINER_DEFAULT_SERVER: tasks.db + ADMINER_DEFAULT_USER: postgres + ADMINER_PLUGINS: tables-filter tinymce edit-calendar edit-foreign enum-option enum-types file-upload slugify struct-comments + ADMINER_DESIGN: 'pepa-linha-dark' + deploy: + rollback_config: + failure_action: continue + update_config: + delay: 2s + failure_action: rollback + order: start-first + placement: + constraints: + - node.labels.services_kind==${SERVICE_KIND:-common} + labels: + - traefik.enable=true + - traefik.http.routers.index.rule=Host(`index.alecodes.page`) + - traefik.http.services.index.loadbalancer.server.port=8080 + + db: + image: postgres + restart: unless-stopped + secrets: + - index_db_pass + volumes: + - index_db:/var/lib/postgresql/data + - type: tmpfs + target: /dev/shm + tmpfs: + size: 134217728 # 128*2^20 bytes = 128Mb + environment: + POSTGRES_PASSWORD_FILE: /run/secrets/index_db_pass + deploy: + rollback_config: + failure_action: continue + update_config: + delay: 2s + failure_action: rollback + order: start-first + placement: + constraints: + - node.labels.services_kind==${SERVICE_KIND:-common}