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

1,037 lines 32.9 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 </span>
279 <div class="template-id-container">
280 <h3 class="template-name"> Blank </h3>
281 <div class="template-actions">
282 <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
283 </div>
284 </div>
285 </div>
286 </div>
287 </script>
288
289 <?php
290 // Templates data.
291 ?>
292 <script type="text/template" id="tmpl-cartflows-steps-list">
293 <# if ( data.items.length ) { #>
294 <# for ( key in data.items ) { #>
295 <#
296 var flow_steps = [];
297 if( data.items[ key ].flow_steps ) {
298 flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
299 return value['id'];
300 });
301 }
302 #>
303 <div class="inner">
304 <div class="template">
305 <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 }}">
306 <div class="template-screenshot">
307 <# if( data.items[ key ].featured_image_url ) { #>
308 <img src="{{ data.items[ key ].featured_image_url }}" />
309 <# } else { #>
310 <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
311 <# } #>
312 </div>
313 <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>
314 <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
315 <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
316 <# } #>
317 </span>
318 <div class="template-id-container">
319 <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
320 <div class="template-actions">
321 <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
322 <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>
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 <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
346
347 <# console.log( data.args.show_all ) #>
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 </script>
363
364 <?php
365 // Step Type.
366 ?>
367 <script type="text/template" id="tmpl-cartflows-step-types">
368 <ul class="wcf-tab nav-tabs">
369 <# if( data.items_count ) { #>
370 <# for( key in data.items ) { #>
371 <# console.log( data.items[ key ].id ) #>
372 <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
373 <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
374 </li>
375 <# } #>
376 <# } #>
377 </ul>
378 </script>
379
380 <?php
381 // Add to library button.
382 ?>
383 <script type="text/template" id="tmpl-templator-add-to-library">
384 <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>
385 </script>
386 <?php
387 }
388
389 /**
390 * Enqueue scripts
391 *
392 * @since 1.0.0
393 *
394 * @hook admin_enqueue_scripts
395 * @param string $hook Current page hook.
396 */
397 function scripts( $hook = '' ) {
398
399 if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
400 return;
401 }
402
403 wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
404 wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
405 wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
406 wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
407
408 $localize_vars = array(
409 '_is_pro_active' => _is_cartflows_pro(),
410
411 // Flow and its rest fields.
412 'flow' => CARTFLOWS_FLOW_POST_TYPE,
413 'flow_fields' => array(
414 'id',
415 'title',
416 'flow_type',
417 'flow_steps',
418 'licence_status',
419 'featured_image_url',
420 'featured_media', // @required for field `featured_image_url`.
421 ),
422
423 // Flow type and rest fields.
424 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
425 'flow_type_fields' => array(
426 'id',
427 'name',
428 'slug',
429 ),
430
431 // Step and its rest fields.
432 'step' => CARTFLOWS_STEP_POST_TYPE,
433 'step_fields' => array(
434 'title',
435 'featured_image_url',
436 'featured_media', // @required for field `featured_image_url`.
437 'id',
438 'flow_type',
439 'licence_status',
440 ),
441
442 // Step type and its rest fields.
443 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
444 'step_type_fields' => array(
445 'id',
446 'name',
447 'slug',
448 ),
449
450 'domain_url' => CARTFLOWS_DOMAIN_URL,
451 'server_url' => CARTFLOWS_TEMPLATES_URL,
452 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
453 'site_url' => site_url(),
454 'admin_url' => admin_url(),
455 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
456 'ajaxurl' => admin_url( 'admin-ajax.php' ),
457 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
458 );
459
460 // Add thickbox.
461 add_thickbox();
462
463 wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
464 wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
465 }
466
467 /**
468 * Load Template
469 *
470 * @since 1.0.0
471 *
472 * @hook cartflows_load_steps
473 * @return void
474 */
475 function load_templates() {
476
477 check_ajax_referer( 'cf-load-steps', 'security' );
478
479 $args = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
480 $templates = CartFlows_API::get_instance()->get_templates( $args );
481
482 if ( $templates['templates_count'] ) {
483 wp_send_json_success( $templates );
484 } else {
485 wp_send_json_error( $templates );
486 }
487 wp_die();
488 }
489
490 /**
491 * Import.
492 *
493 * @since 1.0.0
494 *
495 * @hook wp_ajax_cartflows_import_flow_step
496 * @return void
497 */
498 function import_flow() {
499
500 check_ajax_referer( 'cf-import-flow-step', 'security' );
501
502 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
503 $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
504
505 wcf()->logger->import_log( '------------------------------------' );
506 wcf()->logger->import_log( 'STARTED! Importing FLOW' );
507 wcf()->logger->import_log( '------------------------------------' );
508 wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
509
510 $response = CartFlows_API::get_instance()->get_template( $template_id );
511
512 if ( false === $response['success'] ) {
513 wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
514 wp_send_json_error( $response );
515 }
516
517 wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );
518
519 $new_step_id = wp_insert_post(
520 array(
521 'post_type' => CARTFLOWS_STEP_POST_TYPE,
522 'post_title' => $response['title'],
523 'post_content' => '',
524 'post_status' => 'publish',
525 )
526 );
527
528 if ( is_wp_error( $new_step_id ) ) {
529 wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
530 wp_send_json_error( $new_step_id );
531 }
532
533 wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
534 // insert post meta.
535 update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
536 wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
537
538 /**
539 * Import & Set type.
540 */
541 $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
542 $term_slug = '';
543 if ( $term ) {
544
545 $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
546 $term_exist = term_exists( $term->name, $taxonomy );
547
548 if ( empty( $term_exist ) ) {
549 $terms = array(
550 array(
551 'name' => $term->name,
552 ),
553 );
554
555 Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
556 wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
557 }
558
559 $current_term = term_exists( $term->name, $taxonomy );
560
561 // Set type object.
562 $data = get_term( $current_term['term_id'], $taxonomy );
563 $term_slug = $data->slug;
564 $term_name = $data->name;
565 wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
566 wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
567
568 // Set type.
569 update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
570 wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
571 }
572
573 // Set flow.
574 wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
575 wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
576
577 /**
578 * Update steps for the current flow.
579 */
580 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
581
582 if ( ! is_array( $flow_steps ) ) {
583 $flow_steps = array();
584 }
585
586 $flow_steps[] = array(
587 'id' => $new_step_id,
588 'title' => $response['title'],
589 'type' => $term_slug,
590 );
591 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
592 wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
593
594 // Import Post Meta.
595 self::import_post_meta( $new_step_id, $response );
596
597 wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
598 wcf()->logger->import_log( '------------------------------------' );
599 wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
600 wcf()->logger->import_log( '------------------------------------' );
601
602 do_action( 'cartflows_import_complete' );
603 wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
604
605 // Batch Process.
606 do_action( 'cartflows_after_template_import', $new_step_id, $response );
607
608 /**
609 * End
610 */
611 wp_send_json_success( $new_step_id );
612 }
613
614 /**
615 * Import Step.
616 *
617 * @since 1.0.0
618 * @hook wp_ajax_cartflows_step_import
619 *
620 * @return void
621 */
622 function create_default_flow() {
623
624 check_ajax_referer( 'cf-default-flow', 'security' );
625
626 // Create post object.
627 $new_flow_post = array(
628 'post_content' => '',
629 'post_status' => 'publish',
630 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
631 );
632
633 // Insert the post into the database.
634 $flow_id = wp_insert_post( $new_flow_post );
635
636 if ( is_wp_error( $flow_id ) ) {
637 wp_send_json_error( $flow_id->get_error_message() );
638 }
639
640 $flow_steps = array();
641
642 $steps_data = array(
643 'landing' => __( 'Landing Page', 'cartflows' ),
644 'checkout' => __( 'Checkout Page', 'cartflows' ),
645 'thankyou' => __( 'Thank You Page', 'cartflows' ),
646 );
647
648 foreach ( $steps_data as $slug => $title ) {
649
650 $post_content = '';
651
652 switch ( $slug ) {
653 case 'checkout':
654 $post_content = '';
655 break;
656 case 'thankyou':
657 $post_content = '';
658 break;
659 default:
660 $post_content = '';
661 break;
662 }
663
664 $step_id = wp_insert_post(
665 array(
666 'post_type' => CARTFLOWS_STEP_POST_TYPE,
667 'post_title' => $title,
668 'post_content' => $post_content,
669 'post_status' => 'publish',
670 )
671 );
672
673 if ( is_wp_error( $step_id ) ) {
674 wp_send_json_error( $step_id->get_error_message() );
675 }
676
677 if ( $step_id ) {
678
679 $flow_steps[] = array(
680 'id' => $step_id,
681 'title' => $title,
682 'type' => $slug,
683 );
684
685 // insert post meta.
686 update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
687 update_post_meta( $step_id, 'wcf-step-type', $slug );
688
689 wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
690 wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
691 }
692 }
693
694 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
695
696 wp_send_json_success( $flow_id );
697 }
698
699 /**
700 * Create Flow
701 *
702 * @return void
703 */
704 function create_flow() {
705
706 check_ajax_referer( 'cf-create-flow', 'security' );
707
708 // Create post object.
709 $new_flow_post = array(
710 'post_content' => '',
711 'post_status' => 'publish',
712 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
713 );
714
715 // Insert the post into the database.
716 $flow_id = wp_insert_post( $new_flow_post );
717
718 if ( is_wp_error( $flow_id ) ) {
719 wp_send_json_error( $flow_id->get_error_message() );
720 }
721
722 wp_send_json_success( $flow_id );
723 }
724
725 /**
726 * Create Step
727 *
728 * @return void
729 */
730 function import_step() {
731
732 check_ajax_referer( 'cf-step-import', 'security' );
733
734 $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
735 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
736 $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
737 $step_type = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
738 $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;
739
740 $cartflow_meta = Cartflows_Flow_Meta::get_instance();
741
742 $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
743
744 wcf()->logger->import_log( '------------------------------------' );
745 wcf()->logger->import_log( 'STARTED! Importing STEP' );
746 wcf()->logger->import_log( '------------------------------------' );
747
748 if ( empty( $template_id ) || empty( $post_id ) ) {
749 /* translators: %s: template ID */
750 $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
751 wcf()->logger->import_log( $data );
752 wp_send_json_error( $data );
753 }
754
755 wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
756
757 $response = CartFlows_API::get_instance()->get_template( $template_id );
758
759 wcf()->logger->import_log( json_encode( $response ) );
760
761 // Import Post Meta.
762 self::import_post_meta( $post_id, $response );
763
764 do_action( 'cartflows_import_complete' );
765
766 // Batch Process.
767 do_action( 'cartflows_after_template_import', $post_id, $response );
768
769 wcf()->logger->import_log( '------------------------------------' );
770 wcf()->logger->import_log( 'COMPLETE! Importing Step' );
771 wcf()->logger->import_log( '------------------------------------' );
772
773 wp_send_json_success( $post_id );
774 }
775
776 /**
777 * Import Step.
778 *
779 * @since 1.0.0
780 * @hook wp_ajax_cartflows_step_create_blank
781 *
782 * @return void
783 */
784 function step_create_blank() {
785
786 check_ajax_referer( 'cf-step-create-blank', 'security' );
787
788 $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
789 $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
790 $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
791
792 if ( empty( $flow_id ) || empty( $step_type ) ) {
793 /* translators: %s: flow ID */
794 $data = sprintf( __( 'Invalid flow id %1$s or step type %2$s.', 'cartflows' ), $flow_id, $step_type );
795 wcf()->logger->import_log( $data );
796 wp_send_json_error( $data );
797 }
798
799 wcf()->logger->import_log( '------------------------------------' );
800 wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
801
802 $step_type_title = str_replace( '-', ' ', $step_type );
803 $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
804
805 $new_step_id = wp_insert_post(
806 array(
807 'post_type' => CARTFLOWS_STEP_POST_TYPE,
808 'post_title' => $step_title,
809 'post_content' => '',
810 'post_status' => 'publish',
811 )
812 );
813
814 // insert post meta.
815 update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
816
817 $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
818 $term_exist = term_exists( $step_type_title, $taxonomy );
819
820 if ( empty( $term_exist ) ) {
821 $terms = array(
822 array(
823 'name' => $step_type_title,
824 ),
825 );
826
827 Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
828 wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
829 }
830
831 $current_term = term_exists( $step_type_title, $taxonomy );
832
833 // Set type object.
834 $data = get_term( $current_term['term_id'], $taxonomy );
835 $step_slug = $data->slug;
836 wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
837 wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
838
839 // Set type.
840 update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
841 wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
842
843 // Set flow.
844 wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
845 wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
846
847 CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
848
849 wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
850 wcf()->logger->import_log( '------------------------------------' );
851
852 wp_send_json_success( $new_step_id );
853 }
854
855 /**
856 * Import Post Meta
857 *
858 * @since 1.0.0
859 *
860 * @param integer $post_id Post ID.
861 * @param array $response Post meta.
862 * @return void
863 */
864 public static function import_post_meta( $post_id, $response ) {
865
866 $metadata = (array) $response['post_meta'];
867
868 foreach ( $metadata as $meta_key => $meta_value ) {
869 $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
870
871 if ( $meta_value ) {
872
873 if ( is_serialized( $meta_value, true ) ) {
874 $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
875 } elseif ( is_array( $meta_value ) ) {
876 $raw_data = json_decode( stripslashes( $meta_value ), true );
877 } else {
878 $raw_data = $meta_value;
879 }
880
881 if ( '_elementor_data' === $meta_key ) {
882
883 if ( is_array( $raw_data ) ) {
884 $raw_data = wp_slash( json_encode( $raw_data ) );
885 } else {
886 $raw_data = wp_slash( $raw_data );
887 }
888 wcf()->logger->import_log( $raw_data );
889 }
890
891 if ( is_array( $raw_data ) ) {
892 wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
893 } else {
894 wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
895 }
896
897 update_post_meta( $post_id, $meta_key, $raw_data );
898 }
899 }
900 }
901
902 /**
903 * Import Template for Elementor
904 *
905 * @since 1.0.0
906 *
907 * @param integer $post_id Post ID.
908 * @param array $response Post meta.
909 * @param array $page_build_data Page build data.
910 * @return void
911 */
912 public static function import_template_elementor( $post_id, $response, $page_build_data ) {
913 if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
914 $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
915 wcf()->logger->import_log( $data );
916 wp_send_json_error( $data );
917 }
918
919 require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
920
921 wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
922
923 $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
924 $obj->import_single_template( $post_id );
925
926 wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
927 }
928
929 /**
930 * Supported post types
931 *
932 * @since 1.0.0
933 *
934 * @return array Supported post types.
935 */
936 public static function supported_post_types() {
937 return apply_filters(
938 'cartflows_supported_post_types',
939 array(
940 CARTFLOWS_FLOW_POST_TYPE,
941 )
942 );
943 }
944
945 /**
946 * Check supported post type
947 *
948 * @since 1.0.0
949 *
950 * @param string $post_type Post type.
951 * @return boolean Supported post type status.
952 */
953 public static function is_supported_post( $post_type = '' ) {
954 if ( in_array( $post_type, self::supported_post_types() ) ) {
955 return true;
956 }
957
958 return false;
959 }
960
961 /**
962 * Set steps to the flow
963 *
964 * @param integer $flow_id Flow ID.
965 * @param integer $new_step_id New step ID.
966 * @param string $step_title Flow Type.
967 * @param string $step_slug Flow Type.
968 */
969 function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
970 // Update steps for the current flow.
971 $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
972
973 if ( ! is_array( $flow_steps ) ) {
974 $flow_steps = array();
975 }
976
977 $flow_steps[] = array(
978 'id' => $new_step_id,
979 'title' => $step_title,
980 'type' => $step_slug,
981 );
982 update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
983 wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
984 }
985
986 /**
987 * Localize variables in admin
988 *
989 * @param array $vars variables.
990 */
991 function localize_vars( $vars ) {
992
993 $ajax_actions = array(
994 'cf_step_import',
995 'cf_load_steps',
996 'cf_create_flow',
997 'cf_default_flow',
998 'cf_step_create_blank',
999 'cf_import_flow_step',
1000 );
1001
1002 foreach ( $ajax_actions as $action ) {
1003
1004 $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1005 }
1006
1007 return $vars;
1008 }
1009
1010 /**
1011 * Ajax action to activate plugin
1012 */
1013 public function activate_plugin() {
1014
1015 $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';
1016
1017 if ( ! is_plugin_active( $plugin_slug ) ) {
1018
1019 $activate = activate_plugin( $plugin_slug, '', false, true );
1020
1021 if ( is_wp_error( $activate ) ) {
1022 wp_send_json_error();
1023 }
1024 }
1025
1026 wp_send_json_success();
1027 }
1028
1029 }
1030
1031 /**
1032 * Initialize class object with 'get_instance()' method
1033 */
1034 CartFlows_Importer::get_instance();
1035
1036 endif;
1037