# cartflows/1.1.1/classes/class-cartflows-importer.php

CartFlows – Funnel Builder &amp; Checkout Plugin for WooCommerce, version 1.1.1. 1,135 lines.

- Page: https://pluginprobe.com/plugins/cartflows/1.1.1/code/classes/class-cartflows-importer.php
- Raw: https://pluginprobe.com/plugins/cartflows/1.1.1/raw/classes/class-cartflows-importer.php
- Modified: 2019-01-02T12:49:28+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/cartflows/1.1.1/code/classes/class-cartflows-importer.php#L10-L20`.

```php
<?php
/**
 * CartFlows Admin
 *
 * @package CartFlows
 * @since 1.0.0
 */

if ( ! class_exists( 'CartFlows_Importer' ) ) :

	/**
	 * CartFlows Import
	 *
	 * @since 1.0.0
	 */
	class CartFlows_Importer {

		/**
		 * Instance
		 *
		 * @since 1.0.0
		 * @access private
		 * @var object Class object.
		 */
		private static $instance;

		/**
		 * Installed Plugins
		 *
		 * @since 1.0.0
		 * @access private
		 * @var object Class object.
		 */
		private static $installed_plugins = null;

		/**
		 * Initiator
		 *
		 * @since 1.0.0
		 * @return object initialized object of class.
		 */
		public static function get_instance() {
			if ( ! isset( self::$instance ) ) {
				self::$instance = new self;
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 *
		 * @since 1.0.0
		 */
		public function __construct() {
			add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
			add_action( 'wp_ajax_cartflows_load_steps', array( $this, 'load_templates' ) );
			add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
			add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
			add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
			add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
			add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
			add_action( 'admin_footer', array( $this, 'js_templates' ) );
			add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );

			add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );

			add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
		}

		/**
		 * Clear Cache.
		 *
		 * @since 1.0.0
		 */
		public function clear_cache() {
			// Clear 'Elementor' file cache.
			if ( class_exists( '\Elementor\Plugin' ) ) {
				Elementor\Plugin::$instance->files_manager->clear_cache();
			}
		}

		/**
		 * JS Templates
		 *
		 * @since 1.0.0
		 *
		 * @return void
		 */
		function js_templates() {

			// Loading Templates.
			?>
			<script type="text/template" id="tmpl-cartflows-step-loading">
				<div class="template-message-block cartflows-step-loading">
					<h2>
						<span class="spinner"></span>
						<?php _e( 'Loading Steps', 'cartflows' ); ?>
					</h2>
					<p class="description"><?php _e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
				</div>
			</script>

			<?php
			// Search Templates.
			?>
			<script type="text/template" id="tmpl-cartflows-searching-templates">
				<div class="template-message-block cartflows-searching-templates">
					<h2>
						<span class="spinner"></span>
						<?php _e( 'Searching Template..', 'cartflows' ); ?>
					</h2>
					<p class="description"><?php _e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
				</div>
			</script>

			<?php
			// CartFlows Importing Template.
			?>
			<script type="text/template" id="tmpl-cartflows-step-importing">
				<div class="template-message-block cartflows-step-importing">
					<h2><span class="spinner"></span> <?php _e( 'Importing..', 'cartflows' ); ?></h2>
				</div>
			</script>

			<?php
			// CartFlows Imported.
			?>
			<script type="text/template" id="tmpl-cartflows-step-imported">
				<div class="template-message-block cartflows-step-imported">
					<h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
					<p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
			</script>

			<?php
			// No templates.
			?>
			<script type="text/template" id="tmpl-cartflows-no-steps">
				<div class="cartflows-no-steps">
					<div class="template-message-block">
						<h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
						<p class="description"></p>
					</div>
				</div>
			</script>

			<?php
			// No templates.
			?>
			<script type="text/template" id="tmpl-cartflows-no-flows">
				<div class="cartflows-no-flows">
					<div class="template-message-block">
						<h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
						<p class="description"></p>
					</div>
				</div>
			</script>

			<?php
			// Error handling.
			?>
			<script type="text/template" id="tmpl-templator-error">
				<div class="notice notice-error"><p>{{ data }}</p></div>
			</script>

			<?php
			// Redirect to Elementor.
			?>
			<script type="text/template" id="tmpl-templator-redirect-to-elementor">
				<div class="template-message-block templator-redirect-to-elementor">
					<h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
					<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>
			</script>

			<?php
			/**
			 * Responsive Buttons
			 */
			?>
			<script type="text/template" id="tmpl-cartflows-responsive-view">
				<span class="responsive-view">
					<span class="actions">
						<a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
						<a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
						<a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
					</span>
				</span>
			</script>

			<?php
			// Templates data.
			?>
			<script type="text/template" id="tmpl-cartflows-flows-list">

				<# if ( data.items.length ) { #>
					<# for ( key in data.items ) { #>
					<#
						var flow_steps = [];
						if( data.items[ key ].flow_steps ) {
							flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
								return value['id'];
							});
						}
						#>
						<# console.log( 'here ' + key ); #>
						<div class="inner">
							<div class="template">
								<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 }}">
									<div class="template-screenshot">
										<# if( data.items[ key ].featured_image_url ) { #>
											<img src="{{ data.items[ key ].featured_image_url }}" />
										<# } else { #>
											<img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
										<# } #>
									</div>
									<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>
									<# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
										<span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
									<# } #>
								</span>
								<div class="template-id-container">
									<h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
									<div class="template-actions">

									<#
									if( data.items[ key ].page_builder.slug ) {
										required_plugin_group = data.items[ key ].page_builder.slug;
									} else {
										required_plugin_group = '';
									}

									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 ) {
										import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
									} else {
										import_btn_title = 'Import';
									} #>

									<# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
										<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>
									<# } else if( CartFlowsImportVars._is_pro_active ) { #>
										<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>
									<# } else { #>
										<a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
									<# } #>
									</div>
								</div>
							</div>
						</div>
					<# } #>
				<# } #>
			</script>

			<?php
			// Empty Step.
			?>
			<script type="text/template" id="tmpl-cartflows-create-blank-step">
				<div class="inner">
					<div class="template">
						<span class="thumbnail site-preview cartflows-flow-preview">
							<div class="template-screenshot">
								<img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
							</div>
							<div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
						</span>
						<div class="template-id-container">
							<h3 class="template-name"> Blank </h3>
							<div class="template-actions">
								<a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
							</div>
						</div>
					</div>
				</div>
			</script>

			<?php
			// Templates data.
			?>
			<script type="text/template" id="tmpl-cartflows-steps-list">
				<# if ( data.items.length ) { #>
					<# for ( key in data.items ) { #>
					<#
						var flow_steps = [];
						if( data.items[ key ].flow_steps ) {
							flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
								return value['id'];
							});
						}
						#>
						<div class="inner">
							<div class="template">
								<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 }}">
									<div class="template-screenshot">
										<# if( data.items[ key ].featured_image_url ) { #>
											<img src="{{ data.items[ key ].featured_image_url }}" />
										<# } else { #>
											<img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
										<# } #>
									</div>
									<div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
									<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>
									<# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
										<span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
									<# } #>
								</span>
								<div class="template-id-container">
									<h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
									<div class="template-actions">

									<#

									var required_plugin_group = data.items[ key ].page_builder.slug || '';
									var step_slug  = data.items[ key ].step_type.slug || '';
									var step_title = data.items[ key ].step_type.name || '';

									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 ) {
										import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
									} else {
										import_btn_title = 'Import';
									} #>

									<# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
										<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>
									<# } else if( CartFlowsImportVars._is_pro_active ) { #>
										<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>
									<# } else { #>
										<a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
									<# } #>
									</div>
								</div>
							</div>
						</div>
					<# } #>
				<# } #>
			</script>

			<?php
			/**
			 * TMPL - Filters
			 */
			?>
			<script type="text/template" id="tmpl-cartflows-term-filters">

				<# if ( data ) { #>

					<# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #>
						<ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">

							<# if ( data.args.show_all ) { #>
								<li>
									<a href="#" data-group="all"> All </a>
								</li>
							<# } #>

							<# for ( key in data.items ) { #>
								<li>
									<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>
								</li>
							<# } #>

						</ul>

					<# } else { #>
						<select class="{{ data.args.wrapper_class }} {{ data.args.class }}">

							<# if ( data.args.show_all ) { #>
								<option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
							<# } #>

							<# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
								<option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
							<# } #>

							<# for ( key in data.items ) { #>
								<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>
							<# } #>

						</select>
					<# } #>

				<# } #>
			</script>

			<?php
			// Step Type.
			?>
			<script type="text/template" id="tmpl-cartflows-step-types">
				<ul class="wcf-tab nav-tabs">
					<# if( data.items_count ) { #>
						<# for( key in data.items ) { #>
							<# console.log( data.items[ key ].id ) #>
							<li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
								<a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
							</li>
						<# } #>
					<# } #>
				</ul>
			</script>

			<?php
			// Add to library button.
			?>
			<script type="text/template" id="tmpl-templator-add-to-library">
				<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>
			</script>
			<?php
		}

		/**
		 * Get plugin button string.
		 *
		 * @param  string $plugin_init_file Plguin init file.
		 * @param  string $plugin_title    Plguin title.
		 * @return string
		 */
		function get_plugin_button_string( $plugin_init_file, $plugin_title ) {

			if ( null == self::$installed_plugins ) {
				self::$installed_plugins = get_plugins();
			}

			if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
				/* translators: %s is plugin name. */
				return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
			} elseif ( ! is_plugin_active( $plugin_init_file ) ) {
				/* translators: %s is plugin name. */
				return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
			}

			return __( 'Import', 'cartflows' );
		}

		/**
		 * Get plugin status
		 *
		 * @param  string $plugin_init_file Plguin init file.
		 * @return mixed
		 */
		function get_plugin_status( $plugin_init_file ) {

			if ( null == self::$installed_plugins ) {
				self::$installed_plugins = get_plugins();
			}

			if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
				return 'install';
			} elseif ( ! is_plugin_active( $plugin_init_file ) ) {
				return 'activate';
			}

			return;
		}

		/**
		 * Enqueue scripts
		 *
		 * @since 1.0.0
		 *
		 * @hook admin_enqueue_scripts
		 * @param  string $hook Current page hook.
		 */
		function scripts( $hook = '' ) {

			if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
				return;
			}

			wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
			wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
			wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
			wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );

			$localize_vars = array(
				'_is_pro_active'           => _is_cartflows_pro(),

				// Flow and its rest fields.
				'flow'                     => CARTFLOWS_FLOW_POST_TYPE,
				'flow_fields'              => array(
					'id',
					'title',
					'flow_type',
					'page_builder',
					'flow_steps',
					'licence_status',
					'featured_image_url',
					'featured_media', // @required for field `featured_image_url`.
				),

				// Flow type and rest fields.
				'flow_type'                => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
				'flow_type_fields'         => array(
					'id',
					'name',
					'slug',
				),

				// Flow page builder and rest fields.
				'flow_page_builder'        => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
				'flow_page_builder_fields' => array(
					'id',
					'name',
					'slug',
				),

				// Step page builder and rest fields.
				'step_page_builder'        => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
				'step_page_builder_fields' => array(
					'id',
					'name',
					'slug',
				),

				// Step and its rest fields.
				'step'                     => CARTFLOWS_STEP_POST_TYPE,
				'step_fields'              => array(
					'title',
					'featured_image_url',
					'featured_media', // @required for field `featured_image_url`.
					'id',
					'flow_type',
					'step_type',
					'page_builder',
					'licence_status',
				),

				// Step type and its rest fields.
				'step_type'                => CARTFLOWS_TAXONOMY_STEP_TYPE,
				'step_type_fields'         => array(
					'id',
					'name',
					'slug',
				),

				'domain_url'               => CARTFLOWS_DOMAIN_URL,
				'server_url'               => CARTFLOWS_TEMPLATES_URL,
				'server_rest_url'          => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
				'site_url'                 => site_url(),
				'admin_url'                => admin_url(),
				'licence_args'             => CartFlows_API::get_instance()->get_licence_args(),
				'ajaxurl'                  => admin_url( 'admin-ajax.php' ),
				'debug'                    => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,

				'required_plugins'         => array(
					'elementor' => array(
						'button_title' => $this->get_plugin_button_string( 'elementor/elementor.php', 'Elementor' ),
						'status'       => $this->get_plugin_status( 'elementor/elementor.php' ),
						'plugins'      => array(
							array(
								'slug'   => 'elementor', // For download from wp.org.
								'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
							),
						),
					),
				),
			);

			// Add thickbox.
			add_thickbox();

			wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
			wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
		}

		/**
		 * Load Template
		 *
		 * @since 1.0.0
		 *
		 * @hook cartflows_load_steps
		 * @return void
		 */
		function load_templates() {

			check_ajax_referer( 'cf-load-steps', 'security' );

			$args      = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
			$templates = CartFlows_API::get_instance()->get_templates( $args );

			if ( $templates['templates_count'] ) {
				wp_send_json_success( $templates );
			} else {
				wp_send_json_error( $templates );
			}
			wp_die();
		}

		/**
		 * Import.
		 *
		 * @since 1.0.0
		 *
		 * @hook wp_ajax_cartflows_import_flow_step
		 * @return void
		 */
		function import_flow() {

			check_ajax_referer( 'cf-import-flow-step', 'security' );

			$flow_id     = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
			$template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';

			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( 'STARTED! Importing FLOW' );
			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );

			$response = CartFlows_API::get_instance()->get_template( $template_id );

			if ( false === $response['success'] ) {
				wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
				wp_send_json_error( $response );
			}

			wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );

			$new_step_id = wp_insert_post(
				array(
					'post_type'    => CARTFLOWS_STEP_POST_TYPE,
					'post_title'   => $response['title'],
					'post_content' => '',
					'post_status'  => 'publish',
				)
			);

			if ( is_wp_error( $new_step_id ) ) {
				wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
				wp_send_json_error( $new_step_id );
			}

			wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
			// insert post meta.
			update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
			wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );

			/**
			 * Import & Set type.
			 */
			$term      = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
			$term_slug = '';
			if ( $term ) {

				$taxonomy   = CARTFLOWS_TAXONOMY_STEP_TYPE;
				$term_exist = term_exists( $term->name, $taxonomy );

				if ( empty( $term_exist ) ) {
					$terms = array(
						array(
							'name' => $term->name,
						),
					);

					Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
					wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
				}

				$current_term = term_exists( $term->name, $taxonomy );

				// Set type object.
				$data      = get_term( $current_term['term_id'], $taxonomy );
				$term_slug = $data->slug;
				$term_name = $data->name;
				wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
				wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );

				// Set type.
				update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
				wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
			}

			// Set flow.
			wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
			wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );

			/**
			 * Update steps for the current flow.
			 */
			$flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );

			if ( ! is_array( $flow_steps ) ) {
				$flow_steps = array();
			}

			$flow_steps[] = array(
				'id'    => $new_step_id,
				'title' => $response['title'],
				'type'  => $term_slug,
			);
			update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
			wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );

			// Import Post Meta.
			self::import_post_meta( $new_step_id, $response );

			wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
			wcf()->logger->import_log( '------------------------------------' );

			do_action( 'cartflows_import_complete' );
			wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );

			// Batch Process.
			do_action( 'cartflows_after_template_import', $new_step_id, $response );

			/**
			 * End
			 */
			wp_send_json_success( $new_step_id );
		}

		/**
		 * Import Step.
		 *
		 * @since 1.0.0
		 * @hook wp_ajax_cartflows_step_import
		 *
		 * @return void
		 */
		function create_default_flow() {

			check_ajax_referer( 'cf-default-flow', 'security' );

			// Create post object.
			$new_flow_post = array(
				'post_content' => '',
				'post_status'  => 'publish',
				'post_type'    => CARTFLOWS_FLOW_POST_TYPE,
			);

			// Insert the post into the database.
			$flow_id = wp_insert_post( $new_flow_post );

			if ( is_wp_error( $flow_id ) ) {
				wp_send_json_error( $flow_id->get_error_message() );
			}

			$flow_steps = array();

			$steps_data = array(
				'landing'  => __( 'Landing Page', 'cartflows' ),
				'checkout' => __( 'Checkout Page', 'cartflows' ),
				'thankyou' => __( 'Thank You Page', 'cartflows' ),
			);

			foreach ( $steps_data as $slug => $title ) {

				$post_content = '';

				switch ( $slug ) {
					case 'checkout':
						$post_content = '';
						break;
					case 'thankyou':
						$post_content = '';
						break;
					default:
						$post_content = '';
						break;
				}

				$step_id = wp_insert_post(
					array(
						'post_type'    => CARTFLOWS_STEP_POST_TYPE,
						'post_title'   => $title,
						'post_content' => $post_content,
						'post_status'  => 'publish',
					)
				);

				if ( is_wp_error( $step_id ) ) {
					wp_send_json_error( $step_id->get_error_message() );
				}

				if ( $step_id ) {

					$flow_steps[] = array(
						'id'    => $step_id,
						'title' => $title,
						'type'  => $slug,
					);

					// insert post meta.
					update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
					update_post_meta( $step_id, 'wcf-step-type', $slug );

					wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
					wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
				}
			}

			update_post_meta( $flow_id, 'wcf-steps', $flow_steps );

			wp_send_json_success( $flow_id );
		}

		/**
		 * Create Flow
		 *
		 * @return void
		 */
		function create_flow() {

			check_ajax_referer( 'cf-create-flow', 'security' );

			// Create post object.
			$new_flow_post = array(
				'post_content' => '',
				'post_status'  => 'publish',
				'post_type'    => CARTFLOWS_FLOW_POST_TYPE,
			);

			// Insert the post into the database.
			$flow_id = wp_insert_post( $new_flow_post );

			if ( is_wp_error( $flow_id ) ) {
				wp_send_json_error( $flow_id->get_error_message() );
			}

			wp_send_json_success( $flow_id );
		}

		/**
		 * Create Step
		 *
		 * @return void
		 */
		function import_step() {

			check_ajax_referer( 'cf-step-import', 'security' );

			$template_id       = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
			$flow_id           = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
			$step_title        = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
			$step_type         = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
			$step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;

			$cartflow_meta = Cartflows_Flow_Meta::get_instance();

			$post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );

			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( 'STARTED! Importing STEP' );
			wcf()->logger->import_log( '------------------------------------' );

			if ( empty( $template_id ) || empty( $post_id ) ) {
				/* translators: %s: template ID */
				$data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
				wcf()->logger->import_log( $data );
				wp_send_json_error( $data );
			}

			wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );

			$response = CartFlows_API::get_instance()->get_template( $template_id );

			wcf()->logger->import_log( json_encode( $response ) );

			// Import Post Meta.
			self::import_post_meta( $post_id, $response );

			do_action( 'cartflows_import_complete' );

			// Batch Process.
			do_action( 'cartflows_after_template_import', $post_id, $response );

			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( 'COMPLETE! Importing Step' );
			wcf()->logger->import_log( '------------------------------------' );

			wp_send_json_success( $post_id );
		}

		/**
		 * Import Step.
		 *
		 * @since 1.0.0
		 * @hook wp_ajax_cartflows_step_create_blank
		 *
		 * @return void
		 */
		function step_create_blank() {

			check_ajax_referer( 'cf-step-create-blank', 'security' );

			$flow_id    = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
			$step_type  = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
			$step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';

			if ( empty( $flow_id ) || empty( $step_type ) ) {
				/* translators: %s: flow ID */
				$data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
				wcf()->logger->import_log( $data );
				wp_send_json_error( $data );
			}

			wcf()->logger->import_log( '------------------------------------' );
			wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );

			$step_type_title = str_replace( '-', ' ', $step_type );
			$step_type_slug  = strtolower( str_replace( '-', ' ', $step_type ) );

			$new_step_id = wp_insert_post(
				array(
					'post_type'    => CARTFLOWS_STEP_POST_TYPE,
					'post_title'   => $step_title,
					'post_content' => '',
					'post_status'  => 'publish',
				)
			);

			// insert post meta.
			update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );

			$taxonomy   = CARTFLOWS_TAXONOMY_STEP_TYPE;
			$term_exist = term_exists( $step_type_title, $taxonomy );

			if ( empty( $term_exist ) ) {
				$terms = array(
					array(
						'name' => $step_type_title,
					),
				);

				Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
				wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
			}

			$current_term = term_exists( $step_type_title, $taxonomy );

			// Set type object.
			$data      = get_term( $current_term['term_id'], $taxonomy );
			$step_slug = $data->slug;
			wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
			wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );

			// Set type.
			update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
			wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );

			// Set flow.
			wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
			wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );

			CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );

			wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
			wcf()->logger->import_log( '------------------------------------' );

			wp_send_json_success( $new_step_id );
		}

		/**
		 * Import Post Meta
		 *
		 * @since 1.0.0
		 *
		 * @param  integer $post_id  Post ID.
		 * @param  array   $response  Post meta.
		 * @return void
		 */
		public static function import_post_meta( $post_id, $response ) {

			$metadata = (array) $response['post_meta'];

			foreach ( $metadata as $meta_key => $meta_value ) {
				$meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';

				if ( $meta_value ) {

					if ( is_serialized( $meta_value, true ) ) {
						$raw_data = maybe_unserialize( stripslashes( $meta_value ) );
					} elseif ( is_array( $meta_value ) ) {
						$raw_data = json_decode( stripslashes( $meta_value ), true );
					} else {
						$raw_data = $meta_value;
					}

					if ( '_elementor_data' === $meta_key ) {
						if ( is_array( $raw_data ) ) {
							$raw_data = wp_slash( json_encode( $raw_data ) );
						} else {
							$raw_data = wp_slash( $raw_data );
						}
						wcf()->logger->import_log( $raw_data );
					}

					if ( is_array( $raw_data ) ) {
						wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
					} else {

						if ( ! is_object( $raw_data ) ) {
							wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
						}
					}

					update_post_meta( $post_id, $meta_key, $raw_data );
				}
			}
		}

		/**
		 * Import Template for Elementor
		 *
		 * @since 1.0.0
		 *
		 * @param  integer $post_id  Post ID.
		 * @param  array   $response  Post meta.
		 * @param  array   $page_build_data  Page build data.
		 * @return void
		 */
		public static function import_template_elementor( $post_id, $response, $page_build_data ) {
			if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
				$data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
				wcf()->logger->import_log( $data );
				wp_send_json_error( $data );
			}

			require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';

			wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );

			$obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
			$obj->import_single_template( $post_id );

			wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
		}

		/**
		 * Supported post types
		 *
		 * @since 1.0.0
		 *
		 * @return array Supported post types.
		 */
		public static function supported_post_types() {
			return apply_filters(
				'cartflows_supported_post_types',
				array(
					CARTFLOWS_FLOW_POST_TYPE,
				)
			);
		}

		/**
		 * Check supported post type
		 *
		 * @since 1.0.0
		 *
		 * @param  string $post_type Post type.
		 * @return boolean Supported post type status.
		 */
		public static function is_supported_post( $post_type = '' ) {
			if ( in_array( $post_type, self::supported_post_types() ) ) {
				return true;
			}

			return false;
		}

		/**
		 * Set steps to the flow
		 *
		 * @param integer $flow_id     Flow ID.
		 * @param integer $new_step_id New step ID.
		 * @param string  $step_title    Flow Type.
		 * @param string  $step_slug Flow Type.
		 */
		function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
			// Update steps for the current flow.
			$flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );

			if ( ! is_array( $flow_steps ) ) {
				$flow_steps = array();
			}

			$flow_steps[] = array(
				'id'    => $new_step_id,
				'title' => $step_title,
				'type'  => $step_slug,
			);
			update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
			wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
		}

		/**
		 * Localize variables in admin
		 *
		 * @param array $vars variables.
		 */
		function localize_vars( $vars ) {

			$ajax_actions = array(
				'cf_step_import',
				'cf_load_steps',
				'cf_create_flow',
				'cf_default_flow',
				'cf_step_create_blank',
				'cf_import_flow_step',
			);

			foreach ( $ajax_actions as $action ) {

				$vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
			}

			return $vars;
		}

		/**
		 * Ajax action to activate plugin
		 */
		public function activate_plugin() {

			$plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';

			if ( ! is_plugin_active( $plugin_slug ) ) {

				$activate = activate_plugin( $plugin_slug, '', false, true );

				if ( is_wp_error( $activate ) ) {
					wp_send_json_error();
				}
			}

			wp_send_json_success();
		}

	}

	/**
	 * Initialize class object with 'get_instance()' method
	 */
	CartFlows_Importer::get_instance();

endif;

```
