diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 113ec42be..faa801277 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: php-actions/composer@v6 - - uses: php-actions/phpcs@v1 - with: - path: . - standard: phpcs.xml - - uses: php-actions/phpstan@v3 + - run: composer phpcs + - run: composer phpstan diff --git a/Makefile b/Makefile deleted file mode 100644 index 8c5dcfbf6..000000000 --- a/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -ROOT_DIRECTORY = $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))") -PHP := $(shell which php) -PORT := 8000 - - -.DEFAULT_GOAL := default - - -.PHONY: default -default: compile - -.PHONY: compile -compile: - $(PHP) $(ROOT_DIRECTORY)/compile.php - -.PHONY: server -server: - php \ - --server 127.0.0.1:$(PORT) \ - --docroot $(ROOT_DIRECTORY) - -.PHONY: initialize -initialize: - git \ - -C $(ROOT_DIRECTORY) \ - submodule \ - update \ - --init \ - --recursive - -.PHONY: clean -clean: - rm \ - --recursive \ - --force \ - $(ROOT_DIRECTORY)/adminer.php - -.PHONY: clean.all -clean.all: clean diff --git a/README.md b/README.md index 856aab018..863bbaf41 100644 --- a/README.md +++ b/README.md @@ -22,5 +22,13 @@ If downloaded from Git then run: `git submodule update --init` - `lang.php` - Update translations - `tests/*.html` - Katalon Recorder test suites +## Composer Scripts +Install the development tools first with `composer install`. + +- `composer initialize` - Update Git submodules +- `composer phpcs` - Run the coding standard check using [phpcs.xml](/phpcs.xml) +- `composer phpcbf` - Automatically fix coding standard issues where possible using [phpcs.xml](/phpcs.xml) +- `composer phpstan` - Run PHPStan using `phpstan.neon` + ## Plugins There are several plugins distributed with Adminer, as well as many user-contributed plugins listed on the [Adminer Plugins page](https://www.adminer.org/plugins/). diff --git a/adminer/call.inc.php b/adminer/call.inc.php index b35da5ba6..44ffbdfb3 100644 --- a/adminer/call.inc.php +++ b/adminer/call.inc.php @@ -1,4 +1,5 @@ $field) { $foreign_key = $foreign_keys[$field["type"]]; - $type_field = ($foreign_key !== null ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type + $type_field = (isset($referencable_primary[$foreign_key]) ? $referencable_primary[$foreign_key] : $field); //! can collide with user defined type if ($field["field"] != "") { if (!$field["generated"]) { $field["default"] = null; diff --git a/adminer/database.inc.php b/adminer/database.inc.php index 828f9d176..320a0f26f 100644 --- a/adminer/database.inc.php +++ b/adminer/database.inc.php @@ -1,4 +1,5 @@ "MySQL / MariaDB") + SqlDriver::$drivers; @@ -30,7 +31,7 @@ function attach(string $server, string $username, string $password): string { null, (is_numeric($port) ? intval($port) : ini_get("mysqli.default_port")), (is_numeric($port) ? null : $port), - ($ssl ? ($ssl['verify'] !== false ? 2048 : 64) : 0) // 2048 - MYSQLI_CLIENT_SSL, 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16) + ($ssl ? (isset($ssl['verify']) && $ssl['verify'] === false ? 64 : 2048) : 0) // 2048 - MYSQLI_CLIENT_SSL, 64 - MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT (not available before PHP 5.6.16) ); $this->options(MYSQLI_OPT_LOCAL_INFILE, 0); return ($return ? '' : $this->error); diff --git a/adminer/drivers/oracle.inc.php b/adminer/drivers/oracle.inc.php index 831effc9d..45a682240 100644 --- a/adminer/drivers/oracle.inc.php +++ b/adminer/drivers/oracle.inc.php @@ -1,4 +1,5 @@ = 70100) { - $return = implode("\n", pg_last_notice($this->link, 2)); // 2 - PGSQL_NOTICE_ALL + $notice = pg_last_notice($this->link, 2); // 2 - PGSQL_NOTICE_ALL + $return = implode("\n", (array) $notice); pg_last_notice($this->link, 3); // 3 - PGSQL_NOTICE_CLEAR } else { $return = pg_last_notice($this->link); diff --git a/adminer/drivers/sqlite.inc.php b/adminer/drivers/sqlite.inc.php index f6f5384cb..e8520ee70 100644 --- a/adminer/drivers/sqlite.inc.php +++ b/adminer/drivers/sqlite.inc.php @@ -1,4 +1,5 @@ element */ @@ -172,7 +173,7 @@ function hidden_fields(array $process, array $ignore = array(), string $prefix = /** Print hidden fields for GET forms */ function hidden_fields_get(): void { echo (sid() ? input_hidden(session_name(), session_id()) : ''); - echo (SERVER !== null ? input_hidden(DRIVER, SERVER) : ""); + echo input_hidden(DRIVER, SERVER); echo input_hidden("username", $_GET["username"]); } diff --git a/adminer/include/lang.inc.php b/adminer/include/lang.inc.php index be59a6ed2..c338aecb1 100644 --- a/adminer/include/lang.inc.php +++ b/adminer/include/lang.inc.php @@ -1,4 +1,5 @@ =7.4" }, + "require-dev": { + "phpstan/phpstan": "^1.12", + "squizlabs/php_codesniffer": "^3.11" + }, "scripts": { "check": [ - "phpcs", - "phpstan analyse -c phpstan.neon" + "@phpcs", + "@phpstan" ], "compile": "@php compile.php", - "clean": "rm -f adminer*.php editor*.php" + "clean": "rm -f adminer*.php editor*.php", + "initialize": "git submodule update --init --recursive", + "phpcbf": "sh -c 'if [ -x vendor/bin/phpcbf ]; then exec vendor/bin/phpcbf --standard=phpcs.xml .; fi; bin=\"$(composer global config bin-dir --absolute 2>/dev/null)/phpcbf\"; if [ -x \"$bin\" ]; then exec \"$bin\" --standard=phpcs.xml .; fi; exec phpcbf --standard=phpcs.xml .'", + "phpcs": "sh -c 'if [ -x vendor/bin/phpcs ]; then exec vendor/bin/phpcs --standard=phpcs.xml --report=full .; fi; bin=\"$(composer global config bin-dir --absolute 2>/dev/null)/phpcs\"; if [ -x \"$bin\" ]; then exec \"$bin\" --standard=phpcs.xml --report=full .; fi; exec phpcs --standard=phpcs.xml --report=full .'", + "phpstan": "sh -c 'if [ -x vendor/bin/phpstan ]; then exec vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M; fi; bin=\"$(composer global config bin-dir --absolute 2>/dev/null)/phpstan\"; if [ -x \"$bin\" ]; then exec \"$bin\" analyse -c phpstan.neon --memory-limit=512M; fi; exec phpstan analyse -c phpstan.neon --memory-limit=512M'" } } diff --git a/editor/db.inc.php b/editor/db.inc.php index 301538852..13274e1a0 100644 --- a/editor/db.inc.php +++ b/editor/db.inc.php @@ -1,4 +1,5 @@ select_db(adminer()->database()); diff --git a/editor/include/editing.inc.php b/editor/include/editing.inc.php index 207f361b4..e34d1ad1c 100644 --- a/editor/include/editing.inc.php +++ b/editor/include/editing.inc.php @@ -1,4 +1,5 @@ /externals/ /designs/ /(adminer|editor)[-.] + /vendor @@ -51,6 +52,7 @@ adminer/include/pdo.inc.php adminer/plugins/foreign-system.php adminer/plugins/drivers/ + plugins/* @@ -79,7 +81,6 @@ - @@ -93,19 +94,7 @@ - - - - - - - - - - - - diff --git a/phpstan.neon b/phpstan.neon index 1b2253aea..8c6394b05 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,7 +9,6 @@ parameters: - "~Function Adminer\\\\queries\\(\\) never returns Adminer\\\\Result~" # mysqli_result # not real problems - - identifier: include.fileNotFound # includes in include/ relative from index.php - "~^Function (set_magic_quotes_runtime|mysql_)~" # PHP < 7 functions - "~an unknown class OCI-?Lob~" # this looks like PHPStan bug - "~^Variable \\$error might not be defined~" # declared in bootstrap.inc.php @@ -22,7 +21,6 @@ parameters: - "~expects bool~" # truthy values - "~fread expects int<1, max>, 100000~" # 1e6 - "~'strlen' given~" # used as a bool callback - - "~between int<70100~" # PHP_VERSION_ID check - message: "~ type specified~" # duplicate functions and methods @@ -31,9 +29,6 @@ parameters: - adminer/drivers/* # it probably doesn't like $ar[$key] instead of isset($ar[$key]) and thinks that $ar[$key] is always set - - identifier: identical.alwaysFalse - - identifier: notEqual.alwaysFalse - - identifier: notIdentical.alwaysTrue - identifier: booleanNot.alwaysTrue - identifier: booleanNot.alwaysFalse - identifier: booleanAnd.alwaysFalse @@ -46,7 +41,7 @@ parameters: - identifier: isset.offset - identifier: deadCode.unreachable - "~Function Adminer\\\\get_driver\\(\\) never returns null~" - - "~on array\\{}~" + - "~Strict comparison using === between .* will always evaluate to false\\.~" paths: - adminer/drivers/mysql.inc.php # other drivers inherit the annotations so we take them from here @@ -59,9 +54,15 @@ parameters: - adminer/elastic.php - adminer/sqlite.php + parallel: + jobSize: 20 + processTimeout: 600.0 + maximumNumberOfProcesses: 1 + minimumNumberOfJobsPerProcess: 2 + buffer: 134217728 + phpVersion: - min: 70100 - max: 80499 + 70400 typeAliases: TableStatus: "array{Name:string, Engine?:?string, Comment?:string, Oid?:numeric-string, Rows?:?numeric-string, Collation?:string, Auto_increment?:?numeric-string, Data_length?:numeric-string, Index_length?:numeric-string, Data_free?:numeric-string, Create_options?:string, partition?:numeric-string, nspname?:string}" diff --git a/plugins/drivers/clickhouse.php b/plugins/drivers/clickhouse.php index e443df451..9517df46c 100644 --- a/plugins/drivers/clickhouse.php +++ b/plugins/drivers/clickhouse.php @@ -1,4 +1,5 @@ and link to the uploaded files from select diff --git a/plugins/login-table.php b/plugins/login-table.php index 52c0a23ab..e661bf12f 100644 --- a/plugins/login-table.php +++ b/plugins/login-table.php @@ -1,4 +1,5 @@