What happened?
Description
Entries::_ensureSingleEntry() picks the entry it saves without a site preference (src/services/Entries.php:982-991):
$baseEntryQuery = Entry::find()
->sectionId($section->id)
->siteId($siteIds)
->status(null);
$entry = $baseEntryQuery->typeId($entryTypeIds)->one();
With no unique() the query returns a row per site, and EntryQuery::$defaultOrderBy (entries.postDate DESC, elements.id DESC) ties across all of them for a Single, so ->one() returns whatever the database offers first. That row's siteId decides which locale's content propagates.
handleChangedSection() gets this right for its resave criteria a few lines up, passing 'preferSites' => [primarySite->id] with 'unique' => true (:837-841), which is why the omission looks unintentional.
Steps to reproduce
- Multi-site install, sites A (primary), B, C in one group.
- Single section enabled for all three, entry type with a Matrix field set to "Only save entries to the site they were created in".
- Give each site distinct block content.
- Add site D, enable the Single for it, apply project config.
Expected behavior
Site D seeds from A, matching the resave path.
Actual behavior
Site D seeds from an arbitrary site. On a 26-site install it repeatedly chose a Korean locale over the US English primary. The tie is visible without adding a site:
SELECT es.siteId, e.postDate, e.id
FROM craft_entries e
JOIN craft_elements el ON el.id = e.id
JOIN craft_elements_sites es ON es.elementId = e.id
WHERE e.sectionId = <section id>
AND el.draftId IS NULL AND el.revisionId IS NULL AND el.dateDeleted IS NULL
ORDER BY e.postDate DESC, e.id DESC;
Adding ->preferSites([Craft::$app->getSites()->getPrimarySite()->id])->unique() to $baseEntryQuery fixes it.
Distinct from #18659, which stopped populated locales being overwritten but did not change which site gets picked.
Craft CMS version
5.10.14 (originally hit on 5.9.18)
PHP version
8.3
Operating system and version
No response
Database type and version
MySQL 8
Image driver and version
No response
Installed plugins and versions
No response
What happened?
Description
Entries::_ensureSingleEntry()picks the entry it saves without a site preference (src/services/Entries.php:982-991):With no
unique()the query returns a row per site, andEntryQuery::$defaultOrderBy(entries.postDate DESC, elements.id DESC) ties across all of them for a Single, so->one()returns whatever the database offers first. That row'ssiteIddecides which locale's content propagates.handleChangedSection()gets this right for its resave criteria a few lines up, passing'preferSites' => [primarySite->id]with'unique' => true(:837-841), which is why the omission looks unintentional.Steps to reproduce
Expected behavior
Site D seeds from A, matching the resave path.
Actual behavior
Site D seeds from an arbitrary site. On a 26-site install it repeatedly chose a Korean locale over the US English primary. The tie is visible without adding a site:
Adding
->preferSites([Craft::$app->getSites()->getPrimarySite()->id])->unique()to$baseEntryQueryfixes it.Distinct from #18659, which stopped populated locales being overwritten but did not change which site gets picked.
Craft CMS version
5.10.14 (originally hit on 5.9.18)
PHP version
8.3
Operating system and version
No response
Database type and version
MySQL 8
Image driver and version
No response
Installed plugins and versions
No response