fix: failed library and layout saves name the revision screen (audit L3)
A failed save of a library entry or Theme Builder layout now carries restore_url when a revision exists; a partial write's hint points to the WordPress revision screen and lit-divi-outline instead of lit/revisions-list and lit/revision-restore, which answer not found for these types. Pages keep the default hint. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -127,7 +127,7 @@ final class DiviWriter
|
|||||||
$e->revisionId
|
$e->revisionId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw $e;
|
throw self::withRestorePoint($page, $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
$outline = $this->outline($index, $change);
|
$outline = $this->outline($index, $change);
|
||||||
@@ -177,6 +177,38 @@ final class DiviWriter
|
|||||||
return admin_url('revision.php?revision=' . $revisionId);
|
return admin_url('revision.php?revision=' . $revisionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Audit L3 on the failure path: for a library entry or a Theme Builder layout the error names the WordPress
|
||||||
|
* revision screen (restore_url) and says so in the hint of a partial write, instead of lit/revisions-list and
|
||||||
|
* lit/revision-restore, which answer "not found" for these types. Pages keep the default hint.
|
||||||
|
*/
|
||||||
|
private static function withRestorePoint(DiviPage $page, WriteFailed $e): WriteFailed
|
||||||
|
{
|
||||||
|
if (! $page->isLibraryItem() && ! $page->isThemeBuilderLayout()) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$restore = self::restoreUrl($page, $e->revisionId);
|
||||||
|
$details = $restore === null ? [] : ['restore_url' => $restore];
|
||||||
|
if ($e->rolledBack) {
|
||||||
|
return $details === [] ? $e : $e->withDetails($details);
|
||||||
|
}
|
||||||
|
|
||||||
|
$back = $restore === null
|
||||||
|
? ''
|
||||||
|
: sprintf(
|
||||||
|
' Den vorherigen Stand (Revision %d) bei Bedarf im Revisionsvergleich von WordPress wiederherstellen '
|
||||||
|
. '(restore_url).',
|
||||||
|
(int) $e->revisionId
|
||||||
|
);
|
||||||
|
|
||||||
|
return $e->withDetails(
|
||||||
|
$details,
|
||||||
|
'Den Aufruf nicht einfach wiederholen. Zuerst den aktuellen Stand mit lit-divi-outline prüfen.' . $back
|
||||||
|
. ' Dem Nutzer Bescheid geben.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save() for the Divi tools (E2): pages as before; a library entry keeps its shape, a global one
|
* save() for the Divi tools (E2): pages as before; a library entry keeps its shape, a global one
|
||||||
* needs confirm (dry run first), gets a backup when revisions are off and clears every page's
|
* needs confirm (dry run first), gets a backup when revisions are off and clears every page's
|
||||||
|
|||||||
@@ -438,6 +438,40 @@ final class GlobalEditsTest extends TestCase
|
|||||||
self::assertCount(1, $this->log->partials);
|
self::assertCount(1, $this->log->partials);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Audit L3 on the failure path (re-review): lit/revision-restore answers not found for library entries, so a
|
||||||
|
* failed save names the WordPress revision screen instead.
|
||||||
|
*/
|
||||||
|
public function testAFailedSaveNamesTheRevisionScreenNotRevisionRestore(): void
|
||||||
|
{
|
||||||
|
LibraryFixtures::given([LibraryFixtures::item(1059)]);
|
||||||
|
$this->log = FakeChangeLog::partialsOnly();
|
||||||
|
$cause = new \RuntimeException('hook');
|
||||||
|
foreach (
|
||||||
|
[
|
||||||
|
WriteFailed::partial(DiviSaver::REASON, $cause, postId: 1059, revisionId: 811),
|
||||||
|
WriteFailed::rolledBack(DiviSaver::REASON, $cause, postId: 1059, revisionId: 811),
|
||||||
|
] as $failure
|
||||||
|
) {
|
||||||
|
$this->failure = $failure;
|
||||||
|
try {
|
||||||
|
(new DiviUpdateAbility($this->writer()))->execute(self::relabel(1059, true));
|
||||||
|
self::fail('WriteFailed expected');
|
||||||
|
} catch (WriteFailed $e) {
|
||||||
|
$error = $e->toError();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $error->get_error_data();
|
||||||
|
self::assertSame('https://kunde.test/wp-admin/revision.php?revision=811', $data['restore_url']);
|
||||||
|
self::assertStringNotContainsString('lit/revision-restore', $data['hint']);
|
||||||
|
self::assertStringNotContainsString('lit/revisions-list', $data['hint']);
|
||||||
|
if (! $failure->rolledBack) {
|
||||||
|
self::assertStringContainsString('restore_url', $data['hint']);
|
||||||
|
self::assertStringContainsString('Revision 811', $data['hint']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Ruling P14 (M-2): one page is "Seite". */
|
/** Ruling P14 (M-2): one page is "Seite". */
|
||||||
public function testDeleteNoticeUsesTheSingularForOnePage(): void
|
public function testDeleteNoticeUsesTheSingularForOnePage(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -155,6 +155,23 @@ final class DiviWriterThemeBuilderTest extends TestCase
|
|||||||
self::assertSame([], $this->saved);
|
self::assertSame([], $this->saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Audit L3 on the failure path: a failed layout save names the WordPress revision screen. */
|
||||||
|
public function testAFailedSaveNamesTheRevisionScreen(): void
|
||||||
|
{
|
||||||
|
$this->failures = [WriteFailed::rolledBack(DiviSaver::REASON, new \RuntimeException('hook'), postId: 1062, revisionId: 811)];
|
||||||
|
$ability = new DiviInsertAbility($this->writer([ThemeBuilderFixtures::template()]));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$ability->execute($this->insert($this->body, []));
|
||||||
|
self::fail('WriteFailed expected');
|
||||||
|
} catch (WriteFailed $e) {
|
||||||
|
$error = $e->toError();
|
||||||
|
}
|
||||||
|
|
||||||
|
self::assertSame('https://kunde.test/wp-admin/revision.php?revision=811', $error->get_error_data()['restore_url']);
|
||||||
|
self::assertStringNotContainsString('lit/revision-restore', $error->get_error_data()['hint']);
|
||||||
|
}
|
||||||
|
|
||||||
/** Without a ThemeBuilderEdits (no Theme Builder wiring) a layout is never written. */
|
/** Without a ThemeBuilderEdits (no Theme Builder wiring) a layout is never written. */
|
||||||
public function testWithoutThemeBuilderEditsLayoutsAreNotWritten(): void
|
public function testWithoutThemeBuilderEditsLayoutsAreNotWritten(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user