Problem/Motivation
When you have translatable entity reference field and want to check that specific referenced entity is not used in other translations so you can delete it.
Example data state:
| entity_id | revision_id | langcode | delta | field_tags_target_id |
|---|---|---|---|---|
| 6590308 | 20 | en | 0 | 10000000 |
| 6590308 | 21 | en | 0 | 10000000 |
| 6590308 | 21 | ja | 0 | 10000001 |
| 6590308 | 22 | en | 0 | 10000000 |
| 6590308 | 22 | en | 1 | 10000001 |
| 6590308 | 22 | ja | 0 | 10000002 |
Configured languages: Japanese, German, English.
Let's say I wan't remove reference 10000001 from new EN translation, but I wan't be sure that it's not used in other translations so I can delete it.
I will run a query:
$entity_id = 6590308;
$entity_type = 'node';
$entity = Node::load($entity_id);
// IDs of referenced entities.
$ids = [10000001];
$field_name = 'field_tags';
$storage = $this->entityTypeManager->getStorage($entity_type);
$query = $storage->getQuery();
$query
->allRevisions()
->condition($entity->getEntityType()->getKey('id'), $entity->id(), '=');
$can_be_deleted = [];
$all_languages = \Drupal::languageManager()->getLanguages(LanguageInterface::STATE_CONFIGURABLE);
foreach ($ids as $id) {
$orConditionGroup = $query->orConditionGroup();
foreach ($all_languages as $language) {
if ($entity->language()->getId() != $language->getId()) {
$orConditionGroup->condition($field_name, $id, '=', $language->getId());
}
}
$query->condition($orConditionGroup);
$result = $query->execute();
if (empty($result)) {
$can_be_deleted[] = $id;
}
}
$ids = $can_be_deleted;
Produced SQL query is going to join to the field table based on langcode that were first passed to condition group.
So if the first language in the example above would be Japanese it will succeed, but if the first on would be German query will fail , well not fail but it will return nothing.
Proposed resolution
Join on the langcode only if there is one language in field condition, otherwise add the langcode to the WHERE clause.
Remaining tasks
- Provide test to prove the bug
- Agree on suggested solution
- Implement fix
- Review
- Commit
User interface changes
None
API changes
TBD
Data model changes
NONE
Release notes snippet
TBD
Comments
Comment #2
rosk0Comment #3
dwwI think this is causing trouble at #3092280: Filter by translated taxonomy term for sites with multiple languages too.
I want to be able to do an entity query for a given term name across all languages. It's not clear how to make that work.
It's too bad we have to do all these separate conditions for languages. It'd be great if there was a flag to an entity query to say "find an answer across all languages".
Comment #11
smustgrave commentedThis came up as a daily BSI target
I believe this may still be valid but I don't do a lot of multi-language sites. I am 50/50 if this is a bug vs task but will leave as is.
Maybe getting a test would be a good start?
Comment #12
dwwBlast from the past. Yeah, I'm not really sure this is a bug, now that you mention it.
Tagging for a test. No time right now to write it. 😅