PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 1.1.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v1.1.0
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.0, at classes/class-cartflows-importer.php

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