PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 1.1.2
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v1.1.2
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
cartflows / classes / class-cartflows-importer.php

class-cartflows-importer.php in CartFlows – Funnel Builder & Checkout Plugin for WooCommerce 1.1.2, at classes/class-cartflows-importer.php

1,135 lines 37.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CartFlows Admin
4 *
5 * @package CartFlows
6 * @since 1.0.0
7 */
8
9 if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
11 /**
12 * CartFlows Import
13 *
14 * @since 1.0.0
15 */
16 class CartFlows_Importer {
17
18 /**
19 * Instance
20 *
21 * @since 1.0.0
22 * @access private
23 * @var object Class object.
24 */
25 private static $instance;
26
27 /**
28 * Installed Plugins
29 *
30 * @since 1.0.0
31 * @access private
32 * @var object Class object.
33 */
34 private static $installed_plugins = null;
35
36 /**
37 * Initiator
38 *
39 * @since 1.0.0
40 * @return object initialized object of class.
41 */
42 public static function get_instance() {
43 if ( ! isset( self::$instance ) ) {
44 self::$instance = new self;
45 }
46
47 return self::$instance;
48 }
49
50 /**
51 * Constructor
52 *
53 * @since 1.0.0
54 */
55 public function __construct() {
56 add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
57 add_action( 'wp_ajax_cartflows_load_steps', array( $this, 'load_templates' ) );
58 add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
59 add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
60 add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
61 add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
62 add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
63 add_action( 'admin_footer', array( $this, 'js_templates' ) );
64 add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
65
66 add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
67
68 add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
69 }
70
71 /**
72 * Clear Cache.
73 *
74 * @since 1.0.0
75 */
76 public function clear_cache() {
77 // Clear 'Elementor' file cache.
78 if ( class_exists( '\Elementor\Plugin' ) ) {
79 Elementor\Plugin::$instance->files_manager->clear_cache();
80 }
81 }
82
83 /**
84 * JS Templates
85 *
86 * @since 1.0.0
87 *
88 * @return void
89 */
90 function js_templates() {
91
92 // Loading Templates.
93 ?>
94 <script type="text/template" id="tmpl-cartflows-step-loading">
95 <div class="template-message-block cartflows-step-loading">
96 <h2>
97 <span class="spinner"></span>
98 <?php _e( 'Loading Steps', 'cartflows' ); ?>
99 </h2>
100 <p class="description"><?php _e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
101 </div>
102 </script>
103
104 <?php
105 // Search Templates.
106 ?>
107 <script type="text/template" id="tmpl-cartflows-searching-templates">
108 <div class="template-message-block cartflows-searching-templates">
109 <h2>
110 <span class="spinner"></span>
111 <?php _e( 'Searching Template..', 'cartflows' ); ?>
112 </h2>
113 <p class="description"><?php _e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
114 </div>
115 </script>
116
117 <?php
118 // CartFlows Importing Template.
119 ?>
120 <script type="text/template" id="tmpl-cartflows-step-importing">
121 <div class="template-message-block cartflows-step-importing">
122 <h2><span class="spinner"></span> <?php _e( 'Importing..', 'cartflows' ); ?></h2>
123 </div>
124 </script>
125
126 <?php
127 // CartFlows Imported.
128 ?>
129 <script type="text/template" id="tmpl-cartflows-step-imported">
130 <div class="template-message-block cartflows-step-imported">
131 <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
132 <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
133 </script>
134
135 <?php
136 // No templates.
137 ?>
138 <script type="text/template" id="tmpl-cartflows-no-steps">
139 <div class="cartflows-no-steps">
140 <div class="template-message-block">
141 <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
142 <p class="description"></p>
143 </div>
144 </div>
145 </script>
146
147 <?php
148 // No templates.
149 ?>
150 <script type="text/template" id="tmpl-cartflows-no-flows">
151 <div class="cartflows-no-flows">
152 <div class="template-message-block">
153 <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
154 <p class="description"></p>
155 </div>
156 </div>
157 </script>
158
159 <?php
160 // Error handling.
161 ?>
162 <script type="text/template" id="tmpl-templator-error">
163 <div class="notice notice-error"><p>{{ data }}</p></div>
164 </script>
165
166 <?php
167 // Redirect to Elementor.
168 ?>
169 <script type="text/template" id="tmpl-templator-redirect-to-elementor">
170 <div class="template-message-block templator-redirect-to-elementor">
171 <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
172 <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php _e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
173 </script>
174
175 <?php
176 /**
177 * Responsive Buttons
178 */
179 ?>
180 <script type="text/template" id="tmpl-cartflows-responsive-view">
181 <span class="responsive-view">
182 <span class="actions">
183 <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
184 <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
185 <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
186 </span>
187 </span>
188 </script>
189
190 <?php
191 // Templates data.
192 ?>
193 <script type="text/template" id="tmpl-cartflows-flows-list">
194
195 <# if ( data.items.length ) { #>
196 <# for ( key in data.items ) { #>
197 <#
198 var flow_steps = [];
199 if( data.items[ key ].flow_steps ) {
200 flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
201 return value['id'];
202 });
203 }
204 #>
205 <# console.log( 'here ' + key ); #>
206 <div class="inner">
207 <div class="template">
208 <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
209 <div class="template-screenshot">
210 <# if( data.items[ key ].featured_image_url ) { #>
211 <img src="{{ data.items[ key ].featured_image_url }}" />
212 <# } else { #>
213 <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
214 <# } #>
215 </div>
216 <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
217 <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
218 <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
219 <# } #>
220 </span>
221 <div class="template-id-container">
222 <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
223 <div class="template-actions">
224
225 <#
226 if( data.items[ key ].page_builder.slug ) {
227 required_plugin_group = data.items[ key ].page_builder.slug;
228 } else {
229 required_plugin_group = '';
230 }
231
232 if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
233 import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
234 } else {
235 import_btn_title = 'Import';
236 } #>
237
238 <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
239 <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
240 <# } else if( CartFlowsImportVars._is_pro_active ) { #>
241 <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
242 <# } else { #>
243 <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
244 <# } #>
245 </div>
246 </div>
247 </div>
248 </div>
249 <# } #>
250 <# } #>
251 </script>
252
253 <?php
254 // Empty Step.
255 ?>
256 <script type="text/template" id="tmpl-cartflows-create-blank-step">
257 <div class="inner">
258 <div class="template">
259 <span class="thumbnail site-preview cartflows-flow-preview">
260 <div class="template-screenshot">
261 <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
262 </div>
263 <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
264 </span>
265 <div class="template-id-container">
266 <h3 class="template-name"> Blank </h3>
267 <div class="template-actions">
268 <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
269 </div>
270 </div>
271 </div>
272 </div>
273 </script>
274
275 <?php
276 // Templates data.
277 ?>
278 <script type="text/template" id="tmpl-cartflows-steps-list">
279 <# if ( data.items.length ) { #>
280 <# for ( key in data.items ) { #>
281 <#
282 var flow_steps = [];
283 if( data.items[ key ].flow_steps ) {
284 flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
285 return value['id'];
286 });
287 }
288 #>
289 <div class="inner">
290 <div class="template">
291 <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
292 <div class="template-screenshot">
293 <# if( data.items[ key ].featured_image_url ) { #>
294 <img src="{{ data.items[ key ].featured_image_url }}" />
295 <# } else { #>
296 <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
297 <# } #>
298 </div>
299 <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
300 <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
301 <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
302 <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
303 <# } #>
304 </span>
305 <div class="template-id-container">
306 <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
307 <div class="template-actions">
308
309 <#
310
311 var required_plugin_group = data.items[ key ].page_builder.slug || '';
312 var step_slug = data.items[ key ].step_type.slug || '';
313 var step_title = data.items[ key ].step_type.name || '';
314
315 if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
316 import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
317 } else {
318 import_btn_title = 'Import';
319 } #>
320
321 <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
322 <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
323 <# } else if( CartFlowsImportVars._is_pro_active ) { #>
324 <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
325 <# } else { #>
326 <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
327 <# } #>
328 </div>
329 </div>
330 </div>
331 </div>
332 <# } #>
333 <# } #>
334 </script>
335
336 <?php
337 /**
338 * TMPL - Filters
339 */
340 ?>
341 <script type="text/template" id="tmpl-cartflows-term-filters">
342
343 <# if ( data ) { #>
344
345 <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #>
346 <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
347
348 <# if ( data.args.show_all ) { #>
349 <li>
350 <a href="#" data-group="all"> All </a>
351 </li>
352 <# } #>
353
354 <# for ( key in data.items ) { #>
355 <li>
356 <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
357 </li>
358 <# } #>
359
360 </ul>
361
362 <# } else { #>
363 <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
364
365 <# if ( data.args.show_all ) { #>
366 <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
367 <# } #>
368
369 <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
370 <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
371 <# } #>
372
373 <# for ( key in data.items ) { #>
374 <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
375 <# } #>
376
377 </select>
378 <# } #>
379
380 <# } #>
381 </script>
382
383 <?php
384 // Step Type.
385 ?>
386 <script type="text/template" id="tmpl-cartflows-step-types">
387 <ul class="wcf-tab nav-tabs">
388 <# if( data.items_count ) { #>
389 <# for( key in data.items ) { #>
390 <# console.log( data.items[ key ].id ) #>
391 <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
392 <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
393 </li>
394 <# } #>
395 <# } #>
396 </ul>
397 </script>
398
399 <?php
400 // Add to library button.
401 ?>
402 <script type="text/template" id="tmpl-templator-add-to-library">
403 <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
404 </script>
405 <?php
406 }
407
408 /**
409 * Get plugin button string.
410 *
411 * @param string $plugin_init_file Plguin init file.
412 * @param string $plugin_title Plguin title.
413 * @return string
414 */
415 function get_plugin_button_string( $plugin_init_file, $plugin_title ) {
416
417 if ( null == self::$installed_plugins ) {
418 self::$installed_plugins = get_plugins();
419 }
420
421 if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
422 /* translators: %s is plugin name. */
423 return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
424 } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
425 /* translators: %s is plugin name. */
426 return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
427 }
428
429 return __( 'Import', 'cartflows' );
430 }
431
432 /**
433 * Get plugin status
434 *
435 * @param string $plugin_init_file Plguin init file.
436 * @return mixed
437 */
438 function get_plugin_status( $plugin_init_file ) {
439
440 if ( null == self::$installed_plugins ) {
441 self::$installed_plugins = get_plugins();
442 }
443
444 if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
445 return 'install';
446 } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
447 return 'activate';
448 }
449
450 return;
451 }
452
453 /**
454 * Enqueue scripts
455 *
456 * @since 1.0.0
457 *
458 * @hook admin_enqueue_scripts
459 * @param string $hook Current page hook.
460 */
461 function scripts( $hook = '' ) {
462
463 if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
464 return;
465 }
466
467 wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
468 wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
469 wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
470 wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
471
472 $localize_vars = array(
473 '_is_pro_active' => _is_cartflows_pro(),
474
475 // Flow and its rest fields.
476 'flow' => CARTFLOWS_FLOW_POST_TYPE,
477 'flow_fields' => array(
478 'id',
479 'title',
480 'flow_type',
481 'page_builder',
482 'flow_steps',
483 'licence_status',
484 'featured_image_url',
485 'featured_media', // @required for field `featured_image_url`.
486 ),
487
488 // Flow type and rest fields.
489 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
490 'flow_type_fields' => array(
491 'id',
492 'name',
493 'slug',
494 ),
495
496 // Flow page builder and rest fields.
497 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
498 'flow_page_builder_fields' => array(
499 'id',
500 'name',
501 'slug',
502 ),
503
504 // Step page builder and rest fields.
505 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
506 'step_page_builder_fields' => array(
507 'id',
508 'name',
509 'slug',
510 ),
511
512 // Step and its rest fields.
513 'step' => CARTFLOWS_STEP_POST_TYPE,
514 'step_fields' => array(
515 'title',
516 'featured_image_url',
517 'featured_media', // @required for field `featured_image_url`.
518 'id',
519 'flow_type',
520 'step_type',
521 'page_builder',
522 'licence_status',
523 ),
524
525 // Step type and its rest fields.
526 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
527 'step_type_fields' => array(
528 'id',
529 'name',
530 'slug',
531 ),
532
533 'domain_url' => CARTFLOWS_DOMAIN_URL,
534 'server_url' => CARTFLOWS_TEMPLATES_URL,
535 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
536 'site_url' => site_url(),
537 'admin_url' => admin_url(),
538 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
539 'ajaxurl' => admin_url( 'admin-ajax.php' ),
540 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
541
542 'required_plugins' => array(
543 'elementor' => array(
544 'button_title' => $this->get_plugin_button_string( 'elementor/elementor.php', 'Elementor' ),
545 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
546 'plugins' => array(
547 array(
548 'slug' => 'elementor', // For download from wp.org.
549 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
550 ),
551 ),
552 ),
553 ),
554 );
555
556 // Add thickbox.
557 add_thickbox();
558
559 wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
560 wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
561 }
562
563 /**
564 * Load Template
565 *
566 * @since 1.0.0
567 *
568 * @hook cartflows_load_steps
569 * @return void
570 */
571 function load_templates() {
572
573 check_ajax_referer( 'cf-load-steps', 'security' );
574
575 $args = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
576 $templates = CartFlows_API::get_instance()->get_templates( $args );
577
578 if ( $templates['templates_count'] ) {
579 wp_send_json_success( $templates );
580 } else {
581 wp_send_json_error( $templates );
582 }
583 wp_die();
584 }
585
586 /**
587 * Import.
588 *
589 * @since 1.0.0
590 *
591 * @hook wp_ajax_cartflows_import_flow_step
592 * @return void
593 */
594 function import_flow() {
595
596 check_ajax_referer( 'cf-import-flow-step', 'security' );
597
598 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
599 $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
600
601 wcf()->logger->import_log( '------------------------------------' );
602 wcf()->logger->import_log( 'STARTED! Importing FLOW' );
603 wcf()->logger->import_log( '------------------------------------' );
604 wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
605
606 $response = CartFlows_API::get_instance()->get_template( $template_id );
607
608 if ( false === $response['success'] ) {
609 wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
610 wp_send_json_error( $response );
611 }
612
613 wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );
614
615 $new_step_id = wp_insert_post(
616 array(
617 'post_type' => CARTFLOWS_STEP_POST_TYPE,
618 'post_title' => $response['title'],
619 'post_content' => '',
620 'post_status' => 'publish',
621 )
622 );
623
624 if ( is_wp_error( $new_step_id ) ) {
625 wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
626 wp_send_json_error( $new_step_id );
627 }
628
629 wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
630 // insert post meta.
631 update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
632 wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
633
634 /**
635 * Import & Set type.
636 */
637 $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
638 $term_slug = '';
639 if ( $term ) {
640
641 $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
642 $term_exist = term_exists( $term->name, $taxonomy );
643
644 if ( empty( $term_exist ) ) {
645 $terms = array(
646 array(
647 'name' => $term->name,
648 ),
649 );
650
651 Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
652 wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
653 }
654
655 $current_term = term_exists( $term->name, $taxonomy );
656
657 // Set type object.
658 $data = get_term( $current_term['term_id'], $taxonomy );
659 $term_slug = $data->slug;
660 $term_name = $data->name;
661 wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
662 wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
663
664 // Set type.
665 update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
666 wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
667 }
668
669 // Set flow.
670 wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
671 wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
672
673 /**
674 * Update steps for the current flow.
675 */
676 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
677
678 if ( ! is_array( $flow_steps ) ) {
679 $flow_steps = array();
680 }
681
682 $flow_steps[] = array(
683 'id' => $new_step_id,
684 'title' => $response['title'],
685 'type' => $term_slug,
686 );
687 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
688 wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
689
690 // Import Post Meta.
691 self::import_post_meta( $new_step_id, $response );
692
693 wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
694 wcf()->logger->import_log( '------------------------------------' );
695 wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
696 wcf()->logger->import_log( '------------------------------------' );
697
698 do_action( 'cartflows_import_complete' );
699 wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
700
701 // Batch Process.
702 do_action( 'cartflows_after_template_import', $new_step_id, $response );
703
704 /**
705 * End
706 */
707 wp_send_json_success( $new_step_id );
708 }
709
710 /**
711 * Import Step.
712 *
713 * @since 1.0.0
714 * @hook wp_ajax_cartflows_step_import
715 *
716 * @return void
717 */
718 function create_default_flow() {
719
720 check_ajax_referer( 'cf-default-flow', 'security' );
721
722 // Create post object.
723 $new_flow_post = array(
724 'post_content' => '',
725 'post_status' => 'publish',
726 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
727 );
728
729 // Insert the post into the database.
730 $flow_id = wp_insert_post( $new_flow_post );
731
732 if ( is_wp_error( $flow_id ) ) {
733 wp_send_json_error( $flow_id->get_error_message() );
734 }
735
736 $flow_steps = array();
737
738 $steps_data = array(
739 'landing' => __( 'Landing Page', 'cartflows' ),
740 'checkout' => __( 'Checkout Page', 'cartflows' ),
741 'thankyou' => __( 'Thank You Page', 'cartflows' ),
742 );
743
744 foreach ( $steps_data as $slug => $title ) {
745
746 $post_content = '';
747
748 switch ( $slug ) {
749 case 'checkout':
750 $post_content = '';
751 break;
752 case 'thankyou':
753 $post_content = '';
754 break;
755 default:
756 $post_content = '';
757 break;
758 }
759
760 $step_id = wp_insert_post(
761 array(
762 'post_type' => CARTFLOWS_STEP_POST_TYPE,
763 'post_title' => $title,
764 'post_content' => $post_content,
765 'post_status' => 'publish',
766 )
767 );
768
769 if ( is_wp_error( $step_id ) ) {
770 wp_send_json_error( $step_id->get_error_message() );
771 }
772
773 if ( $step_id ) {
774
775 $flow_steps[] = array(
776 'id' => $step_id,
777 'title' => $title,
778 'type' => $slug,
779 );
780
781 // insert post meta.
782 update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
783 update_post_meta( $step_id, 'wcf-step-type', $slug );
784
785 wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
786 wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
787 }
788 }
789
790 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
791
792 wp_send_json_success( $flow_id );
793 }
794
795 /**
796 * Create Flow
797 *
798 * @return void
799 */
800 function create_flow() {
801
802 check_ajax_referer( 'cf-create-flow', 'security' );
803
804 // Create post object.
805 $new_flow_post = array(
806 'post_content' => '',
807 'post_status' => 'publish',
808 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
809 );
810
811 // Insert the post into the database.
812 $flow_id = wp_insert_post( $new_flow_post );
813
814 if ( is_wp_error( $flow_id ) ) {
815 wp_send_json_error( $flow_id->get_error_message() );
816 }
817
818 wp_send_json_success( $flow_id );
819 }
820
821 /**
822 * Create Step
823 *
824 * @return void
825 */
826 function import_step() {
827
828 check_ajax_referer( 'cf-step-import', 'security' );
829
830 $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
831 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
832 $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
833 $step_type = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
834 $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;
835
836 $cartflow_meta = Cartflows_Flow_Meta::get_instance();
837
838 $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
839
840 wcf()->logger->import_log( '------------------------------------' );
841 wcf()->logger->import_log( 'STARTED! Importing STEP' );
842 wcf()->logger->import_log( '------------------------------------' );
843
844 if ( empty( $template_id ) || empty( $post_id ) ) {
845 /* translators: %s: template ID */
846 $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
847 wcf()->logger->import_log( $data );
848 wp_send_json_error( $data );
849 }
850
851 wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
852
853 $response = CartFlows_API::get_instance()->get_template( $template_id );
854
855 wcf()->logger->import_log( json_encode( $response ) );
856
857 // Import Post Meta.
858 self::import_post_meta( $post_id, $response );
859
860 do_action( 'cartflows_import_complete' );
861
862 // Batch Process.
863 do_action( 'cartflows_after_template_import', $post_id, $response );
864
865 wcf()->logger->import_log( '------------------------------------' );
866 wcf()->logger->import_log( 'COMPLETE! Importing Step' );
867 wcf()->logger->import_log( '------------------------------------' );
868
869 wp_send_json_success( $post_id );
870 }
871
872 /**
873 * Import Step.
874 *
875 * @since 1.0.0
876 * @hook wp_ajax_cartflows_step_create_blank
877 *
878 * @return void
879 */
880 function step_create_blank() {
881
882 check_ajax_referer( 'cf-step-create-blank', 'security' );
883
884 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
885 $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
886 $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
887
888 if ( empty( $flow_id ) || empty( $step_type ) ) {
889 /* translators: %s: flow ID */
890 $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
891 wcf()->logger->import_log( $data );
892 wp_send_json_error( $data );
893 }
894
895 wcf()->logger->import_log( '------------------------------------' );
896 wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
897
898 $step_type_title = str_replace( '-', ' ', $step_type );
899 $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
900
901 $new_step_id = wp_insert_post(
902 array(
903 'post_type' => CARTFLOWS_STEP_POST_TYPE,
904 'post_title' => $step_title,
905 'post_content' => '',
906 'post_status' => 'publish',
907 )
908 );
909
910 // insert post meta.
911 update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
912
913 $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
914 $term_exist = term_exists( $step_type_title, $taxonomy );
915
916 if ( empty( $term_exist ) ) {
917 $terms = array(
918 array(
919 'name' => $step_type_title,
920 ),
921 );
922
923 Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
924 wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
925 }
926
927 $current_term = term_exists( $step_type_title, $taxonomy );
928
929 // Set type object.
930 $data = get_term( $current_term['term_id'], $taxonomy );
931 $step_slug = $data->slug;
932 wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
933 wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
934
935 // Set type.
936 update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
937 wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
938
939 // Set flow.
940 wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
941 wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
942
943 CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
944
945 wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
946 wcf()->logger->import_log( '------------------------------------' );
947
948 wp_send_json_success( $new_step_id );
949 }
950
951 /**
952 * Import Post Meta
953 *
954 * @since 1.0.0
955 *
956 * @param integer $post_id Post ID.
957 * @param array $response Post meta.
958 * @return void
959 */
960 public static function import_post_meta( $post_id, $response ) {
961
962 $metadata = (array) $response['post_meta'];
963
964 foreach ( $metadata as $meta_key => $meta_value ) {
965 $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
966
967 if ( $meta_value ) {
968
969 if ( is_serialized( $meta_value, true ) ) {
970 $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
971 } elseif ( is_array( $meta_value ) ) {
972 $raw_data = json_decode( stripslashes( $meta_value ), true );
973 } else {
974 $raw_data = $meta_value;
975 }
976
977 if ( '_elementor_data' === $meta_key ) {
978 if ( is_array( $raw_data ) ) {
979 $raw_data = wp_slash( json_encode( $raw_data ) );
980 } else {
981 $raw_data = wp_slash( $raw_data );
982 }
983 wcf()->logger->import_log( $raw_data );
984 }
985
986 if ( is_array( $raw_data ) ) {
987 wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
988 } else {
989
990 if ( ! is_object( $raw_data ) ) {
991 wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
992 }
993 }
994
995 update_post_meta( $post_id, $meta_key, $raw_data );
996 }
997 }
998 }
999
1000 /**
1001 * Import Template for Elementor
1002 *
1003 * @since 1.0.0
1004 *
1005 * @param integer $post_id Post ID.
1006 * @param array $response Post meta.
1007 * @param array $page_build_data Page build data.
1008 * @return void
1009 */
1010 public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1011 if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1012 $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1013 wcf()->logger->import_log( $data );
1014 wp_send_json_error( $data );
1015 }
1016
1017 require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1018
1019 wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1020
1021 $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1022 $obj->import_single_template( $post_id );
1023
1024 wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1025 }
1026
1027 /**
1028 * Supported post types
1029 *
1030 * @since 1.0.0
1031 *
1032 * @return array Supported post types.
1033 */
1034 public static function supported_post_types() {
1035 return apply_filters(
1036 'cartflows_supported_post_types',
1037 array(
1038 CARTFLOWS_FLOW_POST_TYPE,
1039 )
1040 );
1041 }
1042
1043 /**
1044 * Check supported post type
1045 *
1046 * @since 1.0.0
1047 *
1048 * @param string $post_type Post type.
1049 * @return boolean Supported post type status.
1050 */
1051 public static function is_supported_post( $post_type = '' ) {
1052 if ( in_array( $post_type, self::supported_post_types() ) ) {
1053 return true;
1054 }
1055
1056 return false;
1057 }
1058
1059 /**
1060 * Set steps to the flow
1061 *
1062 * @param integer $flow_id Flow ID.
1063 * @param integer $new_step_id New step ID.
1064 * @param string $step_title Flow Type.
1065 * @param string $step_slug Flow Type.
1066 */
1067 function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1068 // Update steps for the current flow.
1069 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1070
1071 if ( ! is_array( $flow_steps ) ) {
1072 $flow_steps = array();
1073 }
1074
1075 $flow_steps[] = array(
1076 'id' => $new_step_id,
1077 'title' => $step_title,
1078 'type' => $step_slug,
1079 );
1080 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1081 wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
1082 }
1083
1084 /**
1085 * Localize variables in admin
1086 *
1087 * @param array $vars variables.
1088 */
1089 function localize_vars( $vars ) {
1090
1091 $ajax_actions = array(
1092 'cf_step_import',
1093 'cf_load_steps',
1094 'cf_create_flow',
1095 'cf_default_flow',
1096 'cf_step_create_blank',
1097 'cf_import_flow_step',
1098 );
1099
1100 foreach ( $ajax_actions as $action ) {
1101
1102 $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1103 }
1104
1105 return $vars;
1106 }
1107
1108 /**
1109 * Ajax action to activate plugin
1110 */
1111 public function activate_plugin() {
1112
1113 $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';
1114
1115 if ( ! is_plugin_active( $plugin_slug ) ) {
1116
1117 $activate = activate_plugin( $plugin_slug, '', false, true );
1118
1119 if ( is_wp_error( $activate ) ) {
1120 wp_send_json_error();
1121 }
1122 }
1123
1124 wp_send_json_success();
1125 }
1126
1127 }
1128
1129 /**
1130 * Initialize class object with 'get_instance()' method
1131 */
1132 CartFlows_Importer::get_instance();
1133
1134 endif;
1135