WebformSubmissionStorage::buildPropertyQuery fails when deleting an account and removing all its contents.

Created on 8 March 2024, 8 months ago
Updated 20 April 2024, 7 months ago

Problem/Motivation

When deleting users and selecting "Delete the account and its content. This action cannot be undone." the buildPropertyQuery method on WebformSubmission class creates the following error:

Drupal\Core\Entity\EntityStorageException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3: SELECT "base_table"."sid" AS "sid", "base_table"."sid" AS "base_table_sid" FROM "webform_submission" "base_table" WHERE; Array ( ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->delete() (line 765 of /var/www/html/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).

This happens because the method was refactored on issue 3073301 to allow for multiple ids.

The problem is that when the $accounts returns empty the query condition is not added (though the orCondition group is) and we have an empty condition on the query, also the $varlues['uid'] is unset before returning the query to the parent method without the user id, this last bit wouldn't be a problem if $account returned the entities needed:

protected function buildPropertyQuery(QueryInterface $entity_query, array $values) {
    // Add account query when ever filtered by uid.
    if (isset($values['uid'])) {
      $uids = (array) $values['uid'];
      $accounts = User::loadMultiple($uids);
      $or_condition_group = $entity_query->orConditionGroup();
      foreach ($accounts as $account) {
        $this->addQueryConditions($or_condition_group, NULL, NULL, $account);
      }
      $entity_query->condition($or_condition_group);
      unset($values['uid']);
    }

    parent::buildPropertyQuery($entity_query, $values);
  }

Steps to reproduce

Delete a user and select: "Delete the account and its content. This action cannot be undone."
At the moment a module queries:
\Drupal::entityTypeManager()->getStorage('webform_submission')->loadByProperties(['uid'=> 98]);
It will enter the WebformSubmissionStorage::buildPropertyQuery method;

Proposed resolution

Is is method needed? Since it calls the parent EntityStorageBase::buildPropertyQuery() which adds the conditions for user id:

protected function buildPropertyQuery(QueryInterface $entity_query, array $values) {
    foreach ($values as $name => $value) {
      // Cast scalars to array so we can consistently use an IN condition.
      $entity_query->condition($name, (array) $value, 'IN');
    }
  }

as a reference the old version works well:

/**
   * {@inheritdoc}
   */
  protected function buildPropertyQuery(QueryInterface $entity_query, array $values) {
    // Add account query wheneven filter by uid.
    if (isset($values['uid'])) {
      $account = User::load($values['uid']);
      if ($account instanceof UserInterface) {
        $this->addQueryConditions($entity_query, NULL, NULL, $account);
        unset($values['uid']);
      }
    }

    parent::buildPropertyQuery($entity_query, $values);
  }

Query generated:

Vars status:

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Fixed

Version

6.2

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium gilmar.lima Brussels

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

Merge Requests

Comments & Activities

Production build 0.71.5 2024