Skip to content

Commit

Permalink
Add PHP 8.4 support, require `parameters.laminasframework.serviceMana…
Browse files Browse the repository at this point in the history
…gerLoader` key (#66)
  • Loading branch information
Slamdunk authored Nov 27, 2024
1 parent a054e8d commit bb912ea
Show file tree
Hide file tree
Showing 18 changed files with 30 additions and 238 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
php-version:
- "8.2"
- "8.3"
- "8.4"
dependencies:
- "highest"

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM php:8.2
FROM php:8.3

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

RUN install-php-extensions @composer intl pcov
RUN install-php-extensions @composer intl xdebug pcov

ARG USER_ID
ARG GROUP_ID
Expand Down
16 changes: 6 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,24 @@
}
],
"require": {
"php": "~8.2.0 || ~8.3.0",
"phpstan/phpstan": "^2.0.1"
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
"phpstan/phpstan": "^2.0.2"
},
"require-dev": {
"laminas/laminas-cache": "^3.12.2",
"laminas/laminas-cache-storage-adapter-memory": "^2.3.0",
"laminas/laminas-filter": "^2.39.0",
"laminas/laminas-form": "^3.21.0",
"laminas/laminas-hydrator": "^4.15.0",
"laminas/laminas-hydrator": "^4.16.0",
"laminas/laminas-i18n": "^2.29.0",
"laminas/laminas-inputfilter": "^2.30.1",
"laminas/laminas-mail": "^2.25.1",
"laminas/laminas-mvc": "^3.7.0",
"laminas/laminas-inputfilter": "^2.31.0",
"laminas/laminas-mvc": "^3.8.0",
"laminas/laminas-paginator": "^2.19.0",
"laminas/laminas-validator": "^2.64.1",
"phpstan/phpstan-deprecation-rules": "^2",
"phpstan/phpstan-phpunit": "^2",
"phpstan/phpstan-phpunit": "^2.0.1",
"phpunit/phpunit": "^11.4.3",
"slam/php-cs-fixer-extensions": "^3.11.1"
},
"conflict": {
"laminas/laminas-cache": "<3.12",
"laminas/laminas-filter": "<2.37",
"laminas/laminas-form": "<3.20",
"laminas/laminas-hydrator": "<4.15",
Expand Down
4 changes: 1 addition & 3 deletions extension.neon
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
parameters:
laminasframework:
serviceManagerLoader: null
universalObjectCratesClasses:
- Laminas\Stdlib\ArrayObject

parametersSchema:
laminasframework: structure([
serviceManagerLoader: schema(string(), nullable())
serviceManagerLoader: schema(string())
])

rules:
Expand Down
12 changes: 0 additions & 12 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,6 @@ parameters:
count: 1
path: src/Rules/Laminas/ServiceManagerGetMethodCallRule.php

-
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\.$#'
identifier: argument.type
count: 1
path: src/ServiceManagerLoader.php

-
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\.$#'
identifier: argument.type
count: 1
path: src/ServiceManagerLoader.php

-
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\.$#'
identifier: phpstanApi.runtimeReflection
Expand Down
1 change: 0 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ parameters:
excludePaths:
analyseAndScan:
- tests/Rules/Laminas/ServiceManagerGetMethodCallRule/
- tests/Rules/Laminas/PluginManagerGetMethodCallRule/
- tests/TestAsset/
- tests/LaminasIntegration/data/
59 changes: 6 additions & 53 deletions src/ServiceManagerLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,24 @@
namespace LaminasPhpStan;

use Interop\Container\ContainerInterface as InteropContainerInterface;
use Laminas\Cache\ConfigProvider;
use Laminas\Mvc\Service\ServiceListenerFactory;
use Laminas\Mvc\Service\ServiceManagerConfig;
use Laminas\ServiceManager\ServiceLocatorInterface;
use Laminas\ServiceManager\ServiceManager;
use PHPStan\ShouldNotHappenException;
use Psr\Container\ContainerInterface as PsrContainerInterface;
use ReflectionProperty;

final class ServiceManagerLoader
final readonly class ServiceManagerLoader
{
private ?UnmappedAliasServiceLocatorProxy $serviceLocator = null;

/** @var string[] */
private array $knownModules = [
ConfigProvider::class,
\Laminas\Filter\ConfigProvider::class,
\Laminas\Form\ConfigProvider::class,
\Laminas\Hydrator\ConfigProvider::class,
\Laminas\I18n\ConfigProvider::class,
\Laminas\InputFilter\ConfigProvider::class,
\Laminas\Mail\ConfigProvider::class,
\Laminas\Paginator\ConfigProvider::class,
\Laminas\Router\ConfigProvider::class,
\Laminas\Validator\ConfigProvider::class,
];

/** @var array<string, true> */
private array $serviceManagerNames = [
private const serviceManagerNames = [
ServiceManager::class => true,
ServiceLocatorInterface::class => true,
InteropContainerInterface::class => true,
PsrContainerInterface::class => true,
];

public function __construct(?string $serviceManagerLoader)
{
if (null === $serviceManagerLoader) {
return;
}
private UnmappedAliasServiceLocatorProxy $serviceLocator;

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

public function getServiceLocator(string $serviceManagerName): ServiceLocatorInterface
{
if (null === $this->serviceLocator) {
$serviceManager = new ServiceManager(['services' => ['config' => []]]);
if (\class_exists(ServiceManagerConfig::class)) {
(new ServiceManagerConfig())->configureServiceManager($serviceManager);
}
if (\class_exists(ServiceListenerFactory::class)) {
$refProp = new ReflectionProperty(ServiceListenerFactory::class, 'defaultServiceConfig');
$config = $refProp->getValue(new ServiceListenerFactory());
\assert(\is_array($config));
\assert(\is_array($config['factories']));
unset($config['factories']['config']);
$serviceManager->configure($config);
}
foreach ($this->knownModules as $module) {
if (\class_exists($module)) {
$module = new $module();
\assert(\method_exists($module, 'getDependencyConfig'));
$serviceManager->configure($module->getDependencyConfig());
}
}

$this->serviceLocator = new UnmappedAliasServiceLocatorProxy($serviceManager);
}

$serviceLocator = $this->serviceLocator;
if (! isset($this->serviceManagerNames[$serviceManagerName])) {
if (! isset(self::serviceManagerNames[$serviceManagerName])) {
$serviceLocator = $serviceLocator->get($serviceManagerName);
\assert($serviceLocator instanceof ServiceLocatorInterface);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Type/Laminas/PluginMethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\FunctionVariant;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\ObjectType;
Expand Down Expand Up @@ -96,7 +97,7 @@ public function hasSideEffects(): TrinaryLogic
return TrinaryLogic::createNo();
}

/** @return \PHPStan\Reflection\ParametersAcceptor[] */
/** @return ParametersAcceptor[] */
public function getVariants(): array
{
return [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"message": "Access to an undefined property Laminas\\Mail\\Transport\\Envelope::$foobar.",
"message": "Access to an undefined property Laminas\\ModuleManager\\Listener\\ListenerOptions::$foobar.",
"line": 18,
"ignorable": true
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"message": "Property Laminas\\Mail\\Transport\\Envelope::$from (string|null) does not accept stdClass.",
"message": "Property Laminas\\ModuleManager\\Listener\\ListenerOptions::$configCacheKey (string) does not accept stdClass.",
"line": 19,
"ignorable": true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

namespace LaminasPhpStan\Tests\LaminasIntegration\data;

use Laminas\Mail\Transport\Envelope;
use Laminas\ModuleManager\Listener\ListenerOptions;
use Laminas\Stdlib\AbstractOptions;
use stdClass;

final class stdlibAbstractOptionsProperties
{
public function mainLibrary(): void
{
$envelope = new Envelope();
$envelope = new ListenerOptions();

// Bad
$envelope->foobar = 1;
$envelope->from = new stdClass();
$envelope->foobar = 1;
$envelope->configCacheKey = new stdClass();

// Good
$envelope->from = '[email protected]';
$envelope->configCacheKey = 'my_key';
}

public function custom(): void
Expand Down
25 changes: 0 additions & 25 deletions tests/Rules/Laminas/PluginManagerGetMethodCallRule/Foo.php

This file was deleted.

49 changes: 0 additions & 49 deletions tests/Rules/Laminas/PluginManagerGetMethodCallRuleTest.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace LaminasPhpStan\Tests\Rules\Laminas\ServiceManagerGetMethodCallRule;

use Interop\Container\ContainerInterface;
use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\ControllerManager;
use stdClass;

Expand Down Expand Up @@ -34,7 +33,6 @@ public function foo(): void
$stdClass->get('non_existent_service');

$this->container->get(ControllerManager::class);
$this->container->get(FormElementManager::class);
}

public function get(string $foo): void {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace LaminasPhpStan\Tests\Rules\Laminas\ServiceManagerGetMethodCallRule;

use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\ControllerManager;
use Psr\Container\ContainerInterface;
use stdClass;
Expand Down Expand Up @@ -34,7 +33,6 @@ public function foo(): void
$stdClass->get('non_existent_service');

$this->container->get(ControllerManager::class);
$this->container->get(FormElementManager::class);
}

public function get(string $foo): void {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace LaminasPhpStan\Tests\Rules\Laminas\ServiceManagerGetMethodCallRule;

use Laminas\Form\FormElementManager;
use Laminas\Mvc\Controller\ControllerManager;
use Laminas\ServiceManager\ServiceManager;
use stdClass;
Expand Down Expand Up @@ -34,7 +33,6 @@ public function foo(): void
$stdClass->get('non_existent_service');

$this->serviceManager->get(ControllerManager::class);
$this->serviceManager->get(FormElementManager::class);
}

public function get(string $foo): void {}
Expand Down
Loading

0 comments on commit bb912ea

Please sign in to comment.