Problem/Motivation

Some classes has usage of undefined properties which are not fixed in #3274474: Fix 'Access to an undefined property' PHPStan L0 errors because could be caught by tests only (not phpstan)

The issue intended for all classes except tests

Steps to reproduce

See #3295821-91: Ignore: patch testing issue for PHP 8.2 attributes

Proposed resolution

Define missing properties

Remaining tasks

- collect all changes from testing issue #3295821-91: Ignore: patch testing issue for PHP 8.2 attributes
- make sure tests pass on PHP 8.2
- review/commit

User interface changes

no

API changes

no

Data model changes

no

Release notes snippet

no

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

andypost created an issue. See original summary.

andypost’s picture

Title: Define missing object properties for PHP 8.2 » Define missing object properties on non-testing classes for PHP 8.2
Issue summary: View changes

re-title and scoped

andypost’s picture

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Component/Diff/Engine/DiffEngine.php
    @@ -31,6 +31,16 @@ class DiffEngine {
       const MAX_XREF_LENGTH = 10000;
     
    +  private array $xchanged;
    +  private array $ychanged;
    +  private array $xv;
    +  private array $yv;
    

    so #3274474: Fix 'Access to an undefined property' PHPStan L0 errors took the easy way out and dropped them from that issue, but we still need to fix it.

    needs a core maintainer decision but I expect we still need minimal docs on this one (or also just put the dynamic property annotation on it and make it a problem for another day?)

  2. +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php
    @@ -47,6 +47,10 @@ class ConfigEntityType extends EntityType implements ConfigEntityTypeInterface {
       protected $mergedConfigExport = [];
    +  protected $label_callback;
    +  protected $controllers;
    +  protected $module;
    +  protected $list_path;
     
       /**
    

    The fix IMHO is still to add the AllowedDynamicProperties annotation to \Drupal\Component\Plugin\Definition\PluginDefinition. plugin definitions are imho expected to be extensible. just adding these might fix the core tests for now, but it will not fix contrib. We can have a follow-up to use magic get/set or something, but that should be ok for now.

  3. +++ b/core/lib/Drupal/Core/Session/UserSession.php
    @@ -66,6 +66,23 @@ class UserSession implements AccountInterface {
       protected $timezone;
    +  protected $langcode;
    +  protected $pass;
    +  protected $status;
    +  protected $created;
    +  protected $changed;
    +  protected $login;
    +  protected $init;
    

    this is an absolute mess. we need to clean this up, but instead of adding all these properties, lets also use the annotation on this class.

  4. +++ b/core/modules/block/src/Entity/Block.php
    @@ -137,6 +137,7 @@ class Block extends ConfigEntityBase implements BlockInterface, EntityWithPlugin
        */
       protected $theme;
    +  protected $provider;
    

    this is a config entity class, so this can be removed.

  5. +++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldWidget/TestFieldWidget.php
    @@ -23,6 +23,11 @@
     
    +  /**
    +   * \Drupal\Tests\field_ui\Kernel\EntityFormDisplayTest.
    +   */
    +  public $randomValue;
    +
    

    ok, so that's this part:

        $random_value = $this->randomString();
        $widget->randomValue = $random_value;
        $widget = $form_display->getRenderer($field_name);
        $this->assertEquals($random_value, $widget->randomValue);
    

    Isn't there a better way to check that it's the same object? According to https://www.php.net/manual/en/language.oop5.object-comparison.php, we can simply do a $renderer === $renderer2 comparison, then we can drop this. same for the widget above.

  6. +++ b/core/modules/migrate/src/Plugin/Migration.php
    @@ -327,6 +327,19 @@ class Migration extends PluginBase implements MigrationInterface, RequirementsIn
    +  protected $class;
    +  // phpcs:disable Drupal.Classes.PropertyDeclaration
    +  protected $_discovered_file_path;
    +  protected $deriver;
    +  protected $target_types;
    +  protected $field_plugin_method;
    +
    +  /**
    +   * Drupal\Tests\migrate\Kernel\MigrateSkipRowTest.
    +   */
    +  protected $load;
    +  public $provider;
    

    I think that load thing in MigrateSkipRowTest is a bogus leftover. the test still passes if you comment it out, lets just remove that there.

    the others we either need to document properly or clean up. What I'm not 100% clear about is the different between the plugin definition and the plugin class here. Ah, I see. \Drupal\migrate\Plugin\Migration::__construct() is the culprit, it moves everything from configuration and plugin definition directly to the class. We either need to limit that to existing properties or add the annotation as well, because this could contain anything then.

  7. +++ b/core/modules/migrate_drupal/src/Plugin/migrate/FieldMigration.php
    @@ -21,6 +21,7 @@ class FieldMigration extends Migration implements ContainerFactoryPluginInterfac
       protected $init = FALSE;
    +  protected $field_plugin_method;
     
       /**
        * The migration field discovery service.
    

    same here, this is already on the parent class now.

  8. +++ b/core/modules/system/src/Entity/Action.php
    @@ -79,6 +79,12 @@ class Action extends ConfigEntityBase implements ActionConfigEntityInterface, En
       protected $pluginCollection;
    +  protected $url;
    +  protected $submit;
    +  protected $form_build_id;
    +  protected $form_token;
    +  protected $form_id;
    +  protected $confirm;
     
    

    config entity, safe to remove.

  9. +++ b/core/modules/system/tests/modules/entity_test/src/TypedData/ComputedString.php
    @@ -11,6 +11,11 @@
     class ComputedString extends TypedData implements CacheableDependencyInterface {
     
    +  /**
    +   * Drupal\Tests\jsonapi\Kernel\Normalizer\FieldItemNormalizerTest.
    +   */
    +  protected $value;
    +
    

    this is kind of a weird one.

    the bug is arguably in \Drupal\Core\TypedData\TypedData::setValue, this sets $this->value but doesn't actually define such a property. but that's more or less because the type there isn't defined.

    as a computed string, I don't think this expects to have a value set, but all properties get set to a value through \Drupal\Core\TypedData\Plugin\DataType\Map::setValue(), even if nothing was set for them.

    I think this for now is correct, lets just set a generic docblock like on \Drupal\Core\TypedData\PrimitiveBase.

  10. +++ b/core/modules/user/src/Entity/User.php
    @@ -74,6 +74,8 @@ class User extends ContentEntityBase implements UserInterface {
        */
       protected static $anonymousUser;
    +  // phpcs:disable Drupal.Classes.PropertyDeclaration
    +  public $_skipProtectedUserFieldConstraint;
     
    

    this _should_ go through magic get/set, do tests really fail without this?

Berdir’s picture

> I think this for now is correct, lets just set a generic docblock like on \Drupal\Core\TypedData\PrimitiveBase.

Alternatively, we could overwrite setValue() and ignore the input, as we do not support setting a value.

mondrake’s picture

Re #4.1 the way out was meant to be #3299678: Deprecate DiffEngine and replace with sebastian/diff, but I reckon that is too late for 9.5. IMHO better go for the dynamic property annotation for now, then directionally work to remove DiffEngine.

andypost’s picture

@mondrake maybe better to define this properties and clean up phpstan ignore?

mondrake’s picture

@andypost dunno… it was like that in #3274474: Fix 'Access to an undefined property' PHPStan L0 errors before being expuncted. I guess we need guidance here.

andypost’s picture

There's 2 child issues filed during DrupalConEur sprints

- #3311442: Only set defined properties on config entities in EntityForm::copyFormValuesToEntity - needs to clean-up to remove useless properties access
- #3311466: Remove obsolete ViewExecutable::editing property access - just discovered while working on previous

andypost’s picture

andypost’s picture

Status: Needs work » Needs review
FileSize
1.91 KB
6.66 KB

Added missed hunks and ViewUI attribute

andypost’s picture

Status: Needs review » Needs work

The last submitted patch, 12: 3309748-test-only.patch, failed testing. View results

andypost’s picture

Probably this could be closed because patch will contain only one change after #3311562: Set sqlQuery in Entity\Query\Sql Condition classes on own class

+++ b/core/modules/views/src/ManyToOneHelper.php
@@ -21,6 +21,15 @@
+  public $formula = FALSE;

this is only will left here as other classes are from tests

andypost’s picture

Berdir’s picture

edit: commented on the wrong issue.

andypost’s picture

FileSize
433 bytes

The only remaining fix here, to catch it use \Drupal\Tests\views\Functional\TaxonomyGlossaryTest

andypost’s picture

Added @see to where the property is used as public

Berdir’s picture

+++ b/core/modules/views/src/ManyToOneHelper.php
@@ -21,6 +21,15 @@
+  /**
+   * Should the field to use formula or alias.
+   *
+   * @see \Drupal\views\Plugin\views\argument\StringArgument::query()
+   *

I think the "to" here is not necessary and not valid english, can be removed.

Ratan Priya’s picture

@Berdir,
Made changes as per comment #19.
Needs review.

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Thanks.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views/src/ManyToOneHelper.php
@@ -21,6 +21,15 @@
+  public $formula = FALSE;

Given we added handler with a typehint I think we should be adding this with one too...

so
public bool $formula = FALSE;

  • catch committed 6fc5799 on 10.1.x
    Issue #3309748 by andypost, Ratan Priya, Berdir, mondrake: Define...

  • catch committed a988a5a on 10.0.x
    Issue #3309748 by andypost, Ratan Priya, Berdir, mondrake: Define...

alexpott credited catch.

alexpott’s picture

Status: Needs work » Fixed

Discussed with a @catch - we agreed to make a commit to add the typehint and be done.

Committed and pushed 4a16f2a856 to 10.1.x and 19bd9092bd to 10.0.x. Thanks!

  • alexpott committed 997a059 on 10.1.x
    Issue #3309748 by andypost, Ratan Priya, Berdir, mondrake, catch: Define...

  • alexpott committed 19bd909 on 10.0.x
    Issue #3309748 by andypost, Ratan Priya, Berdir, mondrake, catch: Define...
andypost’s picture

Version: 10.0.x-dev » 9.5.x-dev
Status: Fixed » Needs review
FileSize
617 bytes

Here's a patch for 9.5.x - I bet it safe to backport

alexpott’s picture

--- a/core/modules/views/src/ManyToOneHelper.php
+++ b/core/modules/views/src/ManyToOneHelper.php

@@ -38,6 +38,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+  /**
+   * Should the field use formula or alias.
+   *
+   * @see \Drupal\views\Plugin\views\argument\StringArgument::query()
+   *
+   * @var bool
+   */
+  public $formula = FALSE;

If we're going to backport this then I think we should backport [##3295157] too

longwave’s picture

Status: Needs review » Needs work

This should add the declaration before the constructor, as in 10.1.x.

narendra.rajwar27’s picture

Status: Needs work » Needs review
FileSize
554 bytes
809 bytes

Adding declaration above constructor.

Berdir’s picture

I agree with #30 and I'm at the same time against backporting #3295157: Fix 'Access to an undefined property' PHPStan L0 errors - public properties, I was wrong with an earlier slack thread, I believe *that* issue is what broke search_api in D10 and backporting would break it there too. So, IMHO, we should close this and leave PHP 8.2 support for D10+.

andypost’s picture

Version: 9.5.x-dev » 10.0.x-dev
Status: Needs review » Fixed

Agree with #33

Status: Fixed » Closed (fixed)

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