Problem/Motivation

Drupal core 11.4 added a YamlCacheCollector parameter to the LibraryDiscoveryParser constructor as part of #3486503 (change record: #3593451). The new parameter replaces some uses of FileCache with a persistent cache.file_parsing bin backed by FileParsingCacheCollectorBase.

PatternLibraryParserBase extends LibraryDiscoveryParser and passes arguments through to parent::__construct(). On Drupal 11.4, the parent constructor expects YamlCacheCollector as an additional parameter. Without it, the container falls back to a deprecated service lookup that triggers a ServiceNotFoundException for libraries.parsing_cache in environments where the container is not fully available (unit tests, early bootstrap).

On Drupal 10, the YamlCacheCollector class does not exist. The parameter type hint, parent::__construct() call arity, service definition, and PHPStan configuration must all remain compatible with both Drupal 10.3+ and 11.4+.

Three issues surface from this change:

  1. The parent class LibraryDiscoveryParser stores the application root as $this->root in Drupal 10 via manual assignment, but Drupal 11.4 changes how this property is declared. PatternLibraryParserBase subclasses reference $this->root throughout. To maintain cross-version compatibility, the child class must declare its own protected string $root property and assign it explicitly in the constructor body rather than relying on constructor promotion or the parent's property declaration. The native type must not appear on the constructor parameter itself, or PHP emits a fatal error ("Type must not be defined") when the child's property conflicts with the parent's declaration.
  2. The patternkit.asset.library.parser.base service definition must pass the library.parsing_cache service so YamlCacheCollector reaches parent::__construct() on Drupal 11.4. The service reference must use the optional prefix (@?library.parsing_cache) so the container injects NULL on Drupal 10 where the service does not exist.
  3. PHPStan suppressions with reportUnmatched: false are needed for the cross-version type errors (YamlCacheCollector class not found, extra constructor parameter count). Unit test factories must conditionally create YamlCacheCollector mocks using class_exists() guards, following the same pattern already established for ComponentPluginManager.

Steps to reproduce

  1. Install Patternkit on Drupal 11.4.
  2. Clear caches (drush cr).
  3. Observe a PHP fatal error in PatternLibraryParserBase::__construct() related to the $root property type conflict, or a ServiceNotFoundException for libraries.parsing_cache.
  4. Alternatively, run phpunit tests/src/Unit/ on a Drupal 11.4 environment and observe multiple ServiceNotFoundException failures.

Proposed resolution

Update PatternLibraryParserBase and its service definition for cross-version compatibility with both Drupal 10.3+ and 11.4+.

Constructor changes

src/Asset/PatternLibraryParserBase.php:

  • Remove the native type from the $root constructor parameter to avoid the PHP fatal error when the parent's property declaration differs across core versions.
  • Add an explicit protected $root property declaration (untyped, matching the parent) and assign it in the constructor body. This preserves the $this->root references used by parser subclasses, independent of how the parent class stores the application root.
  • Add a nullable ?YamlCacheCollector $yaml_cache_collector = NULL parameter and pass it through to parent::__construct().
  • Add the @param docblock entry for the new parameter.

Service definition

patternkit.services.yml:

  • Add @?library.parsing_cache (optional service reference) to the patternkit.asset.library.parser.base abstract service arguments, positioned before the existing optional @?plugin.manager.sdc argument. The @? prefix injects NULL on Drupal 10 where the service does not exist, matching the established pattern.

PHPStan cross-version suppressions

phpstan.neon:

  • Suppress the invalid type error for YamlCacheCollector on Drupal 10 where the class does not exist.
  • Suppress the "invoked with 8 parameters" error for parent::__construct() which only accepts 7 parameters on Drupal 10.
  • Use reportUnmatched: false on both suppressions so they do not cause failures when running PHPStan against Drupal 11.4 where the types are valid.

Unit test compatibility

tests/src/Unit/Asset/PatternLibraryParser/PatternLibraryParserTestBase.php:

  • Add a $yamlCacheCollector property with a class_exists(YamlCacheCollector::class) guard in setUpParserDependencies(), following the existing pattern used for $componentPluginManager.
  • Pass the mock (or NULL) to both getParserInstance() and getPartialMock() factory methods.

Remaining tasks

  • Review and test the merge request.
  • CI validation on both Drupal 10 and 11.4.

User interface changes

None.

Introduced terminology

None.

API changes

PatternLibraryParserBase::__construct() gains a new nullable ?YamlCacheCollector parameter before the existing optional $componentPluginManager parameter. Any code that instantiates a PatternLibraryParserBase subclass directly (rather than through the service container) must pass the new argument. In practice, all parser instances are created via services.yml and this change is transparent.

Data model changes

None.

Release notes snippet

Patternkit is now compatible with Drupal 11.4. The PatternLibraryParserBase constructor has been updated to accept the new YamlCacheCollector service introduced in Drupal core 11.4 (#3486503) while remaining backward compatible with Drupal 10.3+. Sites upgrading to Drupal 11.4 should update Patternkit to this release to avoid PHP fatal errors during cache rebuilds.

Issue fork patternkit-3604089

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

slucero created an issue. See original summary.

slucero’s picture

Status: Active » Needs review

slucero’s picture

Status: Needs review » Fixed
Related issues: +#3587714: Revert Reusable Block Support Removal Until Later Release

Resolution for this issue was included in the MR for #3587714: Revert Reusable Block Support Removal Until Later Release as commit 909c29, so as of merging in MR !190 this issue is resolved for inclusion in the 9.1.3 release.
See #3542304: Patternkit 9.1.3 Release Plan.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.