diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml new file mode 100644 index 0000000..5011311 --- /dev/null +++ b/.github/workflows/psalm.yml @@ -0,0 +1,49 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization +# +# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: MIT + +name: Static analysis + +on: pull_request + +concurrency: + group: psalm-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + static-analysis: + runs-on: ubuntu-latest + + name: static-psalm-analysis + steps: + - name: Checkout + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Get php version + id: versions + uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1 + + - name: Set up php${{ steps.versions.outputs.php-available }} + uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1 + with: + php-version: ${{ steps.versions.outputs.php-available }} + extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer remove nextcloud/ocp --dev + composer i + + - name: Install nextcloud/ocp + run: composer require --dev nextcloud/ocp:dev-${{ steps.versions.outputs.branches-max }} --ignore-platform-reqs --with-dependencies + + - name: Run coding standards check + run: composer run psalm diff --git a/composer.json b/composer.json index 28148c2..6802fe1 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,10 @@ "cs:fix": "php-cs-fixer fix", "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l", "test:unit": "phpunit -c phpunit.xml --fail-on-warning --fail-on-risky --color", + "psalm": "./vendor/bin/psalm.phar --show-info=false --no-cache", + "psalm:update-baseline": "./vendor/bin/psalm.phar --update-baseline", + "psalm:fix": "./vendor/bin/psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType", + "psalm:fix:dry": "./vendor/bin/psalm.phar --no-cache --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType --dry-run", "post-install-cmd": [ "@composer bin all install --ignore-platform-reqs # unfortunately the flag is required for 8.0", "vendor/bin/php-scoper add-prefix --force # Scope our dependencies", @@ -41,6 +45,8 @@ }, "require-dev": { "phpunit/phpunit": "^9.5", - "nextcloud/coding-standard": "^1.0" + "nextcloud/coding-standard": "^1.0", + "psalm/phar": "^5.26", + "nextcloud/ocp": "dev-master" } } diff --git a/composer.lock b/composer.lock index 76e6ca2..9b94435 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5634452d94bc38893b6cda6a113cd5d1", + "content-hash": "67ede0e2200d678cc39965c1ea587455", "packages": [ { "name": "bamarni/composer-bin-plugin", @@ -354,6 +354,51 @@ }, "time": "2023-06-01T12:05:01+00:00" }, + { + "name": "nextcloud/ocp", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "6b2abc6f31dbfb3d21ee1d19453dc687fd46ae0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/6b2abc6f31dbfb3d21ee1d19453dc687fd46ae0d", + "reference": "6b2abc6f31dbfb3d21ee1d19453dc687fd46ae0d", + "shasum": "" + }, + "require": { + "php": "~8.0 || ~8.1 || ~8.2 || ~8.3", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", + "psr/event-dispatcher": "^1.0", + "psr/log": "^3.0.2" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "31.0.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christoph Wurst", + "email": "christoph@winzerhof-wurst.at" + } + ], + "description": "Composer package containing Nextcloud's public API (classes, interfaces)", + "support": { + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/master" + }, + "time": "2024-10-16T00:43:10+00:00" + }, { "name": "nikic/php-parser", "version": "v5.0.0", @@ -997,6 +1042,242 @@ ], "time": "2023-12-01T16:55:19+00:00" }, + { + "name": "psalm/phar", + "version": "5.26.1", + "source": { + "type": "git", + "url": "https://github.com/psalm/phar.git", + "reference": "8a38e7ad04499a0ccd2c506fd1da6fc01fff4547" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psalm/phar/zipball/8a38e7ad04499a0ccd2c506fd1da6fc01fff4547", + "reference": "8a38e7ad04499a0ccd2c506fd1da6fc01fff4547", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "vimeo/psalm": "*" + }, + "bin": [ + "psalm.phar" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer-based Psalm Phar", + "support": { + "issues": "https://github.com/psalm/phar/issues", + "source": "https://github.com/psalm/phar/tree/5.26.1" + }, + "time": "2024-09-09T16:22:43+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.1", @@ -2014,11 +2295,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "nextcloud/ocp": 20 + }, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": {}, + "platform-dev": {}, "platform-overrides": { "php": "8.0.2" }, diff --git a/lib/Client.php b/lib/Client.php index 7902804..4782a26 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -41,6 +41,7 @@ use Psr\Log\LoggerInterface; use function explode; use function json_decode; +use function OCP\Log\logger; class Client { public const DEFAULT_PROPERTIES = [ @@ -66,8 +67,6 @@ class Client { /** @var string[] */ private $knownSP2013SystemFolders = ['Forms', 'Item', 'Attachments']; - /** @var array */ - protected $lastResponse; private LoggerInterface $logger; // as there is one client per storage it is a 1:1 Client<->DocumentLibrary relation (lazy-loading) private ?SPList $documentLibrary = null; @@ -232,7 +231,7 @@ public function overwriteFileViaStream($relativeServerPath, $fp, $localPath): vo $request->ensureHeader('X-HTTP-Method', 'PUT'); // yes, PUT $this->context->ensureFormDigest($request); $request->StreamHandle = $fp; - $request->ensureHeader("Content-Length", filesize($localPath)); + $request->ensureHeader("Content-Length", (string)filesize($localPath)); $this->context->executeQueryDirect($request); } @@ -455,10 +454,6 @@ public function getDocumentLibrariesRootFolder(string $documentLibrary): Folder */ public function loadAndExecute(ClientObject $object, array $properties = null) { $this->context->load($object, $properties); - $r = $this->context->getPendingRequest(); - $r->afterExecuteRequest(function (Response $response) { - $this->lastResponse = $response->getContent(); - }); $this->context->executeQuery(); } @@ -485,9 +480,7 @@ private function ensureConnection() { } $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->credentials['user'], $this->credentials['password']); } catch (Exception $e) { - /** @var LoggerInterface $logger */ - $logger = \OC::$server->get(LoggerInterface::class); // FIXME: DI - $logger->debug( + logger('sharepoint')->debug( 'Failed to acquire token for user, fall back to NTLM auth', [ 'app' => 'sharepoint', diff --git a/lib/Listener/ExternalStoragesRegistrationListener.php b/lib/Listener/ExternalStoragesRegistrationListener.php index bf25d7b..85ed6c3 100644 --- a/lib/Listener/ExternalStoragesRegistrationListener.php +++ b/lib/Listener/ExternalStoragesRegistrationListener.php @@ -30,18 +30,15 @@ use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +/** + * @template-implements IEventListener + */ class ExternalStoragesRegistrationListener implements IEventListener { - /** @var BackendService */ - private $backendService; - /** @var BackendProvider */ - private $backendProvider; public function __construct( - BackendService $backendService, - BackendProvider $backendProvider + private BackendService $backendService, + private BackendProvider $backendProvider ) { - $this->backendService = $backendService; - $this->backendProvider = $backendProvider; } public function handle(Event $event): void { diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..6bf76f8 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/stub.phpstub b/tests/stub.phpstub new file mode 100644 index 0000000..98f4f6d --- /dev/null +++ b/tests/stub.phpstub @@ -0,0 +1,163 @@ +