PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/elementor/core/app/modules/import-export/module.php

https://gitlab.com/ebrjose/comcebu
PHP | 318 lines | 225 code | 70 blank | 23 comment | 19 complexity | 695e28fbc25a133d578645e704e73e11 MD5 | raw file
  1. <?php
  2. namespace Elementor\Core\App\Modules\ImportExport;
  3. use Elementor\Core\Base\Document;
  4. use Elementor\Core\Base\Module as BaseModule;
  5. use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
  6. use Elementor\Core\Files\Uploads_Manager;
  7. use Elementor\Plugin;
  8. use Elementor\TemplateLibrary\Source_Local;
  9. use Elementor\Tools;
  10. use Elementor\Utils;
  11. if ( ! defined( 'ABSPATH' ) ) {
  12. exit; // Exit if accessed directly
  13. }
  14. /**
  15. * Import Export Module
  16. *
  17. * Responsible for initializing Elementor App functionality
  18. */
  19. class Module extends BaseModule {
  20. const FORMAT_VERSION = '1.0';
  21. const EXPORT_TRIGGER_KEY = 'elementor_export_kit';
  22. const IMPORT_TRIGGER_KEY = 'elementor_import_kit';
  23. const MANIFEST_ERROR_KEY = 'manifest-error';
  24. /**
  25. * @var Export
  26. */
  27. public $export;
  28. /**
  29. * @var Import
  30. */
  31. public $import;
  32. /**
  33. * Get name.
  34. *
  35. * @access public
  36. *
  37. * @return string
  38. */
  39. public function get_name() {
  40. return 'import-export';
  41. }
  42. public function get_init_settings() {
  43. if ( ! Plugin::$instance->app->is_current() ) {
  44. return [];
  45. }
  46. $export_nonce = wp_create_nonce( 'elementor_export' );
  47. $export_url = add_query_arg( [ '_nonce' => $export_nonce ], Plugin::$instance->app->get_base_url() );
  48. return [
  49. 'exportURL' => $export_url,
  50. 'summaryTitles' => $this->get_summary_titles(),
  51. 'isUnfilteredFilesEnabled' => Uploads_Manager::are_unfiltered_uploads_enabled(),
  52. ];
  53. }
  54. public function get_summary_titles() {
  55. $summary_titles = [];
  56. $document_types = Plugin::$instance->documents->get_document_types();
  57. foreach ( $document_types as $name => $document_type ) {
  58. $summary_titles['templates'][ $name ] = [
  59. 'single' => $document_type::get_title(),
  60. 'plural' => $document_type::get_plural_title(),
  61. ];
  62. }
  63. $post_types = get_post_types_by_support( 'elementor' );
  64. foreach ( $post_types as $post_type ) {
  65. if ( Source_Local::CPT === $post_type ) {
  66. continue;
  67. }
  68. $post_type_object = get_post_type_object( $post_type );
  69. $summary_titles['content'][ $post_type ] = [
  70. 'single' => $post_type_object->labels->singular_name,
  71. 'plural' => $post_type_object->label,
  72. ];
  73. }
  74. $active_kit = Plugin::$instance->kits_manager->get_active_kit();
  75. foreach ( $active_kit->get_tabs() as $key => $tab ) {
  76. $summary_titles['site-settings'][ $key ] = $tab->get_title();
  77. }
  78. return $summary_titles;
  79. }
  80. private function import_stage_1() {
  81. // PHPCS - Already validated in caller function.
  82. if ( ! empty( $_POST['e_import_file'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
  83. $file_url = $_POST['e_import_file']; // phpcs:ignore WordPress.Security.NonceVerification.Missing
  84. if ( ! filter_var( $file_url, FILTER_VALIDATE_URL ) || 0 !== strpos( $file_url, 'http' ) ) {
  85. throw new \Error( __( 'Invalid URL', 'elementor' ) );
  86. }
  87. $remote_zip_request = wp_remote_get( $file_url );
  88. if ( is_wp_error( $remote_zip_request ) ) {
  89. throw new \Error( $remote_zip_request->get_error_message() );
  90. }
  91. if ( 200 !== $remote_zip_request['response']['code'] ) {
  92. throw new \Error( $remote_zip_request['response']['message'] );
  93. }
  94. $file_name = Plugin::$instance->uploads_manager->create_temp_file( $remote_zip_request['body'], 'kit.zip' );
  95. } else {
  96. // PHPCS - Already validated in caller function.
  97. $file_name = $_FILES['e_import_file']['tmp_name']; // phpcs:ignore WordPress.Security.NonceVerification.Missing
  98. }
  99. $extraction_result = Plugin::$instance->uploads_manager->extract_and_validate_zip( $file_name, [ 'json', 'xml' ] );
  100. if ( ! empty( $file_url ) ) {
  101. Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
  102. }
  103. $session_dir = $extraction_result['extraction_directory'];
  104. $manifest_file_content = file_get_contents( $session_dir . 'manifest.json', true );
  105. if ( ! $manifest_file_content ) {
  106. throw new \Error( self::MANIFEST_ERROR_KEY );
  107. }
  108. $manifest_data = json_decode( $manifest_file_content, true );
  109. // In case that the manifest content is not a valid JSON or empty.
  110. if ( ! $manifest_data ) {
  111. throw new \Error( self::MANIFEST_ERROR_KEY );
  112. }
  113. $manifest_data = $this->import->adapt_manifest_structure( $manifest_data );
  114. $result = [
  115. 'session' => $session_dir,
  116. 'manifest' => $manifest_data,
  117. ];
  118. $result = apply_filters( 'elementor/import/stage_1/result', $result );
  119. return $result;
  120. }
  121. private function import_stage_2( $settings_directory ) {
  122. set_time_limit( 0 );
  123. $result = $this->import->run();
  124. Plugin::$instance->uploads_manager->remove_file_or_dir( $settings_directory );
  125. return $result;
  126. }
  127. private function on_admin_init() {
  128. if ( ! isset( $_POST['action'] ) || self::IMPORT_TRIGGER_KEY !== $_POST['action'] || ! wp_verify_nonce( $_POST['_nonce'], Ajax::NONCE_KEY ) ) {
  129. return;
  130. }
  131. $import_settings = json_decode( stripslashes( $_POST['data'] ), true );
  132. // Set the Request's state as an Elementor upload request, in order to support unfiltered file uploads.
  133. Plugin::$instance->uploads_manager->set_elementor_upload_state( true );
  134. try {
  135. $this->import = new Import( $import_settings );
  136. if ( 1 === $import_settings['stage'] ) {
  137. $result = $this->import_stage_1();
  138. } elseif ( 2 === $import_settings['stage'] ) {
  139. $result = $this->import_stage_2( $import_settings['session'] );
  140. }
  141. wp_send_json_success( $result );
  142. } catch ( \Error $error ) {
  143. wp_send_json_error( $error->getMessage() );
  144. }
  145. }
  146. private function on_init() {
  147. if ( ! isset( $_GET[ self::EXPORT_TRIGGER_KEY ] ) || ! wp_verify_nonce( $_GET['_nonce'], 'elementor_export' ) ) {
  148. return;
  149. }
  150. $export_settings = $_GET[ self::EXPORT_TRIGGER_KEY ];
  151. try {
  152. $this->export = new Export( self::merge_properties( [], $export_settings, [ 'include', 'kitInfo' ] ) );
  153. $export_result = $this->export->run();
  154. $file_name = $export_result['file_name'];
  155. $file = file_get_contents( $file_name, true );
  156. Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
  157. wp_send_json_success( [
  158. 'manifest' => $export_result['manifest'],
  159. 'file' => base64_encode( $file ),
  160. ] );
  161. } catch ( \Error $error ) {
  162. wp_send_json_error( $error->getMessage() );
  163. }
  164. }
  165. private function render_import_export_tab_content() {
  166. $intro_text_link = sprintf( '<a href="https://go.elementor.com/wp-dash-import-export-general" target="_blank">%s</a>', esc_html__( 'Learn more', 'elementor' ) );
  167. $intro_text = sprintf(
  168. /* translators: 1: New line break, 2: Learn More link. */
  169. __( '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' ),
  170. '<br>',
  171. $intro_text_link
  172. );
  173. $content_data = [
  174. 'export' => [
  175. 'title' => esc_html__( 'Export a Template Kit', 'elementor' ),
  176. 'button' => [
  177. 'url' => Plugin::$instance->app->get_base_url() . '#/export',
  178. 'text' => esc_html__( 'Start Export', 'elementor' ),
  179. ],
  180. 'description' => esc_html__( 'Bundle your whole site - or just some of its elements - to be used for another website.', 'elementor' ),
  181. 'link' => [
  182. 'url' => 'https://go.elementor.com/wp-dash-import-export-export-flow',
  183. 'text' => esc_html__( 'Learn More', 'elementor' ),
  184. ],
  185. ],
  186. 'import' => [
  187. 'title' => esc_html__( 'Import a Template Kit', 'elementor' ),
  188. 'button' => [
  189. 'url' => Plugin::$instance->app->get_base_url() . '#/import',
  190. 'text' => esc_html__( 'Start Import', 'elementor' ),
  191. ],
  192. 'description' => esc_html__( 'Apply the design and settings of another site to this one.', 'elementor' ),
  193. 'link' => [
  194. 'url' => 'https://go.elementor.com/wp-dash-import-export-import-flow',
  195. 'text' => esc_html__( 'Learn More', 'elementor' ),
  196. ],
  197. ],
  198. ];
  199. $info_text = esc_html__( 'Even after you import and apply a Template Kit, you can undo it by restoring a previous version of your site.', 'elementor' ) . '<br>' . esc_html__( 'Open Site Settings > History > Revisions.', 'elementor' );
  200. ?>
  201. <div class="tab-import-export-kit__content">
  202. <p class="tab-import-export-kit__info"><?php Utils::print_unescaped_internal_string( $intro_text ); ?></p>
  203. <div class="tab-import-export-kit__wrapper">
  204. <?php foreach ( $content_data as $data ) { ?>
  205. <div class="tab-import-export-kit__container">
  206. <div class="tab-import-export-kit__box">
  207. <h2><?php Utils::print_unescaped_internal_string( $data['title'] ); ?></h2>
  208. <a href="<?php Utils::print_unescaped_internal_string( $data['button']['url'] ); ?>" class="elementor-button elementor-button-success">
  209. <?php Utils::print_unescaped_internal_string( $data['button']['text'] ); ?>
  210. </a>
  211. </div>
  212. <p><?php Utils::print_unescaped_internal_string( $data['description'] ); ?></p>
  213. <a href="<?php Utils::print_unescaped_internal_string( $data['link']['url'] ); ?>" target="_blank"><?php Utils::print_unescaped_internal_string( $data['link']['text'] ); ?></a>
  214. </div>
  215. <?php } ?>
  216. </div>
  217. <p class="tab-import-export-kit__info"><?php Utils::print_unescaped_internal_string( $info_text ); ?></p>
  218. </div>
  219. <?php
  220. }
  221. public function register_settings_tab( Tools $tools ) {
  222. $tools->add_tab( 'import-export-kit', [
  223. 'label' => esc_html__( 'Import / Export Kit', 'elementor' ),
  224. 'sections' => [
  225. 'intro' => [
  226. 'label' => esc_html__( 'Template Kits', 'elementor' ),
  227. 'callback' => function() {
  228. $this->render_import_export_tab_content();
  229. },
  230. 'fields' => [],
  231. ],
  232. ],
  233. ] );
  234. }
  235. public function __construct() {
  236. add_action( 'init', function() {
  237. $this->on_init();
  238. } );
  239. add_action( 'admin_init', function() {
  240. $this->on_admin_init();
  241. } );
  242. $page_id = Tools::PAGE_ID;
  243. add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_tab' ] );
  244. if ( Utils::is_wp_cli() ) {
  245. \WP_CLI::add_command( 'elementor kit', WP_CLI::class );
  246. }
  247. }
  248. }