Skip to content

PHPStan 9.x jobs analyse the core as PHP 7.1, which is why the AdminController cast helper exists #142

Description

@mattgoud

Summary

The four PrestaShop 9.x PHPStan configurations do not pin phpVersion, so the 9.x core is analysed with the PHP version taken from the module's composer platform declaration, 7.1.0. At that syntax level PHPStan cannot parse PrestaShop\PrestaShop\Core\Context\LegacyControllerContext, which uses constructor property promotion, readonly and union types. The class is reported as unknown.

That unresolvable class is the reason getAdminController() exists in ps_emailsubscription.php. Its @var AdminController annotation makes the type resolvable again, which silences the error without addressing its cause, and leaves a @return AdminController that is factually wrong on 9.x, where Context::$controller holds a LegacyControllerContext.

Why this matters beyond a cosmetic annotation

The same helper, with a native : AdminController return type instead of a phpdoc, caused a fatal error on the module configuration page of ps_wirepayment on every PrestaShop 9.x shop. See PrestaShop/ps_wirepayment#103. This module is not affected, because its helper is phpdoc only and PHP never enforces a phpdoc. But the annotation is the same untruth, and it is what makes a wrong assumption look verified to static analysis.

Evidence

Measured locally against a PrestaShop 9.2.0 core, PHPStan 1.12.12, level 5, using the same vendor/prestashop/php-dev-tools/phpstan/ps-module-extension.neon merge the shared CI action performs.

Case Result
Current code, helper in place no errors
Helper removed, direct $this->context->controller->getLanguages() 3 errors
Helper removed plus phpVersion: 80100 no errors

The three errors are all this one, at ps_emailsubscription.php lines 1141, 1242 and 1281:

Call to method getLanguages() on an unknown class
PrestaShop\PrestaShop\Core\Context\LegacyControllerContext.

It is worth being precise about the message: it is an unknown class, not an undefined method on the AdminController|FrontController|LegacyControllerContext|null union. The union itself is fine. getLanguages() exists on AdminController and on LegacyControllerContext alike, so the call is correct at runtime on both 8.2 and 9.x.

Proposed fix

  1. Add phpVersion: 80100 to tests/php/phpstan/phpstan-9.0.3.neon, phpstan-9.1.5.neon, phpstan-9.2.x.neon and phpstan-develop.neon. The 9.x matrix only ever runs on PHP 8.1 and above, so this simply states the truth about what is being analysed.
  2. Remove getAdminController() and restore the three direct calls.

tests/php/phpstan/phpstan-8.2.x.neon must stay untouched. LegacyControllerContext does not exist on 8.2, there is no error there, and pinning a PHP 8 syntax level would be wrong for a job that runs on 7.2.

Related, out of scope here

  • composer.json declares require.php: >=7.1 and config.platform.php: 7.1.0, while ps_versions_compliancy has been at 8.2.0 since the alignment on [EPIC] Modules - Cleaning Compatibility PrestaShop#41648, and PrestaShop 8.2 requires PHP 7.2.5. Nothing exercises 7.1: the syntax checker starts at 7.2. Worth aligning on 7.2.5, but it touches composer.lock and does not fix the issue above, since 7.2.5 is still below the PHP 8.0 needed to parse the core class.
  • tests/php/phpstan/phpstan.neon carries text accidentally pasted from the GitHub review UI on its first comment line, Expand commentComment on line R2Resolved.... Harmless since it sits inside a # comment, but committed.

Note on ps_facetedsearch

The same helper exists there and has the same cause, but it is not the same fix, because it reads a property rather than calling a method. Tracked separately in PrestaShop/ps_facetedsearch.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

phpPull requests that update Php code

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions