Skip to content

Commit a209f81

Browse files
committed
CS Fix
1 parent 58648c8 commit a209f81

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

CLAUDE.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,36 @@ Currently `parentPage` is only in `Route:manifest:read`. It needs to be added to
211211

212212
A Behat test should cover: `GET /_/pages` response includes `parentPage` for a page that has one set.
213213

214+
### Bug: PATCH `/_/pages/{uuid}` throws 500 when body contains `componentGroups`
215+
216+
**Symptom (discovered 2026-06-17):** Saving a Page from the Nuxt admin modal returns:
217+
```
218+
500: Warning: Undefined property: Doctrine\Common\Collections\ArrayCollection::$sortValue
219+
```
220+
221+
**Trigger payload:** The Nuxt module admin modal PATCHes the full resource data including `componentGroups` as an array (either IRI strings or embedded JSON-LD objects, depending on what was returned in the GET). Example body:
222+
```json
223+
{
224+
"@type": "Page",
225+
"reference": "My Page",
226+
"layout": "/_/layouts/uuid",
227+
"componentGroups": ["/_/component_groups/uuid1", "/_/component_groups/uuid2"]
228+
}
229+
```
230+
231+
**Likely root cause:** The Symfony deserializer processes the `componentGroups` array and, during denormalization of `ComponentGroup` entities, either a lifecycle callback or the `ComponentPositionNormalizer` accesses `$sortValue` on the `ComponentGroup.componentPositions` `ArrayCollection` as if it were a scalar property — rather than iterating over individual `ComponentPosition` entities. This results in PHP trying to read `$sortValue` on the `ArrayCollection` object itself.
232+
233+
**Where to look:**
234+
- `ComponentGroup` entity — any `#[ORM\PrePersist]` / `#[ORM\PreUpdate]` listener that reads `componentPositions->sortValue`
235+
- `ComponentPositionNormalizer` — any code path triggered during `PATCH` denormalization that accesses the position collection
236+
- Symfony's denormalization of `ComponentGroup.componentPositions` when the PATCH body includes inline `componentGroups`
237+
238+
**Workaround (Nuxt module, committed 2026-06-17):** `PageAdminModal` passes `excludeFields: ['componentGroups']` to `useItemPage`, so `componentGroups` is stripped from the PATCH body before sending. This bypasses the bug without fixing it. A proper API-side fix is still needed so that PATCH requests including `componentGroups` do not 500.
239+
240+
**Test to write:** Behat scenario — `PATCH /_/pages/{uuid}` with `componentGroups` in the request body returns 200, not 500.
241+
242+
---
243+
214244
### Outstanding — UUID-based manifest must walk the `parentPage` chain
215245

216246
**Bug (discovered 2026-06-16):** When the Nuxt module admin accesses a nested `Page` entity directly via its admin URL (e.g. `/_cwa/%2F_api%2F_%2Fpages%2F{child-uuid}`), the fetcher calls `GET /_api/_/resource_manifest/{child-uuid}`. The module code is correct: it uses `irisByDepth[0]` as the parent depth and renders `pageIriAtDepth(depth)` for each level. However, the admin admin page displays only a placeholder (no parent content) because the manifest endpoint currently returns only the accessed page in a single depth group — it does not walk the `parentPage`/`parentPageData` chain upward.

tests/Entity/Core/AbstractPageTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public function test_cycle_via_parent_page_data_reports_correct_field(): void
135135
$pageData->validateNoCircularParent($this->makeContext(1, 'parentPageData'));
136136
}
137137

138-
public function test_initial_parent_selection_uses_parentPage_over_parentPageData(): void
138+
public function test_initial_parent_selection_uses_parent_page_over_parent_page_data(): void
139139
{
140140
// Subject has BOTH parentPage (cyclic) and parentPageData (safe) set simultaneously.
141141
// The initial parent selection on line 100 must pick parentPage first.

tests/Helper/User/UserMailerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function test_exception_thrown_if_mailer_send_throws_exception(): void
125125
->method('error')
126126
->with(
127127
self::anything(),
128-
self::callback(fn (array $ctx) => isset($ctx['exception']) && $ctx['exception'] instanceof MailerTransportException)
128+
self::callback(static fn (array $ctx) => isset($ctx['exception']) && $ctx['exception'] instanceof MailerTransportException)
129129
);
130130

131131
$result = $this->userMailer->sendPasswordResetEmail($user);

0 commit comments

Comments
 (0)