Skip to content

Commit

Permalink
ENH Remove use of ChangeSets from RecursivePublishable
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Feb 13, 2025
1 parent ee61bd5 commit 16c08ac
Showing 1 changed file with 46 additions and 21 deletions.
67 changes: 46 additions & 21 deletions src/RecursivePublishable.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\Queries\SQLUpdate;
use SilverStripe\Model\List\SS_List;
use SilverStripe\UserForms\Model\EditableCustomRule;

/**
* Provides owns / owned_by and recursive publishing API for all objects.
Expand Down Expand Up @@ -63,37 +64,37 @@ public function publishRecursive()
$owner = $this->owner;

// get the last published version
$original = null;
$liveOwner = null;
if ($owner->hasExtension(Versioned::class) && $owner->isPublished()) {
$original = Versioned::get_by_stage($owner->baseClass(), Versioned::LIVE)
$liveOwner = Versioned::get_by_stage($owner->baseClass(), Versioned::LIVE)
->byID($owner->ID);
}

$owner->invokeWithExtensions('onBeforePublishRecursive', $original);

// Create a new changeset for this item and publish it
$changeset = ChangeSet::create();
$changeset->IsInferred = true;
$changeset->Name = _t(
__CLASS__ . '.INFERRED_TITLE',
"Generated by publish of '{title}' at {created}",
[
'title' => $owner->Title,
'created' => DBDatetime::now()->Nice()
]
);
$owner->invokeWithExtensions('onBeforePublishRecursive', $liveOwner);

$changeset->write();
$changeset->addObject($owner);
// Publish this object
if ($owner->hasExtension(Versioned::class)) {
$owner->publishSingle();
}
$draftObjs = $this->getRecursivelyOwnedVersionedDataObjectsByStage($owner, Versioned::DRAFT);
$liveObjs = $this->getRecursivelyOwnedVersionedDataObjectsByStage($liveOwner, Versioned::LIVE);
$liveOnlyKeys = array_diff(array_keys($liveObjs), array_keys($draftObjs));

$result = $changeset->publish(true);
if (!$result) {
return $result;
// Recursively publish owned DataObjects
foreach ($draftObjs as $obj) {
$obj->publishSingle();
}
// Delete any records that were in live but not in draft
// Use deleteFromStage() to avoid writing any to the Versions table before deletion
foreach ($liveOnlyKeys as $key) {
if (array_key_exists($key, $liveObjs)) {
$liveObjs[$key]->deleteFromStage(Versioned::LIVE);
}
}

$owner->invokeWithExtensions('onAfterPublishRecursive', $original);

return $result;
return true;
});
}

Expand Down Expand Up @@ -470,4 +471,28 @@ protected function onAfterDelete(): void
{
RecursiveStagesService::reset();
}

/**
* Returns a map of {dataClass}.{ID} => DataObject of DataObjectsions that are:
* - Recursively owned by the current object
* - Have the Versioned extension
* - Exist in the same stage as the current object
*/
private function getRecursivelyOwnedVersionedDataObjectsByStage(?DataObject $owner, string $stage): array
{
if (!$owner) {
return [];
}
$objs = Versioned::withVersionedMode(function () use ($owner, $stage) {
Versioned::set_stage($stage);
return array_filter(
$owner->findOwned(true)->toArray(),
fn(DataObject $obj) => $obj->hasExtension(Versioned::class)
);
});
return array_combine(
array_map(fn(DataObject $obj) => get_class($obj) . '.' . $obj->ID, $objs),
$objs
);
}
}

0 comments on commit 16c08ac

Please sign in to comment.