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