diff --git a/CHANGELOG.md b/CHANGELOG.md index 62e8acf..a7ef902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 4.5.2 + +### Bug Fix: `sensitive` toggle on a Controller silently fails (TypeError on metadata-only PUT) + +Completes the 4.5.1 fix for the third meta-controller. Toggling `sensitive=1` on a **Controller** (the detail-page toggle) returned HTTP 200 with an empty body and reverted with "Save failed." + +`ControllerController::hook_preprocess` (update) calls `validateControllerUpdate($o, $r)`, which early-returns only when `$o->name === $r['name']`. A metadata-only PUT of `{sensitive:1}` omits `name`, so `$r['name']` is `null`; `"SomeController" === null` is `false`, so it fell through and passed `null` into `checkNameExistsInScope(string $name)` → **TypeError** → caught by the global exception handler (logged as a `KyteError`, hence the empty 200) → the update aborted before `sensitive` was saved. + +Fix: `validateControllerUpdate` now returns early when `name` is absent — `if (!isset($r['name']) || $o->name === $r['name'])`. The name-change path (which always sends `name`) is unaffected. + +This is the Controller-level sibling of the 4.5.1 DataModel/ModelAttribute fixes — all three meta-controllers assumed every update carried the full record. With 4.5.2, sensitive flags can be set at controller, model, and field level. No schema change. + ## 4.5.1 ### Bug Fix: `sensitive` toggle (and any metadata-only PUT) silently fails on DataModel / ModelAttribute diff --git a/src/Mvc/Controller/ControllerController.php b/src/Mvc/Controller/ControllerController.php index 22a6172..a109db7 100644 --- a/src/Mvc/Controller/ControllerController.php +++ b/src/Mvc/Controller/ControllerController.php @@ -62,8 +62,14 @@ private function validateControllerName(string $name, int $applicationId): void */ private function validateControllerUpdate($originalController, array $updateData): void { - // Only validate if the name is actually changing - if ($originalController->name === $updateData['name']) { + // Skip when the update isn't changing the name. A metadata-only + // partial PUT — e.g. the detail page toggling `sensitive` — omits + // `name` entirely. The old `=== $updateData['name']` compared the + // existing string to null (false), so it fell through and passed + // null into checkNameExistsInScope(string $name) -> TypeError -> + // swallowed by the exception handler -> empty 200 -> save aborted + // before `sensitive` persisted. + if (!isset($updateData['name']) || $originalController->name === $updateData['name']) { return; }