Issue #3618612: Raise PHPStan to level 3 with an entity mapping, because the analysis runs at level 0 and lets a wrong type through

Raises PHPStan from level 0 to level 3, and fixes everything the level reports. There is no baseline file: the run is clean.

Why it was affordable. entity_mapping.neon tells phpstan-drupal which class each entity type loads as, which takes the count from 448 to 178 on its own. Without it every $storage->load() is an EntityInterface and every concrete call on one is a finding. The mapping covers orchestra's eleven entity types plus four a submodule integrates with (kessai, audit_trail, domain, easy_email).

Most of the volume was one duplication. drainQueue() had been copied into 75 test classes, and its unguarded while ($item = $queue->claimItem()) accounted for 108 findings by itself. It is now DrainEngineQueueTrait, used by 94 classes, with processNextQueueItem() beside it for the tests that step through a run instead of letting it settle. That is where the net -671 lines come from.

What the level caught in the engine:

  • WorkflowInterface::getLayout() documented nodes and flows only, while the bpmn_io capture also writes nodeLabels and flowLabels. The contract was wrong.
  • DelegationForm::validateForm() declared void, but ContentEntityFormInterface::validateForm() returns the built entity. It now returns it from every exit.
  • Nine places read a plugin's configuration behind a PluginFormInterface check alone, which does not carry getConfiguration(); they require ConfigurableInterface too.
  • Two form-alter hooks called getEntity() on a bare FormInterface, and two Views filters called addWhere(), which belongs to the SQL backend rather than every query plugin.
  • Neither action base declared the execute($entity) signature every subclass implements, so the argument was invisible to callers.
  • Three storage helpers returned EntityStorageInterface, hiding the entity type from analysis. They call the manager directly now.

Test doubles that bound an argument with with() use willReturnMap(), which is what a stub supports; with() on a stub is deprecated in PHPUnit 12.5.11.

Verification. phpstan analyse clean at level 3, phpcs clean (Drupal and DrupalPractice), and the whole kernel suite green locally, including a re-run of 28 classes against a rebuilt test root to rule out an environment flake.

Merge request reports

Loading
Loading