feat: lit/library-save creates library entries like Divi (E4)
Reuses NewDraft for insert and rollback (P6), requires edit_global_library for scope global (P7), refuses opaque and global roots before wrapping (P11) and checks the node with StoredNodeGuard. The source page is never written. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,8 @@ defined('ABSPATH') || exit;
|
||||
* returned like any invalid input; partial write if the delete fails.
|
||||
* - discard(): writing after the insert failed – created terms and the draft are deleted;
|
||||
* rolled back, or partial write if that cleanup failed.
|
||||
* Partial writes are logged with result "partial".
|
||||
* Partial writes are logged with result "partial". lit/library-save reuses it for a new library
|
||||
* entry (ruling P6): no PostWriter (no terms of its own to clean up), $noun names the entry.
|
||||
*/
|
||||
final class NewDraft
|
||||
{
|
||||
@@ -30,11 +31,13 @@ final class NewDraft
|
||||
public const REASON_EXTRAS = 'Felder, Begriffe oder Beitragsbild konnten nicht gespeichert werden.';
|
||||
public const REASON_LAYOUT = 'Das Divi-Layout konnte nicht gespeichert werden.';
|
||||
|
||||
/** @param string $noun What the new post is called in change-log summaries. */
|
||||
public function __construct(
|
||||
private PostWriter $writer,
|
||||
private ?PostWriter $writer,
|
||||
private ChangeLog $log,
|
||||
private string $ability,
|
||||
private string $postType
|
||||
private string $postType,
|
||||
private string $noun = 'Entwurf'
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -50,7 +53,7 @@ final class NewDraft
|
||||
} catch (Throwable $e) {
|
||||
// A hook threw – the row may or may not exist and its ID is unknown; nothing is
|
||||
// searched or deleted, the client is told to check (lit_partial_write without id).
|
||||
$this->logPartial('', 'Anlegen abgebrochen; Entwurf möglicherweise vorhanden');
|
||||
$this->logPartial('', sprintf('Anlegen abgebrochen; %s möglicherweise vorhanden', $this->noun));
|
||||
throw WriteFailed::partial(self::REASON_INSERT, $e);
|
||||
}
|
||||
if ($postId instanceof WP_Error) {
|
||||
@@ -77,7 +80,7 @@ final class NewDraft
|
||||
}
|
||||
|
||||
if (! $deleted) {
|
||||
$summary = sprintf('Entwurf %d: Anlegen nicht zurückgenommen', $postId);
|
||||
$summary = sprintf('%s %d: Anlegen nicht zurückgenommen', $this->noun, $postId);
|
||||
$this->logPartial((string) $postId, $summary);
|
||||
$fields = $denied instanceof WP_Error ? Errors::fieldsOf($denied) : $denied;
|
||||
throw WriteFailed::partial(
|
||||
@@ -102,7 +105,7 @@ final class NewDraft
|
||||
public function discard(int $postId, Throwable $cause, string $reason): never
|
||||
{
|
||||
$problems = Rollback::attempt(
|
||||
fn () => $this->writer->deleteCreatedTerms(),
|
||||
fn () => $this->writer?->deleteCreatedTerms(),
|
||||
static fn () => self::deleteDraft($postId)
|
||||
);
|
||||
|
||||
@@ -111,7 +114,7 @@ final class NewDraft
|
||||
throw WriteFailed::rolledBack($reason, $cause, $detail);
|
||||
}
|
||||
|
||||
$summary = sprintf('Entwurf %d: Anlegen nur teilweise zurückgenommen', $postId);
|
||||
$summary = sprintf('%s %d: Anlegen nur teilweise zurückgenommen', $this->noun, $postId);
|
||||
$this->logPartial((string) $postId, $summary);
|
||||
throw WriteFailed::partial($reason, $cause, $detail . '; rollback: ' . implode('; ', $problems), $postId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user