Repository navigation
2.4.0 — SilverStripe 6 line
Added
- (#119) New
ownspublish mode onPublishOrchestrator,records/$ClassRef/$ID/publish
({"mode": "owns"}),pages/$ID/convert, and batch'spublish/defaultPublish: publishes a
record plus every descendant reachable through its$ownsconfig
(Dynamic\ContentApi\Verify\OwnedTreeWalker, built for #120's parity endpoint), authorization-
checking every one of them (classactionverb +canEdit()) before writing anything — the
same check-everything-first contractsubtreealready has, over an owned-relation graph
instead of aHierarchytree. TakesdryRun(preview the would-publish set);liveOnlyis
subtree-only and refused with400 PAYLOAD_INVALIDonowns. Spec bumped tov1.14.
Fixed
-
(#168, closing the last gap #114 left open, see #119)
CompositionService::publishAll()
andPageHandler::applyTemplate()used to publish a composition's/template's elemental area,
every element, and every element child viapublish($record, 'single', $member)—single
mode performs no authorization at all, and nothing upstream checked theactionverb for those
classes either, since element writes always pass"publish": "none"explicitly. Both call
sites now route through the newPublishOrchestrator::publishOwnedTree()instead of their own
hand-rolled publish loops, closing the gap the same way #114 closed it for each cascade's root
record.PageHandler::applyTemplate()is now also wrapped in aDbTransaction— previously its
publish step could never fail, so nothing rolled it back; now that it can (the same
authorization check as everywhere else), a mid-cascade refusal rolls back the template write
too, matching howcompose()already behaves.publishOwnedTree()'s$additionalparameter
also now refuses a non-DataObject/not-yet-written entry loudly (400 PAYLOAD_INVALID) instead
of silently dropping it, and logs a warning for the one genuinely expected drop case (an
unversioned owned relation, e.g. a plain-DataObjecthas_many child).Behavior change: any class in the walked
$ownscascade — not just elements — that grants
create/updateinapi_accessbut withholdsactionnow gets403 FORBIDDEN_CLASSon a
composition or apply-template publish, where it previously published silently with no error at
all. This reaches further than "elements":File/Imageare versioned, so an owned image
relation (a common pattern for image-bearing elements) is checked too, and asset classes are the
ones most likely to be configured read/create-only today, since publishing an asset was never
previously something this module authorization-checked. Fix: grantactionon every affected
class, or passpublish: "none"if the cascade was never meant to publish it.Known gap, not fixed here (#174):
PageHandler::applyTemplate()'s cascade doesn't include
each element's own has_many children the wayCompositionService::publishAll()'s does — if
dynamic/silverstripe-elemental-templates'TemplateApplicatorduplicates such children, they
can stay on draft after a"recursive"apply. Not verified either way: that package is optional
and isn't a dev dependency of this module, so its actual output shape can't be checked here.