feat: lit/content-create with Divi short form
New input divi (1-30 sections, short form like lit-divi-insert) builds a Divi 5 layout in one divi/placeholder. The whole description is checked before the insert (Divi's map for "no entry yet"); the draft is inserted with its normal WordPress fields only, then DiviContentComposer composes again bound to the new entry and stores it via DiviSaver::saveNew (same kses window as save(), strict DiviFlags). A refusal or failure deletes the draft. Result adds tree_rev and the outline. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,8 @@ use WP_Post;
|
||||
* transition_post_status, wp_after_insert_post and third-party listeners. No MCP input reaches
|
||||
* those hooks except the content itself (already cleaned); anything a third-party hook writes
|
||||
* there is saved without kses, as it would be for an administrator. The rollback write in
|
||||
* restore() uses the same window with the previous stored content.
|
||||
* restore() uses the same window with the previous stored content; saveNew() (the first layout
|
||||
* of a new draft, lit/content-create) uses it for its single wp_update_post().
|
||||
*
|
||||
* Divi's own save filters are NOT kses and are never removed (ruling S7, defense in depth):
|
||||
* Security::initialize() (Divi 5.2.1 Security.php:74-81) registers on wp_insert_post_data
|
||||
@@ -116,6 +117,34 @@ class DiviSaver
|
||||
return ['revision_id' => $revisionId, 'warnings' => $warnings];
|
||||
}
|
||||
|
||||
/**
|
||||
* The first content of a brand-new draft (lit/content-create with divi, which inserted the
|
||||
* draft with its normal WordPress fields – title and excerpt went through kses as usual).
|
||||
* Same kses window as save(), holding only this wp_update_post() and its hooks; no restore
|
||||
* point (the draft has no earlier state) and no static CSS to clear. The Divi flags are part
|
||||
* of the write here: without them the new entry is no Divi layout. Every failure throws –
|
||||
* the caller deletes the draft (all or nothing).
|
||||
*
|
||||
* @return list<string> Warnings (CHANGED_ON_SAVE).
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function saveNew(int $postId, string $content): array
|
||||
{
|
||||
$result = $this->withoutKses(
|
||||
static fn (): int|WP_Error => wp_update_post(wp_slash(['ID' => $postId, 'post_content' => $content]), true)
|
||||
);
|
||||
if ($result instanceof WP_Error || $result === 0) {
|
||||
$message = $result instanceof WP_Error ? $result->get_error_message() : 'returned 0';
|
||||
throw new RuntimeException(sprintf('wp_update_post(%d) refused the Divi layout: %s', $postId, $message));
|
||||
}
|
||||
|
||||
DiviFlags::set($postId);
|
||||
|
||||
$stored = get_post($postId);
|
||||
|
||||
return $stored instanceof WP_Post && (string) $stored->post_content !== $content ? [self::CHANGED_ON_SAVE] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs $write with kses' filters off for users without unfiltered_html (D7); restored in
|
||||
* finally, right when $write returns or throws.
|
||||
|
||||
Reference in New Issue
Block a user