Problem/Motivation

On PHP 8.4, the #[\Deprecated] attribute triggers E_USER_DEPRECATED automatically at runtime whenever an annotated method or constant is accessed. Seven #[\Deprecated] attributes on reusable block deprecation hooks cause excessive watchdog entries and on-screen warnings on every page load when system.logging.error_level is set to verbose.

On PHP 8.3 and earlier, #[\Deprecated] was silently ignored by the engine, so these attributes had no runtime effect. The class docblock on ReusableBlockHooks explicitly states that trigger_error() was intentionally omitted to avoid per-request noise, but the PHP 8.4 attribute behavior reintroduced that exact noise through a different path.

Affected locations:

  • ReusableBlockHooks: 4 hook methods (entityTypeAlter, contextualLinksAlter, localTasksAlter, menuLocalActionsAlter)
  • PatternkitEnvironment: FEATURE_ENABLE_REUSABLE_BLOCKS constant
  • PatternkitBlock derivative: getReusableBlockDerivatives() method

These hooks fire on every request regardless of whether the reusable blocks feature is enabled. The hooks early-return when the feature is off, but the #[\Deprecated] attribute triggers before the method body executes.

Steps to reproduce

  1. Run Patternkit on PHP 8.4 with Drupal 11.4.
  2. Set system.logging.error_level to verbose.
  3. Visit any page.
  4. Check the Drupal log at /admin/reports/dblog filtered to type php.
  5. Observe multiple E_USER_DEPRECATED entries per page load from ReusableBlockHooks methods and the FEATURE_ENABLE_REUSABLE_BLOCKS constant.

Proposed resolution

Remove all 7 #[\Deprecated] attributes from the three affected files. Update the ReusableBlockHooks class docblock to reflect that runtime attributes are no longer used.

The existing deprecation signals remain intact:

  • @deprecated docblocks on all affected classes, methods, and constants (IDE and static analysis visibility)
  • The hook_requirements() warning on /admin/reports/status when reusable blocks exist in the database (site operator visibility)

Drupal core has not yet established guidance on #[\Deprecated] attribute usage for hooks (#3479340: Adopt #[\Deprecated] attribute). The PHP RFC explicitly leaves per-request noise suppression out of scope, making the attribute unsuitable for hooks that fire on every page load. This decision can be revisited once core establishes a convention.

Remaining tasks

  • Review and test the merge request.

User interface changes

Deprecation warnings no longer appear on every page load for sites using verbose error logging on PHP 8.4. The status report warning on /admin/reports/status is unchanged.

Introduced terminology

None.

API changes

None. @deprecated docblocks remain in place. No behavior, interface, or public API change.

Data model changes

None.

Release notes snippet

Removed PHP 8.4 #[\Deprecated] attributes from reusable block deprecation hooks that caused excessive E_USER_DEPRECATED watchdog noise on every page load. The @deprecated docblocks and status report warning remain as the intended deprecation signals.

Issue fork patternkit-3609394

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

Ready for review.

The PHPStan failure has a fix already that will be merged in alongside work in #3608056: Update Drupal 11.4 Hook Attribute Compatibility.

  • slucero committed 02243d0f on 9.1.x
    fix: #3609394 Remove PHP 8.4 Deprecated attributes from reusable block...
slucero’s picture

Status: Needs review » Fixed

Merged 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.