Skip to content

Commit

Permalink
Fixed #15890
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonkelly committed Oct 15, 2024
1 parent fbb526d commit e20799d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Fixed a bug where Craft wasn’t auto-detecting interactive terminals on Windows.
- Fixed a bug where element actions were allowed on nested entries when viewing a revision. ([#15879](https://github.com/craftcms/cms/pull/15879))
- Fixed a bug where element error summaries weren’t linking to recursively-nested Matrix fields properly. ([#15797](https://github.com/craftcms/cms/issues/15797))
- Fixed a bug where eager-loaded relation fields were loading all related elements across all instances of the field. ([#15890](https://github.com/craftcms/cms/issues/15890))
- Fixed a privilege escalation vulnerability.

## 5.4.7.1 - 2024-10-09
Expand Down
59 changes: 39 additions & 20 deletions src/fields/BaseRelationField.php
Original file line number Diff line number Diff line change
Expand Up @@ -958,27 +958,46 @@ public function getEagerLoadingMap(array $sourceElements): array|null|false
{
$sourceSiteId = $sourceElements[0]->siteId;

// Get the source element IDs
$sourceElementIds = array_map(fn(ElementInterface $element) => $element->id, $sourceElements);
$map = [];
$missingSourceElementIds = [];

// Return any relation data on these elements, defined with this field
$map = (new Query())
->select(['sourceId as source', 'targetId as target'])
->from([DbTable::RELATIONS])
->where([
'and',
[
'fieldId' => $this->id,
'sourceId' => $sourceElementIds,
],
[
'or',
['sourceSiteId' => $sourceSiteId],
['sourceSiteId' => null],
],
])
->orderBy(['sortOrder' => SORT_ASC])
->all();
foreach ($sourceElements as $sourceElement) {
$rawValue = $sourceElement->getBehavior('customFields')->{$this->handle} ?? null;
if ($rawValue instanceof ElementQueryInterface) {
$rawValue = $rawValue->where['elements.id'] ?? null;
}
if (is_array($rawValue)) {
foreach ($rawValue as $targetElementId) {
$map[] = ['source' => $sourceElement->id, 'target' => $targetElementId];
}
} elseif ($this->isFirstInstance($sourceElement)) {
// The relation IDs aren't hardcoded yet and this is the first
// instance of this field in the field layout, so fetch the relations
// via the DB table
$missingSourceElementIds[] = $sourceElement->id;
}
}

// Are there any source elements that don't have hardcoded relation IDs yet?
if (!empty($missingSourceElementIds)) {
$missingMappingsQuery = (new Query())
->select(['sourceId as source', 'targetId as target'])
->from([DbTable::RELATIONS])
->where([
'and',
[
'fieldId' => $this->id,
'sourceId' => $missingSourceElementIds,
],
[
'or',
['sourceSiteId' => $sourceSiteId],
['sourceSiteId' => null],
],
])
->orderBy(['sortOrder' => SORT_ASC]);
array_push($map, ...$missingMappingsQuery->all());
}

$criteria = [];

Expand Down

0 comments on commit e20799d

Please sign in to comment.