fix: #3593375 Fixed unsafe usages of new static().

Resolves all 24 "Unsafe usage of new static()" warnings reported by Upgrade Status / PHPStan, using the most appropriate fix for each case:

  1. Autowiring for all 14 forms in src/Form/ (per the proposed resolution, used wherever available)
  • Replaced each form's create() method with core's AutowireTrait (available since 10.2, so fine for our ^10.3 || ^11 requirement). Constructors are unchanged except where noted below.
  • IndexProcessorsForm uses #[Autowire(service: 'logger.channel.search_api')] for its logger parameter, since logger channels cannot be resolved by type hint.
  • IndexAddFieldsForm: the array $parameters constructor parameter (which create() derived from the current request) was replaced with RequestStack $request_stack; the parameters are now derived in the constructor.
  • Added the missing autowiring aliases to search_api.services.yml (BackendPluginManager, DataTypePluginManager, ProcessorPluginManager, IndexingBatchHelperInterface), consistent with the aliases we already declare there. These also let other code autowire those services.
  1. parent::createInstance() pattern for IndexListBuilder
  • The custom constructor is gone; createInstance() now calls the parent and assigns $serverStorage afterwards.
  1. @phpstan-consistent-constructor for the seven API classes where new static() is load-bearing
  • ConfigurablePluginBase, DataTypePluginBase, ParseModePluginBase, DisplayPluginBase, DisplayDeriverBase, ContentEntityDeriver and Query.
  • new self() was not an option here: the plugin interfaces all extend ContainerFactoryPluginInterface, so create() has to stay, and with new self() every subclass inheriting create() (e.g. ViewsDisplayDeriver, plus all processor/backend/datasource plugins in contrib) would silently get an instance of the base class instead of itself.
  • The annotation makes PHPStan (and therefore Upgrade Status) accept new static() by declaring the contract that subclass constructors must stay compatible — which all existing subclasses (in this module and, e.g., in Search API Solr) already satisfy, since they keep the standard ($configuration, $plugin_id, $plugin_definition) signature.
  • AddHierarchy::supportsIndex() is fixed automatically, since it inherits the annotated constructor from ConfigurablePluginBase.
  1. phpstan.neon
  • The blanket Unsafe usage of new static ignore ("we cannot fix that") is removed. 🎉
  • One narrow ignore remains for the variant "Unsafe usage of new static() in abstract class … in static method create()". That rule is only active with PHPStan's bleeding-edge config (which our CI uses but Upgrade Status does not) and cannot be avoided without breaking the plugin API, since it objects to the theoretical possibility of calling e.g. DataTypePluginBase::create() directly on the abstract class.

Not changed: SearchApiDrushCommands and AddDatasourceToIndex also use new static() but are final classes, which PHPStan already considers safe — they were never flagged.

Minor BC notes

  • The forms' public static create() methods are replaced by the trait's autowiring implementation. Behavior through the form builder / entity form handling is identical.
  • IndexAddFieldsForm::__construct() signature changed (last parameter array $parameters → RequestStack $request_stack).
  • IndexListBuilder::__construct() was removed (the parent constructor is used now).

None of these classes are meant to be instantiated directly, and no subclasses exist in this module or known contrib.

Testing done

  • phpstan: zero new static errors; the remaining error set is identical to before this change.
  • phpcs: clean.
  • Unit suite (338 tests) plus the functional tests covering every converted form — IntegrationTest, AddServerFormTest, ProcessorIntegrationTest, FieldIntegrationTest, OverviewPageTest — all pass.

Merge request reports

Loading