← All changes
|
core/utils/document/document-mutator.php
+83
-4
4.3.0-beta1
→
4.3.0-beta3
View file →
| @@ -182,14 +182,33 @@ | ||
| 182 | 182 | return $this->insert_subtree( $tree, $parent_id, $index + 1, $node ); |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | 185 | /** |
| 186 | - * Save an elements tree to a document, downgrading `publish` to `draft` | |
| 187 | - * first so no live changes leak out. | |
| 186 | + * Save an elements tree to a document. | |
| 188 | 187 | * |
| 189 | - * @return true|int|\WP_Error | |
| 188 | + * Default behavior (backwards compatible): downgrade a `publish` post to `draft` | |
| 189 | + * before saving so no live changes leak out, then save on the main document. | |
| 190 | + * | |
| 191 | + * When `$preserve_live_status` is true: the main post status is kept intact and | |
| 192 | + * writes on `publish`/`private` posts are redirected to an autosave revision | |
| 193 | + * (mirroring the editor's in-app "Save as Draft" flow) so the live page keeps | |
| 194 | + * serving the previous version until the user opens the editor and publishes. | |
| 195 | + * In this mode the return value is the Document actually written on success. | |
| 196 | + * | |
| 197 | + * @return bool|Document|\WP_Error | |
| 190 | 198 | */ |
| 191 | - public function save_as_draft( Document $document, array $elements ) { | |
| 199 | + public function save_as_draft( Document $document, array $elements, bool $preserve_live_status = false ) { | |
| 200 | + if ( $preserve_live_status ) { | |
| 201 | + return $this->save_preserving_live_status( $document, $elements ); | |
| 202 | + } | |
| 203 | + | |
| 204 | + return $this->save_downgrading_publish_to_draft( $document, $elements ); | |
| 205 | + } | |
| 206 | + | |
| 207 | + /** | |
| 208 | + * @return bool|int|\WP_Error | |
| 209 | + */ | |
| 210 | + private function save_downgrading_publish_to_draft( Document $document, array $elements ) { | |
| 192 | 211 | if ( 'publish' === get_post_status( $document->get_main_id() ) ) { |
| 193 | 212 | wp_update_post( [ |
| 194 | 213 | 'ID' => $document->get_main_id(), |
| 195 | 214 | 'post_status' => 'draft', |
| @@ -196,8 +215,68 @@ | ||
| 196 | 215 | ] ); |
| 197 | 216 | } |
| 198 | 217 | |
| 199 | 218 | return $document->save( [ 'elements' => $elements ] ); |
| 219 | + } | |
| 220 | + | |
| 221 | + /** | |
| 222 | + * @return Document|\WP_Error | |
| 223 | + */ | |
| 224 | + private function save_preserving_live_status( Document $document, array $elements ) { | |
| 225 | + $target = $this->resolve_autosave_target( $document ); | |
| 226 | + | |
| 227 | + if ( is_wp_error( $target ) ) { | |
| 228 | + return $target; | |
| 229 | + } | |
| 230 | + | |
| 231 | + $saved = $target->save( [ 'elements' => $elements ] ); | |
| 232 | + | |
| 233 | + if ( is_wp_error( $saved ) ) { | |
| 234 | + return $saved; | |
| 235 | + } | |
| 236 | + | |
| 237 | + if ( ! $saved ) { | |
| 238 | + return new \WP_Error( | |
| 239 | + 'elementor_save_failed', | |
| 240 | + __( 'Could not save document.', 'elementor' ), | |
| 241 | + [ 'status' => \WP_Http::INTERNAL_SERVER_ERROR ] | |
| 242 | + ); | |
| 243 | + } | |
| 244 | + | |
| 245 | + return $target; | |
| 246 | + } | |
| 247 | + | |
| 248 | + /** | |
| 249 | + * @return Document|\WP_Error | |
| 250 | + */ | |
| 251 | + private function resolve_autosave_target( Document $document ) { | |
| 252 | + $main_document = Plugin::$instance->documents->get( $document->get_main_id() ); | |
| 253 | + | |
| 254 | + if ( ! $main_document instanceof Document ) { | |
| 255 | + return new \WP_Error( | |
| 256 | + 'elementor_not_found', | |
| 257 | + __( 'Post not found.', 'elementor' ), | |
| 258 | + [ 'status' => \WP_Http::NOT_FOUND ] | |
| 259 | + ); | |
| 260 | + } | |
| 261 | + | |
| 262 | + $main_status = get_post_status( $main_document->get_main_id() ); | |
| 263 | + | |
| 264 | + if ( ! in_array( $main_status, [ 'publish', 'private' ], true ) ) { | |
| 265 | + return $main_document; | |
| 266 | + } | |
| 267 | + | |
| 268 | + $autosave = $main_document->get_autosave( 0, true ); | |
| 269 | + | |
| 270 | + if ( ! $autosave instanceof Document ) { | |
| 271 | + return new \WP_Error( | |
| 272 | + 'elementor_autosave_failed', | |
| 273 | + __( 'Could not create autosave revision.', 'elementor' ), | |
| 274 | + [ 'status' => \WP_Http::INTERNAL_SERVER_ERROR ] | |
| 275 | + ); | |
| 276 | + } | |
| 277 | + | |
| 278 | + return $autosave; | |
| 200 | 279 | } |
| 201 | 280 | |
| 202 | 281 | /** |
| 203 | 282 | * @return array|\WP_Error |