PluginProbe
Elementor Website Builder – more than just a page builder / 3.10.1
Elementor Website Builder – more than just a page builder v3.10.1
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 4.0.7 All 451 releases
elementor / app / modules / import-export / module.php

module.php in Elementor Website Builder – more than just a page builder 3.10.1, at app/modules/import-export/module.php

746 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\App\Modules\ImportExport;
3
4 use Elementor\App\Modules\ImportExport\Processes\Export;
5 use Elementor\App\Modules\ImportExport\Processes\Import;
6 use Elementor\App\Modules\ImportExport\Processes\Revert;
7 use Elementor\Core\Base\Module as BaseModule;
8 use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
9 use Elementor\Core\Files\Uploads_Manager;
10 use Elementor\Modules\System_Info\Reporters\Server;
11 use Elementor\Plugin;
12 use Elementor\Tools;
13 use Elementor\Utils as ElementorUtils;
14 use Elementor\App\Modules\ImportExport\Utils as ImportExportUtils;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit if accessed directly
18 }
19
20 /**
21 * Import Export Module
22 *
23 * Responsible for initializing Elementor App functionality
24 */
25 class Module extends BaseModule {
26 const FORMAT_VERSION = '2.0';
27
28 const EXPORT_TRIGGER_KEY = 'elementor_export_kit';
29
30 const UPLOAD_TRIGGER_KEY = 'elementor_upload_kit';
31
32 const IMPORT_TRIGGER_KEY = 'elementor_import_kit';
33
34 const IMPORT_RUNNER_TRIGGER_KEY = 'elementor_import_kit__runner';
35
36 const REFERRER_KIT_LIBRARY = 'kit-library';
37
38 const REFERRER_LOCAL = 'local';
39
40 const PERMISSIONS_ERROR_KEY = 'plugin-installation-permissions-error';
41
42 const NO_WRITE_PERMISSIONS_KEY = 'no-write-permissions';
43
44 const OPTION_KEY_ELEMENTOR_IMPORT_SESSIONS = 'elementor_import_sessions';
45
46 const OPTION_KEY_ELEMENTOR_REVERT_SESSIONS = 'elementor_revert_sessions';
47
48 const META_KEY_ELEMENTOR_IMPORT_SESSION_ID = '_elementor_import_session_id';
49
50 const META_KEY_ELEMENTOR_EDIT_MODE = '_elementor_edit_mode';
51
52 /**
53 * Assigning the export process to a property, so we can use the process from outside the class.
54 *
55 * @var Export
56 */
57 public $export;
58
59 /**
60 * Assigning the import process to a property, so we can use the process from outside the class.
61 *
62 * @var Import
63 */
64 public $import;
65
66 /**
67 * Assigning the revert process to a property, so we can use the process from outside the class.
68 *
69 * @var Revert
70 */
71 public $revert;
72
73 /**
74 * Get name.
75 *
76 * @access public
77 *
78 * @return string
79 */
80 public function get_name() {
81 return 'import-export';
82 }
83
84 public function __construct() {
85 $this->register_actions();
86
87 if ( ElementorUtils::is_wp_cli() ) {
88 \WP_CLI::add_command( 'elementor kit', WP_CLI::class );
89 }
90
91 ( new Usage() )->register();
92 }
93
94 public function get_init_settings() {
95 if ( ! Plugin::$instance->app->is_current() ) {
96 return [];
97 }
98
99 return $this->get_config_data();
100 }
101
102 /**
103 * Register the import/export tab in elementor tools.
104 */
105 public function register_settings_tab( Tools $tools ) {
106 $tools->add_tab( 'import-export-kit', [
107 'label' => esc_html__( 'Import / Export Kit', 'elementor' ),
108 'sections' => [
109 'intro' => [
110 'label' => esc_html__( 'Template Kits', 'elementor' ),
111 'callback' => function() {
112 $this->render_import_export_tab_content();
113 },
114 'fields' => [],
115 ],
116 ],
117 ] );
118 }
119
120 /**
121 * Render the import/export tab content.
122 */
123 private function render_import_export_tab_content() {
124 $intro_text_link = sprintf( '<a href="https://go.elementor.com/wp-dash-import-export-general/" target="_blank">%s</a>', esc_html__( 'Learn more', 'elementor' ) );
125
126 $intro_text = sprintf(
127 /* translators: 1: New line break, 2: Learn More link. */
128 __( 'Design sites faster with a template kit that contains some or all components of a complete site, like templates, content & site settings.%1$sYou can import a kit and apply it to your site, or export the elements from this site to be used anywhere else. %2$s', 'elementor' ),
129 '<br>',
130 $intro_text_link
131 );
132
133 $content_data = [
134 'export' => [
135 'title' => esc_html__( 'Export a Template Kit', 'elementor' ),
136 'button' => [
137 'url' => Plugin::$instance->app->get_base_url() . '#/export',
138 'text' => esc_html__( 'Start Export', 'elementor' ),
139 ],
140 'description' => esc_html__( 'Bundle your whole site - or just some of its elements - to be used for another website.', 'elementor' ),
141 'link' => [
142 'url' => 'https://go.elementor.com/wp-dash-import-export-export-flow/',
143 'text' => esc_html__( 'Learn More', 'elementor' ),
144 ],
145 ],
146 'import' => [
147 'title' => esc_html__( 'Import a Template Kit', 'elementor' ),
148 'button' => [
149 'url' => Plugin::$instance->app->get_base_url() . '#/import',
150 'text' => esc_html__( 'Start Import', 'elementor' ),
151 ],
152 'description' => esc_html__( 'Apply the design and settings of another site to this one.', 'elementor' ),
153 'link' => [
154 'url' => 'https://go.elementor.com/wp-dash-import-export-import-flow/',
155 'text' => esc_html__( 'Learn More', 'elementor' ),
156 ],
157 ],
158 ];
159
160 $this->revert = new Revert();
161 $last_imported_kit = $this->revert->get_last_import_session();
162 $penultimate_imported_kit = $this->revert->get_penultimate_import_session();
163
164 $user_date_format = get_option( 'date_format' );
165 $user_time_format = get_option( 'time_format' );
166 $date_format = $user_date_format . ' ' . $user_time_format;
167
168 $should_show_revert_section = $this->should_show_revert_section( $last_imported_kit );
169
170 if ( $should_show_revert_section ) {
171 if ( ! empty( $penultimate_imported_kit ) ) {
172 $revert_text = sprintf(
173 esc_html__( 'Remove all the content and site settings that came with "%1$s" on %2$s %3$s and revert to the site setting that came with "%4$s" on %5$s.', 'elementor' ),
174 ! empty( $last_imported_kit['kit_name'] ) ? $last_imported_kit['kit_name'] : esc_html__( 'imported kit', 'elementor' ),
175 gmdate( $date_format, $last_imported_kit['start_timestamp'] ),
176 '<br>',
177 ! empty( $penultimate_imported_kit['kit_name'] ) ? $penultimate_imported_kit['kit_name'] : esc_html__( 'imported kit', 'elementor' ),
178 gmdate( $date_format, $penultimate_imported_kit['start_timestamp'] )
179 );
180 } else {
181 $revert_text = sprintf(
182 esc_html__( 'Remove all the content and site settings that came with "%1$s" on %2$s.%3$s Your original site settings will be restored.', 'elementor' ),
183 ! empty( $last_imported_kit['kit_name'] ) ? $last_imported_kit['kit_name'] : esc_html__( 'imported kit', 'elementor' ),
184 gmdate( $date_format, $last_imported_kit['start_timestamp'] ),
185 '<br>'
186 );
187 }
188 }
189 ?>
190
191 <div class="tab-import-export-kit__content">
192 <p class="tab-import-export-kit__info"><?php ElementorUtils::print_unescaped_internal_string( $intro_text ); ?></p>
193
194 <div class="tab-import-export-kit__wrapper">
195 <?php foreach ( $content_data as $data ) { ?>
196 <div class="tab-import-export-kit__container">
197 <div class="tab-import-export-kit__box">
198 <h2><?php ElementorUtils::print_unescaped_internal_string( $data['title'] ); ?></h2>
199 <a href="<?php ElementorUtils::print_unescaped_internal_string( $data['button']['url'] ); ?>" class="elementor-button elementor-button-success">
200 <?php ElementorUtils::print_unescaped_internal_string( $data['button']['text'] ); ?>
201 </a>
202 </div>
203 <p><?php ElementorUtils::print_unescaped_internal_string( $data['description'] ); ?></p>
204 <a href="<?php ElementorUtils::print_unescaped_internal_string( $data['link']['url'] ); ?>" target="_blank"><?php ElementorUtils::print_unescaped_internal_string( $data['link']['text'] ); ?></a>
205 </div>
206 <?php } ?>
207 </div>
208
209 <?php
210 if ( $should_show_revert_section ) {
211 $link_attributes = [
212 'href' => wp_nonce_url( admin_url( 'admin-post.php?action=elementor_revert_kit' ), 'elementor_revert_kit' ),
213 'id' => 'elementor-import-export__revert_kit',
214 'class' => 'button',
215 ];
216 ?>
217 <div class="tab-import-export-kit__revert">
218 <h2>
219 <?php ElementorUtils::print_unescaped_internal_string( esc_html__( 'Remove the most recent Kit', 'elementor' ) ); ?>
220 </h2>
221 <p class="tab-import-export-kit__info">
222 <?php ElementorUtils::print_unescaped_internal_string( $revert_text ); ?>
223 </p>
224 <a <?php ElementorUtils::print_html_attributes( $link_attributes ); ?> >
225 <?php ElementorUtils::print_unescaped_internal_string( esc_html__( 'Remove Kit', 'elementor' ) ); ?>
226 </a>
227 </div>
228 <?php } ?>
229 </div>
230 <?php
231 }
232
233 /**
234 * Upload a kit zip file and get the kit data.
235 *
236 * Assigning the Import process to the 'import' property,
237 * so it will be available to use in different places such as: WP_Cli, Pro, etc.
238 *
239 * @param string $file Path to the file.
240 * @param string $referrer Referrer of the file 'local' or 'kit-library'.
241 * @return array
242 * @throws \Exception
243 */
244 public function upload_kit( $file, $referrer ) {
245 $this->ensure_writing_permissions();
246
247 $this->import = new Import( $file, [ 'referrer' => $referrer ] );
248
249 return [
250 'session' => $this->import->get_session_id(),
251 'manifest' => $this->import->get_manifest(),
252 'conflicts' => $this->import->get_settings_conflicts(),
253 ];
254 }
255
256 /**
257 * Import a kit by session_id.
258 * Upload and import a kit by kit zip file.
259 *
260 * If the split_to_chunks flag is true, the process won't start
261 * It will initialize the import process and return the session_id and the runners.
262 *
263 * Assigning the Import process to the 'import' property,
264 * so it will be available to use in different places such as: WP_Cli, Pro, etc.
265 *
266 * @param string $path Path to the file or session_id.
267 * @param array $settings Settings the import use to determine which content to import.
268 * (e.g: include, selected_plugins, selected_cpt, selected_override_conditions, etc.)
269 * @param bool $split_to_chunks Determine if the import process should be split into chunks.
270 * @return array
271 * @throws \Exception
272 */
273 public function import_kit( string $path, array $settings, bool $split_to_chunks = false ): array {
274 $this->ensure_writing_permissions();
275
276 $this->import = new Import( $path, $settings );
277 $this->import->register_default_runners();
278
279 do_action( 'elementor/import-export/import-kit', $this->import );
280
281 if ( $split_to_chunks ) {
282 $this->import->init_import_session();
283
284 return [
285 'session' => $this->import->get_session_id(),
286 'runners' => $this->import->get_runners_name(),
287 ];
288 }
289
290 return $this->import->run();
291 }
292
293 /**
294 * Resuming import process by re-creating the import instance and running the specific runner.
295 *
296 * @param string $session_id The id off the import session.
297 * @param string $runner_name The specific runner that we want to run.
298 *
299 * @return array Two types of response.
300 * 1. The status and the runner name.
301 * 2. The imported data. (Only if the runner is the last one in the import process)
302 * @throws \Exception
303 */
304 public function import_kit_by_runner( string $session_id, string $runner_name ): array {
305 // Check session_id
306 $this->import = Import::from_session( $session_id );
307 $runners = $this->import->get_runners_name();
308
309 $run = $this->import->run_runner( $runner_name );
310
311 if ( end( $runners ) === $run['runner'] ) {
312 return $this->import->get_imported_data();
313 }
314
315 return $run;
316 }
317
318 /**
319 * Export a kit.
320 *
321 * Assigning the Export process to the 'export' property,
322 * so it will be available to use in different places such as: WP_Cli, Pro, etc.
323 *
324 * @param array $settings Settings the export use to determine which content to export.
325 * (e.g: include, kit_info, selected_plugins, selected_cpt, etc.)
326 * @return array
327 * @throws \Exception
328 */
329 public function export_kit( array $settings ) {
330 $this->ensure_writing_permissions();
331
332 $this->export = new Export( $settings );
333 $this->export->register_default_runners();
334
335 do_action( 'elementor/import-export/export-kit', $this->export );
336
337 return $this->export->run();
338 }
339
340 /**
341 * Handle revert kit ajax request.
342 */
343 public function revert_last_imported_kit() {
344 $this->revert = new Revert();
345 $this->revert->register_default_runners();
346
347 do_action( 'elementor/import-export/revert-kit', $this->revert );
348
349 $this->revert->run();
350 }
351
352
353 /**
354 * Handle revert last imported kit ajax request.
355 */
356 public function handle_revert_last_imported_kit() {
357 check_admin_referer( 'elementor_revert_kit' );
358
359 $this->revert_last_imported_kit();
360
361 wp_safe_redirect( admin_url( 'admin.php?page=' . Tools::PAGE_ID . '#tab-import-export-kit' ) );
362 die;
363 }
364
365 /**
366 * Register appropriate actions.
367 */
368 private function register_actions() {
369 add_action( 'admin_init', function() {
370 if ( wp_doing_ajax() &&
371 isset( $_POST['action'] ) &&
372 wp_verify_nonce( ElementorUtils::get_super_global_value( $_POST, '_nonce' ), Ajax::NONCE_KEY ) &&
373 current_user_can( 'manage_options' )
374 ) {
375 $this->maybe_handle_ajax();
376 }
377 } );
378
379 add_action( 'admin_post_elementor_revert_kit', [ $this, 'handle_revert_last_imported_kit' ] );
380
381 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
382
383 $page_id = Tools::PAGE_ID;
384
385 add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_tab' ] );
386 }
387
388 private function ensure_writing_permissions() {
389 $server = new Server();
390
391 $paths_to_check = [
392 Server::KEY_PATH_WP_CONTENT_DIR => $server->get_system_path( Server::KEY_PATH_WP_CONTENT_DIR ),
393 Server::KEY_PATH_UPLOADS_DIR => $server->get_system_path( Server::KEY_PATH_UPLOADS_DIR ),
394 Server::KEY_PATH_ELEMENTOR_UPLOADS_DIR => $server->get_system_path( Server::KEY_PATH_ELEMENTOR_UPLOADS_DIR ),
395 ];
396
397 $permissions = $server->get_paths_permissions( $paths_to_check );
398
399 // WP Content dir has to be exists and writable.
400 if ( ! $permissions[ Server::KEY_PATH_WP_CONTENT_DIR ]['write'] ) {
401 throw new \Error( self::NO_WRITE_PERMISSIONS_KEY . 'in - ' . Server::KEY_PATH_WP_CONTENT_DIR );
402 }
403
404 // WP Uploads dir has to be exists and writable.
405 if ( ! $permissions[ Server::KEY_PATH_UPLOADS_DIR ]['write'] ) {
406 throw new \Error( self::NO_WRITE_PERMISSIONS_KEY . 'in - ' . Server::KEY_PATH_UPLOADS_DIR );
407 }
408
409 // Elementor uploads dir permissions is divided to 2 cases:
410 // 1. If the dir exists, it has to be writable.
411 // 2. If the dir doesn't exist, the parent dir has to be writable (wp uploads dir), so we can create it.
412 if ( $permissions[ Server::KEY_PATH_ELEMENTOR_UPLOADS_DIR ]['exists'] && ! $permissions[ Server::KEY_PATH_ELEMENTOR_UPLOADS_DIR ]['write'] ) {
413 throw new \Error( self::NO_WRITE_PERMISSIONS_KEY . 'in - ' . Server::KEY_PATH_ELEMENTOR_UPLOADS_DIR );
414 }
415 }
416
417 /**
418 * Enqueue admin scripts
419 */
420 public function enqueue_scripts() {
421 wp_enqueue_script(
422 'elementor-import-export-admin',
423 $this->get_js_assets_url( 'import-export-admin' ),
424 [ 'elementor-common' ],
425 ELEMENTOR_VERSION,
426 true
427 );
428 }
429
430 /**
431 * Assign each ajax action to a method.
432 */
433 private function maybe_handle_ajax() {
434 // phpcs:ignore WordPress.Security.NonceVerification.Missing
435 $action = ElementorUtils::get_super_global_value( $_POST, 'action' );
436
437 switch ( $action ) {
438 case static::EXPORT_TRIGGER_KEY:
439 $this->handle_export_kit();
440 break;
441
442 case static::UPLOAD_TRIGGER_KEY:
443 $this->handle_upload_kit();
444 break;
445
446 case static::IMPORT_TRIGGER_KEY:
447 $this->handle_import_kit();
448 break;
449
450 case static::IMPORT_RUNNER_TRIGGER_KEY:
451 $this->handle_import_kit__runner();
452 break;
453
454 default:
455 break;
456 }
457 }
458
459 /**
460 * Handle upload kit ajax request.
461 */
462 private function handle_upload_kit() {
463 // PHPCS - A URL that should contain special chars (auth headers information).
464 $file_url = isset( $_POST['e_import_file'] )
465 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
466 ? wp_unslash( $_POST['e_import_file'] )
467 : '';
468
469 // Import from kit library
470 if ( ! empty( $file_url ) ) {
471 if (
472 ! wp_verify_nonce( ElementorUtils::get_super_global_value( $_POST, 'e_kit_library_nonce' ), 'kit-library-import' )
473 ) {
474 throw new \Error( 'Invalid kit library nonce.' );
475 }
476
477 if ( ! filter_var( $file_url, FILTER_VALIDATE_URL ) || 0 !== strpos( $file_url, 'http' ) ) {
478 throw new \Error( 'Invalid URL.' );
479 }
480
481 $remote_zip_request = wp_remote_get( $file_url );
482
483 if ( is_wp_error( $remote_zip_request ) ) {
484 throw new \Error( $remote_zip_request->get_error_message() );
485 }
486
487 if ( 200 !== $remote_zip_request['response']['code'] ) {
488 throw new \Error( $remote_zip_request['response']['message'] );
489 }
490
491 $file_name = Plugin::$instance->uploads_manager->create_temp_file( $remote_zip_request['body'], 'kit.zip' );
492 $referrer = static::REFERRER_KIT_LIBRARY;
493 } else {
494 // PHPCS - Already validated in caller function.
495 $file_name = ElementorUtils::get_super_global_value( $_FILES, 'e_import_file' )['tmp_name'];
496 $referrer = static::REFERRER_LOCAL;
497 }
498
499 $uploaded_kit = $this->upload_kit( $file_name, $referrer );
500 $session_dir = $uploaded_kit['session'];
501 $manifest = $uploaded_kit['manifest'];
502 $conflicts = $uploaded_kit['conflicts'];
503
504 if ( ! empty( $file_url ) ) {
505 Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
506 }
507
508 if ( isset( $manifest['plugins'] ) && ! current_user_can( 'install_plugins' ) ) {
509 throw new \Error( static::PERMISSIONS_ERROR_KEY );
510 }
511
512 $result = [
513 'session' => $session_dir,
514 'manifest' => $manifest,
515 ];
516
517 if ( ! empty( $conflicts ) ) {
518 $result['conflicts'] = $conflicts;
519 } else {
520 // Moved into the IE process \Elementor\App\Modules\ImportExport\Processes\Import::get_default_settings_conflicts
521 // TODO: remove in 3.10.0
522 $result = apply_filters( 'elementor/import/stage_1/result', $result );
523 }
524
525 wp_send_json_success( $result );
526 }
527
528 /**
529 * Handle import kit ajax request.
530 */
531 private function handle_import_kit() {
532 // PHPCS - Already validated in caller function
533 $settings = json_decode( ElementorUtils::get_super_global_value( $_POST, 'data' ), true ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
534 $tmp_folder_id = $settings['session'];
535
536 $import = $this->import_kit( $tmp_folder_id, $settings, true );
537
538 // get_settings_config() added manually because the frontend Ajax request doesn't trigger the get_init_settings().
539 $import['configData'] = $this->get_config_data();
540
541 wp_send_json_success( $import );
542 }
543
544 /**
545 * Handle ajax request for running specific runner in the import kit process.
546 */
547 private function handle_import_kit__runner() {
548 // PHPCS - Already validated in caller function
549 $settings = json_decode( ElementorUtils::get_super_global_value( $_POST, 'data' ), true ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
550 $session_id = $settings['session'];
551 $runner = $settings['runner'];
552
553 $import = $this->import_kit_by_runner( $session_id, $runner );
554
555 // get_settings_config() added manually because the frontend Ajax request doesn't trigger the get_init_settings().
556 $import['configData'] = $this->get_config_data();
557
558 wp_send_json_success( $import );
559 }
560
561 /**
562 * Handle export kit ajax request.
563 */
564 private function handle_export_kit() {
565 // PHPCS - Already validated in caller function
566 $settings = json_decode( ElementorUtils::get_super_global_value( $_POST, 'data' ), true ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
567 $export = $this->export_kit( $settings );
568
569 $file_name = $export['file_name'];
570 $file = ElementorUtils::file_get_contents( $file_name );
571
572 if ( ! $file ) {
573 throw new \Error( 'Could not read the exported file.' );
574 }
575
576 Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
577
578 $result = [
579 'manifest' => $export['manifest'],
580 'file' => base64_encode( $file ),
581 ];
582
583 wp_send_json_success( $result );
584 }
585
586 /**
587 * Get config data that will be exposed to the frontend.
588 */
589 private function get_config_data() {
590 $export_nonce = wp_create_nonce( 'elementor_export' );
591 $export_url = add_query_arg( [ '_nonce' => $export_nonce ], Plugin::$instance->app->get_base_url() );
592
593 return [
594 'exportURL' => $export_url,
595 'summaryTitles' => $this->get_summary_titles(),
596 'builtinWpPostTypes' => ImportExportUtils::get_builtin_wp_post_types(),
597 'elementorPostTypes' => ImportExportUtils::get_elementor_post_types(),
598 'isUnfilteredFilesEnabled' => Uploads_Manager::are_unfiltered_uploads_enabled(),
599 'elementorHomePageUrl' => $this->get_elementor_home_page_url(),
600 'recentlyEditedElementorPageUrl' => $this->get_recently_edited_elementor_page_url(),
601 ];
602 }
603
604 /**
605 * Get labels of Elementor document types, Elementor Post types, WordPress Post types and Custom Post types.
606 */
607 private function get_summary_titles() {
608 $summary_titles = [];
609
610 $document_types = Plugin::$instance->documents->get_document_types();
611
612 foreach ( $document_types as $name => $document_type ) {
613 $summary_titles['templates'][ $name ] = [
614 'single' => $document_type::get_title(),
615 'plural' => $document_type::get_plural_title(),
616 ];
617 }
618
619 $elementor_post_types = ImportExportUtils::get_elementor_post_types();
620 $wp_builtin_post_types = ImportExportUtils::get_builtin_wp_post_types();
621 $post_types = array_merge( $elementor_post_types, $wp_builtin_post_types );
622
623 foreach ( $post_types as $post_type ) {
624 $post_type_object = get_post_type_object( $post_type );
625
626 $summary_titles['content'][ $post_type ] = [
627 'single' => $post_type_object->labels->singular_name,
628 'plural' => $post_type_object->label,
629 ];
630 }
631
632 $custom_post_types = ImportExportUtils::get_registered_cpt_names();
633 if ( ! empty( $custom_post_types ) ) {
634 foreach ( $custom_post_types as $custom_post_type ) {
635
636 $custom_post_types_object = get_post_type_object( $custom_post_type );
637 // CPT data appears in two arrays:
638 // 1. content object: in order to show the export summary when completed in getLabel function
639 $summary_titles['content'][ $custom_post_type ] = [
640 'single' => $custom_post_types_object->labels->singular_name,
641 'plural' => $custom_post_types_object->label,
642 ];
643
644 // 2. customPostTypes object: in order to actually export the data
645 $summary_titles['content']['customPostTypes'][ $custom_post_type ] = [
646 'single' => $custom_post_types_object->labels->singular_name,
647 'plural' => $custom_post_types_object->label,
648 ];
649 }
650 }
651
652 $active_kit = Plugin::$instance->kits_manager->get_active_kit();
653
654 foreach ( $active_kit->get_tabs() as $key => $tab ) {
655 $summary_titles['site-settings'][ $key ] = $tab->get_title();
656 }
657
658 return $summary_titles;
659 }
660
661 public function should_show_revert_section( $last_imported_kit ) {
662 if ( empty( $last_imported_kit ) ) {
663 return false;
664 }
665
666 // TODO: BC - remove in the future
667 // The 'templates' runner was in core and moved to the Pro plugin. (Part of it still exits in the Core for BC)
668 // The runner that is in the core version is missing the revert functionality,
669 // therefore we shouldn't display the revert section if the import process done with the core version.
670 $is_import_templates_ran = isset( $last_imported_kit['runners']['templates'] );
671 if ( $this->has_pro() && $is_import_templates_ran ) {
672 $has_imported_templates = ! empty( $last_imported_kit['runners']['templates'] );
673
674 return $has_imported_templates;
675 }
676
677 return true;
678 }
679
680 public function has_pro(): bool {
681 return ElementorUtils::has_pro();
682 }
683
684 private function get_elementor_editor_home_page_url() {
685 if ( 'page' !== get_option( 'show_on_front' ) ) {
686 return '';
687 }
688
689 $frontpage_id = get_option( 'page_on_front' );
690
691 return $this->get_elementor_editor_page_url( $frontpage_id );
692 }
693
694 private function get_elementor_home_page_url() {
695 if ( 'page' !== get_option( 'show_on_front' ) ) {
696 return '';
697 }
698
699 $frontpage_id = get_option( 'page_on_front' );
700
701 return $this->get_elementor_page_url( $frontpage_id );
702 }
703
704 private function get_recently_edited_elementor_page_url() {
705 $query = ElementorUtils::get_recently_edited_posts_query( [ 'posts_per_page' => 1 ] );
706
707 if ( ! isset( $query->post ) ) {
708 return '';
709 }
710
711 return $this->get_elementor_page_url( $query->post->ID );
712 }
713
714 private function get_recently_edited_elementor_editor_page_url() {
715 $query = ElementorUtils::get_recently_edited_posts_query( [ 'posts_per_page' => 1 ] );
716
717 if ( ! isset( $query->post ) ) {
718 return '';
719 }
720
721 return $this->get_elementor_editor_page_url( $query->post->ID );
722 }
723
724 private function get_elementor_document( $page_id ) {
725 $document = Plugin::$instance->documents->get( $page_id );
726
727 if ( ! $document || ! $document->is_built_with_elementor() ) {
728 return false;
729 }
730
731 return $document;
732 }
733
734 private function get_elementor_page_url( $page_id ) {
735 $document = $this->get_elementor_document( $page_id );
736
737 return $document ? $document->get_preview_url() : '';
738 }
739
740 private function get_elementor_editor_page_url( $page_id ) {
741 $document = $this->get_elementor_document( $page_id );
742
743 return $document ? $document->get_edit_url() : '';
744 }
745 }
746