From 96c337d34da76e8eb3c8e79447c83a9542909163 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 21 Jul 2026 10:57:18 +0200 Subject: [PATCH 1/7] Drop php8.1, change to min php 8.2 --- .github/workflows/ci.yml | 12 ++++++------ .gitignore | 2 +- README.md | 6 +++--- composer.json | 10 +++++----- tools/.phpstan/composer.json | 2 +- tools/.phpstan/composer.lock | 36 +++++++++++++++++++++--------------- tools/.phpunit/composer.json | 2 +- tools/.psalm/composer.json | 2 +- tools/.rector/composer.json | 2 +- 9 files changed, 40 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 557a7733..9529e4b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.2', '8.3', '8.4', '8.5'] experimental: [false] steps: @@ -37,7 +37,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.2', '8.3', '8.4', '8.5'] experimental: [false] steps: - name: Checkout @@ -64,14 +64,14 @@ jobs: run: tools/phpunit --testsuite="BigBlueButton unit test suite,BigBlueButton integration test suite" continue-on-error: true - name: Upload coverage - if: ${{ matrix.php-versions == '8.1' }} + if: ${{ matrix.php-versions == '8.2' }} uses: codecov/codecov-action@v3 - name: Run rector - if: ${{ matrix.php-versions == '8.1' }} + if: ${{ matrix.php-versions == '8.2' }} run: tools/rector process --dry-run - name: Run psalm - if: ${{ matrix.php-versions == '8.1' }} + if: ${{ matrix.php-versions == '8.2' }} run: tools/psalm - name: Run phpstan - if: ${{ matrix.php-versions == '8.1' }} + if: ${{ matrix.php-versions == '8.2' }} run: tools/phpstan diff --git a/.gitignore b/.gitignore index 3fdf8edd..c714baae 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ reports # The library does not locks down the dependencies for several reasons: # # * In the outer world, the lock is not effective. Only the lock of the requiring application is accounted. -# * It makes it hard, to run the library with its deps in the CI as when running `composer require` under PHP 8.1, +# * It makes it hard, to run the library with its deps in the CI as when running `composer require` under PHP 8.2, # an incompatible lock file is created which is unsuable unter PHP 7.x. # # See https://github.com/littleredbutton/bigbluebutton-api-php/pull/115 for the discussion. diff --git a/README.md b/README.md index 9b29b0ef..915ba49f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # :tada: Best BigBlueButton API for PHP The unofficial and easiest to use **BigBlueButton API for PHP**, makes easy for -developers to use [BigBlueButton API] v2.2+ for **PHP 8.1+**. +developers to use [BigBlueButton API] v2.2+ for **PHP 8.2+**. ![Build Status](https://github.com/littleredbutton/bigbluebutton-api-php/workflows/CI/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/littleredbutton/bigbluebutton-api-php/badge.svg?branch=master)](https://coveralls.io/github/littleredbutton/bigbluebutton-api-php?branch=master) @@ -56,7 +56,7 @@ following advantages: - Development is simplified through git hooks and contributor guidelines - Documentation is up-to-date and complete - API is fixed and extended to exploit the full potential -- Require at least PHP 8.1, which allows to make the code more efficient and +- Require at least PHP 8.2, which allows to make the code more efficient and readable ## :gear: Installation and usage @@ -64,7 +64,7 @@ following advantages: In order to use this library you have to make sure to meet the following requirements: -- PHP 8.1 or above. +- PHP 8.2 or above. - curl library installed. - mbstring library installed. - xml library installed. diff --git a/composer.json b/composer.json index d27ba7f3..30d48549 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ "docs": "https://github.com/littleredbutton/bigbluebutton-api-php/blob/master/README.md" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-curl": "*", "ext-simplexml": "*", "ext-mbstring": "*", @@ -143,10 +143,10 @@ } }, "friendsofphp/php-cs-fixer": "^3.3", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10", - "rector/rector": "^1.0", - "vimeo/psalm": "^5.23" + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^11", + "rector/rector": "^2.0", + "vimeo/psalm": "^6.0" } } } diff --git a/tools/.phpstan/composer.json b/tools/.phpstan/composer.json index 90c99dfd..6dea17a8 100644 --- a/tools/.phpstan/composer.json +++ b/tools/.phpstan/composer.json @@ -1,5 +1,5 @@ { "require": { - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^2.0" } } diff --git a/tools/.phpstan/composer.lock b/tools/.phpstan/composer.lock index 2c3ffe96..eebbe4ff 100644 --- a/tools/.phpstan/composer.lock +++ b/tools/.phpstan/composer.lock @@ -4,24 +4,19 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "14812c2a05a5972f00f9d67abbd710a9", + "content-hash": "a1a9a305e36d2c71272f49ce0f9c92fe", "packages": [ { "name": "phpstan/phpstan", - "version": "1.12.3", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009" - }, + "version": "2.2.5", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0fcbf194ab63d8159bb70d9aa3e1350051632009", - "reference": "0fcbf194ab63d8159bb70d9aa3e1350051632009", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0", + "reference": "909c1e5fef7989ac0d0c1c5c42e32a5c4f6198a0", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -40,6 +35,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -62,16 +68,16 @@ "type": "github" } ], - "time": "2024-09-09T08:10:35+00:00" + "time": "2026-07-05T06:31:06+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.6.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/tools/.phpunit/composer.json b/tools/.phpunit/composer.json index 2dc16d75..71198119 100644 --- a/tools/.phpunit/composer.json +++ b/tools/.phpunit/composer.json @@ -1,6 +1,6 @@ { "require": { - "phpunit/phpunit": "^10.0", + "phpunit/phpunit": "^11.0", "fakerphp/faker": "1.24.*" } } diff --git a/tools/.psalm/composer.json b/tools/.psalm/composer.json index 70de5195..7ee4658e 100644 --- a/tools/.psalm/composer.json +++ b/tools/.psalm/composer.json @@ -1,5 +1,5 @@ { "require": { - "vimeo/psalm": "^5.23" + "vimeo/psalm": "^6.0" } } diff --git a/tools/.rector/composer.json b/tools/.rector/composer.json index 056d015c..d4420aba 100644 --- a/tools/.rector/composer.json +++ b/tools/.rector/composer.json @@ -1,5 +1,5 @@ { "require": { - "rector/rector": "^1.0" + "rector/rector": "^2.0" } } From 2901550c86f4521c642f7e9c46f2e7df07302726 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:08:53 +0200 Subject: [PATCH 2/7] Fix rector --- src/Http/SetCookie.php | 2 +- .../Bridge/PsrHttpClient/PsrHttpClientTransport.php | 4 ++-- .../SymfonyHttpClient/SymfonyHttpClientTransport.php | 4 ++-- src/Http/Transport/CurlTransport.php | 4 ++-- src/Util/UrlBuilder.php | 8 ++++---- tests/integration/Http/Transport/Fixtures/web/dump.php | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Http/SetCookie.php b/src/Http/SetCookie.php index 923ad56f..af895158 100644 --- a/src/Http/SetCookie.php +++ b/src/Http/SetCookie.php @@ -62,7 +62,7 @@ public static function fromString(string $cookie): self // Create the default return array $data = self::$defaults; // Explode the cookie string using a series of semicolons - $pieces = array_filter(array_map('trim', explode(';', $cookie))); + $pieces = array_filter(array_map(trim(...), explode(';', $cookie))); // The name of the cookie (first kvp) must exist and include an equal sign. if (!isset($pieces[0]) || !str_contains($pieces[0], '=')) { return new self($data); diff --git a/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php b/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php index befa70d9..2db4c8de 100644 --- a/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php +++ b/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php @@ -67,12 +67,12 @@ /** * Allows to send requests to the BBB server with a {@link https://www.php-fig.org/psr/psr-18/} implementation. */ -final class PsrHttpClientTransport implements TransportInterface +final readonly class PsrHttpClientTransport implements TransportInterface { /** * @param string[] $defaultHeaders additional headers to pass on each request */ - public function __construct(private readonly ClientInterface $httpClient, private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, private readonly array $defaultHeaders = []) + public function __construct(private ClientInterface $httpClient, private RequestFactoryInterface $requestFactory, private StreamFactoryInterface $streamFactory, private array $defaultHeaders = []) { } diff --git a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php index 0545c74d..d0b3e5fd 100644 --- a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php +++ b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php @@ -51,13 +51,13 @@ /** * Allows to send requests to the BBB server with a Symfony HTTP Client contract implementation. */ -final class SymfonyHttpClientTransport implements TransportInterface +final readonly class SymfonyHttpClientTransport implements TransportInterface { /** * @param string[] $defaultHeaders additional HTTP headers to pass on each request * @param mixed[] $defaultOptions Options for Symfony HTTP client passed on every request. See {@link https://symfony.com/doc/current/http_client.html} for details. */ - public function __construct(private readonly HttpClientInterface $httpClient, private readonly array $defaultHeaders = [], private readonly array $defaultOptions = []) + public function __construct(private HttpClientInterface $httpClient, private array $defaultHeaders = [], private array $defaultOptions = []) { } diff --git a/src/Http/Transport/CurlTransport.php b/src/Http/Transport/CurlTransport.php index 8f537677..903fe4d3 100644 --- a/src/Http/Transport/CurlTransport.php +++ b/src/Http/Transport/CurlTransport.php @@ -28,7 +28,7 @@ /** * Allows to send requests to the BBB server with the pure PHP cURL implementation. */ -final class CurlTransport implements TransportInterface +final readonly class CurlTransport implements TransportInterface { public const DEFAULT_CURL_OPTIONS = [ \CURLOPT_SSL_VERIFYPEER => 1, @@ -64,7 +64,7 @@ final class CurlTransport implements TransportInterface * * @param mixed[] $curlOptions A list of cURL options to pass to the cURL handle. Option name as key, option value as value. */ - public function __construct(private readonly array $curlOptions = []) + public function __construct(private array $curlOptions = []) { } diff --git a/src/Util/UrlBuilder.php b/src/Util/UrlBuilder.php index 822e04a9..0a4bba9f 100644 --- a/src/Util/UrlBuilder.php +++ b/src/Util/UrlBuilder.php @@ -30,12 +30,12 @@ * * @internal */ -final class UrlBuilder +final readonly class UrlBuilder { public function __construct( - private readonly string $securitySalt, - private readonly string $bbbServerBaseUrl, - private readonly HashingAlgorithm $hashingAlgorithm, + private string $securitySalt, + private string $bbbServerBaseUrl, + private HashingAlgorithm $hashingAlgorithm, ) { } diff --git a/tests/integration/Http/Transport/Fixtures/web/dump.php b/tests/integration/Http/Transport/Fixtures/web/dump.php index 31445fdc..95c82f62 100644 --- a/tests/integration/Http/Transport/Fixtures/web/dump.php +++ b/tests/integration/Http/Transport/Fixtures/web/dump.php @@ -38,7 +38,7 @@ foreach ($_SERVER as $k => $v) { switch ($k) { default: - if (!str_starts_with($k, 'HTTP_')) { + if (!str_starts_with((string) $k, 'HTTP_')) { continue 2; } // no break From 3ac3366a217c6ac95a919224390f5445d1399b8b Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 21 Jul 2026 11:26:08 +0200 Subject: [PATCH 3/7] Fix psalm --- composer.json | 2 +- psalm.xml | 1 + src/Http/SetCookie.php | 27 +++++++++++-------- .../PsrHttpClient/PsrHttpClientTransport.php | 1 + .../SymfonyHttpClientTransport.php | 3 ++- src/Http/Transport/Cookie.php | 2 +- src/Http/Transport/CurlTransport.php | 1 + src/Parameters/CreateMeetingParameters.php | 1 + src/Parameters/MetaParameters.php | 1 + src/Parameters/UserDataParameters.php | 1 + src/Responses/BaseResponseAsJson.php | 2 +- 11 files changed, 27 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 30d48549..faf69532 100644 --- a/composer.json +++ b/composer.json @@ -114,7 +114,7 @@ "cs-test": "tools/php-cs-fixer fix --dry-run --allow-risky=yes", "psalm": "tools/psalm --threads=1", "psalm-clear": "tools/psalm --clear-cache && tools/psalm --clear-global-cache", - "psalm-fix": "tools/psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType", + "psalm-fix": "tools/psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType,MissingOverrideAttribute", "phpstan": "tools/phpstan analyse", "rector": "tools/rector process --dry-run src/ tests/", "rector-fix": "tools/rector process src/ tests/", diff --git a/psalm.xml b/psalm.xml index 7c0333df..27372f7a 100644 --- a/psalm.xml +++ b/psalm.xml @@ -5,6 +5,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" + findUnusedCode="false" > diff --git a/src/Http/SetCookie.php b/src/Http/SetCookie.php index af895158..429e528b 100644 --- a/src/Http/SetCookie.php +++ b/src/Http/SetCookie.php @@ -110,6 +110,7 @@ public function __construct(array $data = []) } } + #[\Override] public function __toString(): string { $str = $this->data['Name'].'='.$this->data['Value'].'; '; @@ -126,8 +127,12 @@ public function __toString(): string return rtrim($str, '; '); } - /** @return array */ - public function toArray(): array + /** + * @return (bool|int|string|null)[]|null + * + * @psalm-return array|null + */ + public function toArray(): ?array { return $this->data; } @@ -135,7 +140,7 @@ public function toArray(): array /** * Get the cookie name. */ - public function getName(): string + public function getName(): string|bool|int|null { return $this->data['Name']; } @@ -153,7 +158,7 @@ public function setName(string $name): void /** * Get the cookie value. */ - public function getValue(): ?string + public function getValue(): string|bool|int|null { return $this->data['Value']; } @@ -161,9 +166,9 @@ public function getValue(): ?string /** * Set the cookie value. * - * @param string $value Cookie value + * @param string|bool|int|null $value Cookie value */ - public function setValue(string $value): void + public function setValue(string|bool|int|null $value): void { $this->data['Value'] = $value; } @@ -171,7 +176,7 @@ public function setValue(string $value): void /** * Get the domain. */ - public function getDomain(): ?string + public function getDomain(): string|bool|int|null { return $this->data['Domain']; } @@ -187,7 +192,7 @@ public function setDomain(string $domain): void /** * Get the path. */ - public function getPath(): string + public function getPath(): string|bool|int|null { return $this->data['Path']; } @@ -223,7 +228,7 @@ public function setMaxAge(int $maxAge): void /** * The UNIX timestamp when the cookie Expires. */ - public function getExpires(): int|string|null + public function getExpires(): bool|int|string|null { return $this->data['Expires']; } @@ -243,7 +248,7 @@ public function setExpires(int|string $timestamp): void /** * Get whether or not this is a secure cookie. */ - public function getSecure(): ?bool + public function getSecure(): string|bool|int|null { return $this->data['Secure']; } @@ -261,7 +266,7 @@ public function setSecure(bool $secure): void /** * Get whether or not this is a session cookie. */ - public function getDiscard(): ?bool + public function getDiscard(): string|bool|int|null { return $this->data['Discard']; } diff --git a/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php b/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php index 2db4c8de..ed9f94ab 100644 --- a/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php +++ b/src/Http/Transport/Bridge/PsrHttpClient/PsrHttpClientTransport.php @@ -76,6 +76,7 @@ public function __construct(private ClientInterface $httpClient, private Request { } + #[\Override] public function request(TransportRequest $request): TransportResponse { if ('' !== $payload = $request->getPayload()) { diff --git a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php index d0b3e5fd..6c093a13 100644 --- a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php +++ b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php @@ -83,6 +83,7 @@ public static function create(array $defaultHeaders = [], array $defaultOptions // @codeCoverageIgnoreEnd } + #[\Override] public function request(TransportRequest $request): TransportResponse { $headers = $this->defaultHeaders; @@ -125,7 +126,7 @@ public function request(TransportRequest $request): TransportResponse * @throws RedirectionExceptionInterface * @throws ServerExceptionInterface */ - private static function extractJsessionCookie(ResponseInterface $symfonyResponse): ?string + private static function extractJsessionCookie(ResponseInterface $symfonyResponse): bool|int|string|null { $responseHeaders = $symfonyResponse->getHeaders(); diff --git a/src/Http/Transport/Cookie.php b/src/Http/Transport/Cookie.php index 6f7aae89..511bb6d0 100644 --- a/src/Http/Transport/Cookie.php +++ b/src/Http/Transport/Cookie.php @@ -33,7 +33,7 @@ final class Cookie /** * @param string[] $headerValues */ - public static function extractJsessionId(array $headerValues): ?string + public static function extractJsessionId(array $headerValues): bool|int|string|null { foreach ($headerValues as $headerValue) { $cookie = SetCookie::fromString($headerValue); diff --git a/src/Http/Transport/CurlTransport.php b/src/Http/Transport/CurlTransport.php index 903fe4d3..524f48e8 100644 --- a/src/Http/Transport/CurlTransport.php +++ b/src/Http/Transport/CurlTransport.php @@ -78,6 +78,7 @@ public static function createWithDefaultOptions(array $additionalCurlOptions = [ // @codeCoverageIgnoreEnd } + #[\Override] public function request(TransportRequest $request): TransportResponse { // @codeCoverageIgnoreStart diff --git a/src/Parameters/CreateMeetingParameters.php b/src/Parameters/CreateMeetingParameters.php index 89e5edd0..4a14e5c4 100644 --- a/src/Parameters/CreateMeetingParameters.php +++ b/src/Parameters/CreateMeetingParameters.php @@ -460,6 +460,7 @@ public function addPresentationsModule(SimpleXMLElementExtended $xml): void } } + #[\Override] public function getHTTPQuery(): string { $queries = $this->getHTTPQueryArray(); diff --git a/src/Parameters/MetaParameters.php b/src/Parameters/MetaParameters.php index 2adab816..14dc0c99 100644 --- a/src/Parameters/MetaParameters.php +++ b/src/Parameters/MetaParameters.php @@ -42,6 +42,7 @@ public function addMeta(string $key, bool|string $value): static return $this; } + #[\Override] protected function getHTTPQueryArray(): array { $properties = parent::getHTTPQueryArray(); diff --git a/src/Parameters/UserDataParameters.php b/src/Parameters/UserDataParameters.php index a1f788f0..4529a147 100644 --- a/src/Parameters/UserDataParameters.php +++ b/src/Parameters/UserDataParameters.php @@ -42,6 +42,7 @@ public function addUserData(string $key, bool|string $value): self return $this; } + #[\Override] protected function getHTTPQueryArray(): array { $properties = parent::getHTTPQueryArray(); diff --git a/src/Responses/BaseResponseAsJson.php b/src/Responses/BaseResponseAsJson.php index 77b8fa56..aff7bebd 100644 --- a/src/Responses/BaseResponseAsJson.php +++ b/src/Responses/BaseResponseAsJson.php @@ -43,7 +43,7 @@ public function __construct($rawJson) $this->data = json_decode($rawJson); } - public function getRawJson(): string + public function getRawJson(): string|false { return json_encode($this->data); } From 41d95a1551fa6e7095bf7b612eb2c65bc244c575 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:11:03 +0200 Subject: [PATCH 4/7] Fix phpstan # Conflicts: # src/Parameters/CreateMeetingParameters.php --- phpstan.neon | 2 ++ src/Http/SetCookie.php | 30 ++++++++-------- src/Http/Transport/CurlTransport.php | 2 +- tests/bootstrap.php | 20 ++--------- .../Http/Transport/CurlTransportTest.php | 4 ++- tests/unit/Http/SetCookieTest.php | 2 +- .../SymfonyHttpClientTransportTest.php | 36 +++++-------------- tests/unit/Util/ArrayHelperTest.php | 10 +++--- 8 files changed, 38 insertions(+), 68 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 9110ad71..4817ce70 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,6 +9,8 @@ parameters: bootstrapFiles: - tools/bootstrap.php ignoreErrors: + - + identifier: method.alreadyNarrowedType - message: '#^Offset ''input'' does not exist on array\{\}\.$#' path: tests/integration/Http/Transport/CurlTransportTest.php diff --git a/src/Http/SetCookie.php b/src/Http/SetCookie.php index 429e528b..99302b05 100644 --- a/src/Http/SetCookie.php +++ b/src/Http/SetCookie.php @@ -50,7 +50,7 @@ final class SetCookie implements \Stringable /** * @var array Cookie data */ - private ?array $data; + private array $data; /** * Create a new SetCookie object from a string. @@ -96,7 +96,7 @@ public static function fromString(string $cookie): self } /** - * @param array $data Array of cookie data provided by a Cookie parser + * @param array $data Array of cookie data provided by a Cookie parser */ public function __construct(array $data = []) { @@ -128,11 +128,9 @@ public function __toString(): string } /** - * @return (bool|int|string|null)[]|null - * - * @psalm-return array|null + * @return array */ - public function toArray(): ?array + public function toArray(): array { return $this->data; } @@ -140,7 +138,7 @@ public function toArray(): ?array /** * Get the cookie name. */ - public function getName(): string|bool|int|null + public function getName(): string { return $this->data['Name']; } @@ -158,7 +156,7 @@ public function setName(string $name): void /** * Get the cookie value. */ - public function getValue(): string|bool|int|null + public function getValue(): ?string { return $this->data['Value']; } @@ -166,9 +164,9 @@ public function getValue(): string|bool|int|null /** * Set the cookie value. * - * @param string|bool|int|null $value Cookie value + * @param string $value Cookie value */ - public function setValue(string|bool|int|null $value): void + public function setValue(string $value): void { $this->data['Value'] = $value; } @@ -176,7 +174,7 @@ public function setValue(string|bool|int|null $value): void /** * Get the domain. */ - public function getDomain(): string|bool|int|null + public function getDomain(): ?string { return $this->data['Domain']; } @@ -192,7 +190,7 @@ public function setDomain(string $domain): void /** * Get the path. */ - public function getPath(): string|bool|int|null + public function getPath(): string { return $this->data['Path']; } @@ -228,7 +226,7 @@ public function setMaxAge(int $maxAge): void /** * The UNIX timestamp when the cookie Expires. */ - public function getExpires(): bool|int|string|null + public function getExpires(): ?int { return $this->data['Expires']; } @@ -246,9 +244,9 @@ public function setExpires(int|string $timestamp): void } /** - * Get whether or not this is a secure cookie. + * Get whether this is a secure cookie. */ - public function getSecure(): string|bool|int|null + public function getSecure(): ?bool { return $this->data['Secure']; } @@ -266,7 +264,7 @@ public function setSecure(bool $secure): void /** * Get whether or not this is a session cookie. */ - public function getDiscard(): string|bool|int|null + public function getDiscard(): ?bool { return $this->data['Discard']; } diff --git a/src/Http/Transport/CurlTransport.php b/src/Http/Transport/CurlTransport.php index 524f48e8..fea68831 100644 --- a/src/Http/Transport/CurlTransport.php +++ b/src/Http/Transport/CurlTransport.php @@ -194,7 +194,7 @@ private static function getHeadersAndContentFromCurlHandle(\CurlHandle $curlHand { $headers = []; - curl_setopt($curlHandle, \CURLOPT_HEADER, 1); + curl_setopt($curlHandle, \CURLOPT_HEADER, true); $responseContent = curl_exec($curlHandle); // @codeCoverageIgnoreStart diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d22a1a3c..c4419793 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -30,21 +30,5 @@ // Load environment $dotenv = new Dotenv(); -// usePutenv was not available in version 3.4 und early 4.x versions of symfony/dotenv, so make it optional here -if (method_exists($dotenv, 'usePutenv')) { - $dotenv->usePutenv(true); -} - -// loadEnv was not available in version 3.4 und early 4.x versions of symfony/dotenv, so make it optional here -if (method_exists($dotenv, 'loadEnv')) { - $dotenv->loadEnv(dirname(__DIR__).'/.env'); -} else { - $files = []; - foreach ([dirname(__DIR__).'/.env', dirname(__DIR__).'/.env.local'] as $file) { - if (file_exists($file)) { - $files[] = $file; - } - } - - $dotenv->load(...$files); -} +$dotenv->usePutenv(); +$dotenv->loadEnv(dirname(__DIR__).'/.env'); diff --git a/tests/integration/Http/Transport/CurlTransportTest.php b/tests/integration/Http/Transport/CurlTransportTest.php index fb51caa5..4b094207 100644 --- a/tests/integration/Http/Transport/CurlTransportTest.php +++ b/tests/integration/Http/Transport/CurlTransportTest.php @@ -41,7 +41,9 @@ public static function setUpBeforeClass(): void TestHttpServer::start(); } - /** @return array> */ + /** + * @return iterable> + */ public static function provideBadResponseCodes(): iterable { // cURL does not understand codes below 200 properly. diff --git a/tests/unit/Http/SetCookieTest.php b/tests/unit/Http/SetCookieTest.php index 91a3b834..7ef3765e 100644 --- a/tests/unit/Http/SetCookieTest.php +++ b/tests/unit/Http/SetCookieTest.php @@ -181,7 +181,7 @@ public function testMatchesPath(string $cookiePath, string $requestPath, bool $i self::assertSame($isMatch, $cookie->matchesPath($requestPath)); } - /** @return array> */ + /** @return array> */ public static function cookieValidateProvider(): array { return [ diff --git a/tests/unit/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransportTest.php b/tests/unit/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransportTest.php index 10dc5a99..4e571871 100644 --- a/tests/unit/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransportTest.php +++ b/tests/unit/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransportTest.php @@ -63,9 +63,7 @@ public function testRequestWithoutPayload(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertSame('MartyMcFlySession', $response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } public function testRequestWithPayload(): void @@ -87,9 +85,7 @@ public function testRequestWithPayload(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertSame('MartyMcFlySession', $response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } public function testRequestWithoutCookie(): void @@ -110,9 +106,7 @@ public function testRequestWithoutCookie(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertNull($response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } public function testRequestWithEmptyCookie(): void @@ -133,9 +127,7 @@ public function testRequestWithEmptyCookie(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertNull($response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } public function testRequestWithDefaultHeaders(): void @@ -163,9 +155,7 @@ public function testRequestWithDefaultHeaders(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertSame('MartyMcFlySession', $response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } public function testRequestWithDefaultOptions(): void @@ -196,9 +186,7 @@ public function testRequestWithDefaultOptions(): void $this->assertSame('Hi Marty!', $response->getBody(), 'body is OK'); $this->assertSame('MartyMcFlySession', $response->getSessionId(), 'session ID is OK'); - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } /** @return iterable> */ @@ -237,9 +225,7 @@ public function testRequestWithBadResponseCode(int $badCode): void try { $transport->request($request); } finally { - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); - } + $this->assertSame(1, $mockHttpClient->getRequestsCount(), 'one request was made'); } } @@ -275,9 +261,7 @@ public function testRequestWithBadResponseException(HttpExceptionInterface $exce try { $transport->request($request); } finally { - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(0, $mockHttpClient->getRequestsCount(), 'no full request was made'); - } + $this->assertSame(0, $mockHttpClient->getRequestsCount(), 'no full request was made'); } } @@ -302,9 +286,7 @@ public function testRequestWithTransportException(): void try { $transport->request($request); } finally { - if (method_exists($mockHttpClient, 'getRequestsCount')) { - $this->assertSame(0, $mockHttpClient->getRequestsCount(), 'no full request was made'); - } + $this->assertSame(0, $mockHttpClient->getRequestsCount(), 'no full request was made'); } } } diff --git a/tests/unit/Util/ArrayHelperTest.php b/tests/unit/Util/ArrayHelperTest.php index 9c1f5b75..192e5ea6 100644 --- a/tests/unit/Util/ArrayHelperTest.php +++ b/tests/unit/Util/ArrayHelperTest.php @@ -29,7 +29,9 @@ */ final class ArrayHelperTest extends TestCase { - /** @return iterable> */ + /** + * @return iterable, 1: array, 2: bool, 3: array}> + */ public static function provideArrays(): iterable { yield 'simple flat arrays' => [ @@ -61,9 +63,9 @@ public static function provideArrays(): iterable /** * @dataProvider provideArrays * - * @param array $input1 - * @param array $input2 - * @param array $output + * @param array $input1 + * @param array $input2 + * @param array $output */ public function testMergeRecursive(array $input1, array $input2, bool $reorderNested, array $output): void { From 88ec27537fd3e0067c386bd864893e1ecb5f7a5f Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Mon, 21 Sep 2026 17:47:56 +0200 Subject: [PATCH 5/7] Fix rector & psalm --- src/Core/Hook.php | 14 +++++++------- src/Core/ImagePreview.php | 10 +++++----- src/Core/InlinePresentation.php | 4 +++- src/Core/Track.php | 12 ++++++------ src/Core/UrlPresentation.php | 2 ++ src/Http/SetCookie.php | 14 +++++++------- src/Http/Transport/TransportRequest.php | 4 ++-- src/Http/Transport/TransportResponse.php | 4 ++-- src/Responses/GetMeetingInfoResponse.php | 4 +--- 9 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/Core/Hook.php b/src/Core/Hook.php index da8c1ba5..7eb49836 100644 --- a/src/Core/Hook.php +++ b/src/Core/Hook.php @@ -25,19 +25,19 @@ /** * Class Meeting. */ -final class Hook +final readonly class Hook { - private readonly string $hookId; + private string $hookId; - private readonly string $meetingId; + private string $meetingId; - private readonly string $callbackUrl; + private string $callbackUrl; - private readonly bool $permanentHook; + private bool $permanentHook; - private readonly bool $rawData; + private bool $rawData; - public function __construct(private readonly \SimpleXMLElement $rawXml) + public function __construct(private \SimpleXMLElement $rawXml) { $this->hookId = $this->rawXml->hookID->__toString(); $this->callbackUrl = $this->rawXml->callbackURL->__toString(); diff --git a/src/Core/ImagePreview.php b/src/Core/ImagePreview.php index d7584aab..3c1e3b14 100644 --- a/src/Core/ImagePreview.php +++ b/src/Core/ImagePreview.php @@ -21,13 +21,13 @@ namespace BigBlueButton\Core; -final class ImagePreview +final readonly class ImagePreview { public function __construct( - private readonly int $width, - private readonly int $height, - private readonly string $alt, - private readonly string $url, + private int $width, + private int $height, + private string $alt, + private string $url, ) { } diff --git a/src/Core/InlinePresentation.php b/src/Core/InlinePresentation.php index 6b1f839c..44db7336 100644 --- a/src/Core/InlinePresentation.php +++ b/src/Core/InlinePresentation.php @@ -31,11 +31,13 @@ public function __construct(private readonly string $content, string $filename) $this->filename = $filename; } - public function getArrayKey(): string + #[\Override] + public function getArrayKey(): string|null { return $this->filename; } + #[\Override] public function addDocumentToXML(SimpleXMLElementExtended $module): ?SimpleXMLElementExtended { $document = parent::addDocumentToXML($module); diff --git a/src/Core/Track.php b/src/Core/Track.php index ff805c0a..da7ba15b 100644 --- a/src/Core/Track.php +++ b/src/Core/Track.php @@ -25,17 +25,17 @@ /** * Class Track. */ -final class Track +final readonly class Track { - private readonly string $href; + private string $href; - private readonly string $kind; + private string $kind; - private readonly string $label; + private string $label; - private readonly string $lang; + private string $lang; - private readonly string $source; + private string $source; public function __construct(object $track) { diff --git a/src/Core/UrlPresentation.php b/src/Core/UrlPresentation.php index db416bd9..f1ba7875 100644 --- a/src/Core/UrlPresentation.php +++ b/src/Core/UrlPresentation.php @@ -30,11 +30,13 @@ public function __construct(private readonly string $url) { } + #[\Override] public function getArrayKey(): string { return $this->url; } + #[\Override] public function addDocumentToXML(SimpleXMLElementExtended $module): ?SimpleXMLElementExtended { $document = parent::addDocumentToXML($module); diff --git a/src/Http/SetCookie.php b/src/Http/SetCookie.php index 99302b05..25bca177 100644 --- a/src/Http/SetCookie.php +++ b/src/Http/SetCookie.php @@ -138,7 +138,7 @@ public function toArray(): array /** * Get the cookie name. */ - public function getName(): string + public function getName(): string|bool|int|null { return $this->data['Name']; } @@ -156,7 +156,7 @@ public function setName(string $name): void /** * Get the cookie value. */ - public function getValue(): ?string + public function getValue(): string|bool|int|null { return $this->data['Value']; } @@ -174,7 +174,7 @@ public function setValue(string $value): void /** * Get the domain. */ - public function getDomain(): ?string + public function getDomain(): string|bool|int|null { return $this->data['Domain']; } @@ -190,7 +190,7 @@ public function setDomain(string $domain): void /** * Get the path. */ - public function getPath(): string + public function getPath(): string|bool|int|null { return $this->data['Path']; } @@ -226,7 +226,7 @@ public function setMaxAge(int $maxAge): void /** * The UNIX timestamp when the cookie Expires. */ - public function getExpires(): ?int + public function getExpires(): string|bool|int|null { return $this->data['Expires']; } @@ -246,7 +246,7 @@ public function setExpires(int|string $timestamp): void /** * Get whether this is a secure cookie. */ - public function getSecure(): ?bool + public function getSecure(): string|bool|int|null { return $this->data['Secure']; } @@ -264,7 +264,7 @@ public function setSecure(bool $secure): void /** * Get whether or not this is a session cookie. */ - public function getDiscard(): ?bool + public function getDiscard(): string|bool|int|null { return $this->data['Discard']; } diff --git a/src/Http/Transport/TransportRequest.php b/src/Http/Transport/TransportRequest.php index b5ac4c0c..456bdc89 100644 --- a/src/Http/Transport/TransportRequest.php +++ b/src/Http/Transport/TransportRequest.php @@ -24,9 +24,9 @@ /** * Represents request data to be passed to {@link TransportInterface} for talking to BBB server. */ -final class TransportRequest +final readonly class TransportRequest { - public function __construct(private readonly string $url, private readonly string $payload, private readonly string $contentType) + public function __construct(private string $url, private string $payload, private string $contentType) { } diff --git a/src/Http/Transport/TransportResponse.php b/src/Http/Transport/TransportResponse.php index fb1bf02c..f08e539f 100644 --- a/src/Http/Transport/TransportResponse.php +++ b/src/Http/Transport/TransportResponse.php @@ -24,9 +24,9 @@ /** * Represents response returned by {@link TransportInterface} from BBB server. */ -final class TransportResponse +final readonly class TransportResponse { - public function __construct(private readonly string $body, private readonly ?string $sessionId) + public function __construct(private string $body, private ?string $sessionId) { } diff --git a/src/Responses/GetMeetingInfoResponse.php b/src/Responses/GetMeetingInfoResponse.php index 123970c2..b02b9338 100644 --- a/src/Responses/GetMeetingInfoResponse.php +++ b/src/Responses/GetMeetingInfoResponse.php @@ -33,9 +33,7 @@ final class GetMeetingInfoResponse extends BaseResponse public function getMeeting(): Meeting { - if ($this->meeting === null) { - $this->meeting = new Meeting($this->rawXml); - } + $this->meeting ??= new Meeting($this->rawXml); return $this->meeting; } From cc46c56dd93505764ff137644a29e5862f1bf38d Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Mon, 21 Sep 2026 17:59:39 +0200 Subject: [PATCH 6/7] Fix phpstan --- src/Core/InlinePresentation.php | 12 +++++------- src/Http/Transport/CurlTransport.php | 2 +- src/Http/Transport/Header.php | 4 ++-- src/Parameters/CreateMeetingParameters.php | 12 +++++------- src/Parameters/HooksListParameters.php | 4 ++-- src/Parameters/InsertDocumentParameters.php | 4 +--- 6 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/Core/InlinePresentation.php b/src/Core/InlinePresentation.php index 44db7336..6bd901c1 100644 --- a/src/Core/InlinePresentation.php +++ b/src/Core/InlinePresentation.php @@ -32,22 +32,20 @@ public function __construct(private readonly string $content, string $filename) } #[\Override] - public function getArrayKey(): string|null + public function getArrayKey(): string { return $this->filename; } #[\Override] - public function addDocumentToXML(SimpleXMLElementExtended $module): ?SimpleXMLElementExtended + public function addDocumentToXML(SimpleXMLElementExtended $module): SimpleXMLElementExtended { $document = parent::addDocumentToXML($module); - /* @phpstan-ignore-next-line */ - $document[0] = base64_encode($this->content); + $element = dom_import_simplexml($document); + $element->nodeValue = base64_encode($this->content); - if (isset($this->filename)) { - $document->addAttribute('name', $this->filename); - } + $document->addAttribute('name', $this->filename); return $document; } diff --git a/src/Http/Transport/CurlTransport.php b/src/Http/Transport/CurlTransport.php index fea68831..34695d44 100644 --- a/src/Http/Transport/CurlTransport.php +++ b/src/Http/Transport/CurlTransport.php @@ -219,7 +219,7 @@ private static function getHeadersAndContentFromCurlHandle(\CurlHandle $curlHand $splitHeader = explode(': ', $line, 2); // @codeCoverageIgnoreStart - if (!isset($splitHeader[0], $splitHeader[1])) { + if (2 !== \count($splitHeader)) { throw new \InvalidArgumentException(\sprintf('Header value "%s" is invalid. Expected format is "Header-Name: value".', $line)); } // @codeCoverageIgnoreEnd diff --git a/src/Http/Transport/Header.php b/src/Http/Transport/Header.php index ea339ee2..7d2865df 100644 --- a/src/Http/Transport/Header.php +++ b/src/Http/Transport/Header.php @@ -32,7 +32,7 @@ final class Header * Merges multiple arrays of HTTP headers as passed to CURLOPT_HTTPHEADER. Headers given in later arrays will * overwrite the previous one with the same name. * - * @param string[] ...$headers + * @param list ...$headers * * @return string[] */ @@ -50,7 +50,7 @@ public static function mergeCurlHeaders(array ...$headers): array } $splitHeader = explode(': ', $header, 2); - if (!isset($splitHeader[0], $splitHeader[1])) { + if (2 !== \count($splitHeader)) { throw new \InvalidArgumentException(\sprintf('Header value "%s" is invalid. Expected format is "Header-Name: value".', $header)); } diff --git a/src/Parameters/CreateMeetingParameters.php b/src/Parameters/CreateMeetingParameters.php index 4a14e5c4..3d038c66 100644 --- a/src/Parameters/CreateMeetingParameters.php +++ b/src/Parameters/CreateMeetingParameters.php @@ -139,10 +139,10 @@ * @method $this setUserCameraCap(int $cap) * @method int|null getMeetingCameraCap() * @method $this setMeetingCameraCap(int $cap) - * @method array getDisabledFeatures() - * @method $this setDisabledFeatures(array $disabledFeatures) - * @method array getDisabledFeaturesExclude() - * @method $this setDisabledFeaturesExclude(array $disabledFeaturesExclude) + * @method array getDisabledFeatures() + * @method $this setDisabledFeatures(array $disabledFeatures) + * @method array getDisabledFeaturesExclude() + * @method $this setDisabledFeaturesExclude(array $disabledFeaturesExclude) * @method bool|null isPreUploadedPresentationOverrideDefault() * @method $this setPreUploadedPresentationOverrideDefault(bool $preUploadedPresentationOverrideDefault) * @method string|null getPresentationUploadExternalUrl() @@ -453,9 +453,7 @@ public function addPresentationsModule(SimpleXMLElementExtended $xml): void $module->addAttribute('name', 'presentation'); foreach ($this->presentations as $data) { - if ($data instanceof Presentation) { - $data->addDocumentToXML($module); - } + $data->addDocumentToXML($module); } } } diff --git a/src/Parameters/HooksListParameters.php b/src/Parameters/HooksListParameters.php index 0df6305c..1356c49a 100644 --- a/src/Parameters/HooksListParameters.php +++ b/src/Parameters/HooksListParameters.php @@ -25,8 +25,8 @@ /** * Class HooksListParameters. * - * @method string getMeetingID() - * @method $this setMeetingID(string $id) + * @method string|null getMeetingID() + * @method $this setMeetingID(string $id) */ final class HooksListParameters extends MetaParameters { diff --git a/src/Parameters/InsertDocumentParameters.php b/src/Parameters/InsertDocumentParameters.php index 1d799895..8ffad3c8 100644 --- a/src/Parameters/InsertDocumentParameters.php +++ b/src/Parameters/InsertDocumentParameters.php @@ -82,9 +82,7 @@ public function getPresentationsAsXML(): string|false $module->addAttribute('name', 'presentation'); foreach ($this->presentations as $content) { - if ($content instanceof Presentation) { - $content->addDocumentToXML($module); - } + $content->addDocumentToXML($module); } $result = $xml->asXML(); } From a3b42a4348387362171f28941d44af40459c364c Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Mon, 21 Sep 2026 19:46:43 +0200 Subject: [PATCH 7/7] Fixes --- src/Core/InlinePresentation.php | 3 +-- src/Core/Presentation.php | 14 ----------- src/Core/UrlPresentation.php | 9 +++++++ src/Http/SetCookie.php | 25 +++++++++++-------- .../SymfonyHttpClientTransport.php | 2 +- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/Core/InlinePresentation.php b/src/Core/InlinePresentation.php index 6bd901c1..145d8121 100644 --- a/src/Core/InlinePresentation.php +++ b/src/Core/InlinePresentation.php @@ -26,9 +26,8 @@ final class InlinePresentation extends Presentation { - public function __construct(private readonly string $content, string $filename) + public function __construct(private readonly string $content, private readonly string $filename) { - $this->filename = $filename; } #[\Override] diff --git a/src/Core/Presentation.php b/src/Core/Presentation.php index 06b074a2..927f1f23 100644 --- a/src/Core/Presentation.php +++ b/src/Core/Presentation.php @@ -26,8 +26,6 @@ abstract class Presentation { - protected ?string $filename = null; - protected ?bool $current = null; protected ?bool $downloadable = null; @@ -55,18 +53,6 @@ public function addDocumentToXML(SimpleXMLElementExtended $module): ?SimpleXMLEl abstract public function getArrayKey(): string; - public function getFilename(): ?string - { - return $this->filename; - } - - public function setFilename(string $filename): self - { - $this->filename = $filename; - - return $this; - } - public function getCurrent(): ?bool { return $this->current; diff --git a/src/Core/UrlPresentation.php b/src/Core/UrlPresentation.php index f1ba7875..ae4c9976 100644 --- a/src/Core/UrlPresentation.php +++ b/src/Core/UrlPresentation.php @@ -26,6 +26,8 @@ final class UrlPresentation extends Presentation { + private ?string $filename = null; + public function __construct(private readonly string $url) { } @@ -48,4 +50,11 @@ public function addDocumentToXML(SimpleXMLElementExtended $module): ?SimpleXMLEl return $document; } + + public function setFilename(string $filename): self + { + $this->filename = $filename; + + return $this; + } } diff --git a/src/Http/SetCookie.php b/src/Http/SetCookie.php index 25bca177..052abbcd 100644 --- a/src/Http/SetCookie.php +++ b/src/Http/SetCookie.php @@ -47,9 +47,7 @@ final class SetCookie implements \Stringable 'HttpOnly' => false, ]; - /** - * @var array Cookie data - */ + /** @var array Cookie data */ private array $data; /** @@ -238,17 +236,22 @@ public function getExpires(): string|bool|int|null */ public function setExpires(int|string $timestamp): void { - $this->data['Expires'] = is_numeric($timestamp) - ? (int) $timestamp - : strtotime($timestamp); + if (is_numeric($timestamp)) { + $this->data['Expires'] = (int) $timestamp; + + return; + } + + $expires = strtotime($timestamp); + $this->data['Expires'] = $expires !== false ? $expires : null; } /** * Get whether this is a secure cookie. */ - public function getSecure(): string|bool|int|null + public function getSecure(): bool { - return $this->data['Secure']; + return (bool) $this->data['Secure']; } /** @@ -264,9 +267,9 @@ public function setSecure(bool $secure): void /** * Get whether or not this is a session cookie. */ - public function getDiscard(): string|bool|int|null + public function getDiscard(): bool { - return $this->data['Discard']; + return (bool) $this->data['Discard']; } /** @@ -381,7 +384,7 @@ public function isExpired(): bool public function validate(): bool|string { $name = $this->getName(); - if ($name === '') { + if ($name === null || $name === '') { return 'The cookie name must not be empty'; } diff --git a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php index 6c093a13..608092fb 100644 --- a/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php +++ b/src/Http/Transport/Bridge/SymfonyHttpClient/SymfonyHttpClientTransport.php @@ -126,7 +126,7 @@ public function request(TransportRequest $request): TransportResponse * @throws RedirectionExceptionInterface * @throws ServerExceptionInterface */ - private static function extractJsessionCookie(ResponseInterface $symfonyResponse): bool|int|string|null + private static function extractJsessionCookie(ResponseInterface $symfonyResponse): string|int|bool|null { $responseHeaders = $symfonyResponse->getHeaders();