From 31f77c5cebaf8684d2e51c2d5f5e5fdbb1b2ccf8 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Fri, 3 Jul 2026 22:42:27 +0200 Subject: [PATCH 1/2] Modernize test tooling and add static analysis config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the abandoned christophwurst/nextcloud dev stub with nextcloud/ocp so PHPUnit and PHPStan can resolve OCP types without a live Nextcloud install. Modernizes tests/Unit/Controller/PageControllerTest.php to PHPUnit\Framework\TestCase / setUp(): void and fixes it to match PageController's actual constructor (IUserSession, not a raw user id string) — it was silently stale. tests/bootstrap.php now just loads Composer's autoloader; the old full-server bootstrap moves to tests/bootstrap.integration.php for the (still server-dependent) integration suite, which gets its own `make test-integration` target since `make test` previously installed deps with --no-dev and would have stripped PHPUnit itself. Adds a PHPStan config (level 3) with a baseline freezing the 237 pre-existing findings (missing Doctrine DBAL stub types, plus a runtime class_alias() static analysis can't see through — mirrored in tests/phpstan-bootstrap.php) so analysis starts green and only flags newly introduced issues. Verified: make test, composer run lint, composer run phpstan, and composer run test:unit all pass on PHP 8.2, 8.3, and 8.5. Co-Authored-By: Claude Sonnet 5 --- .gitignore | 2 + Makefile | 17 +- composer.json | 24 +- composer.lock | 2045 +++++++++++++++++- phpstan-baseline.neon | 426 ++++ phpstan.neon | 12 + phpunit.integration.xml | 2 +- tests/Integration/AppTest.php | 4 +- tests/Unit/Controller/PageControllerTest.php | 24 +- tests/bootstrap.integration.php | 15 + tests/bootstrap.php | 14 +- tests/phpstan-bootstrap.php | 12 + 12 files changed, 2489 insertions(+), 108 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon create mode 100644 tests/bootstrap.integration.php create mode 100644 tests/phpstan-bootstrap.php diff --git a/.gitignore b/.gitignore index fc85e3b..4c48d12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ js/dist/ js/node_modules/ +vendor/ +.phpunit.result.cache diff --git a/Makefile b/Makefile index 58eeb0f..718aed9 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,22 @@ appstore: --exclude="$(app_name)/js/.*" \ -czf $(appstore_package_name).tar.gz ../$(app_name) +# Installs composer dependencies including require-dev (phpunit, phpstan, +# nextcloud/ocp stubs). Separate from the `composer` target above, which +# passes --no-dev for production/appstore builds. +.PHONY: composer-dev +composer-dev: + composer install --prefer-dist + +# Runs the unit test suite, which only needs the nextcloud/ocp stub package +# (no live Nextcloud instance required) — this is what CI runs. .PHONY: test -test: composer +test: composer-dev $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml + +# Runs the integration test suite. Requires this app to be checked out inside +# a real Nextcloud server's apps/ directory with a working install — not run +# by CI yet (see the linked GitHub issue for the multi-database CI follow-up). +.PHONY: test-integration +test-integration: composer-dev $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml diff --git a/composer.json b/composer.json index b142981..3507361 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,28 @@ ], "require": {}, "require-dev": { - "christophwurst/nextcloud": "^24.0" + "nextcloud/ocp": "^34.0", + "phpunit/phpunit": "^10.5", + "phpstan/phpstan": "^1.11" + }, + "autoload": { + "psr-4": { + "OCA\\TimeTracker\\": "lib/" + } + }, + "autoload-dev": { + "psr-4": { + "OCA\\TimeTracker\\Tests\\": "tests/", + "OCP\\": "vendor/nextcloud/ocp/OCP/", + "NCU\\": "vendor/nextcloud/ocp/NCU/" + } + }, + "scripts": { + "lint": "find . -name '*.php' -not -path './vendor/*' -not -path './build/*' -not -path './js/*' -print0 | xargs -0 -n1 php -l", + "phpstan": "phpstan analyse --no-progress", + "test:unit": "phpunit -c phpunit.xml" + }, + "config": { + "sort-packages": true } } diff --git a/composer.lock b/composer.lock index cffd205..a012416 100644 --- a/composer.lock +++ b/composer.lock @@ -4,33 +4,95 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "296f87db0439fa6556d383ab1bd9038b", + "content-hash": "7389578d322e21100c665e143e0cbe68", "packages": [], "packages-dev": [ { - "name": "christophwurst/nextcloud", - "version": "v24.0.1", + "name": "myclabs/deep-copy", + "version": "1.13.4", "source": { "type": "git", - "url": "https://github.com/ChristophWurst/nextcloud_composer.git", - "reference": "f032acdff1502a7323f95a6524d163290f43b446" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/f032acdff1502a7323f95a6524d163290f43b446", - "reference": "f032acdff1502a7323f95a6524d163290f43b446", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "php": "^7.4 || ~8.0 || ~8.1", - "psr/container": "^1.1.1", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nextcloud/ocp", + "version": "v34.0.1", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/3f920a7f46bae0c55643579ce25b6644a09065ff", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff", + "shasum": "" + }, + "require": { + "php": "~8.2 || ~8.3 || ~8.4 || ~8.5", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", "psr/event-dispatcher": "^1.0", - "psr/log": "^1.1" + "psr/http-client": "^1.0.3", + "psr/log": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "24.0.0-dev" + "dev-stable34": "34.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -41,171 +103,1994 @@ { "name": "Christoph Wurst", "email": "christoph@winzerhof-wurst.at" + }, + { + "name": "Joas Schilling", + "email": "coding@schilljs.com" } ], - "description": "Composer package containing Nextcloud's public API (classes, interfaces)", + "description": "Composer package containing Nextcloud's public OCP API and the unstable NCU API", "support": { - "issues": "https://github.com/ChristophWurst/nextcloud_composer/issues", - "source": "https://github.com/ChristophWurst/nextcloud_composer/tree/v24.0.1" + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/v34.0.1" }, - "abandoned": "nextcloud/ocp", - "time": "2022-06-02T14:16:47+00:00" + "time": "2026-06-18T02:35:58+00:00" }, { - "name": "psr/container", - "version": "1.1.2", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "php": ">=7.4.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Nikita Popov" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "A PHP parser written in PHP", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "parser", + "php" ], "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": ">=7.2.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.12.33", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", + "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-02-28T20:30:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Standard interfaces for event handling.", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ - "events", - "psr", - "psr-14" + "coverage", + "testing", + "xunit" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" }, { - "name": "psr/log", - "version": "1.1.4", + "name": "phpunit/php-file-iterator", + "version": "4.1.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "log", - "psr", - "psr-3" + "template" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, - "time": "2021-05-03T11:20:27+00:00" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.63", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "33198268dad71e926626b618f3ec3966661e4d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", + "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.5", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.4", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-01-27T05:48:37+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/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+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": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:25:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "0735b90f4da94969541dac1da743446e276defa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:09:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:50:56+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..69929e2 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,426 @@ +parameters: + ignoreErrors: + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$content\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$cost\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$email\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$end\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$from\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$group1\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$group2\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$hours\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$interval\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$name\\.$#" + count: 4 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$projectId\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$q\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$status\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$subject\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$timegroup\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$to\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$workItem\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to static property \\$server on an unknown class OC\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Client\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Client\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setHours\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setProjectId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setClientId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setColor\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setCreatedByUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setCreatedAt\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setName\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setFilterClients\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setFilterProjects\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setGroup1\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setGroup2\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setStatus\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTimeGroup\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTimeInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTotalDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setClientName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setCost\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setProjectName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTimeInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTimelineId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTotalDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setAdmin\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setClientId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setAccess\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setAdmin\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setCreatedAt\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setProjectId\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setDetails\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setName\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setProjectId\\(\\)\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setRunning\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setStart\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setCreatedAt\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setTagId\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setWorkIntervalId\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to static method getUser\\(\\) on an unknown class OC_User\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to static method isAdminUser\\(\\) on an unknown class OC_User\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Undefined variable\\: \\$id$#" + count: 5 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$cost on left side of \\?\\? always exists and is not nullable\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$intervals might not be defined\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$repItems might not be defined\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Method OCA\\\\TimeTracker\\\\Db\\\\ProjectMapper\\:\\:delete\\(\\) should return OCP\\\\AppFramework\\\\Db\\\\Entity but empty return statement found\\.$#" + count: 2 + path: lib/Db/ProjectMapper.php + + - + message: "#^Access to an undefined property OCA\\\\TimeTracker\\\\Db\\\\TagMapper\\:\\:\\$dbengine\\.$#" + count: 4 + path: lib/Db/TagMapper.php + + - + message: "#^Call to an undefined method OCP\\\\DB\\\\QueryBuilder\\\\IQueryBuilder\\:\\:execute\\(\\)\\.$#" + count: 6 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method addColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 69 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method setPrimaryKey\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 11 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method addColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 17 + path: lib/Migration/Version000001Date20210719192031.php + + - + message: "#^Call to method hasColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 2 + path: lib/Migration/Version000001Date20210719192031.php + + - + message: "#^Call to method setPrimaryKey\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 2 + path: lib/Migration/Version000001Date20210719192031.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..49e0a9b --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,12 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 3 + paths: + - lib + - appinfo + phpVersion: 80200 + bootstrapFiles: + - vendor/autoload.php + - tests/phpstan-bootstrap.php diff --git a/phpunit.integration.xml b/phpunit.integration.xml index eae19f1..bf0965b 100644 --- a/phpunit.integration.xml +++ b/phpunit.integration.xml @@ -1,4 +1,4 @@ - + ./tests/Integration diff --git a/tests/Integration/AppTest.php b/tests/Integration/AppTest.php index cabd9e5..708bafa 100644 --- a/tests/Integration/AppTest.php +++ b/tests/Integration/AppTest.php @@ -15,13 +15,13 @@ class AppTest extends TestCase { private $container; - public function setUp() { + public function setUp(): void { parent::setUp(); $app = new App('timetracker'); $this->container = $app->getContainer(); } - public function testAppInstalled() { + public function testAppInstalled(): void { $appManager = $this->container->query('OCP\App\IAppManager'); $this->assertTrue($appManager->isInstalled('timetracker')); } diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php index 6df82e6..1c51594 100644 --- a/tests/Unit/Controller/PageControllerTest.php +++ b/tests/Unit/Controller/PageControllerTest.php @@ -2,30 +2,34 @@ namespace OCA\TimeTracker\Tests\Unit\Controller; -use PHPUnit_Framework_TestCase; - use OCP\AppFramework\Http\TemplateResponse; - +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserSession; use OCA\TimeTracker\Controller\PageController; +use PHPUnit\Framework\TestCase; - -class PageControllerTest extends PHPUnit_Framework_TestCase { +class PageControllerTest extends TestCase { private $controller; private $userId = 'john'; - public function setUp() { - $request = $this->getMockBuilder('OCP\IRequest')->getMock(); + public function setUp(): void { + $request = $this->createMock(IRequest::class); + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn($this->userId); + $userSession = $this->createMock(IUserSession::class); + $userSession->method('getUser')->willReturn($user); $this->controller = new PageController( - 'timetracker', $request, $this->userId + 'timetracker', $request, $userSession ); } - public function testIndex() { + public function testIndex(): void { $result = $this->controller->index(); $this->assertEquals('index', $result->getTemplateName()); - $this->assertTrue($result instanceof TemplateResponse); + $this->assertInstanceOf(TemplateResponse::class, $result); } } diff --git a/tests/bootstrap.integration.php b/tests/bootstrap.integration.php new file mode 100644 index 0000000..d09c421 --- /dev/null +++ b/tests/bootstrap.integration.php @@ -0,0 +1,15 @@ +addValidRoot(OC::$SERVERROOT . '/tests'); + +// Fix for "Autoload path not allowed: .../timetracker/tests/testcase.php" +\OC_App::loadApp('timetracker'); + +OC_Hook::clear(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 20a5605..85cd034 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,16 +4,4 @@ define('PHPUNIT_RUN', 1); } -require_once __DIR__.'/../../../lib/base.php'; - -// Fix for "Autoload path not allowed: .../tests/lib/testcase.php" -\OC::$loader->addValidRoot(OC::$SERVERROOT . '/tests'); - -// Fix for "Autoload path not allowed: .../timetracker/tests/testcase.php" -\OC_App::loadApp('timetracker'); - -if(!class_exists('PHPUnit_Framework_TestCase')) { - require_once('PHPUnit/Autoload.php'); -} - -OC_Hook::clear(); +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/tests/phpstan-bootstrap.php b/tests/phpstan-bootstrap.php new file mode 100644 index 0000000..db7c7f3 --- /dev/null +++ b/tests/phpstan-bootstrap.php @@ -0,0 +1,12 @@ + Date: Fri, 3 Jul 2026 22:42:40 +0200 Subject: [PATCH 2/2] Replace Travis with GitHub Actions CI .travis.yml was pinned to PHP 5.6-7.1 and long dead. Adds three free GitHub Actions workflows (unlimited minutes on public repos), each a simplified adaptation of Nextcloud's reusable workflow templates (nextcloud/.github): - lint-php.yml: composer validate + php -l, matrix over PHP 8.2/8.3 - static-analysis.yml: PHPStan against the baseline added in the previous commit - phpunit.yml: the unit suite only (no live server/DB needed, so no external services to boot); the server-backed integration suite is intentionally deferred to the multi-database CI follow-up from the linked issue Closes mtierltd/timetracker#257 (steps 1 and 2 only; unit tests for mappers/report queries and multi-database CI remain as follow-up). Co-Authored-By: Claude Sonnet 5 --- .github/workflows/lint-php.yml | 49 ++++++++++++++++++++ .github/workflows/phpunit.yml | 45 +++++++++++++++++++ .github/workflows/static-analysis.yml | 41 +++++++++++++++++ .travis.yml | 64 --------------------------- 4 files changed, 135 insertions(+), 64 deletions(-) create mode 100644 .github/workflows/lint-php.yml create mode 100644 .github/workflows/phpunit.yml create mode 100644 .github/workflows/static-analysis.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml new file mode 100644 index 0000000..f8b2e8b --- /dev/null +++ b/.github/workflows/lint-php.yml @@ -0,0 +1,49 @@ +# Cheap, high-value check: php -l syntax linting + composer.json validation. +# Adapted from Nextcloud's reusable workflow templates (nextcloud/.github), +# simplified to a fixed PHP matrix instead of deriving one from appinfo/info.xml +# (this app's declared min-version="20" predates PHP 8, which isn't a +# realistic target — see the linked issue for the follow-up on tightening that). +name: Lint PHP + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: lint-php-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + php-lint: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['8.2', '8.3'] + + name: php-lint (PHP ${{ matrix.php-versions }}) + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: composer validate + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Lint (php -l) + run: composer run lint diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..c8ea17e --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,45 @@ +# Unit tests only, against the nextcloud/ocp stub package — no live +# Nextcloud server or database is booted, which keeps this job fast and free +# of external services. tests/Integration (real server + DB) is intentionally +# not run here; see the linked GitHub issue for the multi-database follow-up. +name: PHPUnit + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: phpunit-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + unit-tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['8.2', '8.3'] + + name: unit-tests (PHP ${{ matrix.php-versions }}) + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: PHPUnit + run: composer run test:unit diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..3c9f0f6 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,41 @@ +# Static analysis with PHPStan. Existing findings are frozen in +# phpstan-baseline.neon (mostly missing Doctrine DBAL type stubs and a +# runtime class_alias() static analysis can't see through) so this starts +# green; only newly introduced issues fail the build. +name: Static analysis + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: phpstan-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + phpstan: + runs-on: ubuntu-latest + + name: static-phpstan-analysis + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: '8.3' + coverage: none + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: PHPStan + run: composer run phpstan diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8b535dd..0000000 --- a/.travis.yml +++ /dev/null @@ -1,64 +0,0 @@ -sudo: false -dist: trusty -language: php -php: - - 5.6 - - 7 - - 7.1 -env: - global: - - CORE_BRANCH=stable14 - matrix: - - DB=pgsql - -matrix: - allow_failures: - - env: DB=pgsql CORE_BRANCH=master - include: - - php: 5.6 - env: DB=sqlite - - php: 5.6 - env: DB=mysql - - php: 5.6 - env: DB=pgsql CORE_BRANCH=master - fast_finish: true - - -before_install: - # enable a display for running JavaScript tests - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - nvm install 8 - - npm install -g npm@latest - - make - - make appstore - # install core - - cd ../ - - git clone https://github.com/nextcloud/server.git --recursive --depth 1 -b $CORE_BRANCH nextcloud - - mv "$TRAVIS_BUILD_DIR" nextcloud/apps/timetracker - -before_script: - - if [[ "$DB" == 'pgsql' ]]; then createuser -U travis -s oc_autotest; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e 'create database oc_autotest;'; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "CREATE USER 'oc_autotest'@'localhost' IDENTIFIED BY '';"; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "grant all on oc_autotest.* to 'oc_autotest'@'localhost';"; fi - - cd nextcloud - - mkdir data - - ./occ maintenance:install --database-name oc_autotest --database-user oc_autotest --admin-user admin --admin-pass admin --database $DB --database-pass='' - - ./occ app:enable timetracker - - php -S localhost:8080 & - - cd apps/timetracker - -script: - - make test - -after_failure: - - cat ../../data/nextcloud.log - -addons: - firefox: 'latest' - mariadb: '10.1' - -services: - - postgresql - - mariadb