PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 1.6.4
Kubio AI Page Builder v1.6.4
2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / lib / src / DemoSites / DemoSitesImporter.php
kubio / lib / src / DemoSites Last commit date
DemoPartsRepository.php 3 years ago DemoSites.php 3 years ago DemoSitesHelpers.php 4 years ago DemoSitesImportBlockMap.php 4 years ago DemoSitesImporter.php 3 years ago DemoSitesLogger.php 4 years ago DemoSitesRepository.php 3 years ago WXRExporter.php 4 years ago WXRImporter.php 3 years ago WpCliCommand.php 3 years ago
DemoSitesImporter.php
572 lines
1 <?php
2
3 namespace Kubio\DemoSites;
4
5 use IlluminateAgnostic\Arr\Support\Arr;
6 use Kubio\Core\Importer;
7 use Kubio\Flags;
8
9 class DemoSitesImporter {
10 private $logger = null;
11 private $slug = 0;
12 private $log_file_path;
13
14 private $importer;
15 private $wxr_file;
16 private $before_import_executed = false;
17 private $options;
18 private $config;
19
20 public function __construct( $type = 'ajax', $config = array() ) {
21 if ( $type === 'ajax' ) {
22 // pick up only a few keys from the request.
23 $this->config = wp_parse_args(
24 $_REQUEST,
25 array(
26 'is_stepped' => true,
27 'first_call' => false,
28 'before_import_action' => '',
29 )
30 );
31 } else {
32 $this->config = wp_parse_args(
33 $config,
34 array(
35 'is_stepped' => false,
36 )
37 );
38
39 // on cli we only set these once.
40 $this->setLogger();
41 $this->setImporter( $this->config['is_stepped'] );
42 $this->maybeCleanupData();
43
44 DemoSitesHelpers::setImportStartTime();
45
46 $this->log_file_path = DemoSitesHelpers::getLogFile();
47 $this->logger->logger_file = $this->log_file_path;
48 }
49
50 $this->slug = Arr::get( $this->config, 'slug', 0 );
51 add_action( 'wp_ajax_kubio-demo-site-import-data', array( $this, 'ajaxImportDemoData' ) );
52 }
53
54 public static function load() {
55 new static();
56 }
57
58 /**
59 * This is the ajax callback added to `wp_ajax_kubio-demo-site-import-data` and it will import a demo-data by a
60 * given slug, and it will kill the execution with a json message on success ore failure.
61 *
62 */
63 public function ajaxImportDemoData() {
64 $this->setLogger();
65 $this->setImporter();
66 $this->maybeCleanupData();
67
68 DemoSitesHelpers::verifyAjaxCall();
69
70 // Is this a new AJAX call to continue the previous import?
71 $use_existing_importer_data = $this->useExistingImporterData();
72
73 if ( ! $use_existing_importer_data ) {
74 DemoSitesHelpers::setImportStartTime();
75
76 $this->log_file_path = DemoSitesHelpers::getLogFile();
77 }
78
79 $this->logger->logger_file = $this->log_file_path;
80
81 $this->setIniMemoryLimit();
82
83 if ( ! $use_existing_importer_data ) {
84 $kds_file = Arr::get( $_FILES, 'kds_file', null );
85 if ( ! $kds_file ) {
86 $this->prepareRemoteImport();
87 } else {
88 $this->prepareManualImport( $kds_file );
89 }
90 }
91
92 DemoSitesHelpers::setImportDataTransient( $this->getCurrentImportData() );
93
94 if ( ! $this->before_import_executed ) {
95
96 $before_import_action = Arr::get( $this->config, 'before_import_action', null );
97
98 if ( ! $before_import_action ) {
99 $response = array(
100 'status' => 'requires-new-ajax-call',
101 'before_import_action' => 'init',
102 );
103 wp_send_json( $response );
104 } else {
105 $this->executeBeforeImportAction( $before_import_action );
106 }
107
108 $this->before_import_executed = true;
109 DemoSitesHelpers::setImportDataTransient( $this->getCurrentImportData() );
110 $response = array(
111 'status' => 'requires-new-ajax-call',
112 'log' => 'Before import executed',
113 );
114 wp_send_json( $response );
115
116 }
117
118 if ( $this->wxr_file && file_exists( $this->wxr_file ) ) {
119 add_action( 'kubio/demo-site-import/post-process', array( $this, 'postProcessContentImport' ) );
120 $this->importer->import_content( $this->wxr_file );
121 }
122
123 $this->afterImport();
124 }
125
126 /**
127 * This method is used to import a demo-data design via WP CLI for a given slug.
128 * eg: `wp kubio:import-design accounting-demo-site`
129 *
130 * @return false|string
131 */
132 public function cliImportDemoData( $args ) {
133 $this->setIniMemoryLimit();
134
135 if ( isset( $args['is_custom'] ) && $args['is_custom'] ) {
136 $this->loadKDSFile( $args['kds_url'] );
137 } else {
138 $this->prepareRemoteImport();
139 }
140
141 DemoSitesHelpers::setImportDataTransient( $this->getCurrentImportData() );
142
143 if ( $this->wxr_file && file_exists( $this->wxr_file ) ) {
144 add_action( 'kubio/demo-site-import/post-process', array( $this, 'postProcessContentImport' ) );
145 $this->importer->import_content( $this->wxr_file );
146 }
147
148 return $this->afterImport( false );
149 }
150
151 /**
152 * A methods which sets `$this->logger` as an instance of `DemoSitesLogger`
153 */
154 private function setLogger() {
155 $this->logger = new DemoSitesLogger();
156 $this->logger->min_level = 'info';
157 $this->logger->logger_file = '';
158 }
159
160 /**
161 * A methods which sets `$this->importer` as an instance of `WXRImporter`
162 */
163 private function setImporter( $is_stepped = true ) {
164 if ( ! class_exists( '\WP_Importer' ) ) {
165 require ABSPATH . '/wp-admin/includes/class-wp-importer.php';
166 }
167
168 $this->importer = new WXRImporter(
169 array(
170 'fetch_attachments' => true,
171 'is_stepped' => $is_stepped,
172 ),
173 $this->logger
174 );
175
176 }
177
178 /**
179 * In the first call try to delete old transients.
180 */
181 private function maybeCleanupData() {
182 if ( Arr::get( $this->config, 'first_call', null ) ) {
183 delete_transient( DemoSitesHelpers::IMPORT_TRANSIENT );
184 $this->importer->delete_import_data_transient();
185 }
186 }
187
188 /**
189 * Try to set a ini value of 512M for `memory_limit`.
190 * If it is not allowed warn in the logs about it.
191 */
192 private function setIniMemoryLimit() {
193 if ( ! @ini_set( 'memory_limit', '512M' ) ) {
194 DemoSitesHelpers::appendToFile(
195 esc_html__( 'Warn: Unable set memory_limit', 'kubio' ),
196 $this->log_file_path
197 );
198 }
199 }
200
201 private function useExistingImporterData() {
202 if ( $data = get_transient( DemoSitesHelpers::IMPORT_TRANSIENT ) ) {
203 $this->log_file_path = empty( $data['log_file_path'] ) ? '' : $data['log_file_path'];
204 $this->slug = empty( $data['slug'] ) ? null : $data['slug'];
205 $this->wxr_file = empty( $data['wxr_file'] ) ? array() : $data['wxr_file'];
206 $this->options = empty( $data['options'] ) ? array() : $data['options'];
207 $this->before_import_executed = empty( $data['before_import_executed'] ) ? array() : $data['before_import_executed'];
208
209 return true;
210 }
211
212 return false;
213 }
214
215 private function prepareRemoteImport() {
216 $this->logger->info( 'Prepare remote import' );
217
218 $demo = $this->getDemo();
219 if ( $demo !== null ) {
220 $kds = Arr::get( $demo, 'kds_url', null );
221 $this->loadKDSFile( $kds );
222 } else {
223 // Send JSON Error response to the AJAX call.
224 DemoSitesHelpers::sendAjaxError( esc_html__( 'No import files specified!', 'kubio' ) );
225 }
226 }
227
228
229 private function loadKDSFile( $kds ) {
230 if ( $kds ) {
231 list( $wxr_file, $extra_options ) = DemoSitesHelpers::downloadImportFile( $kds );
232
233 if ( is_wp_error( $wxr_file ) ) {
234 DemoSitesHelpers::logErrorAndSendAjaxResponse(
235 $wxr_file->get_error_message(),
236 $this->log_file_path,
237 esc_html__( 'Downloaded files', 'kubio' )
238 );
239 } else {
240 $this->wxr_file = $wxr_file;
241 $this->options = $extra_options;
242 }
243 } else {
244 DemoSitesHelpers::logErrorAndSendAjaxResponse(
245 esc_html__( 'Import file undefined', 'kubio' ),
246 $this->log_file_path,
247 esc_html__( 'Downloaded files', 'kubio' )
248 );
249 }
250
251 DemoSitesHelpers::appendToFile(
252 sprintf( /* translators: %s - the name of the selected import. */
253 __( 'The import files for: %s were successfully downloaded!', 'kubio' ),
254 $kds
255 ),
256 $this->log_file_path,
257 esc_html__( 'Downloaded files', 'kubio' )
258 );
259 }
260
261 private function getDemo() {
262 $demos = apply_filters( 'kubio/demo-sites/list', array() );
263 $slug = $this->slug;
264
265 return Arr::get( $demos, $slug, null );
266 }
267
268 private function prepareManualImport( $kds_file ) {
269
270 DemoSitesHelpers::appendToFile(
271 __( 'Manual kds import!', 'kubio' ),
272 $this->log_file_path,
273 esc_html__( 'Manual import', 'kubio' )
274 );
275
276 list( $wxr_file, $extra_options ) = DemoSitesHelpers::useUploadedKDSFile( Arr::get( $kds_file, 'tmp_name', null ) );
277 $this->wxr_file = $wxr_file;
278 $this->options = $extra_options;
279 }
280
281 /**
282 * Get the current state of selected data.
283 *
284 * @return array
285 */
286 public function getCurrentImportData() {
287 return array(
288 'log_file_path' => $this->log_file_path,
289 'slug' => $this->slug,
290 'wxr_file' => $this->wxr_file,
291 'options' => $this->options,
292 'before_import_executed' => $this->before_import_executed,
293 );
294 }
295
296 public function getBeforeImportActions() {
297 return array( 'init', 'prepare_templates', 'prepare_template_parts', 'prepare_menus', 'prepare_pages' );
298 }
299
300 /**
301 * This method executes the valid given $action, logs in case of error, and returns the status of ajax/cli queue.
302 * Based on the $ajax parameter it will kill the execution with an `wp_send_json` response or it will print the json.
303 *
304 * @param $action
305 * @param bool $ajax
306 * @return false|string|void
307 */
308 public function executeBeforeImportAction( $action, $ajax = true ) {
309 $actions = $this->getBeforeImportActions();
310 $action_index = array_search( $action, $actions );
311
312 if ( $action_index === false ) {
313 DemoSitesHelpers::sendAjaxError( __( 'Importer action not found', 'kubio' ) );
314 }
315
316 $this->logger->info( "Executing before import step: {$action}" );
317
318 switch ( $action ) {
319
320 case 'init':
321 $site_url = Arr::get( $this->options, 'site_url' );
322 if ( $site_url ) {
323 wp_remote_get( $site_url );
324 }
325 break;
326
327 case 'prepare_templates':
328 $this->prepareTemplates();
329 break;
330
331 case 'prepare_template_parts':
332 $this->prepareTemplateParts();
333 break;
334
335 case 'prepare_pages':
336 $this->preparePages();
337 break;
338
339 case 'prepare_menus':
340 $this->prepareMenus();
341 break;
342 }
343
344 if ( $action_index + 1 < count( $actions ) ) {
345 $response = array(
346 'status' => 'requires-new-ajax-call',
347 'before_import_action' => $actions[ $action_index + 1 ],
348 );
349
350 if ( $ajax ) {
351 wp_send_json( $response );
352 }
353
354 return wp_json_encode( $response );
355 }
356 }
357
358 private function prepareTemplates() {
359 $stylesheet = get_stylesheet();
360 $ids = get_posts(
361 array(
362 'post_type' => 'wp_template',
363 'post_status' => array( 'publish' ),
364 'posts_per_page' => - 1,
365 'tax_query' => array(
366 array(
367 'taxonomy' => 'wp_theme',
368 'field' => 'name',
369 'terms' => array( $stylesheet ),
370 ),
371 ),
372 'fields' => 'ids',
373 )
374 );
375
376 foreach ( $ids as $id ) {
377 wp_delete_post( $id, true );
378 }
379 }
380
381 private function prepareTemplateParts() {
382 $stylesheet = get_stylesheet();
383 $ids = get_posts(
384 array(
385 'post_type' => 'wp_template_part',
386 'post_status' => array( 'publish' ),
387 'posts_per_page' => - 1,
388 'tax_query' => array(
389 array(
390 'taxonomy' => 'wp_theme',
391 'field' => 'name',
392 'terms' => array( $stylesheet ),
393 ),
394 ),
395 'fields' => 'ids',
396 )
397 );
398
399 foreach ( $ids as $id ) {
400 wp_delete_post( $id, true );
401 }
402 }
403
404 private function preparePages() {
405 $ids = get_posts(
406 array(
407 'post_type' => 'page',
408 'post_status' => array( 'publish', 'draft' ),
409 'posts_per_page' => - 1,
410 'fields' => 'ids',
411 )
412 );
413
414 foreach ( $ids as $id ) {
415 wp_delete_post( $id, false );
416 }
417 }
418
419 private function prepareMenus() {
420 $menus = wp_get_nav_menus();
421
422 /** @var \WP_Term $menu */
423 foreach ( $menus as $menu ) {
424 $index = - 1;
425 do {
426 $index ++;
427 list($base_name) = sscanf( $menu->name, '%s - %s' );
428
429 $new_name = sprintf(
430 '%s - %s',
431 $base_name,
432 $index ? sprintf( __( 'Old %s', 'kubio' ), $index ) : __( 'Old', 'kubio' )
433 );
434
435 } while ( ! ! get_term_by( 'name', $new_name, 'nav_menu' ) );
436
437 wp_update_nav_menu_object(
438 $menu->term_id,
439 array(
440 'menu-name' => $new_name,
441 )
442 );
443 }
444
445 }
446
447 /**
448 * Send a JSON response with final report or simply returns the json if $ajax is false.
449 *
450 * @param bool $ajax
451 * @return false|string
452 */
453 private function afterImport( $ajax = true ) {
454
455 $this->useExistingImporterData();
456
457 if ( $this->slug ) {
458 Flags::set( 'last_imported_starter', $this->slug );
459 }
460
461 // Delete importer data transient for current import.
462 delete_transient( DemoSitesHelpers::IMPORT_TRANSIENT );
463
464 $response = array(
465 'status' => 'finished',
466 );
467
468 if ( $ajax ) {
469 wp_send_json( $response );
470 }
471
472 return wp_json_encode( $response );
473 }
474
475 //this updates the count column in the wp_term_taxonomy table because in some cases it was still at 0 showing empty menus
476 public function updateMenuItemsCount( $wxr_importer ) {
477 $update_taxonomy = 'nav_menu';
478 $menus_id_map = Arr::get( $wxr_importer->get_mapping(), 'menus_map', array() );
479 wp_update_term_count_now( $menus_id_map, $update_taxonomy );
480 }
481 /**
482 * @param WXRImporter $wxr_importer
483 */
484 public function postProcessContentImport( $wxr_importer ) {
485 $this->updateThemeMods( $wxr_importer );
486 $this->updateLogos( $wxr_importer );
487 $this->updateFrontPages( $wxr_importer );
488 $this->updateGlobalNonKubioTemplates();
489 $this->updateMenuItemsCount( $wxr_importer );
490 }
491
492
493 private function updateGlobalNonKubioTemplates() {
494 wp_cache_flush();
495 $blog_templates = array(
496 'singular' => 'single',
497 'home' => 'index',
498 );
499
500 foreach ( $blog_templates as $template => $replacement ) {
501 if ( kubio_has_block_template( $template ) ) {
502 $replacement_template = kubio_get_block_template( $replacement );
503 if ( $replacement_template ) {
504 Importer::createTemplate( $template, $replacement_template->content, true, 'kubio' );
505 }
506 }
507 }
508 }
509
510 /**
511 * @param WXRImporter $wxr_importer
512 */
513 private function updateThemeMods( $wxr_importer ) {
514
515 $theme_mods = Arr::get( $this->options, 'customizer', array() );
516
517 unset( $theme_mods[0] );
518
519 // update nav menu locations
520 $menus_id_map = Arr::get( $wxr_importer->get_mapping(), 'menus_map', array() );
521 $nav_menu_locations = Arr::get( $theme_mods, 'nav_menu_locations', array() );
522 foreach ( $nav_menu_locations as $location => $term_id ) {
523 $next_term_id = Arr::get( $menus_id_map, $term_id, null );
524
525 if ( $next_term_id ) {
526 $nav_menu_locations[ $location ] = (int) $next_term_id;
527 } else {
528 unset( $nav_menu_locations[ $location ] );
529 }
530 }
531 $theme_mods['nav_menu_locations'] = $nav_menu_locations;
532
533 $theme = get_option( 'stylesheet' );
534
535 update_option( "theme_mods_$theme", $theme_mods );
536 }
537
538 /**
539 * @param WXRImporter $wxr_importer
540 */
541 private function updateLogos( $wxr_importer ) {
542 $alternate_logo_image = kubio_get_global_data( 'alternateLogo' );
543 $post_mapping = Arr::get( $wxr_importer->get_mapping(), 'post', array() );
544 if ( $alternate_logo_image ) {
545 kubio_set_global_data( 'alternateLogo', Arr::get( $post_mapping, $alternate_logo_image, $alternate_logo_image ) );
546 }
547
548 $logos_options = array( 'site_logo', 'site_icon' );
549
550 foreach ( $logos_options as $option ) {
551 $value = Arr::get( $this->options, "options.{$option}", 0 );
552 $value = Arr::get( $post_mapping, $value, $value );
553 update_option( $option, is_numeric( $value ) ? intval( $value ) : $value );
554 }
555 }
556
557 /**
558 * @param WXRImporter $wxr_importer
559 */
560 private function updateFrontPages( $wxr_importer ) {
561 $page_options = array( 'page_on_front', 'page_for_posts', 'show_on_front' );
562
563 $post_mapping = Arr::get( $wxr_importer->get_mapping(), 'post', array() );
564
565 foreach ( $page_options as $option ) {
566 $value = Arr::get( $this->options, "options.{$option}", 0 );
567 $value = Arr::get( $post_mapping, $value, $value );
568 update_option( $option, is_numeric( $value ) ? intval( $value ) : $value );
569 }
570 }
571 }
572