Magic properties: original on entities, name on UserSession and password on User are not reported as deprecated

Open
#1,074 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@goba is already working on this.

Since Nov 9, 2026.

  • #1076 by @goba — open

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
php
Domain
testing-qa

Research direction

Start by reading EntityFieldReflection and its isDeprecated() and getDeprecatedDescription() methods; the issue identifies these as the failing entry points. Check how deprecations are handled for magic properties and ignored inside DeprecationHelper::backwardsCompatibleCall() callbacks. Done means the three listed properties report Drupal’s deprecation messages while callback uses remain ignored; an open linked pull request (#1076) is already working on this issue.

Written by the indexing model from the issue text.

Description

Summary

Drupal 11.2 deprecated the magic original property of entities. It is removed from Drupal 12. EntityBase::__get(), __set(), __isset() and __unset() trigger, for example:

Getting the original property is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal\Core\Entity\EntityInterface::getOriginal() instead. See https://www.drupal.org/node/3295826

In phpstan-drupal EntityFieldReflection gives original a type, but its isDeprecated() always returns no. So phpstan-drupal and the deprecation rules report nothing, and Upgrade Status, which uses them, doesn't either.

Steps to reproduce

On Drupal 11.5.x-dev, with PHPStan 2.3.5, phpstan-drupal 2.2.2 (the code is the same in 2.3.0) and phpstan-deprecation-rules, at level 2:

<?php

declare(strict_types=1);

namespace Drupal\pst_probe;

use Drupal\node\NodeInterface;

final class Probe {

  public function check(NodeInterface $node): ?string {
    if (isset($node->original)) {
      return $node->original->label();
    }
    return $node->getOriginal()?->label();
  }

}

Result: [OK] No errors.

Expected: lines 12 and 13 are reported as uses of a deprecated property, with core's message.

How often this happens

In unpatched copies of 75 contributed modules and themes from the Drupal CMS stack, ->original is used without DeprecationHelper in webform (7 places), crop, key, ai and search_api. These break on Drupal 12.

Proposed resolution

In EntityFieldReflection, when the property name is original and EntityInterface has a getOriginal() method (Drupal 11.2 and later):

  • isDeprecated() should return yes.
  • getDeprecatedDescription() should return core's text: "in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal\Core\Entity\EntityInterface::getOriginal() instead. See https://www.drupal.org/node/3295826".

Uses inside DeprecationHelper::backwardsCompatibleCall() callbacks should still be ignored, like other deprecations.

Two more magic properties have the same problem. They need to be handled the same way:

  • UserSession::$name, deprecated in drupal:11.3.0 and removed from drupal:12.0.0. Use getAccountName().
  • User::$password, deprecated in drupal:11.4.0 and removed from drupal:12.0.0. See https://www.drupal.org/node/3569185.

LLM disclosure

LLM was used to find and resolve this issue. With human review.

Dominant language
PHP
Stars
208
Forks
88
Avg merge
2d 17h
Merged PRs (30d)
15

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from mglaman/phpstan-drupal

All issues in mglaman/phpstan-drupal

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.