Skip to content

Commit bb912ea

Browse files
authored
Add PHP 8.4 support, require parameters.laminasframework.serviceManagerLoader key (#66)
1 parent a054e8d commit bb912ea

18 files changed

+30
-238
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
php-version:
4646
- "8.2"
4747
- "8.3"
48+
- "8.4"
4849
dependencies:
4950
- "highest"
5051

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM php:8.2
1+
FROM php:8.3
22

33
ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
44

5-
RUN install-php-extensions @composer intl pcov
5+
RUN install-php-extensions @composer intl xdebug pcov
66

77
ARG USER_ID
88
ARG GROUP_ID

composer.json

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,24 @@
1818
}
1919
],
2020
"require": {
21-
"php": "~8.2.0 || ~8.3.0",
22-
"phpstan/phpstan": "^2.0.1"
21+
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
22+
"phpstan/phpstan": "^2.0.2"
2323
},
2424
"require-dev": {
25-
"laminas/laminas-cache": "^3.12.2",
26-
"laminas/laminas-cache-storage-adapter-memory": "^2.3.0",
2725
"laminas/laminas-filter": "^2.39.0",
2826
"laminas/laminas-form": "^3.21.0",
29-
"laminas/laminas-hydrator": "^4.15.0",
27+
"laminas/laminas-hydrator": "^4.16.0",
3028
"laminas/laminas-i18n": "^2.29.0",
31-
"laminas/laminas-inputfilter": "^2.30.1",
32-
"laminas/laminas-mail": "^2.25.1",
33-
"laminas/laminas-mvc": "^3.7.0",
29+
"laminas/laminas-inputfilter": "^2.31.0",
30+
"laminas/laminas-mvc": "^3.8.0",
3431
"laminas/laminas-paginator": "^2.19.0",
3532
"laminas/laminas-validator": "^2.64.1",
3633
"phpstan/phpstan-deprecation-rules": "^2",
37-
"phpstan/phpstan-phpunit": "^2",
34+
"phpstan/phpstan-phpunit": "^2.0.1",
3835
"phpunit/phpunit": "^11.4.3",
3936
"slam/php-cs-fixer-extensions": "^3.11.1"
4037
},
4138
"conflict": {
42-
"laminas/laminas-cache": "<3.12",
4339
"laminas/laminas-filter": "<2.37",
4440
"laminas/laminas-form": "<3.20",
4541
"laminas/laminas-hydrator": "<4.15",

extension.neon

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
parameters:
2-
laminasframework:
3-
serviceManagerLoader: null
42
universalObjectCratesClasses:
53
- Laminas\Stdlib\ArrayObject
64

75
parametersSchema:
86
laminasframework: structure([
9-
serviceManagerLoader: schema(string(), nullable())
7+
serviceManagerLoader: schema(string())
108
])
119

1210
rules:

phpstan-baseline.neon

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,6 @@ parameters:
66
count: 1
77
path: src/Rules/Laminas/ServiceManagerGetMethodCallRule.php
88

9-
-
10-
message: '#^Parameter \#1 \$config of method Laminas\\ServiceManager\\ServiceManager\:\:configure\(\) expects array\{abstract_factories\?\: array\<class\-string\<Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface\>\|Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface\>, aliases\?\: array\<string, string\>, delegators\?\: mixed, factories\?\: mixed, initializers\?\: mixed, invokables\?\: array\<string, string\>, lazy_services\?\: array\{class_map\?\: array\<string, class\-string\>, proxies_namespace\?\: non\-empty\-string, proxies_target_dir\?\: non\-empty\-string, write_proxy_files\?\: bool\}, services\?\: array\<string, array\<mixed\>\|object\>, \.\.\.\}, mixed given\.$#'
11-
identifier: argument.type
12-
count: 1
13-
path: src/ServiceManagerLoader.php
14-
15-
-
16-
message: '#^Parameter \#1 \$config of method Laminas\\ServiceManager\\ServiceManager\:\:configure\(\) expects array\{abstract_factories\?\: array\<class\-string\<Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface\>\|Laminas\\ServiceManager\\Factory\\AbstractFactoryInterface\>, aliases\?\: array\<string, string\>, delegators\?\: mixed, factories\?\: mixed, initializers\?\: mixed, invokables\?\: array\<string, string\>, lazy_services\?\: array\{class_map\?\: array\<string, class\-string\>, proxies_namespace\?\: non\-empty\-string, proxies_target_dir\?\: non\-empty\-string, write_proxy_files\?\: bool\}, services\?\: array\<string, array\<mixed\>\|object\>, \.\.\.\}, non\-empty\-array given\.$#'
17-
identifier: argument.type
18-
count: 1
19-
path: src/ServiceManagerLoader.php
20-
219
-
2210
message: '#^Creating new ReflectionClass is a runtime reflection concept that might not work in PHPStan because it uses fully static reflection engine\. Use objects retrieved from ReflectionProvider instead\.$#'
2311
identifier: phpstanApi.runtimeReflection

phpstan.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@ parameters:
1111
excludePaths:
1212
analyseAndScan:
1313
- tests/Rules/Laminas/ServiceManagerGetMethodCallRule/
14-
- tests/Rules/Laminas/PluginManagerGetMethodCallRule/
1514
- tests/TestAsset/
1615
- tests/LaminasIntegration/data/

src/ServiceManagerLoader.php

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,24 @@
55
namespace LaminasPhpStan;
66

77
use Interop\Container\ContainerInterface as InteropContainerInterface;
8-
use Laminas\Cache\ConfigProvider;
9-
use Laminas\Mvc\Service\ServiceListenerFactory;
10-
use Laminas\Mvc\Service\ServiceManagerConfig;
118
use Laminas\ServiceManager\ServiceLocatorInterface;
129
use Laminas\ServiceManager\ServiceManager;
1310
use PHPStan\ShouldNotHappenException;
1411
use Psr\Container\ContainerInterface as PsrContainerInterface;
15-
use ReflectionProperty;
1612

17-
final class ServiceManagerLoader
13+
final readonly class ServiceManagerLoader
1814
{
19-
private ?UnmappedAliasServiceLocatorProxy $serviceLocator = null;
20-
21-
/** @var string[] */
22-
private array $knownModules = [
23-
ConfigProvider::class,
24-
\Laminas\Filter\ConfigProvider::class,
25-
\Laminas\Form\ConfigProvider::class,
26-
\Laminas\Hydrator\ConfigProvider::class,
27-
\Laminas\I18n\ConfigProvider::class,
28-
\Laminas\InputFilter\ConfigProvider::class,
29-
\Laminas\Mail\ConfigProvider::class,
30-
\Laminas\Paginator\ConfigProvider::class,
31-
\Laminas\Router\ConfigProvider::class,
32-
\Laminas\Validator\ConfigProvider::class,
33-
];
34-
35-
/** @var array<string, true> */
36-
private array $serviceManagerNames = [
15+
private const serviceManagerNames = [
3716
ServiceManager::class => true,
3817
ServiceLocatorInterface::class => true,
3918
InteropContainerInterface::class => true,
4019
PsrContainerInterface::class => true,
4120
];
4221

43-
public function __construct(?string $serviceManagerLoader)
44-
{
45-
if (null === $serviceManagerLoader) {
46-
return;
47-
}
22+
private UnmappedAliasServiceLocatorProxy $serviceLocator;
4823

24+
public function __construct(string $serviceManagerLoader)
25+
{
4926
if (! \file_exists($serviceManagerLoader) || ! \is_readable($serviceManagerLoader)) {
5027
throw new ShouldNotHappenException('Service manager could not be loaded');
5128
}
@@ -60,32 +37,8 @@ public function __construct(?string $serviceManagerLoader)
6037

6138
public function getServiceLocator(string $serviceManagerName): ServiceLocatorInterface
6239
{
63-
if (null === $this->serviceLocator) {
64-
$serviceManager = new ServiceManager(['services' => ['config' => []]]);
65-
if (\class_exists(ServiceManagerConfig::class)) {
66-
(new ServiceManagerConfig())->configureServiceManager($serviceManager);
67-
}
68-
if (\class_exists(ServiceListenerFactory::class)) {
69-
$refProp = new ReflectionProperty(ServiceListenerFactory::class, 'defaultServiceConfig');
70-
$config = $refProp->getValue(new ServiceListenerFactory());
71-
\assert(\is_array($config));
72-
\assert(\is_array($config['factories']));
73-
unset($config['factories']['config']);
74-
$serviceManager->configure($config);
75-
}
76-
foreach ($this->knownModules as $module) {
77-
if (\class_exists($module)) {
78-
$module = new $module();
79-
\assert(\method_exists($module, 'getDependencyConfig'));
80-
$serviceManager->configure($module->getDependencyConfig());
81-
}
82-
}
83-
84-
$this->serviceLocator = new UnmappedAliasServiceLocatorProxy($serviceManager);
85-
}
86-
8740
$serviceLocator = $this->serviceLocator;
88-
if (! isset($this->serviceManagerNames[$serviceManagerName])) {
41+
if (! isset(self::serviceManagerNames[$serviceManagerName])) {
8942
$serviceLocator = $serviceLocator->get($serviceManagerName);
9043
\assert($serviceLocator instanceof ServiceLocatorInterface);
9144
}

src/Type/Laminas/PluginMethodReflection.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPStan\Reflection\ClassReflection;
99
use PHPStan\Reflection\FunctionVariant;
1010
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Reflection\ParametersAcceptor;
1112
use PHPStan\TrinaryLogic;
1213
use PHPStan\Type\Generic\TemplateTypeMap;
1314
use PHPStan\Type\ObjectType;
@@ -96,7 +97,7 @@ public function hasSideEffects(): TrinaryLogic
9697
return TrinaryLogic::createNo();
9798
}
9899

99-
/** @return \PHPStan\Reflection\ParametersAcceptor[] */
100+
/** @return ParametersAcceptor[] */
100101
public function getVariants(): array
101102
{
102103
return [

tests/LaminasIntegration/data/stdlibAbstractOptionsProperties-2.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[
22
{
3-
"message": "Access to an undefined property Laminas\\Mail\\Transport\\Envelope::$foobar.",
3+
"message": "Access to an undefined property Laminas\\ModuleManager\\Listener\\ListenerOptions::$foobar.",
44
"line": 18,
55
"ignorable": true
66
},

tests/LaminasIntegration/data/stdlibAbstractOptionsProperties-3.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[
22
{
3-
"message": "Property Laminas\\Mail\\Transport\\Envelope::$from (string|null) does not accept stdClass.",
3+
"message": "Property Laminas\\ModuleManager\\Listener\\ListenerOptions::$configCacheKey (string) does not accept stdClass.",
44
"line": 19,
55
"ignorable": true
66
}

0 commit comments

Comments
 (0)