From 112a54c043ecd60811483caadb7dc3905f1c85e7 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:33 +0000 Subject: [PATCH 01/10] fix: add missing acquire() and betweenBlockedAttemptsSleepFor() to Lock contract --- src/cache/src/Contracts/Lock.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cache/src/Contracts/Lock.php b/src/cache/src/Contracts/Lock.php index 98a2669a3..c81301b6a 100644 --- a/src/cache/src/Contracts/Lock.php +++ b/src/cache/src/Contracts/Lock.php @@ -6,6 +6,11 @@ interface Lock { + /** + * Attempt to acquire the lock. + */ + public function acquire(): bool; + /** * Attempt to acquire the lock. */ @@ -16,6 +21,11 @@ public function get(?callable $callback = null): mixed; */ public function block(int $seconds, ?callable $callback = null): mixed; + /** + * Specify the number of milliseconds to sleep in between blocked lock acquisition attempts. + */ + public function betweenBlockedAttemptsSleepFor(int $milliseconds): static; + /** * Release the lock. */ From 0dfe6d695de5c9dba81fb9c62a521452ef6cd236 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:36 +0000 Subject: [PATCH 02/10] fix: use intersection type for LockProvider in CacheEventMutex --- .../src/Scheduling/CacheEventMutex.php | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/console/src/Scheduling/CacheEventMutex.php b/src/console/src/Scheduling/CacheEventMutex.php index 8dda537ee..15aab12c2 100644 --- a/src/console/src/Scheduling/CacheEventMutex.php +++ b/src/console/src/Scheduling/CacheEventMutex.php @@ -32,9 +32,11 @@ public function __construct( */ public function create(Event $event): bool { - if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { - /* @phpstan-ignore-next-line */ - return $this->cache->store($this->store)->getStore() + $store = $this->cache->store($this->store)->getStore(); + + if ($this->shouldUseLocks($store)) { + /** @var LockProvider&Store $store */ // @phpstan-ignore varTag.nativeType + return $store ->lock($event->mutexName(), $event->expiresAt * 60) ->acquire(); } @@ -51,9 +53,11 @@ public function create(Event $event): bool */ public function exists(Event $event): bool { - if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { - /* @phpstan-ignore-next-line */ - return ! $this->cache->store($this->store)->getStore() + $store = $this->cache->store($this->store)->getStore(); + + if ($this->shouldUseLocks($store)) { + /** @var LockProvider&Store $store */ // @phpstan-ignore varTag.nativeType + return ! $store ->lock($event->mutexName(), $event->expiresAt * 60) ->get(fn () => true); } @@ -66,9 +70,11 @@ public function exists(Event $event): bool */ public function forget(Event $event): void { - if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { - /* @phpstan-ignore-next-line */ - $this->cache->store($this->store)->getStore() + $store = $this->cache->store($this->store)->getStore(); + + if ($this->shouldUseLocks($store)) { + /** @var LockProvider&Store $store */ // @phpstan-ignore varTag.nativeType + $store ->lock($event->mutexName(), $event->expiresAt * 60) ->forceRelease(); From 4696f18991d62e3b80fe3e9cdb3229185fcfcf1e Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:40 +0000 Subject: [PATCH 03/10] fix: correct Filesystem interface casing in FilesystemManager return types --- src/filesystem/src/FilesystemManager.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/filesystem/src/FilesystemManager.php b/src/filesystem/src/FilesystemManager.php index 011773682..4bfc1e7da 100644 --- a/src/filesystem/src/FilesystemManager.php +++ b/src/filesystem/src/FilesystemManager.php @@ -79,7 +79,7 @@ public function drive(?string $name = null): Filesystem /** * Get a filesystem instance. */ - public function disk(?string $name = null): FileSystem + public function disk(?string $name = null): Filesystem { $name = $name ?: $this->getDefaultDriver(); @@ -100,7 +100,7 @@ public function cloud(): Cloud /** * Build an on-demand disk. */ - public function build(array|string $config): FileSystem + public function build(array|string $config): Filesystem { return $this->resolve('ondemand', is_array($config) ? $config : [ 'driver' => 'local', @@ -111,7 +111,7 @@ public function build(array|string $config): FileSystem /** * Attempt to get the disk from the local cache. */ - protected function get(string $name): FileSystem + protected function get(string $name): Filesystem { return $this->disks[$name] ?? $this->resolve($name); } @@ -121,7 +121,7 @@ protected function get(string $name): FileSystem * * @throws InvalidArgumentException */ - protected function resolve(string $name, ?array $config = null): FileSystem + protected function resolve(string $name, ?array $config = null): Filesystem { $config ??= $this->getConfig($name); @@ -163,7 +163,7 @@ protected function resolve(string $name, ?array $config = null): FileSystem /** * Call a custom driver creator. */ - protected function callCustomCreator(array $config): FileSystem + protected function callCustomCreator(array $config): Filesystem { return $this->customCreators[$config['driver']]($this->app, $config); } @@ -171,7 +171,7 @@ protected function callCustomCreator(array $config): FileSystem /** * Create an instance of the local driver. */ - public function createLocalDriver(array $config, string $name = 'local'): FileSystem + public function createLocalDriver(array $config, string $name = 'local'): Filesystem { $visibility = PortableVisibilityConverter::fromArray( $config['permissions'] ?? [], @@ -204,7 +204,7 @@ public function createLocalDriver(array $config, string $name = 'local'): FileSy /** * Create an instance of the ftp driver. */ - public function createFtpDriver(array $config): FileSystem + public function createFtpDriver(array $config): Filesystem { if (! isset($config['root'])) { $config['root'] = ''; @@ -219,7 +219,7 @@ public function createFtpDriver(array $config): FileSystem /** * Create an instance of the sftp driver. */ - public function createSftpDriver(array $config): FileSystem + public function createSftpDriver(array $config): Filesystem { /* @phpstan-ignore-next-line */ $provider = SftpConnectionProvider::fromArray($config); @@ -353,7 +353,7 @@ protected function createGcsClient(array $config): GcsClient /** * Create a scoped driver. */ - public function createScopedDriver(array $config): FileSystem + public function createScopedDriver(array $config): Filesystem { if (empty($config['disk'])) { throw new InvalidArgumentException('Scoped disk is missing "disk" configuration option.'); From 37b64d1604c0bb88b7c0246563fc0cd0cec89224 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:44 +0000 Subject: [PATCH 04/10] fix: add phpstan ignore rule for nested-set NodeTrait methods on Model --- phpstan.neon.dist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 719dbc862..1554534ff 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -39,6 +39,9 @@ parameters: - '#Method Redis::eval\(\) invoked with [0-9] parameters, 1-3 required.#' - '#Access to an undefined property Hypervel\\Queue\\Jobs\\DatabaseJobRecord::\$.*#' - '#Access to an undefined property Hypervel\\Queue\\Contracts\\Job::\$.*#' + # NodeTrait methods - mixed in at app level, not on base Model class + - message: '#Call to an undefined method Hyperf\\Database\\Model\\Model::new(ScopedQuery|NestedSetQuery)\(\)#' + path: src/nested-set/* - '#Call to an undefined method Hyperf\\Database\\Query\\Builder::where[a-zA-Z0-9\\\\_]+#' - '#Call to an undefined method Hyperf\\Database\\Query\\Builder::firstOrFail\(\)#' - '#Access to an undefined property Hyperf\\Collection\\HigherOrderCollectionProxy#' From 2ad866ca0ecbe07efd0417234576c67e91641ae6 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:47 +0000 Subject: [PATCH 05/10] fix: simplify Closure type on fallbacks property to avoid static vs this variance --- src/prompts/src/Concerns/Fallback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prompts/src/Concerns/Fallback.php b/src/prompts/src/Concerns/Fallback.php index 8c0d68bca..3e2a2c2f3 100644 --- a/src/prompts/src/Concerns/Fallback.php +++ b/src/prompts/src/Concerns/Fallback.php @@ -17,7 +17,7 @@ trait Fallback /** * The fallback implementations. * - * @var array + * @var array */ protected static array $fallbacks = []; From 7ac0029e6553482a4218d756b4f901bc229aedf2 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:51 +0000 Subject: [PATCH 06/10] fix: use inline phpstan-ignore for setContainer on Queue contract --- src/queue/src/QueueManager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/queue/src/QueueManager.php b/src/queue/src/QueueManager.php index 780bc7358..34936b787 100644 --- a/src/queue/src/QueueManager.php +++ b/src/queue/src/QueueManager.php @@ -161,11 +161,10 @@ protected function resolve(string $name): Queue throw new InvalidArgumentException("The [{$name}] queue connection has not been configured."); } - /** @phpstan-ignore-next-line */ $resolver = fn () => $this->getConnector($config['driver']) ->connect($config) ->setConnectionName($name) - ->setContainer($this->app) + ->setContainer($this->app) // @phpstan-ignore method.notFound ->setConfig($config); if (in_array($config['driver'], $this->poolables)) { From f2f782a7c35f18832357c2f736463928e37f307e Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:54 +0000 Subject: [PATCH 07/10] fix: move phpstan-ignore to correct line for setExceptionCallback --- src/queue/src/QueueManagerFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queue/src/QueueManagerFactory.php b/src/queue/src/QueueManagerFactory.php index ec954db5e..691849345 100644 --- a/src/queue/src/QueueManagerFactory.php +++ b/src/queue/src/QueueManagerFactory.php @@ -22,8 +22,8 @@ public function __invoke(ContainerInterface $container): QueueManager $reportHandler = fn (Throwable $e) => $container->get(ExceptionHandler::class)->report($e); foreach ($connectors as $connector) { try { - $manager->connection($connector) // @phpstan-ignore-line - ->setExceptionCallback($reportHandler); + $manager->connection($connector) + ->setExceptionCallback($reportHandler); // @phpstan-ignore method.notFound } catch (InvalidArgumentException) { // Ignore exception when the connector is not configured. } From fbfb952641e3a2cf8c9b2decea423b6650417178 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:35:57 +0000 Subject: [PATCH 08/10] fix: use intersection type for LockProvider in StartSession --- src/session/src/Middleware/StartSession.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/session/src/Middleware/StartSession.php b/src/session/src/Middleware/StartSession.php index 60d299566..049ba9c75 100644 --- a/src/session/src/Middleware/StartSession.php +++ b/src/session/src/Middleware/StartSession.php @@ -11,6 +11,7 @@ use Hyperf\HttpServer\Request; use Hyperf\HttpServer\Router\Dispatched; use Hypervel\Cache\Contracts\Factory as CacheFactoryContract; +use Hypervel\Cache\Contracts\LockProvider; use Hypervel\Cookie\Cookie; use Hypervel\Foundation\Exceptions\Contracts\ExceptionHandler as ExceptionHandlerContract; use Hypervel\Session\Contracts\Session; @@ -82,8 +83,9 @@ protected function handleRequestWhileBlocking(ServerRequestInterface $request, S $waitFor = ($blockingOptions['wait'] ?? $this->manager->defaultRouteBlockWaitSeconds()); - /* @phpstan-ignore-next-line */ - $lock = $this->cache->store($this->manager->blockDriver()) + /** @var \Hypervel\Cache\Contracts\Repository&LockProvider $store */ // @phpstan-ignore varTag.nativeType + $store = $this->cache->store($this->manager->blockDriver()); + $lock = $store ->lock('session:' . $session->getId(), (int) $lockFor) ->betweenBlockedAttemptsSleepFor(50); @@ -92,7 +94,7 @@ protected function handleRequestWhileBlocking(ServerRequestInterface $request, S return $this->handleStatefulRequest($request, $session, $handler); } finally { - $lock?->release(); + $lock->release(); } } From c4f7de79c7773b700b7f051f8442ad0b60bd5464 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:36:00 +0000 Subject: [PATCH 09/10] fix: use inline phpstan-ignore for scope method withTelescopeOptions --- src/telescope/src/Storage/DatabaseEntriesRepository.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/telescope/src/Storage/DatabaseEntriesRepository.php b/src/telescope/src/Storage/DatabaseEntriesRepository.php index f83ac1261..93c395203 100644 --- a/src/telescope/src/Storage/DatabaseEntriesRepository.php +++ b/src/telescope/src/Storage/DatabaseEntriesRepository.php @@ -72,9 +72,8 @@ public function find(mixed $id): EntryResult */ public function get(?string $type, EntryQueryOptions $options): Collection { - /* @phpstan-ignore-next-line */ return EntryModel::on($this->connection) - ->withTelescopeOptions($type, $options) + ->withTelescopeOptions($type, $options) // @phpstan-ignore method.notFound ->take($options->limit) ->orderByDesc('sequence') ->get()->reject(function ($entry) { From 43249c8cf93f7abf94d2f154147f0bd8c93eb570 Mon Sep 17 00:00:00 2001 From: Raj Siva-Rajah Date: Sun, 1 Mar 2026 17:36:27 +0000 Subject: [PATCH 10/10] chore: allow php-http/discovery composer plugin --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d98978269..bf6181685 100644 --- a/composer.json +++ b/composer.json @@ -232,7 +232,10 @@ "audit": { "ignore": ["PKSA-z3gr-8qht-p93v"] }, - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "php-http/discovery": true + } }, "extra": { "hyperf": {