`EntityOwnerInterface::getOwner()` should have nullable return value

Created on 20 January 2023, almost 2 years ago
Updated 8 March 2023, over 1 year ago

Problem/Motivation

Sometimes, users get deleted, but some of their related content may retain a reference to the deleted user. In my case, that includes membership records that might be touched by external systems. I can handle lifecycling the membership when the user is no longer around, however EntityOwnerInterface::getOwner() doesn't foresee a null return value when the user isn't loaded.

Steps to reproduce

Call EntityOwnerInterface::getOwner() on an entity whose owner is deleted.

Proposed resolution

Make the return value typehint nullable.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Needs work

Version

10.1 ✨

Component
User systemΒ  β†’

Last updated about 19 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States bradjones1 Digital Nomad Life

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¦πŸ‡ΊAustralia dpi Perth, Australia

    Thanks for the issue, was about to create this myself after a PHPStan strict run on our codebase. Adding tag.

    Just two things

    Do you mind adding tests for these?

    getOwner may be missing due to a deleted user, so we should document that. I created a very similar issue for getRevisionUser over at πŸ› RevisionLogInterface is typehinted as always returning entity/ids, but cannot guarantee set/existing values Fixed / MR2754, and received similar feedback.

  • πŸ‡ΊπŸ‡ΈUnited States bradjones1 Digital Nomad Life
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    I'm not sure if I agree with this. The bug is in implementation. Implementers should return an anonymous user if the referenced user entity in inaccessible. See the Commerce interface method getCustomer which we used over getOwner for orders: https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/order...

    The implementation:

      /**
       * {@inheritdoc}
       */
      public function getCustomer() {
        $customer = $this->get('uid')->entity;
        // Handle deleted customers.
        if (!$customer) {
          $customer = User::getAnonymousUser();
        }
        return $customer;
      }
    
    
  • πŸ‡³πŸ‡±Netherlands kingdutch

    I'm also not sure I agree. There are hooks in Drupal that should be implemented to properly delete user data. If that data should be persisted then the system should think about what it should do to keep the data integrity alive.

    Currently the EntityOwnerInterface provides a contract to code to say "This thing is owned by something". Making getOwner() possibly return NULL would drastically change the meaning of the interface to EntityMaybeOwnerInterface.

    From a business logic perspective I'd have to handle the NULL case significantly different from the non-null case.

    I agree with Matt (#6) that the anonymous user would make a good fallback to indicate: "We don't know who this user is". This already happens with nodes that are assigned to the anonymous user.

    For Open Social's Real-Time Chat it was important that data integrity was retained since a user may have multiple conversations with different deleted users. Making all of those NULL or the anonymous user would've made it difficult to distinguish between them. Therefore we implemented logic to ensure the data integrity as it made sense for our application to remain intact. We've outlined the work for this and to port it from our proprietary extension to the distribution in #3221021: [Meta] Handle data integrity for deleted users and prepare for non-human actions β†’ .

  • πŸ‡¦πŸ‡ΊAustralia dpi Perth, Australia

    This sounds good, though we're going to need to make sure implementations dont presently return NULL. This will certainly be the case with \Drupal\user\EntityOwnerTrait as ->entity computed property is nullable

Production build 0.71.5 2024