Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/core/documents-manager.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
namespace Elementor\Core;
3
+
4
+
use Elementor\Core\Base\Document;
5
+
use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
6
+
use Elementor\Core\DocumentTypes\Page;
7
+
use Elementor\Core\DocumentTypes\Post;
8
+
use Elementor\Plugin;
9
+
use Elementor\TemplateLibrary\Source_Local;
10
+
use Elementor\Utils;
11
+
12
+
if ( ! defined( 'ABSPATH' ) ) {
13
+
exit; // Exit if accessed directly.
14
+
}
15
+
16
+
/**
17
+
* Elementor documents manager.
18
+
*
19
+
* Elementor documents manager handler class is responsible for registering and
20
+
* managing Elementor documents.
21
+
*
22
+
* @since 2.0.0
23
+
*/
24
+
class Documents_Manager {
25
+
26
+
/**
27
+
* Registered types.
28
+
*
29
+
* Holds the list of all the registered types.
30
+
*
31
+
* @since 2.0.0
32
+
* @access protected
33
+
*
34
+
* @var Document[]
35
+
*/
36
+
protected $types = [];
37
+
38
+
/**
39
+
* Registered documents.
40
+
*
41
+
* Holds the list of all the registered documents.
42
+
*
43
+
* @since 2.0.0
44
+
* @access protected
45
+
*
46
+
* @var Document[]
47
+
*/
48
+
protected $documents = [];
49
+
50
+
/**
51
+
* Current document.
52
+
*
53
+
* Holds the current document.
54
+
*
55
+
* @since 2.0.0
56
+
* @access protected
57
+
*
58
+
* @var Document
59
+
*/
60
+
protected $current_doc;
61
+
62
+
/**
63
+
* Switched data.
64
+
*
65
+
* Holds the current document when changing to the requested post.
66
+
*
67
+
* @since 2.0.0
68
+
* @access protected
69
+
*
70
+
* @var array
71
+
*/
72
+
protected $switched_data = [];
73
+
74
+
protected $cpt = [];
75
+
76
+
/**
77
+
* Documents manager constructor.
78
+
*
79
+
* Initializing the Elementor documents manager.
80
+
*
81
+
* @since 2.0.0
82
+
* @access public
83
+
*/
84
+
public function __construct() {
85
+
add_action( 'elementor/documents/register', [ $this, 'register_default_types' ], 0 );
86
+
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
87
+
add_filter( 'post_row_actions', [ $this, 'filter_post_row_actions' ], 11, 2 );
88
+
add_filter( 'page_row_actions', [ $this, 'filter_post_row_actions' ], 11, 2 );
89
+
add_filter( 'user_has_cap', [ $this, 'remove_user_edit_cap' ], 10, 3 );
90
+
add_filter( 'elementor/editor/localize_settings', [ $this, 'localize_settings' ] );
91
+
add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
92
+
}
93
+
94
+
/**
95
+
* Register ajax actions.
96
+
*
97
+
* Process ajax action handles when saving data and discarding changes.
98
+
*
99
+
* Fired by `elementor/ajax/register_actions` action.
100
+
*
101
+
* @since 2.0.0
102
+
* @access public
103
+
*
104
+
* @param Ajax $ajax_manager An instance of the ajax manager.
105
+
*/
106
+
public function register_ajax_actions( $ajax_manager ) {
107
+
$ajax_manager->register_ajax_action( 'save_builder', [ $this, 'ajax_save' ] );
108
+
$ajax_manager->register_ajax_action( 'discard_changes', [ $this, 'ajax_discard_changes' ] );
109
+
$ajax_manager->register_ajax_action( 'get_document_config', [ $this, 'ajax_get_document_config' ] );
110
+
}
111
+
112
+
/**
113
+
* Register default types.
114
+
*
115
+
* Registers the default document types.
116
+
*
117
+
* @since 2.0.0
118
+
* @access public
119
+
*/
120
+
public function register_default_types() {
121
+
$default_types = [
122
+
'post' => Post::get_class_full_name(), // BC.
123
+
'wp-post' => Post::get_class_full_name(),
124
+
'wp-page' => Page::get_class_full_name(),
125
+
];
126
+
127
+
foreach ( $default_types as $type => $class ) {
128
+
$this->register_document_type( $type, $class );
129
+
}
130
+
}
131
+
132
+
/**
133
+
* Register document type.
134
+
*
135
+
* Registers a single document.
136
+
*
137
+
* @since 2.0.0
138
+
* @access public
139
+
*
140
+
* @param string $type Document type name.
141
+
* @param string $class_name The name of the class that registers the document type.
142
+
* Full name with the namespace.
143
+
*
144
+
* @return Documents_Manager The updated document manager instance.
145
+
*/
146
+
public function register_document_type( $type, $class_name ) {
147
+
$this->types[ $type ] = $class_name;
148
+
149
+
$cpt = $class_name::get_property( 'cpt' );
150
+
151
+
if ( $cpt ) {
152
+
foreach ( $cpt as $post_type ) {
153
+
$this->cpt[ $post_type ] = $type;
154
+
}
155
+
}
156
+
157
+
if ( $class_name::get_property( 'register_type' ) ) {
158
+
Source_Local::add_template_type( $type );
159
+
}
160
+
161
+
return $this;
162
+
}
163
+
164
+
/**
165
+
* Get document.
166
+
*
167
+
* Retrieve the document data based on a post ID.
168
+
*
169
+
* @since 2.0.0
170
+
* @access public
171
+
*
172
+
* @param int $post_id Post ID.
173
+
* @param bool $from_cache Optional. Whether to retrieve cached data. Default is true.
174
+
*
175
+
* @return false|Document Document data or false if post ID was not entered.
176
+
*/
177
+
public function get( $post_id, $from_cache = true ) {
178
+
$this->register_types();
179
+
180
+
$post_id = absint( $post_id );
181
+
182
+
if ( ! $post_id || ! get_post( $post_id ) ) {
183
+
return false;
184
+
}
185
+
186
+
/**
187
+
* Retrieve document post ID.
188
+
*
189
+
* Filters the document post ID.
190
+
*
191
+
* @since 2.0.7
192
+
*
193
+
* @param int $post_id The post ID of the document.
194
+
*/
195
+
$post_id = apply_filters( 'elementor/documents/get/post_id', $post_id );
196
+
197
+
if ( ! $from_cache || ! isset( $this->documents[ $post_id ] ) ) {
198
+
$doc_type = $this->get_doc_type_by_id( $post_id );
199
+
$doc_type_class = $this->get_document_type( $doc_type );
200
+
201
+
$this->documents[ $post_id ] = new $doc_type_class( [
202
+
'post_id' => $post_id,
203
+
] );
204
+
}
205
+
206
+
return $this->documents[ $post_id ];
207
+
}
208
+
209
+
/**
210
+
* Retrieve a document after checking it exist and allowed to edit.
211
+
*
212
+
* @param string $id
213
+
* @return Document
214
+
* @throws \Exception If the document is not found or the current user is not allowed to edit it.
215
+
* @since 3.13.0
216
+
*/
217
+
public function get_with_permissions( $id ): Document {
218
+
$document = $this->get( $id );
219
+
220
+
if ( ! $document ) {
221
+
throw new \Exception( 'Not found.' );
222
+
}
223
+
224
+
if ( ! $document->is_editable_by_current_user() ) {
225
+
throw new \Exception( 'Access denied.' );
226
+
}
227
+
228
+
return $document;
229
+
}
230
+
231
+
/**
232
+
* A `void` version for `get_with_permissions`.
233
+
*
234
+
* @param string $id
235
+
* @return void
236
+
* @throws \Exception If the document is not found or the current user is not allowed to edit it.
237
+
*/
238
+
public function check_permissions( $id ) {
239
+
$this->get_with_permissions( $id );
240
+
}
241
+
242
+
/**
243
+
* Get document or autosave.
244
+
*
245
+
* Retrieve either the document or the autosave.
246
+
*
247
+
* @since 2.0.0
248
+
* @access public
249
+
*
250
+
* @param int $id Optional. Post ID. Default is `0`.
251
+
* @param int $user_id Optional. User ID. Default is `0`.
252
+
*
253
+
* @return false|Document The document if it exist, False otherwise.
254
+
*/
255
+
public function get_doc_or_auto_save( $id, $user_id = 0 ) {
256
+
$document = $this->get( $id );
257
+
if ( $document && $document->get_autosave_id( $user_id ) ) {
258
+
$document = $document->get_autosave( $user_id );
259
+
}
260
+
261
+
return $document;
262
+
}
263
+
264
+
/**
265
+
* Get document for frontend.
266
+
*
267
+
* Retrieve the document for frontend use.
268
+
*
269
+
* @since 2.0.0
270
+
* @access public
271
+
*
272
+
* @param int $post_id Optional. Post ID. Default is `0`.
273
+
*
274
+
* @return false|Document The document if it exist, False otherwise.
275
+
*/
276
+
public function get_doc_for_frontend( $post_id ) {
277
+
$preview_id = (int) Utils::get_super_global_value( $_GET, 'preview_id' );
278
+
$is_preview = is_preview() && $post_id === $preview_id;
279
+
$is_nonce_verify = wp_verify_nonce( Utils::get_super_global_value( $_GET, 'preview_nonce' ), 'post_preview_' . $preview_id );
280
+
281
+
if ( ( $is_preview && $is_nonce_verify ) || Plugin::$instance->preview->is_preview_mode() ) {
282
+
$document = $this->get_doc_or_auto_save( $post_id, get_current_user_id() );
283
+
} else {
284
+
$document = $this->get( $post_id );
285
+
}
286
+
287
+
return $document;
288
+
}
289
+
290
+
/**
291
+
* Get document type.
292
+
*
293
+
* Retrieve the type of any given document.
294
+
*
295
+
* @since 2.0.0
296
+
* @access public
297
+
*
298
+
* @param string $type
299
+
*
300
+
* @param string $fallback
301
+
*
302
+
* @return Document|bool The type of the document.
303
+
*/
304
+
public function get_document_type( $type, $fallback = 'post' ) {
305
+
$types = $this->get_document_types();
306
+
307
+
if ( isset( $types[ $type ] ) ) {
308
+
return $types[ $type ];
309
+
}
310
+
311
+
if ( isset( $types[ $fallback ] ) ) {
312
+
return $types[ $fallback ];
313
+
}
314
+
315
+
return false;
316
+
}
317
+
318
+
/**
319
+
* Get document types.
320
+
*
321
+
* Retrieve the all the registered document types.
322
+
*
323
+
* @since 2.0.0
324
+
* @access public
325
+
*
326
+
* @param array $args Optional. An array of key => value arguments to match against
327
+
* the properties. Default is empty array.
328
+
* @param string $operator Optional. The logical operation to perform. 'or' means only one
329
+
* element from the array needs to match; 'and' means all elements
330
+
* must match; 'not' means no elements may match. Default 'and'.
331
+
*
332
+
* @return Document[] All the registered document types.
333
+
*/
334
+
public function get_document_types( $args = [], $operator = 'and' ) {
335
+
$this->register_types();
336
+
337
+
if ( ! empty( $args ) ) {
338
+
$types_properties = $this->get_types_properties();
339
+
340
+
$filtered = wp_filter_object_list( $types_properties, $args, $operator );
341
+
342
+
return array_intersect_key( $this->types, $filtered );
343
+
}
344
+
345
+
return $this->types;
346
+
}
347
+
348
+
/**
349
+
* Get document types with their properties.
350
+
*
351
+
* @return array A list of properties arrays indexed by the type.
352
+
*/
353
+
public function get_types_properties() {
354
+
$types_properties = [];
355
+
356
+
foreach ( $this->get_document_types() as $type => $class ) {
357
+
$types_properties[ $type ] = $class::get_properties();
358
+
}
359
+
return $types_properties;
360
+
}
361
+
362
+
/**
363
+
* Create a document.
364
+
*
365
+
* Create a new document using any given parameters.
366
+
*
367
+
* @since 2.0.0
368
+
* @access public
369
+
*
370
+
* @param string $type Document type.
371
+
* @param array $post_data An array containing the post data.
372
+
* @param array $meta_data An array containing the post meta data.
373
+
*
374
+
* @return Document The type of the document.
375
+
*/
376
+
public function create( $type, $post_data = [], $meta_data = [] ) {
377
+
$class = $this->get_document_type( $type, false );
378
+
379
+
if ( ! $class ) {
380
+
return new \WP_Error( 500, sprintf( 'Type %s does not exist.', $type ) );
381
+
}
382
+
383
+
if ( empty( $post_data['post_title'] ) ) {
384
+
$post_data['post_title'] = esc_html__( 'Elementor', 'elementor' );
385
+
if ( 'post' !== $type ) {
386
+
$post_data['post_title'] = sprintf(
387
+
/* translators: %s: Document title. */
388
+
__( 'Elementor %s', 'elementor' ),
389
+
call_user_func( [ $class, 'get_title' ] )
390
+
);
391
+
}
392
+
$update_title = true;
393
+
}
394
+
395
+
$meta_data['_elementor_edit_mode'] = 'builder';
396
+
397
+
// Save the type as-is for plugins that hooked at `wp_insert_post`.
398
+
$meta_data[ Document::TYPE_META_KEY ] = $type;
399
+
400
+
$post_data['meta_input'] = $meta_data;
401
+
402
+
$post_types = $class::get_property( 'cpt' );
403
+
404
+
if ( ! empty( $post_types[0] ) && empty( $post_data['post_type'] ) ) {
405
+
$post_data['post_type'] = $post_types[0];
406
+
}
407
+
408
+
$post_id = wp_insert_post( $post_data );
409
+
410
+
if ( ! empty( $update_title ) ) {
411
+
$post_data['ID'] = $post_id;
412
+
$post_data['post_title'] .= ' #' . $post_id;
413
+
414
+
// The meta doesn't need update.
415
+
unset( $post_data['meta_input'] );
416
+
417
+
wp_update_post( $post_data );
418
+
}
419
+
420
+
/** @var Document $document */
421
+
$document = new $class( [
422
+
'post_id' => $post_id,
423
+
] );
424
+
425
+
// Let the $document to re-save the template type by his way + version.
426
+
$document->save( [] );
427
+
428
+
return $document;
429
+
}
430
+
431
+
/**
432
+
* Remove user edit capabilities if document is not editable.
433
+
*
434
+
* Filters the user capabilities to disable editing in admin.
435
+
*
436
+
* @param array $allcaps An array of all the user's capabilities.
437
+
* @param array $caps Actual capabilities for meta capability.
438
+
* @param array $args Optional parameters passed to has_cap(), typically object ID.
439
+
*
440
+
* @return array
441
+
*/
442
+
public function remove_user_edit_cap( $allcaps, $caps, $args ) {
443
+
global $pagenow;
444
+
445
+
if ( ! in_array( $pagenow, [ 'post.php', 'edit.php' ], true ) ) {
446
+
return $allcaps;
447
+
}
448
+
449
+
// Don't touch not existing or not allowed caps.
450
+
if ( empty( $caps[0] ) || empty( $allcaps[ $caps[0] ] ) ) {
451
+
return $allcaps;
452
+
}
453
+
454
+
$capability = $args[0];
455
+
456
+
if ( 'edit_post' !== $capability ) {
457
+
return $allcaps;
458
+
}
459
+
460
+
if ( empty( $args[2] ) ) {
461
+
return $allcaps;
462
+
}
463
+
464
+
$post_id = $args[2];
465
+
466
+
$document = Plugin::$instance->documents->get( $post_id );
467
+
468
+
if ( ! $document ) {
469
+
return $allcaps;
470
+
}
471
+
472
+
$allcaps[ $caps[0] ] = $document::get_property( 'is_editable' );
473
+
474
+
return $allcaps;
475
+
}
476
+
477
+
/**
478
+
* Filter Post Row Actions.
479
+
*
480
+
* Let the Document to filter the array of row action links on the Posts list table.
481
+
*
482
+
* @param array $actions
483
+
* @param \WP_Post $post
484
+
*
485
+
* @return array
486
+
*/
487
+
public function filter_post_row_actions( $actions, $post ) {
488
+
$document = $this->get( $post->ID );
489
+
490
+
if ( $document ) {
491
+
$actions = $document->filter_admin_row_actions( $actions );
492
+
}
493
+
494
+
return $actions;
495
+
}
496
+
497
+
/**
498
+
* Save document data using ajax.
499
+
*
500
+
* Save the document on the builder using ajax, when saving the changes, and refresh the editor.
501
+
*
502
+
* @since 2.0.0
503
+
* @access public
504
+
*
505
+
* @param array $request Post ID.
506
+
*
507
+
* @throws \Exception If current user don't have permissions to edit the post or the post is not using Elementor.
508
+
*
509
+
* @return array The document data after saving.
510
+
*/
511
+
public function ajax_save( $request ) {
512
+
$document = $this->get( $request['editor_post_id'] );
513
+
514
+
if ( ! $document->is_built_with_elementor() || ! $document->is_editable_by_current_user() ) {
515
+
throw new \Exception( 'Access denied.' );
516
+
}
517
+
518
+
$this->switch_to_document( $document );
519
+
520
+
// Set the post as global post.
521
+
Plugin::$instance->db->switch_to_post( $document->get_post()->ID );
522
+
523
+
$status = Document::STATUS_DRAFT;
524
+
525
+
if ( isset( $request['status'] ) && in_array( $request['status'], [ Document::STATUS_PUBLISH, Document::STATUS_PRIVATE, Document::STATUS_PENDING, Document::STATUS_AUTOSAVE ], true ) ) {
526
+
$status = $request['status'];
527
+
}
528
+
529
+
if ( Document::STATUS_AUTOSAVE === $status ) {
530
+
// If the post is a draft - save the `autosave` to the original draft.
531
+
// Allow a revision only if the original post is already published.
532
+
if ( in_array( $document->get_post()->post_status, [ Document::STATUS_PUBLISH, Document::STATUS_PRIVATE ], true ) ) {
533
+
$document = $document->get_autosave( 0, true );
534
+
}
535
+
}
536
+
537
+
// Set default page template because the footer-saver doesn't send default values,
538
+
// But if the template was changed from canvas to default - it needed to save.
539
+
if ( Utils::is_cpt_custom_templates_supported() && ! isset( $request['settings']['template'] ) ) {
540
+
$request['settings']['template'] = 'default';
541
+
}
542
+
543
+
$data = [
544
+
'elements' => $request['elements'],
545
+
'settings' => $request['settings'],
546
+
];
547
+
548
+
$document->save( $data );
549
+
550
+
$post = $document->get_post();
551
+
$main_post = $document->get_main_post();
552
+
553
+
// Refresh after save.
554
+
$document = $this->get( $post->ID, false );
555
+
556
+
$return_data = [
557
+
'status' => $post->post_status,
558
+
'config' => [
559
+
'document' => [
560
+
'last_edited' => $document->get_last_edited(),
561
+
'urls' => [
562
+
'wp_preview' => $document->get_wp_preview_url(),
563
+
],
564
+
],
565
+
],
566
+
];
567
+
568
+
$post_status_object = get_post_status_object( $main_post->post_status );
569
+
570
+
if ( $post_status_object ) {
571
+
$return_data['config']['document']['status'] = [
572
+
'value' => $post_status_object->name,
573
+
'label' => $post_status_object->label,
574
+
];
575
+
}
576
+
577
+
/**
578
+
* Returned documents ajax saved data.
579
+
*
580
+
* Filters the ajax data returned when saving the post on the builder.
581
+
*
582
+
* @since 2.0.0
583
+
*
584
+
* @param array $return_data The returned data.
585
+
* @param Document $document The document instance.
586
+
*/
587
+
$return_data = apply_filters( 'elementor/documents/ajax_save/return_data', $return_data, $document );
588
+
589
+
return $return_data;
590
+
}
591
+
592
+
/**
593
+
* Ajax discard changes.
594
+
*
595
+
* Load the document data from an autosave, deleting unsaved changes.
596
+
*
597
+
* @param array $request
598
+
*
599
+
* @return bool True if changes discarded, False otherwise.
600
+
* @throws \Exception If current user don't have permissions to edit the post or the post is not using Elementor.
601
+
*
602
+
* @since 2.0.0
603
+
* @access public
604
+
*/
605
+
public function ajax_discard_changes( $request ) {
606
+
$document = $this->get_with_permissions( $request['editor_post_id'] );
607
+
608
+
$autosave = $document->get_autosave();
609
+
610
+
if ( $autosave ) {
611
+
$success = $autosave->delete();
612
+
} else {
613
+
$success = true;
614
+
}
615
+
616
+
return $success;
617
+
}
618
+
619
+
public function ajax_get_document_config( $request ) {
620
+
$post_id = absint( $request['id'] );
621
+
622
+
Plugin::$instance->editor->set_post_id( $post_id );
623
+
624
+
$document = $this->get_doc_or_auto_save( $post_id );
625
+
626
+
if ( ! $document ) {
627
+
throw new \Exception( 'Not found.' );
628
+
}
629
+
630
+
if ( ! $document->is_editable_by_current_user() ) {
631
+
throw new \Exception( 'Access denied.' );
632
+
}
633
+
634
+
// Set the global data like $post, $authordata and etc
635
+
Plugin::$instance->db->switch_to_post( $post_id );
636
+
637
+
$this->switch_to_document( $document );
638
+
639
+
// Change mode to Builder
640
+
$document->set_is_built_with_elementor( true );
641
+
642
+
$doc_config = $document->get_config();
643
+
644
+
return $doc_config;
645
+
}
646
+
647
+
/**
648
+
* Switch to document.
649
+
*
650
+
* Change the document to any new given document type.
651
+
*
652
+
* @since 2.0.0
653
+
* @access public
654
+
*
655
+
* @param Document $document The document to switch to.
656
+
*/
657
+
public function switch_to_document( $document ) {
658
+
// If is already switched, or is the same post, return.
659
+
if ( $this->current_doc === $document ) {
660
+
$this->switched_data[] = false;
661
+
return;
662
+
}
663
+
664
+
$this->switched_data[] = [
665
+
'switched_doc' => $document,
666
+
'original_doc' => $this->current_doc, // Note, it can be null if the global isn't set
667
+
];
668
+
669
+
$this->current_doc = $document;
670
+
}
671
+
672
+
/**
673
+
* Restore document.
674
+
*
675
+
* Rollback to the original document.
676
+
*
677
+
* @since 2.0.0
678
+
* @access public
679
+
*/
680
+
public function restore_document() {
681
+
$data = array_pop( $this->switched_data );
682
+
683
+
// If not switched, return.
684
+
if ( ! $data ) {
685
+
return;
686
+
}
687
+
688
+
$this->current_doc = $data['original_doc'];
689
+
}
690
+
691
+
/**
692
+
* Get current document.
693
+
*
694
+
* Retrieve the current document.
695
+
*
696
+
* @since 2.0.0
697
+
* @access public
698
+
*
699
+
* @return Document The current document.
700
+
*/
701
+
public function get_current() {
702
+
return $this->current_doc;
703
+
}
704
+
705
+
public function localize_settings( $settings ) {
706
+
$translations = [];
707
+
708
+
foreach ( $this->get_document_types() as $type => $class ) {
709
+
$translations[ $type ] = $class::get_title();
710
+
}
711
+
712
+
return array_replace_recursive( $settings, [
713
+
'i18n' => $translations,
714
+
] );
715
+
}
716
+
717
+
private function register_types() {
718
+
if ( ! did_action( 'elementor/documents/register' ) ) {
719
+
/**
720
+
* Register Elementor documents.
721
+
*
722
+
* @since 2.0.0
723
+
*
724
+
* @param Documents_Manager $this The document manager instance.
725
+
*/
726
+
do_action( 'elementor/documents/register', $this );
727
+
}
728
+
}
729
+
730
+
/**
731
+
* Get create new post URL.
732
+
*
733
+
* Retrieve a custom URL for creating a new post/page using Elementor.
734
+
*
735
+
* @param string $post_type Optional. Post type slug. Default is 'page'.
736
+
* @param string|null $template_type Optional. Query arg 'template_type'. Default is null.
737
+
*
738
+
* @return string A URL for creating new post using Elementor.
739
+
*/
740
+
public static function get_create_new_post_url( $post_type = 'page', $template_type = null ) {
741
+
$query_args = [
742
+
'action' => 'elementor_new_post',
743
+
'post_type' => $post_type,
744
+
];
745
+
746
+
if ( $template_type ) {
747
+
$query_args['template_type'] = $template_type;
748
+
}
749
+
750
+
$new_post_url = add_query_arg( $query_args, admin_url( 'edit.php' ) );
751
+
752
+
$new_post_url = add_query_arg( '_wpnonce', wp_create_nonce( 'elementor_action_new_post' ), $new_post_url );
753
+
754
+
return $new_post_url;
755
+
}
756
+
757
+
private function get_doc_type_by_id( $post_id ) {
758
+
// Auto-save inherits from the original post.
759
+
if ( wp_is_post_autosave( $post_id ) ) {
760
+
$post_id = wp_get_post_parent_id( $post_id );
761
+
}
762
+
763
+
// Content built with Elementor.
764
+
$template_type = get_post_meta( $post_id, Document::TYPE_META_KEY, true );
765
+
766
+
if ( $template_type && isset( $this->types[ $template_type ] ) ) {
767
+
return $template_type;
768
+
}
769
+
770
+
// Elementor installation on a site with existing content (which doesn't contain Elementor's meta).
771
+
$post_type = get_post_type( $post_id );
772
+
773
+
return $this->cpt[ $post_type ] ?? 'post';
774
+
}
775
+
776
+
public function register_rest_routes() {
777
+
register_rest_route('elementor/v1/documents', '/(?P<id>\d+)/media/import', [
778
+
'methods' => \WP_REST_Server::CREATABLE,
779
+
'callback' => function( $request ) {
780
+
$post_id = $request->get_param( 'id' );
781
+
782
+
try {
783
+
$document = $this->get_with_permissions( $post_id );
784
+
785
+
$elements_data = $document->get_elements_data();
786
+
787
+
$import_data = $document->get_import_data( [
788
+
'content' => $elements_data,
789
+
] );
790
+
791
+
$document->save( [
792
+
'elements' => $import_data['content'],
793
+
] );
794
+
795
+
return new \WP_REST_Response( [
796
+
'success' => true,
797
+
'document_saved' => true,
798
+
], 200 );
799
+
800
+
} catch ( \Exception $e ) {
801
+
return new \WP_Error(
802
+
'elementor_import_error',
803
+
$e->getMessage(),
804
+
[ 'status' => 500 ]
805
+
);
806
+
}
807
+
},
808
+
'permission_callback' => function() {
809
+
return current_user_can( 'manage_options' );
810
+
},
811
+
'args' => [
812
+
'id' => [
813
+
'required' => true,
814
+
'validate_callback' => function( $param ) {
815
+
return is_numeric( $param );
816
+
},
817
+
],
818
+
],
819
+
]);
820
+
}
821
+
}
822
+