PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta3
Elementor Website Builder – more than just a page builder v4.3.0-beta3
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
← All changes | core/utils/document/document-mutator.php +83 -4 4.3.0-beta14.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