Funnel Builder by CartFlows – Create High Converting Sales Funnels For WordPress - Version 1.5.17

Version Description

Download this release

Release Info

Developer sandesh055
Plugin Icon Funnel Builder by CartFlows – Create High Converting Sales Funnels For WordPress
Version 1.5.17
Comparing to
See all releases

Code changes from version 1.5.16 to 1.5.17

assets/js/checkout-template.js CHANGED
@@ -240,11 +240,6 @@
240
  });
241
  }
242
 
243
-
244
- $(window).load(function(){
245
- // $( 'body' ).trigger( 'update_checkout' );
246
- });
247
-
248
  var wcf_checkout_coupons = {
249
 
250
  init: function() {
240
  });
241
  }
242
 
 
 
 
 
 
243
  var wcf_checkout_coupons = {
244
 
245
  init: function() {
assets/min-js/checkout-template.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){function o(){function r(e,o,c,t){""==e||"select"==t&&" "==e?o.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=a("form.woocommerce-checkout #customer_details"),o=e.find("input, textarea"),c=e.find("select");o.blur(function(){var e=a(this),o=e.attr("type"),c=e.closest("p.form-row"),t=e.val();r(t,c,e,o)}),c.blur(function(){var e=a(this).closest("p.form-row"),o=e.find(".select2-container--default"),c=e.find("select").val();r(c,e,o,"select")})}function c(){if("yes"==cartflows.allow_persistence&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",o=function(){var e=[],o=a("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),o.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),a(e+" input, "+e+" select").change(function(){o()})}}a(window).load(function(){});var t={init:function(){a(document.body).on("click",".wcf-submit-coupon",this.submit_coupon),a(document.body).on("click",".wcf-remove-coupon",this.remove_coupon)},submit_coupon:function(e){e.preventDefault();var o=a(".wcf-custom-coupon-field").find(".wcf-coupon-code-input"),c=o.val();if(""==c)return o.addClass("field-required"),!1;o.removeClass("field-required");var t={coupon_code:c,action:"wcf_woo_apply_coupon",security:cartflows.wcf_validate_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:t,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").remove();var c=JSON.parse(e);1==c.status&&a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(c.msg)}})},remove_coupon:function(e){e.preventDefault();var o={coupon_code:a(this).attr("data-coupon"),action:"wcf_woo_remove_coupon",security:cartflows.wcf_validate_remove_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").hide(),e&&(a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(e))}})}};a(document).ready(function(e){c(),o(),function(){a(".cartflows-container").find(".wcf-embed-checkout-form-two-column");var e=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_1_field"),o=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_2_field");e.hasClass("form-row-wide")&&(e.removeClass("form-row-wide"),e.addClass("form-row-first")),o.hasClass("form-row-wide")&&(o.removeClass("form-row-wide"),o.addClass("form-row-last"),o.find("label").hasClass("screen-reader-text")?o.addClass("mt20"):o.removeClass("mt20"));var c=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_1_field"),t=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_2_field");c.hasClass("form-row-wide")&&(c.removeClass("form-row-wide"),c.addClass("form-row-first")),t.hasClass("form-row-wide")&&(t.removeClass("form-row-wide"),t.addClass("form-row-last"),t.find("label").hasClass("screen-reader-text")?t.addClass("mt20"):t.removeClass("mt20")),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_country").on("change",function(e){}),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_country").on("change",function(e){})}(),a(document.body).on("click","#wcf-embed-checkout-form .remove",function(e){e.preventDefault();var c=a(this).attr("data-id"),o={p_key:a(this).attr("data-item-key"),p_id:c,action:"wcf_woo_remove_cart_product",security:cartflows.wcf_validate_remove_cart_product_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=JSON.parse(e);0==o.need_shipping&&a("#wcf-embed-checkout-form").find("#ship-to-different-address-checkbox").attr("checked",!1),a("#wcf-embed-checkout-form").find(".woocommerce-notices-wrapper").first().html(o.msg),a(document).trigger("cartflows_remove_product",[c]),a("#wcf-embed-checkout-form").trigger("update_checkout")}})}),t.init()})}(jQuery);
1
+ !function(a){function o(){function r(e,o,c,t){""==e||"select"==t&&" "==e?o.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=a("form.woocommerce-checkout #customer_details"),o=e.find("input, textarea"),c=e.find("select");o.blur(function(){var e=a(this),o=e.attr("type"),c=e.closest("p.form-row"),t=e.val();r(t,c,e,o)}),c.blur(function(){var e=a(this).closest("p.form-row"),o=e.find(".select2-container--default"),c=e.find("select").val();r(c,e,o,"select")})}function c(){if("yes"==cartflows.allow_persistence&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",o=function(){var e=[],o=a("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),o.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),a(e+" input, "+e+" select").change(function(){o()})}}var t={init:function(){a(document.body).on("click",".wcf-submit-coupon",this.submit_coupon),a(document.body).on("click",".wcf-remove-coupon",this.remove_coupon)},submit_coupon:function(e){e.preventDefault();var o=a(".wcf-custom-coupon-field").find(".wcf-coupon-code-input"),c=o.val();if(""==c)return o.addClass("field-required"),!1;o.removeClass("field-required");var t={coupon_code:c,action:"wcf_woo_apply_coupon",security:cartflows.wcf_validate_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:t,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").remove();var c=JSON.parse(e);1==c.status&&a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(c.msg)}})},remove_coupon:function(e){e.preventDefault();var o={coupon_code:a(this).attr("data-coupon"),action:"wcf_woo_remove_coupon",security:cartflows.wcf_validate_remove_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").hide(),e&&(a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(e))}})}};a(document).ready(function(e){c(),o(),function(){a(".cartflows-container").find(".wcf-embed-checkout-form-two-column");var e=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_1_field"),o=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_2_field");e.hasClass("form-row-wide")&&(e.removeClass("form-row-wide"),e.addClass("form-row-first")),o.hasClass("form-row-wide")&&(o.removeClass("form-row-wide"),o.addClass("form-row-last"),o.find("label").hasClass("screen-reader-text")?o.addClass("mt20"):o.removeClass("mt20"));var c=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_1_field"),t=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_2_field");c.hasClass("form-row-wide")&&(c.removeClass("form-row-wide"),c.addClass("form-row-first")),t.hasClass("form-row-wide")&&(t.removeClass("form-row-wide"),t.addClass("form-row-last"),t.find("label").hasClass("screen-reader-text")?t.addClass("mt20"):t.removeClass("mt20")),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_country").on("change",function(e){}),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_country").on("change",function(e){})}(),a(document.body).on("click","#wcf-embed-checkout-form .remove",function(e){e.preventDefault();var c=a(this).attr("data-id"),o={p_key:a(this).attr("data-item-key"),p_id:c,action:"wcf_woo_remove_cart_product",security:cartflows.wcf_validate_remove_cart_product_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=JSON.parse(e);0==o.need_shipping&&a("#wcf-embed-checkout-form").find("#ship-to-different-address-checkbox").attr("checked",!1),a("#wcf-embed-checkout-form").find(".woocommerce-notices-wrapper").first().html(o.msg),a(document).trigger("cartflows_remove_product",[c]),a("#wcf-embed-checkout-form").trigger("update_checkout")}})}),t.init()})}(jQuery);
cartflows.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.5.16
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
+ * Version: 1.5.17
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  Version 1.5.16 - Tuesday, 25th August 2020
2
  - Improvement: Hardened the security of the plugin.
3
  - Fix: User's account was not getting created from the Optin step.
1
+ Version 1.5.17 - Tuesday, 8th September 2020
2
+ - New: Added Braintree subscription product compatibility. Now, you can select it on the checkout page meta setting.
3
+ - Improvement: Added compatibility for a future release of CartFlows Pro.
4
+ - Fix: CartFlows meta boxes were stuck in the side panel.
5
+ - Fix: Groups Menu was getting redirected to the home page in BuddyBoss Theme.
6
+ - Fix: Checkout page was not displaying the rest of the product if one product goes out of stock.
7
+
8
  Version 1.5.16 - Tuesday, 25th August 2020
9
  - Improvement: Hardened the security of the plugin.
10
  - Fix: User's account was not getting created from the Optin step.
classes/class-cartflows-admin.php CHANGED
@@ -1,713 +1,740 @@
1
- <?php
2
- /**
3
- * CartFlows Admin.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Admin.
10
- */
11
- class Cartflows_Admin {
12
-
13
- /**
14
- * Calls on initialization
15
- *
16
- * @since 1.0.0
17
- */
18
- public static function init() {
19
-
20
- self::initialise_plugin();
21
- self::init_hooks();
22
- }
23
-
24
- /**
25
- * Init Hooks.
26
- *
27
- * @since 1.0.0
28
- * @return void
29
- */
30
- public static function init_hooks() {
31
-
32
- if ( ! is_admin() ) {
33
- return;
34
- }
35
-
36
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
-
38
- /*
39
- Add CARTFLOWS menu option to admin.
40
- add_action( 'network_admin_menu', __CLASS__ . '::menu' );
41
- */
42
- add_action( 'admin_menu', __CLASS__ . '::menu' );
43
- add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
44
-
45
- add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
46
-
47
- add_action( 'admin_init', __CLASS__ . '::settings_admin_scripts' );
48
-
49
- /* Global Addmin Script */
50
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
51
-
52
- add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
53
-
54
- /* Add lite version class to body */
55
- add_action( 'admin_body_class', __CLASS__ . '::add_admin_body_class' );
56
-
57
- add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, __CLASS__ . '::add_action_links' );
58
-
59
- add_action( 'admin_init', __CLASS__ . '::cartflows_after_save_permalinks' );
60
-
61
- add_action( 'in_admin_header', __CLASS__ . '::embed_page_header' );
62
- }
63
-
64
- /**
65
- * After save of permalinks.
66
- */
67
- public static function cartflows_after_save_permalinks() {
68
-
69
- $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
70
- if ( $has_saved_permalinks ) {
71
- flush_rewrite_rules();
72
- delete_option( 'cartflows_permalink_saved' );
73
- }
74
- }
75
-
76
-
77
- /**
78
- * Initialize after Cartflows pro get loaded.
79
- */
80
- public static function settings_admin_scripts() {
81
- // Enqueue admin scripts.
82
- if ( isset( $_GET['page'] ) && ( 'cartflows' === $_GET['page'] || false !== strpos( $_GET['page'], 'cartflows_' ) ) ) { //phpcs:ignore
83
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
84
-
85
- self::save_settings();
86
- }
87
- }
88
- /**
89
- * Show action on plugin page.
90
- *
91
- * @param array $links links.
92
- * @return array
93
- */
94
- public static function add_action_links( $links ) {
95
- $mylinks = array(
96
- '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
97
- '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
98
- );
99
-
100
- if ( ! _is_cartflows_pro() ) {
101
- array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
102
- }
103
-
104
- return array_merge( $links, $mylinks );
105
- }
106
-
107
- /**
108
- * Initialises the Plugin Name.
109
- *
110
- * @since 1.0.0
111
- * @return void
112
- */
113
- public static function initialise_plugin() {
114
-
115
- $name = 'Cartflows';
116
- $short_name = 'Cflows';
117
-
118
- define( 'CARTFLOWS_PLUGIN_NAME', $name );
119
- define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
120
- }
121
-
122
- /**
123
- * Renders the admin settings menu.
124
- *
125
- * @since 1.0.0
126
- * @return void
127
- */
128
- public static function menu() {
129
-
130
- if ( ! current_user_can( 'manage_options' ) ) {
131
- return;
132
- }
133
-
134
- add_menu_page(
135
- 'CartFlows',
136
- 'CartFlows',
137
- 'manage_options',
138
- CARTFLOWS_SLUG,
139
- __CLASS__ . '::render',
140
- 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
141
- 39.7
142
- );
143
-
144
- }
145
-
146
- /**
147
- * Add submenu to admin menu.
148
- *
149
- * @since 1.0.0
150
- */
151
- public static function submenu() {
152
-
153
- global $submenu;
154
-
155
- $parent_slug = CARTFLOWS_SLUG;
156
- $capability = 'manage_options';
157
-
158
- // Home menu.
159
- $submenu[ $parent_slug ][0][0] = __( 'Home', 'cartflows' ); //phpcs:ignore
160
-
161
- // Add settings menu.
162
- add_submenu_page(
163
- $parent_slug,
164
- __( 'Settings', 'cartflows' ),
165
- __( 'Settings', 'cartflows' ),
166
- $capability,
167
- 'cartflows_settings',
168
- __CLASS__ . '::render'
169
- );
170
- }
171
-
172
- /**
173
- * Renders the admin settings.
174
- *
175
- * @since 1.0.0
176
- * @return void
177
- */
178
- public static function render() {
179
- $menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore
180
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
181
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
182
- $action = str_replace( '_', '-', $action );
183
-
184
- // Enable header icon filter below.
185
- $header_wrapper_class = apply_filters( 'cartflows_admin_header_wrapper_class', array( $action, $menu_page_slug ) );
186
-
187
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
188
- }
189
-
190
- /**
191
- * Renders the admin settings content.
192
- *
193
- * @since 1.0.0
194
- * @param sting $menu_page_slug current page name.
195
- *
196
- * @return void
197
- */
198
- public static function render_content( $menu_page_slug ) {
199
-
200
- if ( CARTFLOWS_SETTINGS === $menu_page_slug ) {
201
-
202
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
203
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
204
- $action = str_replace( '_', '-', $action );
205
- $action = 'general';
206
-
207
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
208
- }
209
-
210
- if ( 'cartflows' === $menu_page_slug ) {
211
-
212
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
213
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
214
- $action = str_replace( '_', '-', $action );
215
- $action = 'general';
216
-
217
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-home.php';
218
- }
219
- }
220
-
221
- /**
222
- * Save Global Setting options.
223
- *
224
- * @since 1.0.0
225
- */
226
- public static function save_common_settings() {
227
-
228
- if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
229
-
230
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
231
- $new_settings = array();
232
-
233
- if ( isset( $_POST['_cartflows_common'] ) ) {
234
- // Loop through the input and sanitize each of the values.
235
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
236
- }
237
-
238
- Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
239
-
240
- $query = array(
241
- 'message' => 'saved',
242
- );
243
-
244
- $redirect_to = add_query_arg( $query, $url );
245
-
246
- wp_safe_redirect( $redirect_to );
247
- exit;
248
- } // End if statement.
249
- }
250
-
251
- /**
252
- * Save Debug Setting options.
253
- *
254
- * @since 1.1.14
255
- */
256
- public static function save_debug_settings() {
257
-
258
- if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
259
-
260
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
261
- $new_settings = array();
262
-
263
- if ( isset( $_POST['_cartflows_debug_data'] ) ) {
264
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
265
- }
266
-
267
- Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
268
-
269
- $query = array(
270
- 'message' => 'saved',
271
- );
272
-
273
- $redirect_to = add_query_arg( $query, $url );
274
-
275
- wp_safe_redirect( $redirect_to );
276
- exit;
277
-
278
- }
279
- }
280
-
281
-
282
- /**
283
- * Save permalink Setting options.
284
- *
285
- * @since 1.1.14
286
- */
287
- public static function save_permalink_settings() {
288
-
289
- if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
290
-
291
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
292
- $new_settings = array();
293
-
294
- if ( isset( $_POST['reset'] ) ) {
295
- $_POST['_cartflows_permalink'] = array(
296
- 'permalink' => CARTFLOWS_STEP_POST_TYPE,
297
- 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
298
- 'permalink_structure' => '',
299
- );
300
-
301
- }
302
-
303
- if ( isset( $_POST['_cartflows_permalink'] ) ) {
304
- $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
305
-
306
- if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
307
- $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
308
- } else {
309
- $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
310
- }
311
-
312
- if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
313
- $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
314
- } else {
315
- $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
316
- }
317
-
318
- $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
319
-
320
- }
321
-
322
- Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
323
-
324
- $query = array(
325
- 'message' => 'saved',
326
- );
327
-
328
- $redirect_to = add_query_arg( $query, $url );
329
-
330
- update_option( 'cartflows_permalink_saved', true );
331
-
332
- wp_safe_redirect( $redirect_to );
333
- exit;
334
-
335
- }
336
- }
337
-
338
- /**
339
- * Save google analytics Setting options.
340
- *
341
- * @since 1.1.14
342
- */
343
- public static function save_google_analytics_settings() {
344
-
345
- if ( isset( $_POST['cartflows-google-analytics-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-google-analytics-settings-nonce'] ) ), 'cartflows-google-analytics-settings' ) ) {
346
-
347
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
348
- $new_settings = array();
349
-
350
- if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
351
- $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
352
-
353
- }
354
-
355
- Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
356
-
357
- $query = array(
358
- 'message' => 'saved',
359
- );
360
-
361
- $redirect_to = add_query_arg( $query, $url );
362
-
363
- wp_safe_redirect( $redirect_to );
364
- exit;
365
-
366
- }
367
- }
368
-
369
- /**
370
- * Loop through the input and sanitize each of the values.
371
- *
372
- * @param array $input_settings input settings.
373
- * @return array
374
- */
375
- public static function sanitize_form_inputs( $input_settings = array() ) {
376
- $new_settings = array();
377
- foreach ( $input_settings as $key => $val ) {
378
-
379
- if ( is_array( $val ) ) {
380
- foreach ( $val as $k => $v ) {
381
- $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
382
- }
383
- } else {
384
- $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
385
- }
386
- }
387
- return $new_settings;
388
- }
389
-
390
- /**
391
- * Check is cartflows admin.
392
- *
393
- * @since 1.0.0
394
- * @return boolean
395
- */
396
- public static function is_global_admin() {
397
-
398
- $current_screen = get_current_screen();
399
-
400
- if (
401
- is_object( $current_screen ) &&
402
- isset( $current_screen->post_type ) &&
403
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
404
- CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
405
- )
406
- ) {
407
- return true;
408
- }
409
- return false;
410
- }
411
-
412
- /**
413
- * Check is flow admin.
414
- *
415
- * @since 1.0.0
416
- * @return boolean
417
- */
418
- public static function is_flow_edit_admin() {
419
-
420
- $current_screen = get_current_screen();
421
-
422
- if (
423
- is_object( $current_screen ) &&
424
- isset( $current_screen->post_type ) &&
425
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
426
- isset( $current_screen->base ) &&
427
- ( 'post' === $current_screen->base )
428
- ) {
429
- return true;
430
- }
431
- return false;
432
- }
433
-
434
- /**
435
- * Global Admin Scripts.
436
- *
437
- * @since 1.0.0
438
- */
439
- public static function global_admin_scripts() {
440
-
441
- $installed_plugins = get_plugins();
442
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
443
- $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
444
- $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
445
-
446
- $localize = array(
447
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
448
- 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
449
- 'wc_status' => array(
450
- 'installed' => $is_wc_installed,
451
- 'active' => wcf()->is_woo_active,
452
- ),
453
- 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
454
- 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
455
- 'wcf_edit_test_mode' => $edit_test_mode,
456
- 'wcf_fetch_stats_nonce' => wp_create_nonce( 'wcf-fetch-stats' ),
457
- );
458
-
459
- $localize = apply_filters( 'cartflows_admin_js_localize', $localize );
460
-
461
- $localize_script = '<!-- script to print the admin localized variables -->';
462
- $localize_script .= '<script type="text/javascript">';
463
- $localize_script .= 'var cartflows_admin = ' . wp_json_encode( $localize ) . ';';
464
- $localize_script .= '</script>';
465
-
466
- echo $localize_script;
467
-
468
- if ( self::is_global_admin() ) {
469
-
470
- // Styles.
471
- wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
472
- wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
473
-
474
- wp_enqueue_script(
475
- 'wcf-global-admin',
476
- CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
477
- array( 'jquery' ),
478
- CARTFLOWS_VER,
479
- true
480
- );
481
-
482
- do_action( 'cartflows_global_admin_scripts' );
483
- }
484
- }
485
-
486
- /**
487
- * Global Admin Data.
488
- *
489
- * @since 1.0.0
490
- */
491
- public static function global_admin_data() {
492
-
493
- $current_screen = get_current_screen();
494
-
495
- if ( ! $current_screen ) {
496
- return;
497
- }
498
-
499
- if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
500
- return;
501
- }
502
-
503
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
504
- ?>
505
-
506
- <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
507
- <div class="wcf-templates-popup-content">
508
- <div class="spinner"></div>
509
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
510
-
511
- <div id="wcf-remote-flow-actions" class="wcf-template-header">
512
- <div class="wcf-template-logo-wrap">
513
- <span class="wcf-cartflows-logo-img">
514
- <span class="cartflows-logo-icon"></span>
515
- </span>
516
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
517
- </div>
518
- <div class="wcf-tab-wrapper">
519
- <?php if ( 'other' !== $default_page_builder ) { ?>
520
- <div id="wcf-get-started-steps">
521
- <ul class="filter-links ">
522
- <li>
523
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
524
- </li>
525
- <li>
526
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
527
- </li>
528
- </ul>
529
- </div>
530
- <?php } ?>
531
- </div>
532
- <div class="wcf-popup-close-wrap">
533
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
534
- </div>
535
- </div>
536
- <!-- <div class="wcf-search-form">
537
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
538
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
539
- </div> -->
540
-
541
- <div id="wcf-remote-content">
542
- <?php if ( 'other' !== $default_page_builder ) { ?>
543
- <div id="wcf-ready-templates">
544
- <div id="wcf-remote-filters">
545
- <div id="wcf-page-builders"></div>
546
- <div id="wcf-categories"></div>
547
- </div>
548
- <div class="wcf-page-builder-notice"></div>
549
- <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
550
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
551
- </div>
552
- <?php } ?>
553
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
554
- <div class="inner">
555
- <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
556
- <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
557
- </div>
558
- </div>
559
- </div>
560
- </div>
561
- </div>
562
- </div>
563
-
564
- <?php
565
- }
566
-
567
- /**
568
- * Enqueues the needed CSS/JS for the builder's admin settings page.
569
- *
570
- * @since 1.0.0
571
- */
572
- public static function styles_scripts() {
573
-
574
- // Styles.
575
- wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
576
- wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
577
-
578
- // Script.
579
- wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
580
-
581
- $localize = array(
582
- 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
583
- );
584
-
585
- wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
586
-
587
- do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
588
- }
589
-
590
- /**
591
- * Save All admin settings here
592
- */
593
- public static function save_settings() {
594
-
595
- // Only admins can save settings.
596
- if ( ! current_user_can( 'manage_options' ) ) {
597
- return;
598
- }
599
-
600
- self::save_common_settings();
601
- self::save_debug_settings();
602
- self::save_permalink_settings();
603
-
604
- self::save_google_analytics_settings();
605
- self::save_facebook_settings();
606
-
607
- // Let extensions hook into saving.
608
- do_action( 'cartflows_admin_settings_save' );
609
- }
610
-
611
- /**
612
- * Get and return page URL
613
- *
614
- * @param string $menu_slug Menu name.
615
- * @since 1.0.0
616
- * @return string page url
617
- */
618
- public static function get_page_url( $menu_slug ) {
619
-
620
- $parent_page = self::$default_menu_position;
621
-
622
- if ( strpos( $parent_page, '?' ) !== false ) {
623
- $query_var = '&page=' . self::$plugin_slug;
624
- } else {
625
- $query_var = '?page=' . self::$plugin_slug;
626
- }
627
-
628
- $parent_page_url = admin_url( $parent_page . $query_var );
629
-
630
- $url = $parent_page_url . '&action=' . $menu_slug;
631
-
632
- return esc_url( $url );
633
- }
634
-
635
- /**
636
- * Admin body classes.
637
- *
638
- * Body classes to be added to <body> tag in admin page
639
- *
640
- * @param String $classes body classes returned from the filter.
641
- * @return String body classes to be added to <body> tag in admin page
642
- */
643
- public static function add_admin_body_class( $classes ) {
644
-
645
- $classes .= ' cartflows-' . CARTFLOWS_VER;
646
-
647
- return $classes;
648
- }
649
-
650
- /**
651
- * Save Global Setting options.
652
- *
653
- * @since 1.0.0
654
- */
655
- public static function save_facebook_settings() {
656
-
657
- if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
658
-
659
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
660
- $new_settings = array();
661
-
662
- if ( isset( $_POST['_cartflows_facebook'] ) ) {
663
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
664
- }
665
-
666
- Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
667
- $query = array(
668
- 'message' => 'saved',
669
- );
670
- $redirect_to = add_query_arg( $query, $url );
671
- wp_safe_redirect( $redirect_to );
672
- exit;
673
- }
674
- }
675
-
676
- /**
677
- * Show embed header.
678
- *
679
- * @since 1.0.0
680
- */
681
- public static function show_embed_header() {
682
-
683
- $current_screen = get_current_screen();
684
-
685
- if (
686
- is_object( $current_screen ) &&
687
- isset( $current_screen->post_type ) &&
688
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
689
- isset( $current_screen->base ) &&
690
- ( 'post' === $current_screen->base || 'edit' === $current_screen->base )
691
- ) {
692
- return true;
693
- }
694
-
695
- return false;
696
- }
697
- /**
698
- * Set up a div for the header embed to render into.
699
- * The initial contents here are meant as a place loader for when the PHP page initialy loads.
700
- */
701
- public static function embed_page_header() {
702
-
703
- if ( ! is_admin() || ! self::show_embed_header() ) {
704
- return;
705
- }
706
-
707
- wp_enqueue_style( 'cartflows-admin-embed-header', CARTFLOWS_URL . 'admin/assets/css/admin-embed-header.css', array(), CARTFLOWS_VER );
708
-
709
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin-header.php';
710
- }
711
- }
712
-
713
- Cartflows_Admin::init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows Admin.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Admin.
10
+ */
11
+ class Cartflows_Admin {
12
+
13
+ /**
14
+ * Calls on initialization
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ public static function init() {
19
+
20
+ self::initialise_plugin();
21
+ self::init_hooks();
22
+ }
23
+
24
+ /**
25
+ * Init Hooks.
26
+ *
27
+ * @since 1.0.0
28
+ * @return void
29
+ */
30
+ public static function init_hooks() {
31
+
32
+ if ( ! is_admin() ) {
33
+ return;
34
+ }
35
+
36
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
+
38
+ /*
39
+ Add CARTFLOWS menu option to admin.
40
+ add_action( 'network_admin_menu', __CLASS__ . '::menu' );
41
+ */
42
+ add_action( 'admin_menu', __CLASS__ . '::menu' );
43
+ add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
44
+
45
+ add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
46
+
47
+ add_action( 'admin_init', __CLASS__ . '::settings_admin_scripts' );
48
+
49
+ /* Global Addmin Script */
50
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
51
+
52
+ add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
53
+
54
+ /* Add lite version class to body */
55
+ add_action( 'admin_body_class', __CLASS__ . '::add_admin_body_class' );
56
+
57
+ add_filter( 'plugin_action_links_' . CARTFLOWS_BASE, __CLASS__ . '::add_action_links' );
58
+
59
+ add_action( 'admin_init', __CLASS__ . '::cartflows_after_save_permalinks' );
60
+
61
+ add_action( 'in_admin_header', __CLASS__ . '::embed_page_header' );
62
+
63
+ add_filter( 'get_user_option_meta-box-order_' . CARTFLOWS_STEP_POST_TYPE, __CLASS__ . '::metabox_order' );
64
+ }
65
+
66
+ /**
67
+ * Metabox fixed orders.
68
+ *
69
+ * @param array $metabox_orders Orders.
70
+ * @return array
71
+ */
72
+ public static function metabox_order( $metabox_orders ) {
73
+
74
+ if ( isset( $metabox_orders['side'] ) ) {
75
+
76
+ $metabox_orders['side'] = str_replace(
77
+ array(
78
+ 'wcf-checkout-settings',
79
+ 'wcf-ladning-settings',
80
+ 'wcf-optin-settings',
81
+ 'wcf-thankyou-settings',
82
+ ),
83
+ '',
84
+ $metabox_orders['side']
85
+ );
86
+ }
87
+
88
+ return $metabox_orders;
89
+ }
90
+
91
+ /**
92
+ * After save of permalinks.
93
+ */
94
+ public static function cartflows_after_save_permalinks() {
95
+
96
+ $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
97
+ if ( $has_saved_permalinks ) {
98
+ flush_rewrite_rules();
99
+ delete_option( 'cartflows_permalink_saved' );
100
+ }
101
+ }
102
+
103
+
104
+ /**
105
+ * Initialize after Cartflows pro get loaded.
106
+ */
107
+ public static function settings_admin_scripts() {
108
+ // Enqueue admin scripts.
109
+ if ( isset( $_GET['page'] ) && ( 'cartflows' === $_GET['page'] || false !== strpos( $_GET['page'], 'cartflows_' ) ) ) { //phpcs:ignore
110
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
111
+
112
+ self::save_settings();
113
+ }
114
+ }
115
+ /**
116
+ * Show action on plugin page.
117
+ *
118
+ * @param array $links links.
119
+ * @return array
120
+ */
121
+ public static function add_action_links( $links ) {
122
+ $mylinks = array(
123
+ '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
124
+ '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
125
+ );
126
+
127
+ if ( ! _is_cartflows_pro() ) {
128
+ array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
129
+ }
130
+
131
+ return array_merge( $links, $mylinks );
132
+ }
133
+
134
+ /**
135
+ * Initialises the Plugin Name.
136
+ *
137
+ * @since 1.0.0
138
+ * @return void
139
+ */
140
+ public static function initialise_plugin() {
141
+
142
+ $name = 'Cartflows';
143
+ $short_name = 'Cflows';
144
+
145
+ define( 'CARTFLOWS_PLUGIN_NAME', $name );
146
+ define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
147
+ }
148
+
149
+ /**
150
+ * Renders the admin settings menu.
151
+ *
152
+ * @since 1.0.0
153
+ * @return void
154
+ */
155
+ public static function menu() {
156
+
157
+ if ( ! current_user_can( 'manage_options' ) ) {
158
+ return;
159
+ }
160
+
161
+ add_menu_page(
162
+ 'CartFlows',
163
+ 'CartFlows',
164
+ 'manage_options',
165
+ CARTFLOWS_SLUG,
166
+ __CLASS__ . '::render',
167
+ 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
168
+ 39.7
169
+ );
170
+
171
+ }
172
+
173
+ /**
174
+ * Add submenu to admin menu.
175
+ *
176
+ * @since 1.0.0
177
+ */
178
+ public static function submenu() {
179
+
180
+ global $submenu;
181
+
182
+ $parent_slug = CARTFLOWS_SLUG;
183
+ $capability = 'manage_options';
184
+
185
+ // Home menu.
186
+ $submenu[ $parent_slug ][0][0] = __( 'Home', 'cartflows' ); //phpcs:ignore
187
+
188
+ // Add settings menu.
189
+ add_submenu_page(
190
+ $parent_slug,
191
+ __( 'Settings', 'cartflows' ),
192
+ __( 'Settings', 'cartflows' ),
193
+ $capability,
194
+ 'cartflows_settings',
195
+ __CLASS__ . '::render'
196
+ );
197
+ }
198
+
199
+ /**
200
+ * Renders the admin settings.
201
+ *
202
+ * @since 1.0.0
203
+ * @return void
204
+ */
205
+ public static function render() {
206
+ $menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore
207
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
208
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
209
+ $action = str_replace( '_', '-', $action );
210
+
211
+ // Enable header icon filter below.
212
+ $header_wrapper_class = apply_filters( 'cartflows_admin_header_wrapper_class', array( $action, $menu_page_slug ) );
213
+
214
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
215
+ }
216
+
217
+ /**
218
+ * Renders the admin settings content.
219
+ *
220
+ * @since 1.0.0
221
+ * @param sting $menu_page_slug current page name.
222
+ *
223
+ * @return void
224
+ */
225
+ public static function render_content( $menu_page_slug ) {
226
+
227
+ if ( CARTFLOWS_SETTINGS === $menu_page_slug ) {
228
+
229
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
230
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
231
+ $action = str_replace( '_', '-', $action );
232
+ $action = 'general';
233
+
234
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
235
+ }
236
+
237
+ if ( 'cartflows' === $menu_page_slug ) {
238
+
239
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
240
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
241
+ $action = str_replace( '_', '-', $action );
242
+ $action = 'general';
243
+
244
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-home.php';
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Save Global Setting options.
250
+ *
251
+ * @since 1.0.0
252
+ */
253
+ public static function save_common_settings() {
254
+
255
+ if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
256
+
257
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
258
+ $new_settings = array();
259
+
260
+ if ( isset( $_POST['_cartflows_common'] ) ) {
261
+ // Loop through the input and sanitize each of the values.
262
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
263
+ }
264
+
265
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
266
+
267
+ $query = array(
268
+ 'message' => 'saved',
269
+ );
270
+
271
+ $redirect_to = add_query_arg( $query, $url );
272
+
273
+ wp_safe_redirect( $redirect_to );
274
+ exit;
275
+ } // End if statement.
276
+ }
277
+
278
+ /**
279
+ * Save Debug Setting options.
280
+ *
281
+ * @since 1.1.14
282
+ */
283
+ public static function save_debug_settings() {
284
+
285
+ if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
286
+
287
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
288
+ $new_settings = array();
289
+
290
+ if ( isset( $_POST['_cartflows_debug_data'] ) ) {
291
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
292
+ }
293
+
294
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
295
+
296
+ $query = array(
297
+ 'message' => 'saved',
298
+ );
299
+
300
+ $redirect_to = add_query_arg( $query, $url );
301
+
302
+ wp_safe_redirect( $redirect_to );
303
+ exit;
304
+
305
+ }
306
+ }
307
+
308
+
309
+ /**
310
+ * Save permalink Setting options.
311
+ *
312
+ * @since 1.1.14
313
+ */
314
+ public static function save_permalink_settings() {
315
+
316
+ if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
317
+
318
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
319
+ $new_settings = array();
320
+
321
+ if ( isset( $_POST['reset'] ) ) {
322
+ $_POST['_cartflows_permalink'] = array(
323
+ 'permalink' => CARTFLOWS_STEP_POST_TYPE,
324
+ 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
325
+ 'permalink_structure' => '',
326
+ );
327
+
328
+ }
329
+
330
+ if ( isset( $_POST['_cartflows_permalink'] ) ) {
331
+ $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
332
+
333
+ if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
334
+ $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
335
+ } else {
336
+ $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
337
+ }
338
+
339
+ if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
340
+ $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
341
+ } else {
342
+ $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
343
+ }
344
+
345
+ $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
346
+
347
+ }
348
+
349
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
350
+
351
+ $query = array(
352
+ 'message' => 'saved',
353
+ );
354
+
355
+ $redirect_to = add_query_arg( $query, $url );
356
+
357
+ update_option( 'cartflows_permalink_saved', true );
358
+
359
+ wp_safe_redirect( $redirect_to );
360
+ exit;
361
+
362
+ }
363
+ }
364
+
365
+ /**
366
+ * Save google analytics Setting options.
367
+ *
368
+ * @since 1.1.14
369
+ */
370
+ public static function save_google_analytics_settings() {
371
+
372
+ if ( isset( $_POST['cartflows-google-analytics-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-google-analytics-settings-nonce'] ) ), 'cartflows-google-analytics-settings' ) ) {
373
+
374
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
375
+ $new_settings = array();
376
+
377
+ if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
378
+ $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
379
+
380
+ }
381
+
382
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
383
+
384
+ $query = array(
385
+ 'message' => 'saved',
386
+ );
387
+
388
+ $redirect_to = add_query_arg( $query, $url );
389
+
390
+ wp_safe_redirect( $redirect_to );
391
+ exit;
392
+
393
+ }
394
+ }
395
+
396
+ /**
397
+ * Loop through the input and sanitize each of the values.
398
+ *
399
+ * @param array $input_settings input settings.
400
+ * @return array
401
+ */
402
+ public static function sanitize_form_inputs( $input_settings = array() ) {
403
+ $new_settings = array();
404
+ foreach ( $input_settings as $key => $val ) {
405
+
406
+ if ( is_array( $val ) ) {
407
+ foreach ( $val as $k => $v ) {
408
+ $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
409
+ }
410
+ } else {
411
+ $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
412
+ }
413
+ }
414
+ return $new_settings;
415
+ }
416
+
417
+ /**
418
+ * Check is cartflows admin.
419
+ *
420
+ * @since 1.0.0
421
+ * @return boolean
422
+ */
423
+ public static function is_global_admin() {
424
+
425
+ $current_screen = get_current_screen();
426
+
427
+ if (
428
+ is_object( $current_screen ) &&
429
+ isset( $current_screen->post_type ) &&
430
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
431
+ CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
432
+ )
433
+ ) {
434
+ return true;
435
+ }
436
+ return false;
437
+ }
438
+
439
+ /**
440
+ * Check is flow admin.
441
+ *
442
+ * @since 1.0.0
443
+ * @return boolean
444
+ */
445
+ public static function is_flow_edit_admin() {
446
+
447
+ $current_screen = get_current_screen();
448
+
449
+ if (
450
+ is_object( $current_screen ) &&
451
+ isset( $current_screen->post_type ) &&
452
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
453
+ isset( $current_screen->base ) &&
454
+ ( 'post' === $current_screen->base )
455
+ ) {
456
+ return true;
457
+ }
458
+ return false;
459
+ }
460
+
461
+ /**
462
+ * Global Admin Scripts.
463
+ *
464
+ * @since 1.0.0
465
+ */
466
+ public static function global_admin_scripts() {
467
+
468
+ $installed_plugins = get_plugins();
469
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
470
+ $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
471
+ $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
472
+
473
+ $localize = array(
474
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
475
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
476
+ 'wc_status' => array(
477
+ 'installed' => $is_wc_installed,
478
+ 'active' => wcf()->is_woo_active,
479
+ ),
480
+ 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
481
+ 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
482
+ 'wcf_edit_test_mode' => $edit_test_mode,
483
+ 'wcf_fetch_stats_nonce' => wp_create_nonce( 'wcf-fetch-stats' ),
484
+ );
485
+
486
+ $localize = apply_filters( 'cartflows_admin_js_localize', $localize );
487
+
488
+ $localize_script = '<!-- script to print the admin localized variables -->';
489
+ $localize_script .= '<script type="text/javascript">';
490
+ $localize_script .= 'var cartflows_admin = ' . wp_json_encode( $localize ) . ';';
491
+ $localize_script .= '</script>';
492
+
493
+ echo $localize_script;
494
+
495
+ if ( self::is_global_admin() ) {
496
+
497
+ // Styles.
498
+ wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
499
+ wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
500
+
501
+ wp_enqueue_script(
502
+ 'wcf-global-admin',
503
+ CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
504
+ array( 'jquery' ),
505
+ CARTFLOWS_VER,
506
+ true
507
+ );
508
+
509
+ do_action( 'cartflows_global_admin_scripts' );
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Global Admin Data.
515
+ *
516
+ * @since 1.0.0
517
+ */
518
+ public static function global_admin_data() {
519
+
520
+ $current_screen = get_current_screen();
521
+
522
+ if ( ! $current_screen ) {
523
+ return;
524
+ }
525
+
526
+ if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
527
+ return;
528
+ }
529
+
530
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
531
+ ?>
532
+
533
+ <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
534
+ <div class="wcf-templates-popup-content">
535
+ <div class="spinner"></div>
536
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
537
+
538
+ <div id="wcf-remote-flow-actions" class="wcf-template-header">
539
+ <div class="wcf-template-logo-wrap">
540
+ <span class="wcf-cartflows-logo-img">
541
+ <span class="cartflows-logo-icon"></span>
542
+ </span>
543
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
544
+ </div>
545
+ <div class="wcf-tab-wrapper">
546
+ <?php if ( 'other' !== $default_page_builder ) { ?>
547
+ <div id="wcf-get-started-steps">
548
+ <ul class="filter-links ">
549
+ <li>
550
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
551
+ </li>
552
+ <li>
553
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
554
+ </li>
555
+ </ul>
556
+ </div>
557
+ <?php } ?>
558
+ </div>
559
+ <div class="wcf-popup-close-wrap">
560
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
561
+ </div>
562
+ </div>
563
+ <!-- <div class="wcf-search-form">
564
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
565
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
566
+ </div> -->
567
+
568
+ <div id="wcf-remote-content">
569
+ <?php if ( 'other' !== $default_page_builder ) { ?>
570
+ <div id="wcf-ready-templates">
571
+ <div id="wcf-remote-filters">
572
+ <div id="wcf-page-builders"></div>
573
+ <div id="wcf-categories"></div>
574
+ </div>
575
+ <div class="wcf-page-builder-notice"></div>
576
+ <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
577
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
578
+ </div>
579
+ <?php } ?>
580
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
581
+ <div class="inner">
582
+ <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
583
+ <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
584
+ </div>
585
+ </div>
586
+ </div>
587
+ </div>
588
+ </div>
589
+ </div>
590
+
591
+ <?php
592
+ }
593
+
594
+ /**
595
+ * Enqueues the needed CSS/JS for the builder's admin settings page.
596
+ *
597
+ * @since 1.0.0
598
+ */
599
+ public static function styles_scripts() {
600
+
601
+ // Styles.
602
+ wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
603
+ wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
604
+
605
+ // Script.
606
+ wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
607
+
608
+ $localize = array(
609
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
610
+ );
611
+
612
+ wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
613
+
614
+ do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
615
+ }
616
+
617
+ /**
618
+ * Save All admin settings here
619
+ */
620
+ public static function save_settings() {
621
+
622
+ // Only admins can save settings.
623
+ if ( ! current_user_can( 'manage_options' ) ) {
624
+ return;
625
+ }
626
+
627
+ self::save_common_settings();
628
+ self::save_debug_settings();
629
+ self::save_permalink_settings();
630
+
631
+ self::save_google_analytics_settings();
632
+ self::save_facebook_settings();
633
+
634
+ // Let extensions hook into saving.
635
+ do_action( 'cartflows_admin_settings_save' );
636
+ }
637
+
638
+ /**
639
+ * Get and return page URL
640
+ *
641
+ * @param string $menu_slug Menu name.
642
+ * @since 1.0.0
643
+ * @return string page url
644
+ */
645
+ public static function get_page_url( $menu_slug ) {
646
+
647
+ $parent_page = self::$default_menu_position;
648
+
649
+ if ( strpos( $parent_page, '?' ) !== false ) {
650
+ $query_var = '&page=' . self::$plugin_slug;
651
+ } else {
652
+ $query_var = '?page=' . self::$plugin_slug;
653
+ }
654
+
655
+ $parent_page_url = admin_url( $parent_page . $query_var );
656
+
657
+ $url = $parent_page_url . '&action=' . $menu_slug;
658
+
659
+ return esc_url( $url );
660
+ }
661
+
662
+ /**
663
+ * Admin body classes.
664
+ *
665
+ * Body classes to be added to <body> tag in admin page
666
+ *
667
+ * @param String $classes body classes returned from the filter.
668
+ * @return String body classes to be added to <body> tag in admin page
669
+ */
670
+ public static function add_admin_body_class( $classes ) {
671
+
672
+ $classes .= ' cartflows-' . CARTFLOWS_VER;
673
+
674
+ return $classes;
675
+ }
676
+
677
+ /**
678
+ * Save Global Setting options.
679
+ *
680
+ * @since 1.0.0
681
+ */
682
+ public static function save_facebook_settings() {
683
+
684
+ if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
685
+
686
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
687
+ $new_settings = array();
688
+
689
+ if ( isset( $_POST['_cartflows_facebook'] ) ) {
690
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
691
+ }
692
+
693
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
694
+ $query = array(
695
+ 'message' => 'saved',
696
+ );
697
+ $redirect_to = add_query_arg( $query, $url );
698
+ wp_safe_redirect( $redirect_to );
699
+ exit;
700
+ }
701
+ }
702
+
703
+ /**
704
+ * Show embed header.
705
+ *
706
+ * @since 1.0.0
707
+ */
708
+ public static function show_embed_header() {
709
+
710
+ $current_screen = get_current_screen();
711
+
712
+ if (
713
+ is_object( $current_screen ) &&
714
+ isset( $current_screen->post_type ) &&
715
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
716
+ isset( $current_screen->base ) &&
717
+ ( 'post' === $current_screen->base || 'edit' === $current_screen->base )
718
+ ) {
719
+ return true;
720
+ }
721
+
722
+ return false;
723
+ }
724
+ /**
725
+ * Set up a div for the header embed to render into.
726
+ * The initial contents here are meant as a place loader for when the PHP page initialy loads.
727
+ */
728
+ public static function embed_page_header() {
729
+
730
+ if ( ! is_admin() || ! self::show_embed_header() ) {
731
+ return;
732
+ }
733
+
734
+ wp_enqueue_style( 'cartflows-admin-embed-header', CARTFLOWS_URL . 'admin/assets/css/admin-embed-header.css', array(), CARTFLOWS_VER );
735
+
736
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin-header.php';
737
+ }
738
+ }
739
+
740
+ Cartflows_Admin::init();
classes/class-cartflows-importer.php CHANGED
@@ -1,1742 +1,1742 @@
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
-
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_import_flow_step', array( $this, 'import_flow' ) );
52
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
-
55
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
-
58
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
-
60
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
-
62
- add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
- add_action( 'admin_init', array( $this, 'export_json' ) );
64
- add_action( 'admin_init', array( $this, 'import_json' ) );
65
- add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
- add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
- }
68
-
69
- /**
70
- * Add the export link to action list for flows row actions
71
- *
72
- * @since 1.1.4
73
- *
74
- * @param array $actions Actions array.
75
- * @param object $post Post object.
76
- *
77
- * @return array
78
- */
79
- public function export_link( $actions, $post ) {
80
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
- $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
- }
83
- return $actions;
84
- }
85
-
86
- /**
87
- * Add menus
88
- *
89
- * @since 1.1.4
90
- */
91
- public function add_to_menus() {
92
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
- }
95
-
96
- /**
97
- * Export flow with steps and its meta
98
- *
99
- * @since 1.1.4
100
- */
101
- public function export_flow() {
102
-
103
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
- wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
- }
106
-
107
- if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
- return;
109
- }
110
-
111
- // Get the original post id.
112
- $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
-
114
- $flows = array();
115
- $flows[] = $this->get_flow_export_data( $flow_id );
116
- $flows = apply_filters( 'cartflows_export_data', $flows );
117
-
118
- nocache_headers();
119
- header( 'Content-Type: application/json; charset=utf-8' );
120
- header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
- header( 'Expires: 0' );
122
-
123
- echo wp_json_encode( $flows );
124
- exit;
125
- }
126
-
127
- /**
128
- * Export flow markup
129
- *
130
- * @since 1.1.4
131
- */
132
- public function exporter_markup() {
133
- include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
- }
135
-
136
- /**
137
- * Import flow markup
138
- *
139
- * @since 1.1.4
140
- */
141
- public function importer_markup() {
142
- include_once CARTFLOWS_DIR . 'includes/importer.php';
143
- }
144
-
145
- /**
146
- * Export flow
147
- *
148
- * @since 1.1.4
149
- */
150
- public function export_json() {
151
- if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
- return;
153
- }
154
-
155
- if ( ! isset( $_POST['cartflows-action-nonce'] ) || empty( $_POST['cartflows-action-nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
- return;
157
- }
158
-
159
- if ( ! current_user_can( 'manage_options' ) ) {
160
- return;
161
- }
162
-
163
- $flows = $this->get_all_flow_export_data();
164
- $flows = apply_filters( 'cartflows_export_data', $flows );
165
-
166
- nocache_headers();
167
- header( 'Content-Type: application/json; charset=utf-8' );
168
- header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
- header( 'Expires: 0' );
170
-
171
- echo wp_json_encode( $flows );
172
- exit;
173
- }
174
-
175
- /**
176
- * Get flow export data
177
- *
178
- * @since 1.1.4
179
- *
180
- * @param integer $flow_id Flow ID.
181
- * @return array
182
- */
183
- public function get_flow_export_data( $flow_id ) {
184
-
185
- $export_all = apply_filters( 'cartflows_export_all', true );
186
-
187
- $valid_step_meta_keys = array(
188
- '_wp_page_template',
189
- '_thumbnail_id',
190
- 'classic-editor-remember',
191
- );
192
-
193
- $new_steps = array();
194
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
- if ( $steps ) {
196
- foreach ( $steps as $key => $step ) {
197
-
198
- // Add step post meta.
199
- $new_all_meta = array();
200
- $all_meta = get_post_meta( $step['id'] );
201
-
202
- // Add single step.
203
- $step_data_arr = array(
204
- 'title' => get_the_title( $step['id'] ),
205
- 'type' => $step['type'],
206
- 'meta' => $all_meta,
207
- 'post_content' => '',
208
- );
209
-
210
- if ( $export_all ) {
211
-
212
- $step_post_obj = get_post( $step['id'] );
213
-
214
- $step_data_arr['post_content'] = $step_post_obj->post_content;
215
- }
216
-
217
- $new_steps[] = $step_data_arr;
218
- }
219
- }
220
-
221
- // Add single flow.
222
- return array(
223
- 'title' => get_the_title( $flow_id ),
224
- 'steps' => $new_steps,
225
- );
226
- }
227
-
228
- /**
229
- * Get all flow export data
230
- *
231
- * @since 1.1.4
232
- */
233
- public function get_all_flow_export_data() {
234
-
235
- $query_args = array(
236
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
-
238
- // Query performance optimization.
239
- 'fields' => 'ids',
240
- 'no_found_rows' => true,
241
- 'posts_per_page' => -1,
242
- );
243
-
244
- $query = new WP_Query( $query_args );
245
- $flows = array();
246
- if ( $query->posts ) {
247
- foreach ( $query->posts as $key => $post_id ) {
248
- $flows[] = $this->get_flow_export_data( $post_id );
249
- }
250
- }
251
-
252
- return $flows;
253
- }
254
-
255
- /**
256
- * Import our exported file
257
- *
258
- * @since 1.1.4
259
- */
260
- public function import_json() {
261
- if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
- return;
263
- }
264
-
265
- if ( ! isset( $_POST['cartflows-action-nonce'] ) || empty( $_POST['cartflows-action-nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
- return;
267
- }
268
-
269
- if ( ! current_user_can( 'manage_options' ) ) {
270
- return;
271
- }
272
-
273
- $filename = $_FILES['file']['name']; //phpcs:ignore
274
- $file_info = explode( '.', $filename );
275
- $extension = end( $file_info );
276
-
277
- if ( 'json' != $extension ) {
278
- wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
- }
280
-
281
- $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
-
283
- if ( empty( $file ) ) {
284
- wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
- }
286
-
287
- // Retrieve the settings from the file and convert the JSON object to an array.
288
- $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
-
290
- $this->import_from_json_data( $flows );
291
-
292
- add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
- }
294
-
295
- /**
296
- * Import flow from the JSON data
297
- *
298
- * @since x.x.x
299
- * @param array $flows JSON array.
300
- * @return void
301
- */
302
- public function import_from_json_data( $flows ) {
303
- if ( $flows ) {
304
-
305
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
-
307
- foreach ( $flows as $key => $flow ) {
308
-
309
- $flow_title = $flow['title'];
310
- if ( post_exists( $flow['title'] ) ) {
311
- $flow_title = $flow['title'] . ' Copy';
312
- }
313
-
314
- // Create post object.
315
- $new_flow_args = apply_filters(
316
- 'cartflows_flow_importer_args',
317
- array(
318
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
- 'post_title' => $flow_title,
320
- 'post_status' => 'publish',
321
- )
322
- );
323
-
324
- // Insert the post into the database.
325
- $flow_id = wp_insert_post( $new_flow_args );
326
-
327
- /**
328
- * Fire after flow import
329
- *
330
- * @since x.x.x
331
- * @param int $flow_id Flow ID.
332
- * @param array $new_flow_args Flow post args.
333
- * @param array $flows Flow JSON data.
334
- */
335
- do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
-
337
- if ( $flow['steps'] ) {
338
- foreach ( $flow['steps'] as $key => $step ) {
339
-
340
- $new_all_meta = array();
341
- if ( is_array( $step['meta'] ) ) {
342
- foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
- $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
- }
345
- }
346
- $new_step_args = apply_filters(
347
- 'cartflows_step_importer_args',
348
- array(
349
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
- 'post_title' => $step['title'],
351
- 'post_status' => 'publish',
352
- 'meta_input' => $new_all_meta,
353
- 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
- )
355
- );
356
-
357
- $new_step_id = wp_insert_post( $new_step_args );
358
-
359
- /**
360
- * Fire after step import
361
- *
362
- * @since x.x.x
363
- * @param int $new_step_id step ID.
364
- * @param int $flow_id flow ID.
365
- * @param array $new_step_args Step post args.
366
- * @param array $flow_steps Flow steps.
367
- * @param array $flows All flows JSON data.
368
- */
369
- do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
-
371
- // Insert post meta.
372
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
-
374
- $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
- $current_term = term_exists( $step['type'], $step_taxonomy );
376
-
377
- // // Set type object.
378
- $data = get_term( $current_term['term_id'], $step_taxonomy );
379
- $step_slug = $data->slug;
380
- wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
-
382
- // Set type.
383
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
-
385
- // Set flow.
386
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
-
388
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
-
390
- if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
-
392
- // Download and replace images.
393
- $content = $this->get_content( $step['post_content'] );
394
-
395
- // Update post content.
396
- wp_update_post(
397
- array(
398
- 'ID' => $new_step_id,
399
- 'post_content' => $content,
400
- )
401
- );
402
- }
403
-
404
- // Elementor Data.
405
- if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
- // Add "elementor" in import [queue].
407
- // @todo Remove required `allow_url_fopen` support.
408
- if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
- $obj->import_single_template( $new_step_id );
411
- }
412
- }
413
-
414
- // Beaver Builder.
415
- if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
- if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
- CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
- }
419
- }
420
- }
421
- }
422
- }
423
- }
424
- }
425
-
426
- /**
427
- * Download and Replace hotlink images
428
- *
429
- * @since x.x.x
430
- *
431
- * @param string $content Mixed post content.
432
- * @return array Hotlink image array.
433
- */
434
- public function get_content( $content = '' ) {
435
-
436
- $content = stripslashes( $content );
437
-
438
- // Extract all links.
439
- $all_links = wp_extract_urls( $content );
440
-
441
- // Not have any link.
442
- if ( empty( $all_links ) ) {
443
- return $content;
444
- }
445
-
446
- $link_mapping = array();
447
- $image_links = array();
448
- $other_links = array();
449
-
450
- // Extract normal and image links.
451
- foreach ( $all_links as $key => $link ) {
452
- if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
-
454
- // Get all image links.
455
- // Avoid *-150x, *-300x and *-1024x images.
456
- if (
457
- false === strpos( $link, '-150x' ) &&
458
- false === strpos( $link, '-300x' ) &&
459
- false === strpos( $link, '-1024x' )
460
- ) {
461
- $image_links[] = $link;
462
- }
463
- } else {
464
-
465
- // Collect other links.
466
- $other_links[] = $link;
467
- }
468
- }
469
-
470
- // Step 1: Download images.
471
- if ( ! empty( $image_links ) ) {
472
- foreach ( $image_links as $key => $image_url ) {
473
- // Download remote image.
474
- $image = array(
475
- 'url' => $image_url,
476
- 'id' => 0,
477
- );
478
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
-
480
- // Old and New image mapping links.
481
- $link_mapping[ $image_url ] = $downloaded_image['url'];
482
- }
483
- }
484
-
485
- // Step 3: Replace mapping links.
486
- foreach ( $link_mapping as $old_url => $new_url ) {
487
- $content = str_replace( $old_url, $new_url, $content );
488
-
489
- // Replace the slashed URLs if any exist.
490
- $old_url = str_replace( '/', '/\\', $old_url );
491
- $new_url = str_replace( '/', '/\\', $new_url );
492
- $content = str_replace( $old_url, $new_url, $content );
493
- }
494
-
495
- return $content;
496
- }
497
-
498
- /**
499
- * Imported notice
500
- *
501
- * @since 1.1.4
502
- */
503
- public function imported_successfully() {
504
- ?>
505
- <div class="notice notice-success">
506
- <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
- </div>
508
- <?php
509
- }
510
-
511
- /**
512
- * Clear Cache.
513
- *
514
- * @since 1.0.0
515
- */
516
- public function clear_cache() {
517
- // Clear 'Elementor' file cache.
518
- if ( class_exists( '\Elementor\Plugin' ) ) {
519
- \Elementor\Plugin::$instance->files_manager->clear_cache();
520
- }
521
- }
522
-
523
- /**
524
- * JS Templates
525
- *
526
- * @since 1.0.0
527
- *
528
- * @return void
529
- */
530
- public function js_templates() {
531
-
532
- // Loading Templates.
533
- ?>
534
- <script type="text/template" id="tmpl-cartflows-step-loading">
535
- <div class="template-message-block cartflows-step-loading">
536
- <h2>
537
- <span class="spinner"></span>
538
- <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
- </h2>
540
- <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
- </div>
542
- </script>
543
-
544
- <?php
545
- // Search Templates.
546
- ?>
547
- <script type="text/template" id="tmpl-cartflows-searching-templates">
548
- <div class="template-message-block cartflows-searching-templates">
549
- <h2>
550
- <span class="spinner"></span>
551
- <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
- </h2>
553
- <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
- </div>
555
- </script>
556
-
557
- <?php
558
- // CartFlows Importing Template.
559
- ?>
560
- <script type="text/template" id="tmpl-cartflows-step-importing">
561
- <div class="template-message-block cartflows-step-importing">
562
- <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
- </div>
564
- </script>
565
-
566
- <?php
567
- // CartFlows Imported.
568
- ?>
569
- <script type="text/template" id="tmpl-cartflows-step-imported">
570
- <div class="template-message-block cartflows-step-imported">
571
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
- </script>
574
-
575
- <?php
576
- // No templates.
577
- ?>
578
- <script type="text/template" id="tmpl-cartflows-no-steps">
579
- <div class="cartflows-no-steps">
580
- <div class="template-message-block">
581
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
- <p class="description"></p>
583
- </div>
584
- </div>
585
- </script>
586
-
587
- <?php
588
- // No templates.
589
- ?>
590
- <script type="text/template" id="tmpl-cartflows-no-flows">
591
- <div class="cartflows-no-flows">
592
- <div class="template-message-block">
593
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
- <p class="description"></p>
595
- </div>
596
- </div>
597
- </script>
598
-
599
- <?php
600
- // Error handling.
601
- ?>
602
- <script type="text/template" id="tmpl-templator-error">
603
- <div class="notice notice-error"><p>{{ data }}</p></div>
604
- </script>
605
-
606
- <?php
607
- // Redirect to Elementor.
608
- ?>
609
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
- <div class="template-message-block templator-redirect-to-elementor">
611
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
- </script>
614
-
615
- <?php
616
- /**
617
- * Responsive Buttons
618
- */
619
- ?>
620
- <script type="text/template" id="tmpl-cartflows-responsive-view">
621
- <span class="responsive-view">
622
- <span class="actions">
623
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
- </span>
627
- </span>
628
- </script>
629
-
630
- <?php
631
- // Templates data.
632
- ?>
633
- <script type="text/template" id="tmpl-cartflows-flows-list">
634
-
635
- <# console.log( data.items.length ) #>
636
- <# console.log( data.items ) #>
637
- <# if ( data.items.length ) { #>
638
- <# for ( key in data.items ) { #>
639
- <#
640
- var flow_steps = [];
641
- if( data.items[ key ].flow_steps ) {
642
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
- return value['id'];
644
- });
645
- }
646
- #>
647
- <div class="inner">
648
- <div class="template">
649
- <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 }}">
650
- <div class="template-screenshot">
651
- <# if( data.items[ key ].featured_image_url ) { #>
652
- <img src="{{ data.items[ key ].featured_image_url }}" />
653
- <# } else { #>
654
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
- <# } #>
656
- </div>
657
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
- <# } #>
660
- <# if( data.items[ key ].woo_required ) { #>
661
- <div class="notice notice-info" style="width: auto;">
662
- <p class="wcf-learn-how">
663
- Install/Activate WooCommerce to use this template.
664
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
- <i class="dashicons dashicons-external"></i>
667
- </a>
668
- </p>
669
- </div>
670
- <# } else { #>
671
- <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>
672
- <# } #>
673
-
674
- </span>
675
- <div class="template-id-container">
676
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
- <div class="template-actions">
678
-
679
- <#
680
- if( data.items[ key ].page_builder.slug ) {
681
- required_plugin_group = data.items[ key ].page_builder.slug;
682
- } else {
683
- required_plugin_group = '';
684
- }
685
-
686
- 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 ) {
687
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
- } else {
689
- import_btn_title = 'Import';
690
- } #>
691
-
692
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
- <# if( ! data.items[ key ].woo_required ) { #>
694
- <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>
695
- <# } else { #>
696
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
- <# } #>
698
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
- <# } else { #>
701
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
- <# } #>
703
- </div>
704
- </div>
705
- </div>
706
- </div>
707
- <# } #>
708
- <# } #>
709
- </script>
710
-
711
- <?php
712
- // Empty Step.
713
- ?>
714
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
- <div class="inner">
716
- <div class="template">
717
- <span class="thumbnail site-preview cartflows-flow-preview">
718
- <div class="template-screenshot">
719
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
- </div>
721
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
- </span>
723
- <div class="template-id-container">
724
- <h3 class="template-name"> Blank </h3>
725
- <div class="template-actions">
726
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
- </div>
728
- </div>
729
- </div>
730
- </div>
731
- </script>
732
-
733
- <?php
734
- // Templates data.
735
- ?>
736
- <script type="text/template" id="tmpl-cartflows-steps-list">
737
- <# if ( data.items.length ) { #>
738
- <# for ( key in data.items ) { #>
739
- <#
740
- var flow_steps = [];
741
- if( data.items[ key ].flow_steps ) {
742
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
- return value['id'];
744
- });
745
- }
746
- #>
747
- <div class="inner">
748
- <div class="template">
749
- <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 }}">
750
- <div class="template-screenshot">
751
- <# if( data.items[ key ].featured_image_url ) { #>
752
- <img src="{{ data.items[ key ].featured_image_url }}" />
753
- <# } else { #>
754
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
- <# } #>
756
- </div>
757
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
-
759
- <# if( data.items[ key ].woo_required ) { #>
760
- <div class="notice notice-info" style="width: auto;">
761
- <p class="wcf-learn-how">
762
- Install/Activate WooCommerce to use this template.
763
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
- <i class="dashicons dashicons-external"></i>
766
- </a>
767
- </p>
768
- </div>
769
- <# } else { #>
770
- <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>
771
- <# } #>
772
-
773
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
- <# } #>
776
- </span>
777
- <div class="template-id-container">
778
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
- <div class="template-actions">
780
-
781
- <#
782
-
783
- var step_slug = data.items[ key ].step_type.slug || '';
784
- var step_title = data.items[ key ].step_type.name || '';
785
- var import_btn_title = 'Import';
786
-
787
- var required_plugin_group = '';
788
- if( data.items[ key ].page_builder ) {
789
- required_plugin_group = data.items[ key ].page_builder.slug;
790
-
791
- 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 ) {
792
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
- }
794
- }
795
- #>
796
-
797
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
-
799
- <# if( ! data.items[ key ].woo_required ) { #>
800
- <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>
801
- <# } else { #>
802
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
- <# } #>
804
-
805
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
- <# } else { #>
808
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
- <# } #>
810
- </div>
811
- </div>
812
- </div>
813
- </div>
814
- <# } #>
815
- <# } #>
816
- </script>
817
-
818
- <?php
819
- /**
820
- * TMPL - Website Unreachable
821
- */
822
- ?>
823
- <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
- <div class="postbox cartflows-website-unreachable">
825
- <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
- <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
- <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
- </div>
829
- </script>
830
-
831
- <?php
832
- /**
833
- * TMPL - Filters
834
- */
835
- ?>
836
- <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
- <?php
838
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
- $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
- $title = $page_builder['title'];
841
-
842
- $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
- $theme_status = '';
844
- if ( 'divi' === $default_page_builder ) {
845
-
846
- $theme_status = $page_builder['theme-status'];
847
- $plugin_status = $page_builder['plugin-status'];
848
-
849
- if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
- $plugin_string = 'Please activate ' . esc_html( $title );
851
- } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
- $plugin_string = 'Please install and activate ' . esc_html( $title );
853
- }
854
- }
855
- ?>
856
- <div class="wcf-page-builder-message">
857
- <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
- <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
- <p>We plan to add design templates made with more page builder shortly!</p>
860
- </div>
861
- </script>
862
-
863
- <?php
864
- /**
865
- * TMPL - Filters
866
- */
867
- ?>
868
- <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
- <# if ( data ) { #>
870
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
- <# if ( data.args.show_all ) { #>
872
- <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
- <# } #>
874
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
- <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
- <# } #>
877
- <# var step_slug_data = []; #>
878
- <# for ( key in data.items ) { #>
879
- <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>
880
-
881
- <# step_slug_data.push( data.items[ key ].slug ); #>
882
-
883
- <# } #>
884
- <# if( step_slug_data.indexOf("optin") === -1){ #>
885
- <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
- <# } #>
887
- </select>
888
- <# } #>
889
- </script>
890
-
891
- <script type="text/template" id="tmpl-cartflows-term-filters">
892
-
893
- <# if ( data ) { #>
894
-
895
- <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
-
898
- <# if ( data.args.show_all ) { #>
899
- <li>
900
- <a href="#" data-group="all"> All </a>
901
- </li>
902
- <# } #>
903
-
904
- <# for ( key in data.items ) { #>
905
- <li>
906
- <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>
907
- </li>
908
- <# } #>
909
-
910
- </ul>
911
-
912
- <?php
913
-
914
- /**
915
- <# } else { #>
916
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
-
918
- <# if ( data.args.show_all ) { #>
919
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
- <# } #>
921
-
922
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
- <# } #>
925
-
926
- <# for ( key in data.items ) { #>
927
- <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>
928
- <# } #>
929
-
930
- </select>
931
- */
932
- ?>
933
-
934
- <?php /* <# } #> */ ?>
935
-
936
- <# } #>
937
- </script>
938
-
939
- <?php
940
- // Step Type.
941
- ?>
942
- <script type="text/template" id="tmpl-cartflows-step-types">
943
- <ul class="wcf-tab nav-tabs">
944
- <# if( data.items_count ) { #>
945
- <# for( key in data.items ) { #>
946
- <# console.log( data.items[ key ].id ) #>
947
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
- </li>
950
- <# } #>
951
- <# } #>
952
- </ul>
953
- </script>
954
-
955
- <?php
956
- // Add to library button.
957
- ?>
958
- <script type="text/template" id="tmpl-templator-add-to-library">
959
- <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>
960
- </script>
961
- <?php
962
- }
963
-
964
- /**
965
- * Enqueue scripts
966
- *
967
- * @since 1.0.0
968
- *
969
- * @hook admin_enqueue_scripts
970
- * @param string $hook Current page hook.
971
- */
972
- public function scripts( $hook = '' ) {
973
-
974
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
- return;
976
- }
977
-
978
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
-
983
- $installed_plugins = get_plugins();
984
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
- $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
-
987
- $localize_vars = array(
988
- '_is_pro_active' => _is_cartflows_pro(),
989
- 'is_wc_installed' => $is_wc_installed,
990
- 'is_wc_activated' => $is_wc_activated,
991
-
992
- // Set API headers for the CartFlows API Calls only.
993
- 'headers' => array(),
994
-
995
- // Flow and its rest fields.
996
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
997
- 'flow_fields' => array(
998
- 'id',
999
- 'title',
1000
- 'flow_type',
1001
- 'page_builder',
1002
- 'flow_steps',
1003
- 'licence_status',
1004
- 'featured_image_url',
1005
- 'featured_media', // @required for field `featured_image_url`.
1006
- ),
1007
-
1008
- // Flow type and rest fields.
1009
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1010
- 'flow_type_fields' => array(
1011
- 'id',
1012
- 'name',
1013
- 'slug',
1014
- ),
1015
-
1016
- // Flow page builder and rest fields.
1017
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1018
- 'flow_page_builder_fields' => array(
1019
- 'id',
1020
- 'name',
1021
- 'slug',
1022
- ),
1023
-
1024
- // Step page builder and rest fields.
1025
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1026
- 'step_page_builder_fields' => array(
1027
- 'id',
1028
- 'name',
1029
- 'slug',
1030
- ),
1031
-
1032
- // Step and its rest fields.
1033
- 'step' => CARTFLOWS_STEP_POST_TYPE,
1034
- 'step_fields' => array(
1035
- 'title',
1036
- 'featured_image_url',
1037
- 'featured_media', // @required for field `featured_image_url`.
1038
- 'id',
1039
- 'flow_type',
1040
- 'step_type',
1041
- 'page_builder',
1042
- 'licence_status',
1043
- ),
1044
-
1045
- // Step type and its rest fields.
1046
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1047
- 'step_type_fields' => array(
1048
- 'id',
1049
- 'name',
1050
- 'slug',
1051
- ),
1052
-
1053
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
1054
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
1055
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1056
- 'site_url' => site_url(),
1057
- 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1058
- 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1059
- 'admin_url' => admin_url(),
1060
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1061
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1062
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1063
-
1064
- 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1065
-
1066
- 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1067
- );
1068
-
1069
- $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1070
-
1071
- // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1072
- // wp_die( );
1073
- // Add thickbox.
1074
- add_thickbox();
1075
-
1076
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1077
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1078
- }
1079
-
1080
- /**
1081
- * Import.
1082
- *
1083
- * @since 1.0.0
1084
- *
1085
- * @hook wp_ajax_cartflows_import_flow_step
1086
- * @return void
1087
- */
1088
- public function import_flow() {
1089
-
1090
- if ( ! current_user_can( 'manage_options' ) ) {
1091
- return;
1092
- }
1093
-
1094
- check_ajax_referer( 'cf-import-flow-step', 'security' );
1095
-
1096
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1097
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1098
-
1099
- wcf()->logger->import_log( '------------------------------------' );
1100
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1101
- wcf()->logger->import_log( '------------------------------------' );
1102
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1103
-
1104
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1105
-
1106
- $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1107
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1108
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1109
- $post_content = $response['data']['divi_content'];
1110
- }
1111
- }
1112
-
1113
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1114
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1115
- $post_content = $response['data']['divi_content'];
1116
- }
1117
- }
1118
-
1119
- if ( false === $response['success'] ) {
1120
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1121
- wp_send_json_error( $response );
1122
- }
1123
-
1124
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1125
-
1126
- $new_step_id = wp_insert_post(
1127
- array(
1128
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1129
- 'post_title' => $response['title'],
1130
- 'post_content' => $post_content,
1131
- 'post_status' => 'publish',
1132
- )
1133
- );
1134
-
1135
- if ( is_wp_error( $new_step_id ) ) {
1136
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1137
- wp_send_json_error( $new_step_id );
1138
- }
1139
-
1140
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1141
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1142
- update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1143
- }
1144
- }
1145
-
1146
- /* Imported Step */
1147
- update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1148
-
1149
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1150
- // insert post meta.
1151
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1152
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1153
-
1154
- /**
1155
- * Import & Set type.
1156
- */
1157
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1158
-
1159
- $term_slug = '';
1160
- if ( $term ) {
1161
-
1162
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1163
- $term_exist = term_exists( $term->slug, $taxonomy );
1164
-
1165
- if ( empty( $term_exist ) ) {
1166
- $terms = array(
1167
- array(
1168
- 'name' => $term->name,
1169
- 'slug' => $term->slug,
1170
- ),
1171
- );
1172
-
1173
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1174
- wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1175
- }
1176
-
1177
- $current_term = term_exists( $term->slug, $taxonomy );
1178
-
1179
- // Set type object.
1180
- $data = get_term( $current_term['term_id'], $taxonomy );
1181
- $term_slug = $data->slug;
1182
- $term_name = $data->name;
1183
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1184
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1185
-
1186
- // Set type.
1187
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1188
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1189
- }
1190
-
1191
- // Set flow.
1192
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1193
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1194
-
1195
- /**
1196
- * Update steps for the current flow.
1197
- */
1198
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1199
-
1200
- if ( ! is_array( $flow_steps ) ) {
1201
- $flow_steps = array();
1202
- }
1203
-
1204
- $flow_steps[] = array(
1205
- 'id' => $new_step_id,
1206
- 'title' => $response['title'],
1207
- 'type' => $term_slug,
1208
- );
1209
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1210
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1211
-
1212
- // Import Post Meta.
1213
- self::import_post_meta( $new_step_id, $response );
1214
-
1215
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1216
- wcf()->logger->import_log( '------------------------------------' );
1217
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1218
- wcf()->logger->import_log( '------------------------------------' );
1219
-
1220
- do_action( 'cartflows_import_complete' );
1221
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1222
-
1223
- // Batch Process.
1224
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
1225
-
1226
- /**
1227
- * End
1228
- */
1229
- wp_send_json_success( $new_step_id );
1230
- }
1231
-
1232
- /**
1233
- * Import Step.
1234
- *
1235
- * @since 1.0.0
1236
- * @hook wp_ajax_cartflows_step_import
1237
- *
1238
- * @return void
1239
- */
1240
- public function create_default_flow() {
1241
-
1242
- if ( ! current_user_can( 'manage_options' ) ) {
1243
- return;
1244
- }
1245
-
1246
- check_ajax_referer( 'cf-default-flow', 'security' );
1247
-
1248
- // Create post object.
1249
- $new_flow_post = array(
1250
- 'post_content' => '',
1251
- 'post_status' => 'publish',
1252
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1253
- );
1254
-
1255
- // Insert the post into the database.
1256
- $flow_id = wp_insert_post( $new_flow_post );
1257
-
1258
- if ( is_wp_error( $flow_id ) ) {
1259
- wp_send_json_error( $flow_id->get_error_message() );
1260
- }
1261
-
1262
- $flow_steps = array();
1263
-
1264
- if ( wcf()->is_woo_active ) {
1265
- $steps_data = array(
1266
- 'sales' => array(
1267
- 'title' => __( 'Sales Landing', 'cartflows' ),
1268
- 'type' => 'landing',
1269
- ),
1270
- 'order-form' => array(
1271
- 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1272
- 'type' => 'checkout',
1273
- ),
1274
- 'order-confirmation' => array(
1275
- 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1276
- 'type' => 'thankyou',
1277
- ),
1278
- );
1279
-
1280
- } else {
1281
- $steps_data = array(
1282
- 'landing' => array(
1283
- 'title' => __( 'Landing', 'cartflows' ),
1284
- 'type' => 'landing',
1285
- ),
1286
- 'thankyou' => array(
1287
- 'title' => __( 'Thank You', 'cartflows' ),
1288
- 'type' => 'landing',
1289
- ),
1290
- );
1291
- }
1292
-
1293
- foreach ( $steps_data as $slug => $data ) {
1294
-
1295
- $post_content = '';
1296
- $step_type = trim( $data['type'] );
1297
-
1298
- $step_id = wp_insert_post(
1299
- array(
1300
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1301
- 'post_title' => $data['title'],
1302
- 'post_content' => $post_content,
1303
- 'post_status' => 'publish',
1304
- )
1305
- );
1306
-
1307
- if ( is_wp_error( $step_id ) ) {
1308
- wp_send_json_error( $step_id->get_error_message() );
1309
- }
1310
-
1311
- if ( $step_id ) {
1312
-
1313
- $flow_steps[] = array(
1314
- 'id' => $step_id,
1315
- 'title' => $data['title'],
1316
- 'type' => $step_type,
1317
- );
1318
-
1319
- // insert post meta.
1320
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1321
- update_post_meta( $step_id, 'wcf-step-type', $step_type );
1322
-
1323
- wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1324
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1325
-
1326
- update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1327
- }
1328
- }
1329
-
1330
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1331
-
1332
- wp_send_json_success( $flow_id );
1333
- }
1334
-
1335
- /**
1336
- * Create Flow
1337
- *
1338
- * @return void
1339
- */
1340
- public function create_flow() {
1341
-
1342
- if ( ! current_user_can( 'manage_options' ) ) {
1343
- return;
1344
- }
1345
-
1346
- check_ajax_referer( 'cf-create-flow', 'security' );
1347
-
1348
- // Create post object.
1349
- $new_flow_post = array(
1350
- 'post_content' => '',
1351
- 'post_status' => 'publish',
1352
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1353
- );
1354
-
1355
- // Insert the post into the database.
1356
- $flow_id = wp_insert_post( $new_flow_post );
1357
-
1358
- if ( is_wp_error( $flow_id ) ) {
1359
- wp_send_json_error( $flow_id->get_error_message() );
1360
- }
1361
-
1362
- /* Imported Flow */
1363
- update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1364
-
1365
- wp_send_json_success( $flow_id );
1366
- }
1367
-
1368
- /**
1369
- * Create Step
1370
- *
1371
- * @return void
1372
- */
1373
- public function import_step() {
1374
-
1375
- if ( ! current_user_can( 'manage_options' ) ) {
1376
- return;
1377
- }
1378
-
1379
- check_ajax_referer( 'cf-step-import', 'security' );
1380
-
1381
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1382
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1383
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1384
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1385
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1386
-
1387
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1388
-
1389
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1390
-
1391
- wcf()->logger->import_log( '------------------------------------' );
1392
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
1393
- wcf()->logger->import_log( '------------------------------------' );
1394
-
1395
- if ( empty( $template_id ) || empty( $post_id ) ) {
1396
- /* translators: %s: template ID */
1397
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1398
- wcf()->logger->import_log( $data );
1399
- wp_send_json_error( $data );
1400
- }
1401
-
1402
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1403
-
1404
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1405
-
1406
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1407
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1408
-
1409
- update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1410
-
1411
- wp_update_post(
1412
- array(
1413
- 'ID' => $post_id,
1414
- 'post_content' => $response['data']['divi_content'],
1415
- )
1416
- );
1417
- }
1418
- }
1419
-
1420
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1421
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1422
-
1423
- wp_update_post(
1424
- array(
1425
- 'ID' => $post_id,
1426
- 'post_content' => $response['data']['divi_content'],
1427
- )
1428
- );
1429
- }
1430
- }
1431
-
1432
- /* Imported Step */
1433
- update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1434
-
1435
- // Import Post Meta.
1436
- self::import_post_meta( $post_id, $response );
1437
-
1438
- do_action( 'cartflows_import_complete' );
1439
-
1440
- // Batch Process.
1441
- do_action( 'cartflows_after_template_import', $post_id, $response );
1442
-
1443
- wcf()->logger->import_log( '------------------------------------' );
1444
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1445
- wcf()->logger->import_log( '------------------------------------' );
1446
-
1447
- wp_send_json_success( $post_id );
1448
- }
1449
-
1450
- /**
1451
- * Import Step.
1452
- *
1453
- * @since 1.0.0
1454
- * @hook wp_ajax_cartflows_step_create_blank
1455
- *
1456
- * @return void
1457
- */
1458
- public function step_create_blank() {
1459
-
1460
- if ( ! current_user_can( 'manage_options' ) ) {
1461
- return;
1462
- }
1463
-
1464
- check_ajax_referer( 'cf-step-create-blank', 'security' );
1465
-
1466
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1467
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1468
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1469
-
1470
- if ( empty( $flow_id ) || empty( $step_type ) ) {
1471
- /* translators: %s: flow ID */
1472
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1473
- wcf()->logger->import_log( $data );
1474
- wp_send_json_error( $data );
1475
- }
1476
-
1477
- wcf()->logger->import_log( '------------------------------------' );
1478
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1479
-
1480
- $step_type_title = str_replace( '-', ' ', $step_type );
1481
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1482
-
1483
- $new_step_id = wp_insert_post(
1484
- array(
1485
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1486
- 'post_title' => $step_title,
1487
- 'post_content' => '',
1488
- 'post_status' => 'publish',
1489
- )
1490
- );
1491
-
1492
- // insert post meta.
1493
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1494
-
1495
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1496
- $term_exist = term_exists( $step_type_slug, $taxonomy );
1497
-
1498
- if ( empty( $term_exist ) ) {
1499
- $terms = array(
1500
- array(
1501
- 'name' => $step_type_title,
1502
- 'slug' => $step_type_slug,
1503
- ),
1504
- );
1505
-
1506
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1507
- wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1508
- }
1509
-
1510
- $current_term = term_exists( $step_type_slug, $taxonomy );
1511
-
1512
- // Set type object.
1513
- $data = get_term( $current_term['term_id'], $taxonomy );
1514
- $step_slug = $data->slug;
1515
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1516
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1517
-
1518
- // Set Default page Layout.
1519
- update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1520
-
1521
- // Set type.
1522
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1523
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1524
-
1525
- // Set flow.
1526
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1527
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1528
-
1529
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1530
-
1531
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1532
- wcf()->logger->import_log( '------------------------------------' );
1533
-
1534
- wp_send_json_success( $new_step_id );
1535
- }
1536
-
1537
- /**
1538
- * Import Post Meta
1539
- *
1540
- * @since 1.0.0
1541
- *
1542
- * @param integer $post_id Post ID.
1543
- * @param array $response Post meta.
1544
- * @return void
1545
- */
1546
- public static function import_post_meta( $post_id, $response ) {
1547
-
1548
- $metadata = (array) $response['post_meta'];
1549
-
1550
- foreach ( $metadata as $meta_key => $meta_value ) {
1551
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1552
-
1553
- if ( $meta_value ) {
1554
-
1555
- if ( is_serialized( $meta_value, true ) ) {
1556
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1557
- } elseif ( is_array( $meta_value ) ) {
1558
- $raw_data = json_decode( stripslashes( $meta_value ), true );
1559
- } else {
1560
- $raw_data = $meta_value;
1561
- }
1562
-
1563
- if ( '_elementor_data' === $meta_key ) {
1564
- if ( is_array( $raw_data ) ) {
1565
- $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1566
- } else {
1567
- $raw_data = wp_slash( $raw_data );
1568
- }
1569
- }
1570
- if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1571
- if ( is_array( $raw_data ) ) {
1572
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1573
- } else {
1574
- if ( ! is_object( $raw_data ) ) {
1575
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1576
- }
1577
- }
1578
- }
1579
-
1580
- update_post_meta( $post_id, $meta_key, $raw_data );
1581
- }
1582
- }
1583
- }
1584
-
1585
- /**
1586
- * Import Template for Elementor
1587
- *
1588
- * @since 1.0.0
1589
- *
1590
- * @param integer $post_id Post ID.
1591
- * @param array $response Post meta.
1592
- * @param array $page_build_data Page build data.
1593
- * @return void
1594
- */
1595
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1596
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1597
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1598
- wcf()->logger->import_log( $data );
1599
- wp_send_json_error( $data );
1600
- }
1601
-
1602
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1603
-
1604
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1605
-
1606
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1607
- $obj->import_single_template( $post_id );
1608
-
1609
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1610
- }
1611
-
1612
- /**
1613
- * Supported post types
1614
- *
1615
- * @since 1.0.0
1616
- *
1617
- * @return array Supported post types.
1618
- */
1619
- public static function supported_post_types() {
1620
- return apply_filters(
1621
- 'cartflows_supported_post_types',
1622
- array(
1623
- CARTFLOWS_FLOW_POST_TYPE,
1624
- )
1625
- );
1626
- }
1627
-
1628
- /**
1629
- * Check supported post type
1630
- *
1631
- * @since 1.0.0
1632
- *
1633
- * @param string $post_type Post type.
1634
- * @return boolean Supported post type status.
1635
- */
1636
- public static function is_supported_post( $post_type = '' ) {
1637
-
1638
- if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1639
- return true;
1640
- }
1641
-
1642
- return false;
1643
- }
1644
-
1645
- /**
1646
- * Set steps to the flow
1647
- *
1648
- * @param integer $flow_id Flow ID.
1649
- * @param integer $new_step_id New step ID.
1650
- * @param string $step_title Flow Type.
1651
- * @param string $step_slug Flow Type.
1652
- */
1653
- public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1654
- // Update steps for the current flow.
1655
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1656
-
1657
- if ( ! is_array( $flow_steps ) ) {
1658
- $flow_steps = array();
1659
- }
1660
-
1661
- $flow_steps[] = array(
1662
- 'id' => $new_step_id,
1663
- 'title' => $step_title,
1664
- 'type' => $step_slug,
1665
- );
1666
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1667
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1668
- }
1669
-
1670
- /**
1671
- * Localize variables in admin
1672
- *
1673
- * @param array $vars variables.
1674
- */
1675
- public function localize_vars( $vars ) {
1676
-
1677
- $ajax_actions = array(
1678
- 'cf_step_import',
1679
- 'cf_load_steps',
1680
- 'cf_create_flow',
1681
- 'cf_default_flow',
1682
- 'cf_step_create_blank',
1683
- 'cf_import_flow_step',
1684
- );
1685
-
1686
- foreach ( $ajax_actions as $action ) {
1687
-
1688
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1689
- }
1690
-
1691
- return $vars;
1692
- }
1693
-
1694
- /**
1695
- * Ajax action to activate plugin
1696
- */
1697
- public function activate_plugin() {
1698
-
1699
- if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1700
- wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1701
- }
1702
-
1703
- if ( ! current_user_can( 'activate_plugins' ) ) {
1704
- wp_send_json_error(
1705
- array(
1706
- 'success' => false,
1707
- 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1708
- )
1709
- );
1710
- }
1711
-
1712
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1713
-
1714
- $activate = activate_plugin( $plugin_init, '', false, true );
1715
-
1716
- if ( is_wp_error( $activate ) ) {
1717
- wp_send_json_error(
1718
- array(
1719
- 'success' => false,
1720
- 'message' => $activate->get_error_message(),
1721
- 'init' => $plugin_init,
1722
- )
1723
- );
1724
- }
1725
-
1726
- wp_send_json_success(
1727
- array(
1728
- 'success' => true,
1729
- 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1730
- 'init' => $plugin_init,
1731
- )
1732
- );
1733
- }
1734
-
1735
- }
1736
-
1737
- /**
1738
- * Initialize class object with 'get_instance()' method
1739
- */
1740
- CartFlows_Importer::get_instance();
1741
-
1742
- endif;
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
+
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_import_flow_step', array( $this, 'import_flow' ) );
52
+ add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
+ add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
+
55
+ add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
+ add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
+
58
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
+
60
+ add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
+
62
+ add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
+ add_action( 'admin_init', array( $this, 'export_json' ) );
64
+ add_action( 'admin_init', array( $this, 'import_json' ) );
65
+ add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
+ add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
+ }
68
+
69
+ /**
70
+ * Add the export link to action list for flows row actions
71
+ *
72
+ * @since 1.1.4
73
+ *
74
+ * @param array $actions Actions array.
75
+ * @param object $post Post object.
76
+ *
77
+ * @return array
78
+ */
79
+ public function export_link( $actions, $post ) {
80
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
+ $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
+ }
83
+ return $actions;
84
+ }
85
+
86
+ /**
87
+ * Add menus
88
+ *
89
+ * @since 1.1.4
90
+ */
91
+ public function add_to_menus() {
92
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
+ }
95
+
96
+ /**
97
+ * Export flow with steps and its meta
98
+ *
99
+ * @since 1.1.4
100
+ */
101
+ public function export_flow() {
102
+
103
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
+ wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
+ }
106
+
107
+ if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
+ return;
109
+ }
110
+
111
+ // Get the original post id.
112
+ $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
+
114
+ $flows = array();
115
+ $flows[] = $this->get_flow_export_data( $flow_id );
116
+ $flows = apply_filters( 'cartflows_export_data', $flows );
117
+
118
+ nocache_headers();
119
+ header( 'Content-Type: application/json; charset=utf-8' );
120
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
+ header( 'Expires: 0' );
122
+
123
+ echo wp_json_encode( $flows );
124
+ exit;
125
+ }
126
+
127
+ /**
128
+ * Export flow markup
129
+ *
130
+ * @since 1.1.4
131
+ */
132
+ public function exporter_markup() {
133
+ include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
+ }
135
+
136
+ /**
137
+ * Import flow markup
138
+ *
139
+ * @since 1.1.4
140
+ */
141
+ public function importer_markup() {
142
+ include_once CARTFLOWS_DIR . 'includes/importer.php';
143
+ }
144
+
145
+ /**
146
+ * Export flow
147
+ *
148
+ * @since 1.1.4
149
+ */
150
+ public function export_json() {
151
+ if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
+ return;
153
+ }
154
+
155
+ if ( ! isset( $_POST['cartflows-action-nonce'] ) || empty( $_POST['cartflows-action-nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
+ return;
157
+ }
158
+
159
+ if ( ! current_user_can( 'manage_options' ) ) {
160
+ return;
161
+ }
162
+
163
+ $flows = $this->get_all_flow_export_data();
164
+ $flows = apply_filters( 'cartflows_export_data', $flows );
165
+
166
+ nocache_headers();
167
+ header( 'Content-Type: application/json; charset=utf-8' );
168
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
+ header( 'Expires: 0' );
170
+
171
+ echo wp_json_encode( $flows );
172
+ exit;
173
+ }
174
+
175
+ /**
176
+ * Get flow export data
177
+ *
178
+ * @since 1.1.4
179
+ *
180
+ * @param integer $flow_id Flow ID.
181
+ * @return array
182
+ */
183
+ public function get_flow_export_data( $flow_id ) {
184
+
185
+ $export_all = apply_filters( 'cartflows_export_all', true );
186
+
187
+ $valid_step_meta_keys = array(
188
+ '_wp_page_template',
189
+ '_thumbnail_id',
190
+ 'classic-editor-remember',
191
+ );
192
+
193
+ $new_steps = array();
194
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
+ if ( $steps ) {
196
+ foreach ( $steps as $key => $step ) {
197
+
198
+ // Add step post meta.
199
+ $new_all_meta = array();
200
+ $all_meta = get_post_meta( $step['id'] );
201
+
202
+ // Add single step.
203
+ $step_data_arr = array(
204
+ 'title' => get_the_title( $step['id'] ),
205
+ 'type' => $step['type'],
206
+ 'meta' => $all_meta,
207
+ 'post_content' => '',
208
+ );
209
+
210
+ if ( $export_all ) {
211
+
212
+ $step_post_obj = get_post( $step['id'] );
213
+
214
+ $step_data_arr['post_content'] = $step_post_obj->post_content;
215
+ }
216
+
217
+ $new_steps[] = $step_data_arr;
218
+ }
219
+ }
220
+
221
+ // Add single flow.
222
+ return array(
223
+ 'title' => get_the_title( $flow_id ),
224
+ 'steps' => $new_steps,
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Get all flow export data
230
+ *
231
+ * @since 1.1.4
232
+ */
233
+ public function get_all_flow_export_data() {
234
+
235
+ $query_args = array(
236
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
+
238
+ // Query performance optimization.
239
+ 'fields' => 'ids',
240
+ 'no_found_rows' => true,
241
+ 'posts_per_page' => -1,
242
+ );
243
+
244
+ $query = new WP_Query( $query_args );
245
+ $flows = array();
246
+ if ( $query->posts ) {
247
+ foreach ( $query->posts as $key => $post_id ) {
248
+ $flows[] = $this->get_flow_export_data( $post_id );
249
+ }
250
+ }
251
+
252
+ return $flows;
253
+ }
254
+
255
+ /**
256
+ * Import our exported file
257
+ *
258
+ * @since 1.1.4
259
+ */
260
+ public function import_json() {
261
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
+ return;
263
+ }
264
+
265
+ if ( ! isset( $_POST['cartflows-action-nonce'] ) || empty( $_POST['cartflows-action-nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
+ return;
267
+ }
268
+
269
+ if ( ! current_user_can( 'manage_options' ) ) {
270
+ return;
271
+ }
272
+
273
+ $filename = $_FILES['file']['name']; //phpcs:ignore
274
+ $file_info = explode( '.', $filename );
275
+ $extension = end( $file_info );
276
+
277
+ if ( 'json' != $extension ) {
278
+ wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
+ }
280
+
281
+ $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
+
283
+ if ( empty( $file ) ) {
284
+ wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
+ }
286
+
287
+ // Retrieve the settings from the file and convert the JSON object to an array.
288
+ $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
+
290
+ $this->import_from_json_data( $flows );
291
+
292
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
+ }
294
+
295
+ /**
296
+ * Import flow from the JSON data
297
+ *
298
+ * @since x.x.x
299
+ * @param array $flows JSON array.
300
+ * @return void
301
+ */
302
+ public function import_from_json_data( $flows ) {
303
+ if ( $flows ) {
304
+
305
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
+
307
+ foreach ( $flows as $key => $flow ) {
308
+
309
+ $flow_title = $flow['title'];
310
+ if ( post_exists( $flow['title'] ) ) {
311
+ $flow_title = $flow['title'] . ' Copy';
312
+ }
313
+
314
+ // Create post object.
315
+ $new_flow_args = apply_filters(
316
+ 'cartflows_flow_importer_args',
317
+ array(
318
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
+ 'post_title' => $flow_title,
320
+ 'post_status' => 'publish',
321
+ )
322
+ );
323
+
324
+ // Insert the post into the database.
325
+ $flow_id = wp_insert_post( $new_flow_args );
326
+
327
+ /**
328
+ * Fire after flow import
329
+ *
330
+ * @since x.x.x
331
+ * @param int $flow_id Flow ID.
332
+ * @param array $new_flow_args Flow post args.
333
+ * @param array $flows Flow JSON data.
334
+ */
335
+ do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
+
337
+ if ( $flow['steps'] ) {
338
+ foreach ( $flow['steps'] as $key => $step ) {
339
+
340
+ $new_all_meta = array();
341
+ if ( is_array( $step['meta'] ) ) {
342
+ foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
+ }
345
+ }
346
+ $new_step_args = apply_filters(
347
+ 'cartflows_step_importer_args',
348
+ array(
349
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
+ 'post_title' => $step['title'],
351
+ 'post_status' => 'publish',
352
+ 'meta_input' => $new_all_meta,
353
+ 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
+ )
355
+ );
356
+
357
+ $new_step_id = wp_insert_post( $new_step_args );
358
+
359
+ /**
360
+ * Fire after step import
361
+ *
362
+ * @since x.x.x
363
+ * @param int $new_step_id step ID.
364
+ * @param int $flow_id flow ID.
365
+ * @param array $new_step_args Step post args.
366
+ * @param array $flow_steps Flow steps.
367
+ * @param array $flows All flows JSON data.
368
+ */
369
+ do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
+
371
+ // Insert post meta.
372
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
+
374
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
+ $current_term = term_exists( $step['type'], $step_taxonomy );
376
+
377
+ // // Set type object.
378
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
379
+ $step_slug = $data->slug;
380
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
+
382
+ // Set type.
383
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
+
385
+ // Set flow.
386
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
+
388
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
+
390
+ if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
+
392
+ // Download and replace images.
393
+ $content = $this->get_content( $step['post_content'] );
394
+
395
+ // Update post content.
396
+ wp_update_post(
397
+ array(
398
+ 'ID' => $new_step_id,
399
+ 'post_content' => $content,
400
+ )
401
+ );
402
+ }
403
+
404
+ // Elementor Data.
405
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
+ // Add "elementor" in import [queue].
407
+ // @todo Remove required `allow_url_fopen` support.
408
+ if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
+ $obj->import_single_template( $new_step_id );
411
+ }
412
+ }
413
+
414
+ // Beaver Builder.
415
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
+ if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
+ CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Download and Replace hotlink images
428
+ *
429
+ * @since x.x.x
430
+ *
431
+ * @param string $content Mixed post content.
432
+ * @return array Hotlink image array.
433
+ */
434
+ public function get_content( $content = '' ) {
435
+
436
+ $content = stripslashes( $content );
437
+
438
+ // Extract all links.
439
+ $all_links = wp_extract_urls( $content );
440
+
441
+ // Not have any link.
442
+ if ( empty( $all_links ) ) {
443
+ return $content;
444
+ }
445
+
446
+ $link_mapping = array();
447
+ $image_links = array();
448
+ $other_links = array();
449
+
450
+ // Extract normal and image links.
451
+ foreach ( $all_links as $key => $link ) {
452
+ if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
+
454
+ // Get all image links.
455
+ // Avoid *-150x, *-300x and *-1024x images.
456
+ if (
457
+ false === strpos( $link, '-150x' ) &&
458
+ false === strpos( $link, '-300x' ) &&
459
+ false === strpos( $link, '-1024x' )
460
+ ) {
461
+ $image_links[] = $link;
462
+ }
463
+ } else {
464
+
465
+ // Collect other links.
466
+ $other_links[] = $link;
467
+ }
468
+ }
469
+
470
+ // Step 1: Download images.
471
+ if ( ! empty( $image_links ) ) {
472
+ foreach ( $image_links as $key => $image_url ) {
473
+ // Download remote image.
474
+ $image = array(
475
+ 'url' => $image_url,
476
+ 'id' => 0,
477
+ );
478
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
+
480
+ // Old and New image mapping links.
481
+ $link_mapping[ $image_url ] = $downloaded_image['url'];
482
+ }
483
+ }
484
+
485
+ // Step 3: Replace mapping links.
486
+ foreach ( $link_mapping as $old_url => $new_url ) {
487
+ $content = str_replace( $old_url, $new_url, $content );
488
+
489
+ // Replace the slashed URLs if any exist.
490
+ $old_url = str_replace( '/', '/\\', $old_url );
491
+ $new_url = str_replace( '/', '/\\', $new_url );
492
+ $content = str_replace( $old_url, $new_url, $content );
493
+ }
494
+
495
+ return $content;
496
+ }
497
+
498
+ /**
499
+ * Imported notice
500
+ *
501
+ * @since 1.1.4
502
+ */
503
+ public function imported_successfully() {
504
+ ?>
505
+ <div class="notice notice-success">
506
+ <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
+ </div>
508
+ <?php
509
+ }
510
+
511
+ /**
512
+ * Clear Cache.
513
+ *
514
+ * @since 1.0.0
515
+ */
516
+ public function clear_cache() {
517
+ // Clear 'Elementor' file cache.
518
+ if ( class_exists( '\Elementor\Plugin' ) ) {
519
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
520
+ }
521
+ }
522
+
523
+ /**
524
+ * JS Templates
525
+ *
526
+ * @since 1.0.0
527
+ *
528
+ * @return void
529
+ */
530
+ public function js_templates() {
531
+
532
+ // Loading Templates.
533
+ ?>
534
+ <script type="text/template" id="tmpl-cartflows-step-loading">
535
+ <div class="template-message-block cartflows-step-loading">
536
+ <h2>
537
+ <span class="spinner"></span>
538
+ <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
+ </h2>
540
+ <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
+ </div>
542
+ </script>
543
+
544
+ <?php
545
+ // Search Templates.
546
+ ?>
547
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
548
+ <div class="template-message-block cartflows-searching-templates">
549
+ <h2>
550
+ <span class="spinner"></span>
551
+ <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
+ </h2>
553
+ <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
+ </div>
555
+ </script>
556
+
557
+ <?php
558
+ // CartFlows Importing Template.
559
+ ?>
560
+ <script type="text/template" id="tmpl-cartflows-step-importing">
561
+ <div class="template-message-block cartflows-step-importing">
562
+ <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
+ </div>
564
+ </script>
565
+
566
+ <?php
567
+ // CartFlows Imported.
568
+ ?>
569
+ <script type="text/template" id="tmpl-cartflows-step-imported">
570
+ <div class="template-message-block cartflows-step-imported">
571
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
+ </script>
574
+
575
+ <?php
576
+ // No templates.
577
+ ?>
578
+ <script type="text/template" id="tmpl-cartflows-no-steps">
579
+ <div class="cartflows-no-steps">
580
+ <div class="template-message-block">
581
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
+ <p class="description"></p>
583
+ </div>
584
+ </div>
585
+ </script>
586
+
587
+ <?php
588
+ // No templates.
589
+ ?>
590
+ <script type="text/template" id="tmpl-cartflows-no-flows">
591
+ <div class="cartflows-no-flows">
592
+ <div class="template-message-block">
593
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
+ <p class="description"></p>
595
+ </div>
596
+ </div>
597
+ </script>
598
+
599
+ <?php
600
+ // Error handling.
601
+ ?>
602
+ <script type="text/template" id="tmpl-templator-error">
603
+ <div class="notice notice-error"><p>{{ data }}</p></div>
604
+ </script>
605
+
606
+ <?php
607
+ // Redirect to Elementor.
608
+ ?>
609
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
+ <div class="template-message-block templator-redirect-to-elementor">
611
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
+ </script>
614
+
615
+ <?php
616
+ /**
617
+ * Responsive Buttons
618
+ */
619
+ ?>
620
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
621
+ <span class="responsive-view">
622
+ <span class="actions">
623
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
+ </span>
627
+ </span>
628
+ </script>
629
+
630
+ <?php
631
+ // Templates data.
632
+ ?>
633
+ <script type="text/template" id="tmpl-cartflows-flows-list">
634
+
635
+ <# console.log( data.items.length ) #>
636
+ <# console.log( data.items ) #>
637
+ <# if ( data.items.length ) { #>
638
+ <# for ( key in data.items ) { #>
639
+ <#
640
+ var flow_steps = [];
641
+ if( data.items[ key ].flow_steps ) {
642
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
+ return value['id'];
644
+ });
645
+ }
646
+ #>
647
+ <div class="inner">
648
+ <div class="template">
649
+ <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 }}">
650
+ <div class="template-screenshot">
651
+ <# if( data.items[ key ].featured_image_url ) { #>
652
+ <img src="{{ data.items[ key ].featured_image_url }}" />
653
+ <# } else { #>
654
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
+ <# } #>
656
+ </div>
657
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
+ <# } #>
660
+ <# if( data.items[ key ].woo_required ) { #>
661
+ <div class="notice notice-info" style="width: auto;">
662
+ <p class="wcf-learn-how">
663
+ Install/Activate WooCommerce to use this template.
664
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
+ <i class="dashicons dashicons-external"></i>
667
+ </a>
668
+ </p>
669
+ </div>
670
+ <# } else { #>
671
+ <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>
672
+ <# } #>
673
+
674
+ </span>
675
+ <div class="template-id-container">
676
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
+ <div class="template-actions">
678
+
679
+ <#
680
+ if( data.items[ key ].page_builder.slug ) {
681
+ required_plugin_group = data.items[ key ].page_builder.slug;
682
+ } else {
683
+ required_plugin_group = '';
684
+ }
685
+
686
+ 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 ) {
687
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
+ } else {
689
+ import_btn_title = 'Import';
690
+ } #>
691
+
692
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
+ <# if( ! data.items[ key ].woo_required ) { #>
694
+ <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>
695
+ <# } else { #>
696
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
+ <# } #>
698
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
+ <# } else { #>
701
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
+ <# } #>
703
+ </div>
704
+ </div>
705
+ </div>
706
+ </div>
707
+ <# } #>
708
+ <# } #>
709
+ </script>
710
+
711
+ <?php
712
+ // Empty Step.
713
+ ?>
714
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
+ <div class="inner">
716
+ <div class="template">
717
+ <span class="thumbnail site-preview cartflows-flow-preview">
718
+ <div class="template-screenshot">
719
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
+ </div>
721
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
+ </span>
723
+ <div class="template-id-container">
724
+ <h3 class="template-name"> Blank </h3>
725
+ <div class="template-actions">
726
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
+ </div>
728
+ </div>
729
+ </div>
730
+ </div>
731
+ </script>
732
+
733
+ <?php
734
+ // Templates data.
735
+ ?>
736
+ <script type="text/template" id="tmpl-cartflows-steps-list">
737
+ <# if ( data.items.length ) { #>
738
+ <# for ( key in data.items ) { #>
739
+ <#
740
+ var flow_steps = [];
741
+ if( data.items[ key ].flow_steps ) {
742
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
+ return value['id'];
744
+ });
745
+ }
746
+ #>
747
+ <div class="inner">
748
+ <div class="template">
749
+ <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 }}">
750
+ <div class="template-screenshot">
751
+ <# if( data.items[ key ].featured_image_url ) { #>
752
+ <img src="{{ data.items[ key ].featured_image_url }}" />
753
+ <# } else { #>
754
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
+ <# } #>
756
+ </div>
757
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
+
759
+ <# if( data.items[ key ].woo_required ) { #>
760
+ <div class="notice notice-info" style="width: auto;">
761
+ <p class="wcf-learn-how">
762
+ Install/Activate WooCommerce to use this template.
763
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
+ <i class="dashicons dashicons-external"></i>
766
+ </a>
767
+ </p>
768
+ </div>
769
+ <# } else { #>
770
+ <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>
771
+ <# } #>
772
+
773
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
+ <# } #>
776
+ </span>
777
+ <div class="template-id-container">
778
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
+ <div class="template-actions">
780
+
781
+ <#
782
+
783
+ var step_slug = data.items[ key ].step_type.slug || '';
784
+ var step_title = data.items[ key ].step_type.name || '';
785
+ var import_btn_title = 'Import';
786
+
787
+ var required_plugin_group = '';
788
+ if( data.items[ key ].page_builder ) {
789
+ required_plugin_group = data.items[ key ].page_builder.slug;
790
+
791
+ 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 ) {
792
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
+ }
794
+ }
795
+ #>
796
+
797
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
+
799
+ <# if( ! data.items[ key ].woo_required ) { #>
800
+ <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>
801
+ <# } else { #>
802
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
+ <# } #>
804
+
805
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
+ <# } else { #>
808
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
+ <# } #>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ </div>
814
+ <# } #>
815
+ <# } #>
816
+ </script>
817
+
818
+ <?php
819
+ /**
820
+ * TMPL - Website Unreachable
821
+ */
822
+ ?>
823
+ <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
+ <div class="postbox cartflows-website-unreachable">
825
+ <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
+ <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
+ <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
+ </div>
829
+ </script>
830
+
831
+ <?php
832
+ /**
833
+ * TMPL - Filters
834
+ */
835
+ ?>
836
+ <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
+ <?php
838
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
+ $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
+ $title = $page_builder['title'];
841
+
842
+ $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
+ $theme_status = '';
844
+ if ( 'divi' === $default_page_builder ) {
845
+
846
+ $theme_status = $page_builder['theme-status'];
847
+ $plugin_status = $page_builder['plugin-status'];
848
+
849
+ if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
+ $plugin_string = 'Please activate ' . esc_html( $title );
851
+ } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
+ $plugin_string = 'Please install and activate ' . esc_html( $title );
853
+ }
854
+ }
855
+ ?>
856
+ <div class="wcf-page-builder-message">
857
+ <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
+ <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
+ <p>We plan to add design templates made with more page builder shortly!</p>
860
+ </div>
861
+ </script>
862
+
863
+ <?php
864
+ /**
865
+ * TMPL - Filters
866
+ */
867
+ ?>
868
+ <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
+ <# if ( data ) { #>
870
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
+ <# if ( data.args.show_all ) { #>
872
+ <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
+ <# } #>
874
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
+ <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
+ <# } #>
877
+ <# var step_slug_data = []; #>
878
+ <# for ( key in data.items ) { #>
879
+ <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>
880
+
881
+ <# step_slug_data.push( data.items[ key ].slug ); #>
882
+
883
+ <# } #>
884
+ <# if( step_slug_data.indexOf("optin") === -1){ #>
885
+ <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
+ <# } #>
887
+ </select>
888
+ <# } #>
889
+ </script>
890
+
891
+ <script type="text/template" id="tmpl-cartflows-term-filters">
892
+
893
+ <# if ( data ) { #>
894
+
895
+ <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
+
898
+ <# if ( data.args.show_all ) { #>
899
+ <li>
900
+ <a href="#" data-group="all"> All </a>
901
+ </li>
902
+ <# } #>
903
+
904
+ <# for ( key in data.items ) { #>
905
+ <li>
906
+ <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>
907
+ </li>
908
+ <# } #>
909
+
910
+ </ul>
911
+
912
+ <?php
913
+
914
+ /**
915
+ <# } else { #>
916
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
+
918
+ <# if ( data.args.show_all ) { #>
919
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
+ <# } #>
921
+
922
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
+ <# } #>
925
+
926
+ <# for ( key in data.items ) { #>
927
+ <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>
928
+ <# } #>
929
+
930
+ </select>
931
+ */
932
+ ?>
933
+
934
+ <?php /* <# } #> */ ?>
935
+
936
+ <# } #>
937
+ </script>
938
+
939
+ <?php
940
+ // Step Type.
941
+ ?>
942
+ <script type="text/template" id="tmpl-cartflows-step-types">
943
+ <ul class="wcf-tab nav-tabs">
944
+ <# if( data.items_count ) { #>
945
+ <# for( key in data.items ) { #>
946
+ <# console.log( data.items[ key ].id ) #>
947
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
+ </li>
950
+ <# } #>
951
+ <# } #>
952
+ </ul>
953
+ </script>
954
+
955
+ <?php
956
+ // Add to library button.
957
+ ?>
958
+ <script type="text/template" id="tmpl-templator-add-to-library">
959
+ <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>
960
+ </script>
961
+ <?php
962
+ }
963
+
964
+ /**
965
+ * Enqueue scripts
966
+ *
967
+ * @since 1.0.0
968
+ *
969
+ * @hook admin_enqueue_scripts
970
+ * @param string $hook Current page hook.
971
+ */
972
+ public function scripts( $hook = '' ) {
973
+
974
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
+ return;
976
+ }
977
+
978
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
+
983
+ $installed_plugins = get_plugins();
984
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
+ $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
+
987
+ $localize_vars = array(
988
+ '_is_pro_active' => _is_cartflows_pro(),
989
+ 'is_wc_installed' => $is_wc_installed,
990
+ 'is_wc_activated' => $is_wc_activated,
991
+
992
+ // Set API headers for the CartFlows API Calls only.
993
+ 'headers' => array(),
994
+
995
+ // Flow and its rest fields.
996
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
997
+ 'flow_fields' => array(
998
+ 'id',
999
+ 'title',
1000
+ 'flow_type',
1001
+ 'page_builder',
1002
+ 'flow_steps',
1003
+ 'licence_status',
1004
+ 'featured_image_url',
1005
+ 'featured_media', // @required for field `featured_image_url`.
1006
+ ),
1007
+
1008
+ // Flow type and rest fields.
1009
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1010
+ 'flow_type_fields' => array(
1011
+ 'id',
1012
+ 'name',
1013
+ 'slug',
1014
+ ),
1015
+
1016
+ // Flow page builder and rest fields.
1017
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1018
+ 'flow_page_builder_fields' => array(
1019
+ 'id',
1020
+ 'name',
1021
+ 'slug',
1022
+ ),
1023
+
1024
+ // Step page builder and rest fields.
1025
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1026
+ 'step_page_builder_fields' => array(
1027
+ 'id',
1028
+ 'name',
1029
+ 'slug',
1030
+ ),
1031
+
1032
+ // Step and its rest fields.
1033
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1034
+ 'step_fields' => array(
1035
+ 'title',
1036
+ 'featured_image_url',
1037
+ 'featured_media', // @required for field `featured_image_url`.
1038
+ 'id',
1039
+ 'flow_type',
1040
+ 'step_type',
1041
+ 'page_builder',
1042
+ 'licence_status',
1043
+ ),
1044
+
1045
+ // Step type and its rest fields.
1046
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1047
+ 'step_type_fields' => array(
1048
+ 'id',
1049
+ 'name',
1050
+ 'slug',
1051
+ ),
1052
+
1053
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1054
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1055
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1056
+ 'site_url' => site_url(),
1057
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1058
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1059
+ 'admin_url' => admin_url(),
1060
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1061
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1062
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1063
+
1064
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1065
+
1066
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1067
+ );
1068
+
1069
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1070
+
1071
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1072
+ // wp_die( );
1073
+ // Add thickbox.
1074
+ add_thickbox();
1075
+
1076
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1077
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1078
+ }
1079
+
1080
+ /**
1081
+ * Import.
1082
+ *
1083
+ * @since 1.0.0
1084
+ *
1085
+ * @hook wp_ajax_cartflows_import_flow_step
1086
+ * @return void
1087
+ */
1088
+ public function import_flow() {
1089
+
1090
+ if ( ! current_user_can( 'manage_options' ) ) {
1091
+ return;
1092
+ }
1093
+
1094
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1095
+
1096
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1097
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1098
+
1099
+ wcf()->logger->import_log( '------------------------------------' );
1100
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1101
+ wcf()->logger->import_log( '------------------------------------' );
1102
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1103
+
1104
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1105
+
1106
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1107
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1108
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1109
+ $post_content = $response['data']['divi_content'];
1110
+ }
1111
+ }
1112
+
1113
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1114
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1115
+ $post_content = $response['data']['divi_content'];
1116
+ }
1117
+ }
1118
+
1119
+ if ( false === $response['success'] ) {
1120
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1121
+ wp_send_json_error( $response );
1122
+ }
1123
+
1124
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1125
+
1126
+ $new_step_id = wp_insert_post(
1127
+ array(
1128
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1129
+ 'post_title' => $response['title'],
1130
+ 'post_content' => $post_content,
1131
+ 'post_status' => 'publish',
1132
+ )
1133
+ );
1134
+
1135
+ if ( is_wp_error( $new_step_id ) ) {
1136
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1137
+ wp_send_json_error( $new_step_id );
1138
+ }
1139
+
1140
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1141
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1142
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1143
+ }
1144
+ }
1145
+
1146
+ /* Imported Step */
1147
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1148
+
1149
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1150
+ // insert post meta.
1151
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1152
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1153
+
1154
+ /**
1155
+ * Import & Set type.
1156
+ */
1157
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1158
+
1159
+ $term_slug = '';
1160
+ if ( $term ) {
1161
+
1162
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1163
+ $term_exist = term_exists( $term->slug, $taxonomy );
1164
+
1165
+ if ( empty( $term_exist ) ) {
1166
+ $terms = array(
1167
+ array(
1168
+ 'name' => $term->name,
1169
+ 'slug' => $term->slug,
1170
+ ),
1171
+ );
1172
+
1173
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1174
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1175
+ }
1176
+
1177
+ $current_term = term_exists( $term->slug, $taxonomy );
1178
+
1179
+ // Set type object.
1180
+ $data = get_term( $current_term['term_id'], $taxonomy );
1181
+ $term_slug = $data->slug;
1182
+ $term_name = $data->name;
1183
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1184
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1185
+
1186
+ // Set type.
1187
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1188
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1189
+ }
1190
+
1191
+ // Set flow.
1192
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1193
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1194
+
1195
+ /**
1196
+ * Update steps for the current flow.
1197
+ */
1198
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1199
+
1200
+ if ( ! is_array( $flow_steps ) ) {
1201
+ $flow_steps = array();
1202
+ }
1203
+
1204
+ $flow_steps[] = array(
1205
+ 'id' => $new_step_id,
1206
+ 'title' => $response['title'],
1207
+ 'type' => $term_slug,
1208
+ );
1209
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1210
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1211
+
1212
+ // Import Post Meta.
1213
+ self::import_post_meta( $new_step_id, $response );
1214
+
1215
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1216
+ wcf()->logger->import_log( '------------------------------------' );
1217
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1218
+ wcf()->logger->import_log( '------------------------------------' );
1219
+
1220
+ do_action( 'cartflows_import_complete' );
1221
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1222
+
1223
+ // Batch Process.
1224
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1225
+
1226
+ /**
1227
+ * End
1228
+ */
1229
+ wp_send_json_success( $new_step_id );
1230
+ }
1231
+
1232
+ /**
1233
+ * Import Step.
1234
+ *
1235
+ * @since 1.0.0
1236
+ * @hook wp_ajax_cartflows_step_import
1237
+ *
1238
+ * @return void
1239
+ */
1240
+ public function create_default_flow() {
1241
+
1242
+ if ( ! current_user_can( 'manage_options' ) ) {
1243
+ return;
1244
+ }
1245
+
1246
+ check_ajax_referer( 'cf-default-flow', 'security' );
1247
+
1248
+ // Create post object.
1249
+ $new_flow_post = array(
1250
+ 'post_content' => '',
1251
+ 'post_status' => 'publish',
1252
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1253
+ );
1254
+
1255
+ // Insert the post into the database.
1256
+ $flow_id = wp_insert_post( $new_flow_post );
1257
+
1258
+ if ( is_wp_error( $flow_id ) ) {
1259
+ wp_send_json_error( $flow_id->get_error_message() );
1260
+ }
1261
+
1262
+ $flow_steps = array();
1263
+
1264
+ if ( wcf()->is_woo_active ) {
1265
+ $steps_data = array(
1266
+ 'sales' => array(
1267
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1268
+ 'type' => 'landing',
1269
+ ),
1270
+ 'order-form' => array(
1271
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1272
+ 'type' => 'checkout',
1273
+ ),
1274
+ 'order-confirmation' => array(
1275
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1276
+ 'type' => 'thankyou',
1277
+ ),
1278
+ );
1279
+
1280
+ } else {
1281
+ $steps_data = array(
1282
+ 'landing' => array(
1283
+ 'title' => __( 'Landing', 'cartflows' ),
1284
+ 'type' => 'landing',
1285
+ ),
1286
+ 'thankyou' => array(
1287
+ 'title' => __( 'Thank You', 'cartflows' ),
1288
+ 'type' => 'landing',
1289
+ ),
1290
+ );
1291
+ }
1292
+
1293
+ foreach ( $steps_data as $slug => $data ) {
1294
+
1295
+ $post_content = '';
1296
+ $step_type = trim( $data['type'] );
1297
+
1298
+ $step_id = wp_insert_post(
1299
+ array(
1300
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1301
+ 'post_title' => $data['title'],
1302
+ 'post_content' => $post_content,
1303
+ 'post_status' => 'publish',
1304
+ )
1305
+ );
1306
+
1307
+ if ( is_wp_error( $step_id ) ) {
1308
+ wp_send_json_error( $step_id->get_error_message() );
1309
+ }
1310
+
1311
+ if ( $step_id ) {
1312
+
1313
+ $flow_steps[] = array(
1314
+ 'id' => $step_id,
1315
+ 'title' => $data['title'],
1316
+ 'type' => $step_type,
1317
+ );
1318
+
1319
+ // insert post meta.
1320
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1321
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1322
+
1323
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1324
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1325
+
1326
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1327
+ }
1328
+ }
1329
+
1330
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1331
+
1332
+ wp_send_json_success( $flow_id );
1333
+ }
1334
+
1335
+ /**
1336
+ * Create Flow
1337
+ *
1338
+ * @return void
1339
+ */
1340
+ public function create_flow() {
1341
+
1342
+ if ( ! current_user_can( 'manage_options' ) ) {
1343
+ return;
1344
+ }
1345
+
1346
+ check_ajax_referer( 'cf-create-flow', 'security' );
1347
+
1348
+ // Create post object.
1349
+ $new_flow_post = array(
1350
+ 'post_content' => '',
1351
+ 'post_status' => 'publish',
1352
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1353
+ );
1354
+
1355
+ // Insert the post into the database.
1356
+ $flow_id = wp_insert_post( $new_flow_post );
1357
+
1358
+ if ( is_wp_error( $flow_id ) ) {
1359
+ wp_send_json_error( $flow_id->get_error_message() );
1360
+ }
1361
+
1362
+ /* Imported Flow */
1363
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1364
+
1365
+ wp_send_json_success( $flow_id );
1366
+ }
1367
+
1368
+ /**
1369
+ * Create Step
1370
+ *
1371
+ * @return void
1372
+ */
1373
+ public function import_step() {
1374
+
1375
+ if ( ! current_user_can( 'manage_options' ) ) {
1376
+ return;
1377
+ }
1378
+
1379
+ check_ajax_referer( 'cf-step-import', 'security' );
1380
+
1381
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1382
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1383
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1384
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1385
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1386
+
1387
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1388
+
1389
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1390
+
1391
+ wcf()->logger->import_log( '------------------------------------' );
1392
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1393
+ wcf()->logger->import_log( '------------------------------------' );
1394
+
1395
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1396
+ /* translators: %s: template ID */
1397
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1398
+ wcf()->logger->import_log( $data );
1399
+ wp_send_json_error( $data );
1400
+ }
1401
+
1402
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1403
+
1404
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1405
+
1406
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1407
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1408
+
1409
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1410
+
1411
+ wp_update_post(
1412
+ array(
1413
+ 'ID' => $post_id,
1414
+ 'post_content' => $response['data']['divi_content'],
1415
+ )
1416
+ );
1417
+ }
1418
+ }
1419
+
1420
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1421
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1422
+
1423
+ wp_update_post(
1424
+ array(
1425
+ 'ID' => $post_id,
1426
+ 'post_content' => $response['data']['divi_content'],
1427
+ )
1428
+ );
1429
+ }
1430
+ }
1431
+
1432
+ /* Imported Step */
1433
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1434
+
1435
+ // Import Post Meta.
1436
+ self::import_post_meta( $post_id, $response );
1437
+
1438
+ do_action( 'cartflows_import_complete' );
1439
+
1440
+ // Batch Process.
1441
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1442
+
1443
+ wcf()->logger->import_log( '------------------------------------' );
1444
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1445
+ wcf()->logger->import_log( '------------------------------------' );
1446
+
1447
+ wp_send_json_success( $post_id );
1448
+ }
1449
+
1450
+ /**
1451
+ * Import Step.
1452
+ *
1453
+ * @since 1.0.0
1454
+ * @hook wp_ajax_cartflows_step_create_blank
1455
+ *
1456
+ * @return void
1457
+ */
1458
+ public function step_create_blank() {
1459
+
1460
+ if ( ! current_user_can( 'manage_options' ) ) {
1461
+ return;
1462
+ }
1463
+
1464
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1465
+
1466
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1467
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1468
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1469
+
1470
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1471
+ /* translators: %s: flow ID */
1472
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1473
+ wcf()->logger->import_log( $data );
1474
+ wp_send_json_error( $data );
1475
+ }
1476
+
1477
+ wcf()->logger->import_log( '------------------------------------' );
1478
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1479
+
1480
+ $step_type_title = str_replace( '-', ' ', $step_type );
1481
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1482
+
1483
+ $new_step_id = wp_insert_post(
1484
+ array(
1485
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1486
+ 'post_title' => $step_title,
1487
+ 'post_content' => '',
1488
+ 'post_status' => 'publish',
1489
+ )
1490
+ );
1491
+
1492
+ // insert post meta.
1493
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1494
+
1495
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1496
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1497
+
1498
+ if ( empty( $term_exist ) ) {
1499
+ $terms = array(
1500
+ array(
1501
+ 'name' => $step_type_title,
1502
+ 'slug' => $step_type_slug,
1503
+ ),
1504
+ );
1505
+
1506
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1507
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1508
+ }
1509
+
1510
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1511
+
1512
+ // Set type object.
1513
+ $data = get_term( $current_term['term_id'], $taxonomy );
1514
+ $step_slug = $data->slug;
1515
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1516
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1517
+
1518
+ // Set Default page Layout.
1519
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1520
+
1521
+ // Set type.
1522
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1523
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1524
+
1525
+ // Set flow.
1526
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1527
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1528
+
1529
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1530
+
1531
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1532
+ wcf()->logger->import_log( '------------------------------------' );
1533
+
1534
+ wp_send_json_success( $new_step_id );
1535
+ }
1536
+
1537
+ /**
1538
+ * Import Post Meta
1539
+ *
1540
+ * @since 1.0.0
1541
+ *
1542
+ * @param integer $post_id Post ID.
1543
+ * @param array $response Post meta.
1544
+ * @return void
1545
+ */
1546
+ public static function import_post_meta( $post_id, $response ) {
1547
+
1548
+ $metadata = (array) $response['post_meta'];
1549
+
1550
+ foreach ( $metadata as $meta_key => $meta_value ) {
1551
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1552
+
1553
+ if ( $meta_value ) {
1554
+
1555
+ if ( is_serialized( $meta_value, true ) ) {
1556
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1557
+ } elseif ( is_array( $meta_value ) ) {
1558
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1559
+ } else {
1560
+ $raw_data = $meta_value;
1561
+ }
1562
+
1563
+ if ( '_elementor_data' === $meta_key ) {
1564
+ if ( is_array( $raw_data ) ) {
1565
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1566
+ } else {
1567
+ $raw_data = wp_slash( $raw_data );
1568
+ }
1569
+ }
1570
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1571
+ if ( is_array( $raw_data ) ) {
1572
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1573
+ } else {
1574
+ if ( ! is_object( $raw_data ) ) {
1575
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1576
+ }
1577
+ }
1578
+ }
1579
+
1580
+ update_post_meta( $post_id, $meta_key, $raw_data );
1581
+ }
1582
+ }
1583
+ }
1584
+
1585
+ /**
1586
+ * Import Template for Elementor
1587
+ *
1588
+ * @since 1.0.0
1589
+ *
1590
+ * @param integer $post_id Post ID.
1591
+ * @param array $response Post meta.
1592
+ * @param array $page_build_data Page build data.
1593
+ * @return void
1594
+ */
1595
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1596
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1597
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1598
+ wcf()->logger->import_log( $data );
1599
+ wp_send_json_error( $data );
1600
+ }
1601
+
1602
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1603
+
1604
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1605
+
1606
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1607
+ $obj->import_single_template( $post_id );
1608
+
1609
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1610
+ }
1611
+
1612
+ /**
1613
+ * Supported post types
1614
+ *
1615
+ * @since 1.0.0
1616
+ *
1617
+ * @return array Supported post types.
1618
+ */
1619
+ public static function supported_post_types() {
1620
+ return apply_filters(
1621
+ 'cartflows_supported_post_types',
1622
+ array(
1623
+ CARTFLOWS_FLOW_POST_TYPE,
1624
+ )
1625
+ );
1626
+ }
1627
+
1628
+ /**
1629
+ * Check supported post type
1630
+ *
1631
+ * @since 1.0.0
1632
+ *
1633
+ * @param string $post_type Post type.
1634
+ * @return boolean Supported post type status.
1635
+ */
1636
+ public static function is_supported_post( $post_type = '' ) {
1637
+
1638
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1639
+ return true;
1640
+ }
1641
+
1642
+ return false;
1643
+ }
1644
+
1645
+ /**
1646
+ * Set steps to the flow
1647
+ *
1648
+ * @param integer $flow_id Flow ID.
1649
+ * @param integer $new_step_id New step ID.
1650
+ * @param string $step_title Flow Type.
1651
+ * @param string $step_slug Flow Type.
1652
+ */
1653
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1654
+ // Update steps for the current flow.
1655
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1656
+
1657
+ if ( ! is_array( $flow_steps ) ) {
1658
+ $flow_steps = array();
1659
+ }
1660
+
1661
+ $flow_steps[] = array(
1662
+ 'id' => $new_step_id,
1663
+ 'title' => $step_title,
1664
+ 'type' => $step_slug,
1665
+ );
1666
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1667
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1668
+ }
1669
+
1670
+ /**
1671
+ * Localize variables in admin
1672
+ *
1673
+ * @param array $vars variables.
1674
+ */
1675
+ public function localize_vars( $vars ) {
1676
+
1677
+ $ajax_actions = array(
1678
+ 'cf_step_import',
1679
+ 'cf_load_steps',
1680
+ 'cf_create_flow',
1681
+ 'cf_default_flow',
1682
+ 'cf_step_create_blank',
1683
+ 'cf_import_flow_step',
1684
+ );
1685
+
1686
+ foreach ( $ajax_actions as $action ) {
1687
+
1688
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1689
+ }
1690
+
1691
+ return $vars;
1692
+ }
1693
+
1694
+ /**
1695
+ * Ajax action to activate plugin
1696
+ */
1697
+ public function activate_plugin() {
1698
+
1699
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1700
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1701
+ }
1702
+
1703
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1704
+ wp_send_json_error(
1705
+ array(
1706
+ 'success' => false,
1707
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1708
+ )
1709
+ );
1710
+ }
1711
+
1712
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1713
+
1714
+ $activate = activate_plugin( $plugin_init, '', false, true );
1715
+
1716
+ if ( is_wp_error( $activate ) ) {
1717
+ wp_send_json_error(
1718
+ array(
1719
+ 'success' => false,
1720
+ 'message' => $activate->get_error_message(),
1721
+ 'init' => $plugin_init,
1722
+ )
1723
+ );
1724
+ }
1725
+
1726
+ wp_send_json_success(
1727
+ array(
1728
+ 'success' => true,
1729
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1730
+ 'init' => $plugin_init,
1731
+ )
1732
+ );
1733
+ }
1734
+
1735
+ }
1736
+
1737
+ /**
1738
+ * Initialize class object with 'get_instance()' method
1739
+ */
1740
+ CartFlows_Importer::get_instance();
1741
+
1742
+ endif;
classes/class-cartflows-loader.php CHANGED
@@ -133,7 +133,7 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
133
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
134
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
135
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
136
- define( 'CARTFLOWS_VER', '1.5.16' );
137
  define( 'CARTFLOWS_SLUG', 'cartflows' );
138
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
139
 
133
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
134
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
135
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
136
+ define( 'CARTFLOWS_VER', '1.5.17' );
137
  define( 'CARTFLOWS_SLUG', 'cartflows' );
138
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
139
 
classes/class-cartflows-logger.php CHANGED
@@ -1,183 +1,183 @@
1
- <?php
2
- /**
3
- * Logger.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Logger {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var logger
27
- */
28
- public $logger;
29
-
30
- /**
31
- * Initiator
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- */
43
- public function __construct() {
44
-
45
- /* Load WC Logger */
46
- add_action( 'init', array( $this, 'init_wc_logger' ), 99 );
47
-
48
- $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
49
-
50
- if ( CARTFLOWS_SETTINGS === $page ) {
51
- add_filter( 'admin_footer_text', array( $this, 'add_footer_link' ), 99 );
52
- }
53
-
54
- }
55
-
56
- /**
57
- * Add footer link.
58
- */
59
- public function add_footer_link() {
60
- $settings_url = add_query_arg(
61
- array(
62
- 'page' => CARTFLOWS_SETTINGS,
63
- 'cartflows-error-log' => 1,
64
- ),
65
- admin_url( '/admin.php' )
66
- );
67
-
68
- echo '<span id="footer-thankyou"> Thank you for using <a href="https://cartflows.com/">CartFlows</a></span> | <a href="' . $settings_url . '"> View Logs </a>';
69
- }
70
-
71
- /**
72
- * Inint Logger.
73
- *
74
- * @since 1.0.0
75
- */
76
- public function init_wc_logger() {
77
- if ( class_exists( 'CartFlows_WC_Logger' ) ) {
78
- $this->logger = new CartFlows_WC_Logger();
79
- }
80
- }
81
-
82
- /**
83
- * Write log
84
- *
85
- * @param string $message log message.
86
- * @param string $level type of log.
87
- * @since 1.0.0
88
- */
89
- public function log( $message, $level = 'info' ) {
90
-
91
- $enable_log = apply_filters( 'cartflows_enable_log', 'enable' );
92
-
93
- if ( 'enable' === $enable_log &&
94
- is_a( $this->logger, 'CartFlows_WC_Logger' ) &&
95
- did_action( 'plugins_loaded' )
96
- ) {
97
-
98
- $this->logger->log( $level, $message, array( 'source' => 'cartflows' ) );
99
- }
100
- }
101
-
102
- /**
103
- * Write log
104
- *
105
- * @param string $message log message.
106
- * @param string $level type of log.
107
- * @since 1.0.0
108
- */
109
- public function import_log( $message, $level = 'info' ) {
110
-
111
- if ( defined( 'WP_DEBUG' ) &&
112
- WP_DEBUG &&
113
- is_a( $this->logger, 'CartFlows_WC_Logger' ) &&
114
- did_action( 'plugins_loaded' )
115
- ) {
116
-
117
- $this->logger->log( $level, $message, array( 'source' => 'cartflows-import' ) );
118
- }
119
- }
120
-
121
- /**
122
- * Get all log files in the log directory.
123
- *
124
- * @return array
125
- */
126
- public static function get_log_files() {
127
- $files = scandir( CARTFLOWS_LOG_DIR );
128
- $result = array();
129
-
130
- if ( ! empty( $files ) ) {
131
- foreach ( $files as $key => $value ) {
132
- if ( ! in_array( $value, array( '.', '..' ), true ) ) {
133
- if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
134
- $result[ sanitize_title( $value ) ] = $value;
135
- }
136
- }
137
- }
138
- }
139
-
140
- return $result;
141
- }
142
-
143
- /**
144
- * Return the log file handle.
145
- *
146
- * @param string $filename Filename to get the handle for.
147
- * @return string
148
- */
149
- public static function get_log_file_handle( $filename ) {
150
- return substr( $filename, 0, strlen( $filename ) > 48 ? strlen( $filename ) - 48 : strlen( $filename ) - 4 );
151
- }
152
-
153
- /**
154
- * Show the log page contents for file log handler.
155
- */
156
- public static function status_logs_file() {
157
-
158
- if ( ! empty( $_REQUEST['handle'] ) ) {
159
-
160
- if ( ! isset( $_REQUEST['_wpnonce'] ) || empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'remove_log' ) ) {
161
- wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'cartflows' ) );
162
- }
163
- wp_delete_file( CARTFLOWS_LOG_DIR . rtrim( $_REQUEST['handle'], '-log' ) . '.log' ); //phpcs:ignore
164
- echo "<div style='padding: 15px;' class='updated inline'> Log deleted successfully! </div>";
165
- }
166
-
167
- $logs = self::get_log_files();
168
- if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) {
169
- $viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ];
170
- } elseif ( ! empty( $logs ) ) {
171
- $viewed_log = current( $logs );
172
- }
173
- $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : '';
174
-
175
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-error-log.php';
176
- }
177
-
178
- }
179
-
180
- /**
181
- * Kicking this off by calling 'get_instance()' method
182
- */
183
- Cartflows_Logger::get_instance();
1
+ <?php
2
+ /**
3
+ * Logger.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Logger {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var logger
27
+ */
28
+ public $logger;
29
+
30
+ /**
31
+ * Initiator
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+
45
+ /* Load WC Logger */
46
+ add_action( 'init', array( $this, 'init_wc_logger' ), 99 );
47
+
48
+ $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
49
+
50
+ if ( CARTFLOWS_SETTINGS === $page ) {
51
+ add_filter( 'admin_footer_text', array( $this, 'add_footer_link' ), 99 );
52
+ }
53
+
54
+ }
55
+
56
+ /**
57
+ * Add footer link.
58
+ */
59
+ public function add_footer_link() {
60
+ $settings_url = add_query_arg(
61
+ array(
62
+ 'page' => CARTFLOWS_SETTINGS,
63
+ 'cartflows-error-log' => 1,
64
+ ),
65
+ admin_url( '/admin.php' )
66
+ );
67
+
68
+ echo '<span id="footer-thankyou"> Thank you for using <a href="https://cartflows.com/">CartFlows</a></span> | <a href="' . $settings_url . '"> View Logs </a>';
69
+ }
70
+
71
+ /**
72
+ * Inint Logger.
73
+ *
74
+ * @since 1.0.0
75
+ */
76
+ public function init_wc_logger() {
77
+ if ( class_exists( 'CartFlows_WC_Logger' ) ) {
78
+ $this->logger = new CartFlows_WC_Logger();
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Write log
84
+ *
85
+ * @param string $message log message.
86
+ * @param string $level type of log.
87
+ * @since 1.0.0
88
+ */
89
+ public function log( $message, $level = 'info' ) {
90
+
91
+ $enable_log = apply_filters( 'cartflows_enable_log', 'enable' );
92
+
93
+ if ( 'enable' === $enable_log &&
94
+ is_a( $this->logger, 'CartFlows_WC_Logger' ) &&
95
+ did_action( 'plugins_loaded' )
96
+ ) {
97
+
98
+ $this->logger->log( $level, $message, array( 'source' => 'cartflows' ) );
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Write log
104
+ *
105
+ * @param string $message log message.
106
+ * @param string $level type of log.
107
+ * @since 1.0.0
108
+ */
109
+ public function import_log( $message, $level = 'info' ) {
110
+
111
+ if ( defined( 'WP_DEBUG' ) &&
112
+ WP_DEBUG &&
113
+ is_a( $this->logger, 'CartFlows_WC_Logger' ) &&
114
+ did_action( 'plugins_loaded' )
115
+ ) {
116
+
117
+ $this->logger->log( $level, $message, array( 'source' => 'cartflows-import' ) );
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Get all log files in the log directory.
123
+ *
124
+ * @return array
125
+ */
126
+ public static function get_log_files() {
127
+ $files = scandir( CARTFLOWS_LOG_DIR );
128
+ $result = array();
129
+
130
+ if ( ! empty( $files ) ) {
131
+ foreach ( $files as $key => $value ) {
132
+ if ( ! in_array( $value, array( '.', '..' ), true ) ) {
133
+ if ( ! is_dir( $value ) && strstr( $value, '.log' ) ) {
134
+ $result[ sanitize_title( $value ) ] = $value;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ return $result;
141
+ }
142
+
143
+ /**
144
+ * Return the log file handle.
145
+ *
146
+ * @param string $filename Filename to get the handle for.
147
+ * @return string
148
+ */
149
+ public static function get_log_file_handle( $filename ) {
150
+ return substr( $filename, 0, strlen( $filename ) > 48 ? strlen( $filename ) - 48 : strlen( $filename ) - 4 );
151
+ }
152
+
153
+ /**
154
+ * Show the log page contents for file log handler.
155
+ */
156
+ public static function status_logs_file() {
157
+
158
+ if ( ! empty( $_REQUEST['handle'] ) ) {
159
+
160
+ if ( ! isset( $_REQUEST['_wpnonce'] ) || empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ), 'remove_log' ) ) {
161
+ wp_die( esc_html__( 'Action failed. Please refresh the page and retry.', 'cartflows' ) );
162
+ }
163
+ wp_delete_file( CARTFLOWS_LOG_DIR . rtrim( $_REQUEST['handle'], '-log' ) . '.log' ); //phpcs:ignore
164
+ echo "<div style='padding: 15px;' class='updated inline'> Log deleted successfully! </div>";
165
+ }
166
+
167
+ $logs = self::get_log_files();
168
+ if ( ! empty( $_REQUEST['log_file'] ) && isset( $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ] ) ) {
169
+ $viewed_log = $logs[ sanitize_title( wp_unslash( $_REQUEST['log_file'] ) ) ];
170
+ } elseif ( ! empty( $logs ) ) {
171
+ $viewed_log = current( $logs );
172
+ }
173
+ $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : '';
174
+
175
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-error-log.php';
176
+ }
177
+
178
+ }
179
+
180
+ /**
181
+ * Kicking this off by calling 'get_instance()' method
182
+ */
183
+ Cartflows_Logger::get_instance();
includes/meta-fields/generate-product-repeater.php CHANGED
@@ -1,99 +1,99 @@
1
- <?php
2
- /**
3
- * Generate product repeater.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $hide_advance = 'wcf-hide-advance';
9
-
10
- if ( empty( $selected_data ) ) {
11
-
12
- $selected_data = array(
13
- 'quantity' => 1,
14
- 'discount_type' => '',
15
- 'discount_value' => '',
16
- 'unique_id' => '',
17
- );
18
- }
19
-
20
- ?>
21
-
22
- <div class="wcf-repeatable-row" data-key="<?php echo $id; ?>">
23
- <div class="wcf_display_advance_fields wcf-repeater-fields-head-wrap">
24
- <div class="wcf-repeatable-row-standard-fields">
25
- <div class="wcf-checkout-products-dashicon dashicons dashicons-menu"></div>
26
-
27
- <!-- Product Name -->
28
- <div class="wcf-repeatable-fields wcf-sel-product">
29
- <span class="wcf-repeatable-row-setting-field">
30
- <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-excluded_product_types = "grouped" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="wcf_json_search_products_and_variations"><?php echo $options; ?></select>
31
- </span>
32
-
33
- <span class="wcf-repeatable-row-actions">
34
- <a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">
35
- <span class="dashicons dashicons-trash"></span>
36
- <span class="wcf-repeatable-remove-button"><?php echo __( 'Remove', 'cartflows' ); ?></span>
37
- </a>
38
- </span>
39
- </div>
40
-
41
- <div class="wcf_toggle_advance_fields"><i class="dashicons dashicons-arrow-down"></i></div>
42
- </div>
43
- </div>
44
-
45
- <div class="wcf-repeatable-row-advance-fields <?php echo $hide_advance; ?>">
46
-
47
- <!-- Qty field. -->
48
- <div class="wcf-repeatable-row-qty-field wcf-checkout-products-qty-<?php echo $id; ?>">
49
- <div class="wcf-field-row">
50
- <div class="wcf-field-row-heading">
51
- <label><?php echo __( 'Product Quantity', 'cartflows' ); ?></label>
52
- </div>
53
-
54
- <div class="wcf-field-row-content wcf-field-row-advance-content">
55
- <input type="number" class="input-text qty text" step="1" min="1" max="" name="wcf-checkout-products[<?php echo $id; ?>][quantity]" value="<?php echo $selected_data['quantity']; ?>" title="Qty" inputmode="numeric">
56
- </div>
57
- </div>
58
- </div>
59
- <!-- Qty field end -->
60
-
61
- <!-- Type field. -->
62
- <div class="wcf-repeatable-discount-type-field">
63
- <div class="wcf-field-row">
64
- <div class="wcf-field-row-heading">
65
- <label><?php echo __( 'Discount Type', 'cartflows' ); ?></label>
66
- </div>
67
-
68
- <div class="wcf-field-row-content wcf-field-row-advance-content">
69
- <select name="wcf-checkout-products[<?php echo $id; ?>][discount_type]" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Select Discount Type', 'cartflows' ); ?>">
70
- <option value="" <?php selected( $selected_data['discount_type'], '', true ); ?>><?php echo __( 'Original', 'cartflows' ); ?></option>
71
- <option value="discount_percent" <?php selected( $selected_data['discount_type'], 'discount_percent', true ); ?>><?php echo __( 'Percentage', 'cartflows' ); ?></option>
72
- <option value="discount_price" <?php selected( $selected_data['discount_type'], 'discount_price', true ); ?>><?php echo __( 'Price', 'cartflows' ); ?></option>
73
- </select>
74
- </div>
75
- </div>
76
- </div>
77
- <!-- Type field end -->
78
-
79
- <!-- Discount field -->
80
- <div class="wcf-repeatable-row-discount-field <?php echo $hide_advance; ?> wcf-checkout-products-discount-<?php echo $id; ?>">
81
- <div class="wcf-field-row">
82
- <div class="wcf-field-row-heading">
83
- <label><?php echo __( 'Discount Value', 'cartflows' ); ?></label>
84
- <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
85
- <span class="wcf-tooltip-text"><?php echo __( 'Discount value will apply for each quantity of product.', 'cartflows' ); ?></span>
86
- </div>
87
- <div class="wcf-field-row-content wcf-field-row-advance-content">
88
- <input type="text" class="input-text text" name="wcf-checkout-products[<?php echo $id; ?>][discount_value]" value="<?php echo $selected_data['discount_value']; ?>" title="" inputmode="numeric">
89
- </div>
90
- </div>
91
- </div>
92
-
93
- <div class="wcf-repeatable-row-unique-id-field">
94
- <input name="wcf-checkout-products[<?php echo $id; ?>][unique_id]" type="hidden" class="wcf-checkout-product-unique" value="<?php echo $selected_data['unique_id']; ?>">
95
- </div>
96
-
97
- <?php do_action( 'cartflows_repeatable_row_advance_fields', $id ); ?>
98
- </div>
99
- </div>
1
+ <?php
2
+ /**
3
+ * Generate product repeater.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $hide_advance = 'wcf-hide-advance';
9
+
10
+ if ( empty( $selected_data ) ) {
11
+
12
+ $selected_data = array(
13
+ 'quantity' => 1,
14
+ 'discount_type' => '',
15
+ 'discount_value' => '',
16
+ 'unique_id' => '',
17
+ );
18
+ }
19
+
20
+ ?>
21
+
22
+ <div class="wcf-repeatable-row" data-key="<?php echo $id; ?>">
23
+ <div class="wcf_display_advance_fields wcf-repeater-fields-head-wrap">
24
+ <div class="wcf-repeatable-row-standard-fields">
25
+ <div class="wcf-checkout-products-dashicon dashicons dashicons-menu"></div>
26
+
27
+ <!-- Product Name -->
28
+ <div class="wcf-repeatable-fields wcf-sel-product">
29
+ <span class="wcf-repeatable-row-setting-field">
30
+ <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-include_product_types= "braintree-subscription, braintree-variable-subscription" data-excluded_product_types = "grouped" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="wcf_json_search_products_and_variations"><?php echo $options; ?></select>
31
+ </span>
32
+
33
+ <span class="wcf-repeatable-row-actions">
34
+ <a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">
35
+ <span class="dashicons dashicons-trash"></span>
36
+ <span class="wcf-repeatable-remove-button"><?php echo __( 'Remove', 'cartflows' ); ?></span>
37
+ </a>
38
+ </span>
39
+ </div>
40
+
41
+ <div class="wcf_toggle_advance_fields"><i class="dashicons dashicons-arrow-down"></i></div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="wcf-repeatable-row-advance-fields <?php echo $hide_advance; ?>">
46
+
47
+ <!-- Qty field. -->
48
+ <div class="wcf-repeatable-row-qty-field wcf-checkout-products-qty-<?php echo $id; ?>">
49
+ <div class="wcf-field-row">
50
+ <div class="wcf-field-row-heading">
51
+ <label><?php echo __( 'Product Quantity', 'cartflows' ); ?></label>
52
+ </div>
53
+
54
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
55
+ <input type="number" class="input-text qty text" step="1" min="1" max="" name="wcf-checkout-products[<?php echo $id; ?>][quantity]" value="<?php echo $selected_data['quantity']; ?>" title="Qty" inputmode="numeric">
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <!-- Qty field end -->
60
+
61
+ <!-- Type field. -->
62
+ <div class="wcf-repeatable-discount-type-field">
63
+ <div class="wcf-field-row">
64
+ <div class="wcf-field-row-heading">
65
+ <label><?php echo __( 'Discount Type', 'cartflows' ); ?></label>
66
+ </div>
67
+
68
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
69
+ <select name="wcf-checkout-products[<?php echo $id; ?>][discount_type]" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Select Discount Type', 'cartflows' ); ?>">
70
+ <option value="" <?php selected( $selected_data['discount_type'], '', true ); ?>><?php echo __( 'Original', 'cartflows' ); ?></option>
71
+ <option value="discount_percent" <?php selected( $selected_data['discount_type'], 'discount_percent', true ); ?>><?php echo __( 'Percentage', 'cartflows' ); ?></option>
72
+ <option value="discount_price" <?php selected( $selected_data['discount_type'], 'discount_price', true ); ?>><?php echo __( 'Price', 'cartflows' ); ?></option>
73
+ </select>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <!-- Type field end -->
78
+
79
+ <!-- Discount field -->
80
+ <div class="wcf-repeatable-row-discount-field <?php echo $hide_advance; ?> wcf-checkout-products-discount-<?php echo $id; ?>">
81
+ <div class="wcf-field-row">
82
+ <div class="wcf-field-row-heading">
83
+ <label><?php echo __( 'Discount Value', 'cartflows' ); ?></label>
84
+ <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
85
+ <span class="wcf-tooltip-text"><?php echo __( 'Discount value will apply for each quantity of product.', 'cartflows' ); ?></span>
86
+ </div>
87
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
88
+ <input type="text" class="input-text text" name="wcf-checkout-products[<?php echo $id; ?>][discount_value]" value="<?php echo $selected_data['discount_value']; ?>" title="" inputmode="numeric">
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <div class="wcf-repeatable-row-unique-id-field">
94
+ <input name="wcf-checkout-products[<?php echo $id; ?>][unique_id]" type="hidden" class="wcf-checkout-product-unique" value="<?php echo $selected_data['unique_id']; ?>">
95
+ </div>
96
+
97
+ <?php do_action( 'cartflows_repeatable_row_advance_fields', $id ); ?>
98
+ </div>
99
+ </div>
languages/cartflows.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: CartFlows 1.5.16\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2020-08-25 07:56:45+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -92,53 +92,53 @@ msgid ""
92
  "Please read information about how to set up Global Checkout %1$shere%2$s."
93
  msgstr ""
94
 
95
- #: classes/class-cartflows-admin.php:159 includes/admin/cartflows-home.php:11
96
  msgid "Home"
97
  msgstr ""
98
 
99
- #: classes/class-cartflows-admin.php:164 classes/class-cartflows-admin.php:165
100
  #: modules/optin/classes/class-cartflows-optin-meta.php:150
101
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
102
  msgid "Settings"
103
  msgstr ""
104
 
105
- #: classes/class-cartflows-admin.php:453
106
  msgid "Installing and activating.."
107
  msgstr ""
108
 
109
- #: classes/class-cartflows-admin.php:454
110
  msgid "There was an error with the installation of plugin."
111
  msgstr ""
112
 
113
- #: classes/class-cartflows-admin.php:516
114
  msgid "Flows Library"
115
  msgstr ""
116
 
117
- #: classes/class-cartflows-admin.php:523
118
  #: modules/flow/view/view-remote-importer.php:26
119
  msgid "Ready Templates"
120
  msgstr ""
121
 
122
- #: classes/class-cartflows-admin.php:526
123
  #: modules/flow/view/view-remote-importer.php:29
124
  msgid "Create Your Own"
125
  msgstr ""
126
 
127
- #: classes/class-cartflows-admin.php:537
128
  #: modules/flow/view/view-remote-importer.php:41
129
  msgid "Search Sites"
130
  msgstr ""
131
 
132
- #: classes/class-cartflows-admin.php:538
133
  #: modules/flow/view/view-remote-importer.php:42
134
  msgid "Search Flow..."
135
  msgstr ""
136
 
137
- #: classes/class-cartflows-admin.php:555
138
  msgid "Design Your Flow"
139
  msgstr ""
140
 
141
- #: classes/class-cartflows-admin.php:556
142
  #: classes/class-cartflows-importer.php:665
143
  #: classes/class-cartflows-importer.php:764
144
  #: modules/flow/view/view-remote-importer.php:72
@@ -1071,33 +1071,33 @@ msgstr ""
1071
  msgid "Variations Not set"
1072
  msgstr ""
1073
 
1074
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:530
1075
  msgid "This product can't be purchased"
1076
  msgstr ""
1077
 
1078
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:975
1079
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1018
1080
  msgid "Coupon Code"
1081
  msgstr ""
1082
 
1083
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:976
1084
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1027
1085
  msgid "Apply"
1086
  msgstr ""
1087
 
1088
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1183
1089
  msgid "Sorry there was a problem removing this coupon."
1090
  msgstr ""
1091
 
1092
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1186
1093
  msgid "Coupon has been removed."
1094
  msgstr ""
1095
 
1096
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1205
1097
  msgid "Sorry there was a problem removing "
1098
  msgstr ""
1099
 
1100
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1208
1101
  msgid " has been removed."
1102
  msgstr ""
1103
 
@@ -1872,7 +1872,7 @@ msgstr ""
1872
 
1873
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1874
  #: woocommerce/template/checkout/thankyou.php:41
1875
- #: woocommerce/template/checkout/thankyou.php:83
1876
  msgid "Thank you. Your order has been received."
1877
  msgstr ""
1878
 
@@ -2035,13 +2035,13 @@ msgid "Update totals"
2035
  msgstr ""
2036
 
2037
  #: woocommerce/template/checkout/review-order.php:26
2038
- #: woocommerce/template/order/order-details.php:51
2039
  msgid "Product"
2040
  msgstr ""
2041
 
2042
  #: woocommerce/template/checkout/review-order.php:27
2043
  #: woocommerce/template/checkout/review-order.php:107
2044
- #: woocommerce/template/order/order-details.php:52
2045
  msgid "Total"
2046
  msgstr ""
2047
 
@@ -2064,23 +2064,23 @@ msgstr ""
2064
  msgid "My account"
2065
  msgstr ""
2066
 
2067
- #: woocommerce/template/checkout/thankyou.php:46
2068
  msgid "Order number:"
2069
  msgstr ""
2070
 
2071
- #: woocommerce/template/checkout/thankyou.php:51
2072
  msgid "Date:"
2073
  msgstr ""
2074
 
2075
- #: woocommerce/template/checkout/thankyou.php:57
2076
  msgid "Email:"
2077
  msgstr ""
2078
 
2079
- #: woocommerce/template/checkout/thankyou.php:63
2080
  msgid "Total:"
2081
  msgstr ""
2082
 
2083
- #: woocommerce/template/checkout/thankyou.php:69
2084
  msgid "Payment method:"
2085
  msgstr ""
2086
 
@@ -2104,11 +2104,11 @@ msgstr ""
2104
  msgid "Lost your password?"
2105
  msgstr ""
2106
 
2107
- #: woocommerce/template/order/order-details.php:45
2108
  msgid "Order details"
2109
  msgstr ""
2110
 
2111
- #: woocommerce/template/order/order-details.php:93
2112
  msgid "Note:"
2113
  msgstr ""
2114
 
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: CartFlows 1.5.17\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-09-08 06:13:47+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
92
  "Please read information about how to set up Global Checkout %1$shere%2$s."
93
  msgstr ""
94
 
95
+ #: classes/class-cartflows-admin.php:186 includes/admin/cartflows-home.php:11
96
  msgid "Home"
97
  msgstr ""
98
 
99
+ #: classes/class-cartflows-admin.php:191 classes/class-cartflows-admin.php:192
100
  #: modules/optin/classes/class-cartflows-optin-meta.php:150
101
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
102
  msgid "Settings"
103
  msgstr ""
104
 
105
+ #: classes/class-cartflows-admin.php:480
106
  msgid "Installing and activating.."
107
  msgstr ""
108
 
109
+ #: classes/class-cartflows-admin.php:481
110
  msgid "There was an error with the installation of plugin."
111
  msgstr ""
112
 
113
+ #: classes/class-cartflows-admin.php:543
114
  msgid "Flows Library"
115
  msgstr ""
116
 
117
+ #: classes/class-cartflows-admin.php:550
118
  #: modules/flow/view/view-remote-importer.php:26
119
  msgid "Ready Templates"
120
  msgstr ""
121
 
122
+ #: classes/class-cartflows-admin.php:553
123
  #: modules/flow/view/view-remote-importer.php:29
124
  msgid "Create Your Own"
125
  msgstr ""
126
 
127
+ #: classes/class-cartflows-admin.php:564
128
  #: modules/flow/view/view-remote-importer.php:41
129
  msgid "Search Sites"
130
  msgstr ""
131
 
132
+ #: classes/class-cartflows-admin.php:565
133
  #: modules/flow/view/view-remote-importer.php:42
134
  msgid "Search Flow..."
135
  msgstr ""
136
 
137
+ #: classes/class-cartflows-admin.php:582
138
  msgid "Design Your Flow"
139
  msgstr ""
140
 
141
+ #: classes/class-cartflows-admin.php:583
142
  #: classes/class-cartflows-importer.php:665
143
  #: classes/class-cartflows-importer.php:764
144
  #: modules/flow/view/view-remote-importer.php:72
1071
  msgid "Variations Not set"
1072
  msgstr ""
1073
 
1074
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:533
1075
  msgid "This product can't be purchased"
1076
  msgstr ""
1077
 
1078
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:978
1079
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1021
1080
  msgid "Coupon Code"
1081
  msgstr ""
1082
 
1083
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:979
1084
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1030
1085
  msgid "Apply"
1086
  msgstr ""
1087
 
1088
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1186
1089
  msgid "Sorry there was a problem removing this coupon."
1090
  msgstr ""
1091
 
1092
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1189
1093
  msgid "Coupon has been removed."
1094
  msgstr ""
1095
 
1096
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1208
1097
  msgid "Sorry there was a problem removing "
1098
  msgstr ""
1099
 
1100
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1211
1101
  msgid " has been removed."
1102
  msgstr ""
1103
 
1872
 
1873
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1874
  #: woocommerce/template/checkout/thankyou.php:41
1875
+ #: woocommerce/template/checkout/thankyou.php:86
1876
  msgid "Thank you. Your order has been received."
1877
  msgstr ""
1878
 
2035
  msgstr ""
2036
 
2037
  #: woocommerce/template/checkout/review-order.php:26
2038
+ #: woocommerce/template/order/order-details.php:57
2039
  msgid "Product"
2040
  msgstr ""
2041
 
2042
  #: woocommerce/template/checkout/review-order.php:27
2043
  #: woocommerce/template/checkout/review-order.php:107
2044
+ #: woocommerce/template/order/order-details.php:58
2045
  msgid "Total"
2046
  msgstr ""
2047
 
2064
  msgid "My account"
2065
  msgstr ""
2066
 
2067
+ #: woocommerce/template/checkout/thankyou.php:49
2068
  msgid "Order number:"
2069
  msgstr ""
2070
 
2071
+ #: woocommerce/template/checkout/thankyou.php:54
2072
  msgid "Date:"
2073
  msgstr ""
2074
 
2075
+ #: woocommerce/template/checkout/thankyou.php:60
2076
  msgid "Email:"
2077
  msgstr ""
2078
 
2079
+ #: woocommerce/template/checkout/thankyou.php:67
2080
  msgid "Total:"
2081
  msgstr ""
2082
 
2083
+ #: woocommerce/template/checkout/thankyou.php:74
2084
  msgid "Payment method:"
2085
  msgstr ""
2086
 
2104
  msgid "Lost your password?"
2105
  msgstr ""
2106
 
2107
+ #: woocommerce/template/order/order-details.php:51
2108
  msgid "Order details"
2109
  msgstr ""
2110
 
2111
+ #: woocommerce/template/order/order-details.php:99
2112
  msgid "Note:"
2113
  msgstr ""
2114
 
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1289 +1,1292 @@
1
- <?php
2
- /**
3
- * Checkout markup.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Checkout_Markup {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var object instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- */
25
- public static function get_instance() {
26
- if ( ! isset( self::$instance ) ) {
27
- self::$instance = new self();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Set is checkout flag */
38
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
-
40
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
-
42
- /* Show notice if cart is empty */
43
- add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
-
45
- /* Checkout Shortcode */
46
- add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
-
48
- /* Preconfigured cart data */
49
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
-
51
- /* Embed Checkout */
52
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
-
54
- /* Ajax Endpoint */
55
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
-
57
- add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
-
59
- add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
-
61
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
-
63
- add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
- add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
-
66
- add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
-
68
- /* Global Checkout */
69
- add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
-
71
- add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
-
74
- add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
-
77
- add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
-
79
- add_filter( 'woocommerce_paypal_express_checkout_payment_button_data', array( $this, 'change_return_cancel_url' ), 10, 2 );
80
-
81
- add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
82
-
83
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
84
- }
85
-
86
- /**
87
- * Modify WooCommerce paypal arguments.
88
- *
89
- * @param array $args argumenets for payment.
90
- * @param WC_Order $order order data.
91
- * @return array
92
- */
93
- public function modify_paypal_args( $args, $order ) {
94
-
95
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
96
-
97
- if ( ! $checkout_id ) {
98
- return $args;
99
- }
100
-
101
- // Set cancel return URL.
102
- $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
103
-
104
- return $args;
105
- }
106
-
107
- /**
108
- * Change PayPal Express cancel URL.
109
- *
110
- * @param array $data button data.
111
- * @param string $page current page.
112
- * @return array $data modified button data with new cancel url.
113
- */
114
- public function change_return_cancel_url( $data, $page ) {
115
-
116
- global $post;
117
-
118
- if ( _is_wcf_checkout_type() ) {
119
-
120
- $checkout_id = $post->ID;
121
-
122
- if ( $checkout_id ) {
123
-
124
- // Change the default Cart URL with the CartFlows Checkout page.
125
- $data['cancel_url'] = esc_url_raw( get_permalink( $checkout_id ) );
126
- }
127
- }
128
-
129
- // Returing the modified data.
130
- return $data;
131
- }
132
-
133
- /**
134
- * Modify WooCommerce paypal arguments.
135
- *
136
- * @param string $product_name product name.
137
- * @param object $cart_item cart item.
138
- * @param string $cart_item_key cart item key.
139
- * @return string
140
- */
141
- public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
142
-
143
- $checkout_id = get_the_ID();
144
- if ( ! $checkout_id ) {
145
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
146
- }
147
-
148
- if ( ! empty( $checkout_id ) ) {
149
- $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
150
- if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
151
- $remove_label = apply_filters(
152
- 'woocommerce_cart_item_remove_link',
153
- sprintf(
154
- '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
155
- esc_attr( $cart_item['product_id'] ),
156
- $cart_item_key
157
- ),
158
- $cart_item_key
159
- );
160
-
161
- $product_name = $remove_label . $product_name;
162
- }
163
- }
164
-
165
- return $product_name;
166
-
167
- }
168
-
169
- /**
170
- * Change order button text .
171
- *
172
- * @param string $woo_button_text place order.
173
- * @return string
174
- */
175
- public function place_order_button_text( $woo_button_text ) {
176
-
177
- $checkout_id = get_the_ID();
178
- if ( ! $checkout_id ) {
179
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
180
- }
181
-
182
- $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
183
-
184
- if ( ! empty( $wcf_order_button_text ) ) {
185
- $woo_button_text = $wcf_order_button_text;
186
- }
187
-
188
- return $woo_button_text;
189
- }
190
-
191
- /**
192
- * Display all WooCommerce notices.
193
- *
194
- * @since 1.1.5
195
- */
196
- public function display_woo_notices() {
197
-
198
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
199
- woocommerce_output_all_notices();
200
- }
201
- }
202
-
203
-
204
- /**
205
- * Redirect from default to the global checkout page
206
- *
207
- * @since 1.0.0
208
- */
209
- public function global_checkout_template_redirect() {
210
-
211
- if ( ! is_checkout() ) {
212
- return;
213
- }
214
-
215
- if ( wcf()->utils->is_step_post_type() ) {
216
- return;
217
- }
218
-
219
- // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
220
- if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
221
- return;
222
- }
223
-
224
- // redirect only for cartflows checkout pages.
225
- $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
226
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
227
-
228
- $common = Cartflows_Helper::get_common_settings();
229
-
230
- $global_checkout = $common['global_checkout'];
231
-
232
- if (
233
- isset( $_SERVER['REQUEST_URI'] ) &&
234
- // ignore on order-pay.
235
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
236
- // ignore on TY page.
237
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
238
- // ignore if order-pay in query param.
239
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
240
- ) {
241
-
242
- if ( '' !== $global_checkout ) {
243
-
244
- $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
245
-
246
- if ( ! empty( $link ) ) {
247
-
248
- wp_safe_redirect( $link );
249
- die();
250
- }
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * Check for checkout flag
257
- *
258
- * @param bool $is_checkout is checkout.
259
- *
260
- * @return bool
261
- */
262
- public function woo_checkout_flag( $is_checkout ) {
263
-
264
- if ( ! is_admin() ) {
265
-
266
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
267
-
268
- $is_checkout = true;
269
- }
270
- }
271
-
272
- return $is_checkout;
273
- }
274
-
275
- /**
276
- * Render checkout shortcode markup.
277
- *
278
- * @param array $atts attributes.
279
- * @return string
280
- */
281
- public function checkout_shortcode_markup( $atts ) {
282
-
283
- if ( ! function_exists( 'wc_print_notices' ) ) {
284
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
285
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
286
-
287
- return $notice_out;
288
- }
289
-
290
- $atts = shortcode_atts(
291
- array(
292
- 'id' => 0,
293
- ),
294
- $atts
295
- );
296
-
297
- $checkout_id = intval( $atts['id'] );
298
-
299
- if ( empty( $checkout_id ) ) {
300
-
301
- if ( ! _is_wcf_checkout_type() ) {
302
-
303
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
304
- }
305
-
306
- global $post;
307
-
308
- $checkout_id = intval( $post->ID );
309
- }
310
-
311
- $output = '';
312
-
313
- ob_start();
314
-
315
- do_action( 'cartflows_checkout_form_before', $checkout_id );
316
-
317
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
318
-
319
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
320
-
321
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
322
-
323
- if ( file_exists( $template_layout ) ) {
324
- include $template_layout;
325
- } else {
326
- include $template_default;
327
- }
328
-
329
- $output .= ob_get_clean();
330
-
331
- return $output;
332
- }
333
-
334
- /**
335
- * Configure Cart Data.
336
- *
337
- * @since 1.0.0
338
- *
339
- * @return void
340
- */
341
- public function preconfigured_cart_data() {
342
-
343
- if ( is_admin() ) {
344
- return;
345
- }
346
-
347
- global $post;
348
-
349
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
350
-
351
- if ( wp_doing_ajax() ) {
352
- return;
353
- } else {
354
-
355
- if ( _is_wcf_checkout_type() ) {
356
- $checkout_id = $post->ID;
357
- } else {
358
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
359
- }
360
-
361
- $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
362
-
363
- if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
364
-
365
- if ( WC()->cart->is_empty() ) {
366
- wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
367
- }
368
-
369
- return;
370
- }
371
-
372
- if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
373
- return;
374
- }
375
-
376
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
377
-
378
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
379
-
380
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
381
- $products = 'dummy';
382
- } else {
383
- $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
384
- }
385
-
386
- if ( ! is_array( $products ) ) {
387
-
388
- if ( 'dummy' === $products ) {
389
-
390
- $args = array(
391
- 'posts_per_page' => 1,
392
- 'orderby' => 'rand',
393
- 'post_type' => 'product',
394
- 'meta_query' => array( //phpcs:ignore
395
- // Exclude out of stock products.
396
- array(
397
- 'key' => '_stock_status',
398
- 'value' => 'outofstock',
399
- 'compare' => 'NOT IN',
400
- ),
401
- ),
402
- 'tax_query' => array( //phpcs:ignore
403
- array(
404
- 'taxonomy' => 'product_type',
405
- 'field' => 'slug',
406
- 'terms' => 'simple',
407
- ),
408
- ),
409
- );
410
-
411
- $random_product = get_posts( $args );
412
-
413
- if ( isset( $random_product[0]->ID ) ) {
414
- $products = array(
415
- array(
416
- 'product' => $random_product[0]->ID,
417
- 'add_to_cart' => true,
418
- ),
419
- );
420
- } else {
421
- return;
422
- }
423
- } else {
424
- return;
425
- }
426
- }
427
-
428
- /* Empty the current cart */
429
- WC()->cart->empty_cart();
430
-
431
- if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
432
- wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
433
- return;
434
- }
435
-
436
- /* Set customer session if not set */
437
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
438
- WC()->session->set_customer_session_cookie( true );
439
- }
440
-
441
- $cart_product_count = 0;
442
- $cart_key = '';
443
- $products_new = array();
444
-
445
- $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
446
-
447
- foreach ( $products as $index => $data ) {
448
-
449
- if ( ! isset( $data['product'] ) ) {
450
- continue;
451
- }
452
-
453
- if ( empty( $data['add_to_cart'] ) ) {
454
- continue;
455
- }
456
-
457
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
458
- break;
459
- }
460
-
461
- $product_id = $data['product'];
462
- $_product = wc_get_product( $product_id );
463
-
464
- if ( ! empty( $_product ) ) {
465
-
466
- $quantity = 1;
467
-
468
- if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
469
- $quantity = $data['quantity'];
470
- }
471
-
472
- $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
473
- $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
474
- $_product_price = $_product->get_price( $data['product'] );
475
-
476
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
477
-
478
- $cart_item_data = array();
479
-
480
- // Set the Product's custom price even if it is zero. Discount may have applied.
481
- if ( $custom_price >= 0 && '' !== $custom_price ) {
482
-
483
- $cart_item_data = array(
484
- 'custom_price' => $custom_price,
485
- );
486
- }
487
-
488
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
489
-
490
- if ( $_product->is_type( 'variable' ) ) {
491
-
492
- $default_attributes = $_product->get_default_attributes();
493
-
494
- if ( ! empty( $default_attributes ) ) {
495
-
496
- foreach ( $_product->get_children() as $variation_id ) {
497
-
498
- $single_variation = new WC_Product_Variation( $variation_id );
499
-
500
- if ( $default_attributes == $single_variation->get_attributes() ) {
501
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
502
- $cart_product_count++;
503
- }
504
- }
505
- } else {
506
-
507
- $product_childrens = $_product->get_children();
508
-
509
- if ( isset( $product_childrens[0] ) ) {
510
- $variation = wc_get_product( $product_childrens[0] );
511
- $_product_price = $variation->get_price();
512
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
513
- if ( ! empty( $custom_price ) ) {
514
- $cart_item_data = array(
515
- 'custom_price' => $custom_price,
516
- 'data' => $data,
517
- );
518
- }
519
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
520
- $cart_product_count++;
521
- } else {
522
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
523
- }
524
- }
525
- } else {
526
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
527
- $cart_product_count++;
528
- }
529
- } else {
530
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
531
- wc_add_notice( $wrong_product_notice );
532
- /**
533
- WC()->cart->add_to_cart( $product_id, $quantity );.
534
- */
535
- }
536
- }
537
- $products_new[ $index ] = array(
538
- 'cart_item_key' => $cart_key,
539
- );
540
- }
541
-
542
- /* Set checkout products data */
543
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
544
-
545
- /* Since 1.2.2 */
546
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
547
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
548
- }
549
- }
550
- }
551
-
552
- /**
553
- * Load shortcode data.
554
- *
555
- * @return void
556
- */
557
- public function shortcode_load_data() {
558
-
559
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
560
-
561
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
562
-
563
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
564
-
565
- /* Show notices if cart has errors */
566
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
567
-
568
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
569
-
570
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
571
-
572
- // Outputting the hidden field in checkout page.
573
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
575
-
576
- remove_all_actions( 'woocommerce_checkout_billing' );
577
- remove_all_actions( 'woocommerce_checkout_shipping' );
578
-
579
- // Hook in actions once.
580
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
581
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
582
-
583
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
584
-
585
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
586
-
587
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
588
-
589
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
590
-
591
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
592
-
593
- global $post;
594
-
595
- if ( _is_wcf_checkout_type() ) {
596
- $checkout_id = $post->ID;
597
- } else {
598
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
599
- }
600
-
601
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
602
- }
603
- }
604
-
605
- /**
606
- * Render checkout ID hidden field.
607
- *
608
- * @param array $checkout checkout session data.
609
- * @return void
610
- */
611
- public function checkout_shortcode_post_id( $checkout ) {
612
-
613
- global $post;
614
-
615
- if ( _is_wcf_checkout_type() ) {
616
- $checkout_id = $post->ID;
617
- } else {
618
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
619
- }
620
-
621
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
622
-
623
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
624
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
625
- }
626
-
627
- /**
628
- * Load shortcode scripts.
629
- *
630
- * @return void
631
- */
632
- public function shortcode_scripts() {
633
-
634
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
635
-
636
- wp_enqueue_script(
637
- 'wcf-checkout-template',
638
- wcf()->utils->get_js_url( 'checkout-template' ),
639
- array( 'jquery' ),
640
- CARTFLOWS_VER,
641
- true
642
- );
643
-
644
- do_action( 'cartflows_checkout_scripts' );
645
-
646
- $style = $this->generate_style();
647
-
648
- wp_add_inline_style( 'wcf-checkout-template', $style );
649
-
650
- }
651
-
652
- /**
653
- * Load compatibility scripts.
654
- *
655
- * @return void
656
- */
657
- public function compatibility_scripts() {
658
-
659
- global $post;
660
-
661
- if ( _is_wcf_checkout_type() ) {
662
- $checkout_id = $post->ID;
663
- } else {
664
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
665
- }
666
-
667
- // Add DIVI Compatibility css if DIVI theme is enabled.
668
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
669
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
670
- ) {
671
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
672
- }
673
-
674
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
675
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
676
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
677
- }
678
-
679
- // Add The7 Compatibility css if The7 theme is enabled.
680
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
681
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
682
- }
683
- }
684
-
685
- /**
686
- * Generate styles.
687
- *
688
- * @return string
689
- */
690
- public function generate_style() {
691
-
692
- global $post;
693
-
694
- if ( _is_wcf_checkout_type() ) {
695
- $checkout_id = $post->ID;
696
- } else {
697
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
698
- }
699
-
700
- /*Output css variable */
701
- $output = '';
702
-
703
- CartFlows_Font_Families::render_fonts( $checkout_id );
704
-
705
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
706
-
707
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
708
-
709
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
710
-
711
- /**
712
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
713
- $r = '';
714
- $g = '';
715
- $b = '';
716
-
717
- $field_tb_padding = '';
718
- $field_lr_padding = '';
719
-
720
- $field_heading_color = '';
721
- $field_color = '';
722
- $field_bg_color = '';
723
- $field_border_color = '';
724
- $field_label_color = '';
725
- $submit_tb_padding = '';
726
- $submit_lr_padding = '';
727
- $hl_bg_color = '';
728
- $field_input_size = '';
729
- $box_border_color = '';
730
- $section_bg_color = '';
731
- $submit_button_height = '';
732
- $submit_color = '';
733
- $submit_bg_color = $primary_color;
734
- $submit_border_color = $primary_color;
735
-
736
- $submit_hover_color = '';
737
- $submit_bg_hover_color = $primary_color;
738
- $submit_border_hover_color = $primary_color;
739
-
740
- $section_heading_color = '';
741
-
742
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
743
-
744
- $button_font_family = '';
745
- $button_font_weight = '';
746
- $input_font_family = '';
747
- $input_font_weight = '';
748
- $heading_font_family = '';
749
- $heading_font_weight = '';
750
- $base_font_family = $base_font_family;
751
- /**
752
- $base_font_weight = $base_font_weight;*/
753
-
754
- if ( 'yes' == $is_advance_option ) {
755
-
756
- /**
757
- * Get Font Family and Font Weight weight values
758
- */
759
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
760
-
761
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
762
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
763
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
764
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
765
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
766
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
767
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
768
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
769
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
770
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
771
-
772
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
773
-
774
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
775
-
776
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
777
-
778
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
779
-
780
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
781
-
782
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
783
-
784
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
785
-
786
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
787
-
788
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
789
-
790
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
791
-
792
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
793
-
794
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
795
-
796
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
797
-
798
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
799
-
800
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
801
-
802
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
803
-
804
- /**
805
- * Get font values
806
- */
807
-
808
- if ( 'custom' == $submit_button_height ) {
809
- $submit_button_height = '38px';
810
- }
811
-
812
- if ( 'custom' == $field_input_size ) {
813
- $field_input_size = '38px';
814
- }
815
- }
816
- if ( isset( $primary_color ) ) {
817
-
818
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
819
- }
820
-
821
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
822
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
823
-
824
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
825
-
826
- } else {
827
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
828
- }
829
-
830
- return $output;
831
- }
832
-
833
- /**
834
- * Get ajax end points.
835
- *
836
- * @param string $endpoint_url end point URL.
837
- * @param string $request end point request.
838
- * @return string
839
- */
840
- public function get_ajax_endpoint( $endpoint_url, $request ) {
841
-
842
- global $post;
843
-
844
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
845
-
846
- if ( _is_wcf_checkout_type() ) {
847
-
848
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
849
-
850
- if ( '' === $request ) {
851
- $query_args = array(
852
- 'wc-ajax' => '%%endpoint%%',
853
- );
854
- } else {
855
- $query_args = array(
856
- 'wc-ajax' => $request,
857
- );
858
- }
859
-
860
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
861
- $uri = $uri[0];
862
-
863
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
864
- }
865
- }
866
- }
867
-
868
- return $endpoint_url;
869
- }
870
-
871
-
872
- /**
873
- * Save checkout fields.
874
- *
875
- * @param int $order_id order id.
876
- * @param array $posted posted data.
877
- * @return void
878
- */
879
- public function save_checkout_fields( $order_id, $posted ) {
880
-
881
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
882
-
883
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
884
-
885
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
886
-
887
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
888
-
889
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
890
-
891
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
892
- }
893
- }
894
-
895
- }
896
-
897
- /**
898
- * Enable Logo In Header Of Checkout Page
899
- *
900
- * @return void
901
- */
902
- public function enable_logo_in_header() {
903
- global $post;
904
-
905
- if ( _is_wcf_checkout_type() ) {
906
- $checkout_id = $post->ID;
907
- } else {
908
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
909
- }
910
-
911
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
912
- $add_image_markup = '';
913
-
914
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
915
- $add_image_markup = '<div class="wcf-checkout-header-image">';
916
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
917
- $add_image_markup .= '</div>';
918
- }
919
-
920
- echo $add_image_markup;
921
- }
922
-
923
- /**
924
- * Add text to the bootom of the checkout page.
925
- *
926
- * @return void
927
- */
928
- public function show_cartflows_copyright_message() {
929
- $output_string = '';
930
-
931
- $output_string .= '<div class="wcf-footer-primary">';
932
- $output_string .= '<div class="wcf-footer-content">';
933
- $output_string .= '<p class="wcf-footer-message">';
934
- $output_string .= 'Checkout powered by CartFlows';
935
- $output_string .= '</p>';
936
- $output_string .= '</div>';
937
- $output_string .= '</div>';
938
-
939
- echo $output_string;
940
- }
941
-
942
- /**
943
- * Redirect users to our checkout if hidden param
944
- *
945
- * @param string $redirect redirect url.
946
- * @param object $user user.
947
- * @return string
948
- */
949
- public function after_login_redirect( $redirect, $user ) {
950
-
951
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
952
-
953
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
954
-
955
- $redirect = get_permalink( $checkout_id );
956
- }
957
-
958
- return $redirect;
959
- }
960
-
961
- /**
962
- * Display coupon code field after review order fields.
963
- */
964
- public function display_custom_coupon_field() {
965
-
966
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
967
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
968
-
969
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
970
- return;
971
-
972
- }
973
-
974
- $coupon_field = array(
975
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
976
- 'button_text' => __( 'Apply', 'cartflows' ),
977
- 'class' => '',
978
- );
979
-
980
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
981
-
982
- ob_start();
983
- ?>
984
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
985
- <div class="wcf-coupon-col-1">
986
- <span>
987
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
988
- </span>
989
- </div>
990
- <div class="wcf-coupon-col-2">
991
- <span>
992
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
993
- </span>
994
- </div>
995
- </div>
996
- <?php
997
- echo ob_get_clean();
998
- }
999
-
1000
- /**
1001
- * Apply filter to change class of remove coupon field.
1002
- *
1003
- * @param string $coupon coupon.
1004
- * @return string
1005
- */
1006
- public function remove_coupon_text( $coupon ) {
1007
-
1008
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1009
- return $coupon;
1010
-
1011
- }
1012
- /**
1013
- * Apply filter to change the placeholder text of coupon field.
1014
- *
1015
- * @return string
1016
- */
1017
- public function coupon_field_placeholder() {
1018
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1019
- }
1020
-
1021
- /**
1022
- * Apply filter to change the button text of coupon field.
1023
- *
1024
- * @return string
1025
- */
1026
- public function coupon_button_text() {
1027
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1028
- }
1029
-
1030
- /**
1031
- * Apply coupon on submit of custom coupon form.
1032
- */
1033
- public function apply_coupon() {
1034
-
1035
- $response = '';
1036
-
1037
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1038
- if ( ! empty( $_POST['coupon_code'] ) ) {
1039
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1040
- } else {
1041
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1042
- }
1043
-
1044
- $response = array(
1045
- 'status' => $result,
1046
- 'msg' => wc_print_notices( true ),
1047
- );
1048
-
1049
- echo wp_json_encode( $response );
1050
-
1051
- die();
1052
- }
1053
-
1054
-
1055
- /**
1056
- * Added ajax nonce to localize variable.
1057
- *
1058
- * @param array $vars localize variables.
1059
- */
1060
- public function add_localize_vars( $vars ) {
1061
-
1062
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1063
-
1064
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1065
-
1066
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1067
-
1068
- $vars['allow_persistence'] = wcf_apply_filters_deprecated( 'cartflows_allow_persistace', array( 'yes' ), '1.6.0', 'cartflows_allow_persistence' );
1069
-
1070
- return $vars;
1071
- }
1072
-
1073
- /**
1074
- * Add custom class to the fields to change the UI to three column.
1075
- *
1076
- * @param array $fields fields.
1077
- */
1078
- public function add_three_column_layout_fields( $fields ) {
1079
-
1080
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
1081
-
1082
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1083
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1084
- }
1085
- }
1086
-
1087
- if ( ! empty( $fields['billing']['billing_company'] ) ) {
1088
-
1089
- if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1090
- $fields['billing']['billing_company']['class'][] = 'form-row-full';
1091
- }
1092
- }
1093
-
1094
- if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1095
-
1096
- if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1097
- $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1098
- }
1099
- }
1100
-
1101
- if ( ! empty( $fields['billing']['billing_country'] ) ) {
1102
-
1103
- if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1104
- $fields['billing']['billing_country']['class'][] = 'form-row-full';
1105
- }
1106
- }
1107
-
1108
- if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1109
-
1110
- if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1111
- $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1112
- }
1113
- }
1114
-
1115
- if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1116
-
1117
- if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1118
- $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1119
- }
1120
- }
1121
-
1122
- if ( ! empty( $fields['billing']['billing_email'] ) ) {
1123
-
1124
- if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1125
- $fields['billing']['billing_email']['class'][] = 'form-row-full';
1126
- }
1127
- }
1128
-
1129
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1130
-
1131
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1132
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1133
- }
1134
- }
1135
-
1136
- if ( isset( $fields['billing']['billing_city'] ) &&
1137
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1138
-
1139
- $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1140
- $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1141
- $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1142
- }
1143
-
1144
- if ( isset( $fields['shipping']['shipping_city'] ) &&
1145
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1146
-
1147
- $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1148
- $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1149
- $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1150
- }
1151
-
1152
- return $fields;
1153
- }
1154
-
1155
- /**
1156
- * Add opening dev
1157
- *
1158
- * @since 1.0.0
1159
- */
1160
- public function order_wrap_div_start() {
1161
-
1162
- echo "<div class='wcf-order-wrap'> ";
1163
- }
1164
-
1165
- /**
1166
- * Add closing dev
1167
- *
1168
- * @since 1.0.0
1169
- */
1170
- public function order_wrap_div_end() {
1171
-
1172
- echo '</div> ';
1173
- }
1174
- /**
1175
- * Remove coupon.
1176
- */
1177
- public function remove_coupon() {
1178
-
1179
- check_ajax_referer( 'wcf-remove-coupon', 'security' );
1180
- $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1181
-
1182
- if ( empty( $coupon ) ) {
1183
- echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1184
- } else {
1185
- WC()->cart->remove_coupon( $coupon );
1186
- echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1187
- }
1188
- wc_print_notices();
1189
- wp_die();
1190
- }
1191
-
1192
- /**
1193
- * Remove cart item.
1194
- */
1195
- public function wcf_woo_remove_cart_product() {
1196
-
1197
- check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1198
- $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1199
- $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1200
- $product_title = get_the_title( $product_id );
1201
-
1202
- $needs_shipping = false;
1203
-
1204
- if ( empty( $product_key ) ) {
1205
- $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1206
- } else {
1207
- WC()->cart->remove_cart_item( $product_key );
1208
- $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1209
- }
1210
-
1211
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1212
- if ( $values['data']->needs_shipping() ) {
1213
- $needs_shipping = true;
1214
- break;
1215
- }
1216
- }
1217
-
1218
- $response = array(
1219
- 'need_shipping' => $needs_shipping,
1220
- 'msg' => $msg,
1221
- );
1222
-
1223
- echo wp_json_encode( $response );
1224
- wp_die();
1225
- }
1226
-
1227
- /**
1228
- * Calculate discount for product.
1229
- *
1230
- * @param string $discount_coupon discount coupon.
1231
- * @param string $discount_type discount type.
1232
- * @param int $discount_value discount value.
1233
- * @param int $_product_price product price.
1234
- * @return int
1235
- * @since 1.1.5
1236
- */
1237
- public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1238
-
1239
- $custom_price = '';
1240
-
1241
- if ( ! empty( $discount_type ) ) {
1242
- if ( 'discount_percent' === $discount_type ) {
1243
-
1244
- if ( $discount_value > 0 ) {
1245
- $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1246
- }
1247
- } elseif ( 'discount_price' === $discount_type ) {
1248
-
1249
- if ( $discount_value > 0 ) {
1250
- $custom_price = $_product_price - $discount_value;
1251
- }
1252
- } elseif ( 'coupon' === $discount_type ) {
1253
-
1254
- if ( ! empty( $discount_coupon ) ) {
1255
- WC()->cart->add_discount( $discount_coupon );
1256
- }
1257
- }
1258
- }
1259
-
1260
- return $custom_price;
1261
- }
1262
-
1263
- /**
1264
- * Preserve the custom item price added by Variations & Quantity feature
1265
- *
1266
- * @param array $cart_object cart object.
1267
- * @since 1.0.0
1268
- */
1269
- public function custom_price_to_cart_item( $cart_object ) {
1270
-
1271
- if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1272
-
1273
- foreach ( $cart_object->cart_contents as $key => $value ) {
1274
-
1275
- if ( isset( $value['custom_price'] ) ) {
1276
-
1277
- $custom_price = floatval( $value['custom_price'] );
1278
- $value['data']->set_price( $custom_price );
1279
- }
1280
- }
1281
- }
1282
- }
1283
-
1284
- }
1285
-
1286
- /**
1287
- * Kicking this off by calling 'get_instance()' method
1288
- */
1289
- Cartflows_Checkout_Markup::get_instance();
 
 
 
1
+ <?php
2
+ /**
3
+ * Checkout markup.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Checkout_Markup {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var object instance
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Initiator
24
+ */
25
+ public static function get_instance() {
26
+ if ( ! isset( self::$instance ) ) {
27
+ self::$instance = new self();
28
+ }
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Set is checkout flag */
38
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
+
40
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
+
42
+ /* Show notice if cart is empty */
43
+ add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
+
45
+ /* Checkout Shortcode */
46
+ add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
+
48
+ /* Preconfigured cart data */
49
+ add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
+
51
+ /* Embed Checkout */
52
+ add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
+
54
+ /* Ajax Endpoint */
55
+ add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
+
57
+ add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
+
59
+ add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
+
61
+ add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
+
63
+ add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
+ add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
+
66
+ add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
+
68
+ /* Global Checkout */
69
+ add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
+
71
+ add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
+
74
+ add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
+
77
+ add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
+
79
+ add_filter( 'woocommerce_paypal_express_checkout_payment_button_data', array( $this, 'change_return_cancel_url' ), 10, 2 );
80
+
81
+ add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
82
+
83
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
84
+ }
85
+
86
+ /**
87
+ * Modify WooCommerce paypal arguments.
88
+ *
89
+ * @param array $args argumenets for payment.
90
+ * @param WC_Order $order order data.
91
+ * @return array
92
+ */
93
+ public function modify_paypal_args( $args, $order ) {
94
+
95
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
96
+
97
+ if ( ! $checkout_id ) {
98
+ return $args;
99
+ }
100
+
101
+ // Set cancel return URL.
102
+ $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
103
+
104
+ return $args;
105
+ }
106
+
107
+ /**
108
+ * Change PayPal Express cancel URL.
109
+ *
110
+ * @param array $data button data.
111
+ * @param string $page current page.
112
+ * @return array $data modified button data with new cancel url.
113
+ */
114
+ public function change_return_cancel_url( $data, $page ) {
115
+
116
+ global $post;
117
+
118
+ if ( _is_wcf_checkout_type() ) {
119
+
120
+ $checkout_id = $post->ID;
121
+
122
+ if ( $checkout_id ) {
123
+
124
+ // Change the default Cart URL with the CartFlows Checkout page.
125
+ $data['cancel_url'] = esc_url_raw( get_permalink( $checkout_id ) );
126
+ }
127
+ }
128
+
129
+ // Returing the modified data.
130
+ return $data;
131
+ }
132
+
133
+ /**
134
+ * Modify WooCommerce paypal arguments.
135
+ *
136
+ * @param string $product_name product name.
137
+ * @param object $cart_item cart item.
138
+ * @param string $cart_item_key cart item key.
139
+ * @return string
140
+ */
141
+ public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
142
+
143
+ $checkout_id = get_the_ID();
144
+ if ( ! $checkout_id ) {
145
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
146
+ }
147
+
148
+ if ( ! empty( $checkout_id ) ) {
149
+ $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
150
+ if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
151
+ $remove_label = apply_filters(
152
+ 'woocommerce_cart_item_remove_link',
153
+ sprintf(
154
+ '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
155
+ esc_attr( $cart_item['product_id'] ),
156
+ $cart_item_key
157
+ ),
158
+ $cart_item_key
159
+ );
160
+
161
+ $product_name = $remove_label . $product_name;
162
+ }
163
+ }
164
+
165
+ return $product_name;
166
+
167
+ }
168
+
169
+ /**
170
+ * Change order button text .
171
+ *
172
+ * @param string $woo_button_text place order.
173
+ * @return string
174
+ */
175
+ public function place_order_button_text( $woo_button_text ) {
176
+
177
+ $checkout_id = get_the_ID();
178
+ if ( ! $checkout_id ) {
179
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
180
+ }
181
+
182
+ $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
183
+
184
+ if ( ! empty( $wcf_order_button_text ) ) {
185
+ $woo_button_text = $wcf_order_button_text;
186
+ }
187
+
188
+ return $woo_button_text;
189
+ }
190
+
191
+ /**
192
+ * Display all WooCommerce notices.
193
+ *
194
+ * @since 1.1.5
195
+ */
196
+ public function display_woo_notices() {
197
+
198
+ if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
199
+ woocommerce_output_all_notices();
200
+ }
201
+ }
202
+
203
+
204
+ /**
205
+ * Redirect from default to the global checkout page
206
+ *
207
+ * @since 1.0.0
208
+ */
209
+ public function global_checkout_template_redirect() {
210
+
211
+ if ( ! is_checkout() ) {
212
+ return;
213
+ }
214
+
215
+ if ( wcf()->utils->is_step_post_type() ) {
216
+ return;
217
+ }
218
+
219
+ // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
220
+ if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
221
+ return;
222
+ }
223
+
224
+ // redirect only for cartflows checkout pages.
225
+ $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
226
+ $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
227
+
228
+ $common = Cartflows_Helper::get_common_settings();
229
+
230
+ $global_checkout = $common['global_checkout'];
231
+
232
+ if (
233
+ isset( $_SERVER['REQUEST_URI'] ) &&
234
+ // ignore on order-pay.
235
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
236
+ // ignore on TY page.
237
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
238
+ // ignore if order-pay in query param.
239
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
240
+ ) {
241
+
242
+ if ( '' !== $global_checkout ) {
243
+
244
+ $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
245
+
246
+ if ( ! empty( $link ) ) {
247
+
248
+ wp_safe_redirect( $link );
249
+ die();
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Check for checkout flag
257
+ *
258
+ * @param bool $is_checkout is checkout.
259
+ *
260
+ * @return bool
261
+ */
262
+ public function woo_checkout_flag( $is_checkout ) {
263
+
264
+ if ( ! is_admin() ) {
265
+
266
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
267
+
268
+ $is_checkout = true;
269
+ }
270
+ }
271
+
272
+ return $is_checkout;
273
+ }
274
+
275
+ /**
276
+ * Render checkout shortcode markup.
277
+ *
278
+ * @param array $atts attributes.
279
+ * @return string
280
+ */
281
+ public function checkout_shortcode_markup( $atts ) {
282
+
283
+ if ( ! function_exists( 'wc_print_notices' ) ) {
284
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
285
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
286
+
287
+ return $notice_out;
288
+ }
289
+
290
+ $atts = shortcode_atts(
291
+ array(
292
+ 'id' => 0,
293
+ ),
294
+ $atts
295
+ );
296
+
297
+ $checkout_id = intval( $atts['id'] );
298
+
299
+ if ( empty( $checkout_id ) ) {
300
+
301
+ if ( ! _is_wcf_checkout_type() ) {
302
+
303
+ return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
304
+ }
305
+
306
+ global $post;
307
+
308
+ $checkout_id = intval( $post->ID );
309
+ }
310
+
311
+ $output = '';
312
+
313
+ ob_start();
314
+
315
+ do_action( 'cartflows_checkout_form_before', $checkout_id );
316
+
317
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
318
+
319
+ $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
320
+
321
+ $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
322
+
323
+ if ( file_exists( $template_layout ) ) {
324
+ include $template_layout;
325
+ } else {
326
+ include $template_default;
327
+ }
328
+
329
+ $output .= ob_get_clean();
330
+
331
+ return $output;
332
+ }
333
+
334
+ /**
335
+ * Configure Cart Data.
336
+ *
337
+ * @since 1.0.0
338
+ *
339
+ * @return void
340
+ */
341
+ public function preconfigured_cart_data() {
342
+
343
+ if ( is_admin() ) {
344
+ return;
345
+ }
346
+
347
+ global $post;
348
+
349
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
350
+
351
+ if ( wp_doing_ajax() ) {
352
+ return;
353
+ } else {
354
+
355
+ if ( _is_wcf_checkout_type() ) {
356
+ $checkout_id = $post->ID;
357
+ } else {
358
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
359
+ }
360
+
361
+ $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
362
+
363
+ if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
364
+
365
+ if ( WC()->cart->is_empty() ) {
366
+ wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
367
+ }
368
+
369
+ return;
370
+ }
371
+
372
+ if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
373
+ return;
374
+ }
375
+
376
+ do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
377
+
378
+ $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
379
+
380
+ if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
381
+ $products = 'dummy';
382
+ } else {
383
+ $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
384
+ }
385
+
386
+ if ( ! is_array( $products ) ) {
387
+
388
+ if ( 'dummy' === $products ) {
389
+
390
+ $args = array(
391
+ 'posts_per_page' => 1,
392
+ 'orderby' => 'rand',
393
+ 'post_type' => 'product',
394
+ 'meta_query' => array( //phpcs:ignore
395
+ // Exclude out of stock products.
396
+ array(
397
+ 'key' => '_stock_status',
398
+ 'value' => 'outofstock',
399
+ 'compare' => 'NOT IN',
400
+ ),
401
+ ),
402
+ 'tax_query' => array( //phpcs:ignore
403
+ array(
404
+ 'taxonomy' => 'product_type',
405
+ 'field' => 'slug',
406
+ 'terms' => 'simple',
407
+ ),
408
+ ),
409
+ );
410
+
411
+ $random_product = get_posts( $args );
412
+
413
+ if ( isset( $random_product[0]->ID ) ) {
414
+ $products = array(
415
+ array(
416
+ 'product' => $random_product[0]->ID,
417
+ 'add_to_cart' => true,
418
+ ),
419
+ );
420
+ } else {
421
+ return;
422
+ }
423
+ } else {
424
+ return;
425
+ }
426
+ }
427
+
428
+ /* Empty the current cart */
429
+ WC()->cart->empty_cart();
430
+
431
+ if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
432
+ wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
433
+ return;
434
+ }
435
+
436
+ /* Set customer session if not set */
437
+ if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
438
+ WC()->session->set_customer_session_cookie( true );
439
+ }
440
+
441
+ $cart_product_count = 0;
442
+ $cart_key = '';
443
+ $products_new = array();
444
+
445
+ $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
446
+
447
+ foreach ( $products as $index => $data ) {
448
+
449
+ if ( ! isset( $data['product'] ) ) {
450
+ continue;
451
+ }
452
+
453
+ if ( empty( $data['add_to_cart'] ) ) {
454
+ continue;
455
+ }
456
+
457
+ if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
458
+ break;
459
+ }
460
+
461
+ $product_id = $data['product'];
462
+ $_product = wc_get_product( $product_id );
463
+
464
+ if ( ! empty( $_product ) ) {
465
+
466
+ $quantity = 1;
467
+
468
+ if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
469
+ $quantity = $data['quantity'];
470
+ }
471
+
472
+ $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
473
+ $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
474
+ $_product_price = $_product->get_price( $data['product'] );
475
+
476
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
477
+
478
+ $cart_item_data = array();
479
+
480
+ // Set the Product's custom price even if it is zero. Discount may have applied.
481
+ if ( $custom_price >= 0 && '' !== $custom_price ) {
482
+
483
+ $cart_item_data = array(
484
+ 'custom_price' => $custom_price,
485
+ );
486
+ }
487
+
488
+ if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
489
+
490
+ if ( $_product->is_type( 'variable' ) ) {
491
+
492
+ $default_attributes = $_product->get_default_attributes();
493
+
494
+ if ( ! empty( $default_attributes ) ) {
495
+
496
+ foreach ( $_product->get_children() as $variation_id ) {
497
+
498
+ $single_variation = new WC_Product_Variation( $variation_id );
499
+
500
+ if ( $default_attributes == $single_variation->get_attributes() ) {
501
+ $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
502
+ $cart_product_count++;
503
+ }
504
+ }
505
+ } else {
506
+
507
+ $product_childrens = $_product->get_children();
508
+
509
+ if ( isset( $product_childrens[0] ) ) {
510
+ $variation = wc_get_product( $product_childrens[0] );
511
+ $_product_price = $variation->get_price();
512
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
513
+ if ( ! empty( $custom_price ) ) {
514
+ $cart_item_data = array(
515
+ 'custom_price' => $custom_price,
516
+ 'data' => $data,
517
+ );
518
+ }
519
+ $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
520
+ $cart_product_count++;
521
+ } else {
522
+ echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
523
+ }
524
+ }
525
+ } else {
526
+ $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
527
+
528
+ if ( false !== $cart_key ) {
529
+ $cart_product_count++;
530
+ }
531
+ }
532
+ } else {
533
+ $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
534
+ wc_add_notice( $wrong_product_notice );
535
+ /**
536
+ WC()->cart->add_to_cart( $product_id, $quantity );.
537
+ */
538
+ }
539
+ }
540
+ $products_new[ $index ] = array(
541
+ 'cart_item_key' => $cart_key,
542
+ );
543
+ }
544
+
545
+ /* Set checkout products data */
546
+ wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
547
+
548
+ /* Since 1.2.2 */
549
+ wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
550
+ do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
551
+ }
552
+ }
553
+ }
554
+
555
+ /**
556
+ * Load shortcode data.
557
+ *
558
+ * @return void
559
+ */
560
+ public function shortcode_load_data() {
561
+
562
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
563
+
564
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
565
+
566
+ add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
567
+
568
+ /* Show notices if cart has errors */
569
+ add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
570
+
571
+ add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
572
+
573
+ add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
574
+
575
+ // Outputting the hidden field in checkout page.
576
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
577
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
578
+
579
+ remove_all_actions( 'woocommerce_checkout_billing' );
580
+ remove_all_actions( 'woocommerce_checkout_shipping' );
581
+
582
+ // Hook in actions once.
583
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
584
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
585
+
586
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
587
+
588
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
589
+
590
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
591
+
592
+ add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
593
+
594
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
595
+
596
+ global $post;
597
+
598
+ if ( _is_wcf_checkout_type() ) {
599
+ $checkout_id = $post->ID;
600
+ } else {
601
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
602
+ }
603
+
604
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
605
+ }
606
+ }
607
+
608
+ /**
609
+ * Render checkout ID hidden field.
610
+ *
611
+ * @param array $checkout checkout session data.
612
+ * @return void
613
+ */
614
+ public function checkout_shortcode_post_id( $checkout ) {
615
+
616
+ global $post;
617
+
618
+ if ( _is_wcf_checkout_type() ) {
619
+ $checkout_id = $post->ID;
620
+ } else {
621
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
622
+ }
623
+
624
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
625
+
626
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
627
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
628
+ }
629
+
630
+ /**
631
+ * Load shortcode scripts.
632
+ *
633
+ * @return void
634
+ */
635
+ public function shortcode_scripts() {
636
+
637
+ wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
638
+
639
+ wp_enqueue_script(
640
+ 'wcf-checkout-template',
641
+ wcf()->utils->get_js_url( 'checkout-template' ),
642
+ array( 'jquery' ),
643
+ CARTFLOWS_VER,
644
+ true
645
+ );
646
+
647
+ do_action( 'cartflows_checkout_scripts' );
648
+
649
+ $style = $this->generate_style();
650
+
651
+ wp_add_inline_style( 'wcf-checkout-template', $style );
652
+
653
+ }
654
+
655
+ /**
656
+ * Load compatibility scripts.
657
+ *
658
+ * @return void
659
+ */
660
+ public function compatibility_scripts() {
661
+
662
+ global $post;
663
+
664
+ if ( _is_wcf_checkout_type() ) {
665
+ $checkout_id = $post->ID;
666
+ } else {
667
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
668
+ }
669
+
670
+ // Add DIVI Compatibility css if DIVI theme is enabled.
671
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
672
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
673
+ ) {
674
+ wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
675
+ }
676
+
677
+ // Add Flatsome Compatibility css if Flatsome theme is enabled.
678
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
679
+ wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
680
+ }
681
+
682
+ // Add The7 Compatibility css if The7 theme is enabled.
683
+ if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
684
+ wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
685
+ }
686
+ }
687
+
688
+ /**
689
+ * Generate styles.
690
+ *
691
+ * @return string
692
+ */
693
+ public function generate_style() {
694
+
695
+ global $post;
696
+
697
+ if ( _is_wcf_checkout_type() ) {
698
+ $checkout_id = $post->ID;
699
+ } else {
700
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
701
+ }
702
+
703
+ /*Output css variable */
704
+ $output = '';
705
+
706
+ CartFlows_Font_Families::render_fonts( $checkout_id );
707
+
708
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
709
+
710
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
711
+
712
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
713
+
714
+ /**
715
+ $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
716
+ $r = '';
717
+ $g = '';
718
+ $b = '';
719
+
720
+ $field_tb_padding = '';
721
+ $field_lr_padding = '';
722
+
723
+ $field_heading_color = '';
724
+ $field_color = '';
725
+ $field_bg_color = '';
726
+ $field_border_color = '';
727
+ $field_label_color = '';
728
+ $submit_tb_padding = '';
729
+ $submit_lr_padding = '';
730
+ $hl_bg_color = '';
731
+ $field_input_size = '';
732
+ $box_border_color = '';
733
+ $section_bg_color = '';
734
+ $submit_button_height = '';
735
+ $submit_color = '';
736
+ $submit_bg_color = $primary_color;
737
+ $submit_border_color = $primary_color;
738
+
739
+ $submit_hover_color = '';
740
+ $submit_bg_hover_color = $primary_color;
741
+ $submit_border_hover_color = $primary_color;
742
+
743
+ $section_heading_color = '';
744
+
745
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
746
+
747
+ $button_font_family = '';
748
+ $button_font_weight = '';
749
+ $input_font_family = '';
750
+ $input_font_weight = '';
751
+ $heading_font_family = '';
752
+ $heading_font_weight = '';
753
+ $base_font_family = $base_font_family;
754
+ /**
755
+ $base_font_weight = $base_font_weight;*/
756
+
757
+ if ( 'yes' == $is_advance_option ) {
758
+
759
+ /**
760
+ * Get Font Family and Font Weight weight values
761
+ */
762
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
763
+
764
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
765
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
766
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
767
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
768
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
769
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
770
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
771
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
772
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
773
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
774
+
775
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
776
+
777
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
778
+
779
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
780
+
781
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
782
+
783
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
784
+
785
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
786
+
787
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
788
+
789
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
790
+
791
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
792
+
793
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
794
+
795
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
796
+
797
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
798
+
799
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
800
+
801
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
802
+
803
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
804
+
805
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
806
+
807
+ /**
808
+ * Get font values
809
+ */
810
+
811
+ if ( 'custom' == $submit_button_height ) {
812
+ $submit_button_height = '38px';
813
+ }
814
+
815
+ if ( 'custom' == $field_input_size ) {
816
+ $field_input_size = '38px';
817
+ }
818
+ }
819
+ if ( isset( $primary_color ) ) {
820
+
821
+ list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
822
+ }
823
+
824
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
825
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
826
+
827
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
828
+
829
+ } else {
830
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
831
+ }
832
+
833
+ return $output;
834
+ }
835
+
836
+ /**
837
+ * Get ajax end points.
838
+ *
839
+ * @param string $endpoint_url end point URL.
840
+ * @param string $request end point request.
841
+ * @return string
842
+ */
843
+ public function get_ajax_endpoint( $endpoint_url, $request ) {
844
+
845
+ global $post;
846
+
847
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
848
+
849
+ if ( _is_wcf_checkout_type() ) {
850
+
851
+ if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
852
+
853
+ if ( '' === $request ) {
854
+ $query_args = array(
855
+ 'wc-ajax' => '%%endpoint%%',
856
+ );
857
+ } else {
858
+ $query_args = array(
859
+ 'wc-ajax' => $request,
860
+ );
861
+ }
862
+
863
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
864
+ $uri = $uri[0];
865
+
866
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
867
+ }
868
+ }
869
+ }
870
+
871
+ return $endpoint_url;
872
+ }
873
+
874
+
875
+ /**
876
+ * Save checkout fields.
877
+ *
878
+ * @param int $order_id order id.
879
+ * @param array $posted posted data.
880
+ * @return void
881
+ */
882
+ public function save_checkout_fields( $order_id, $posted ) {
883
+
884
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
885
+
886
+ $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
887
+
888
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
889
+
890
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
891
+
892
+ $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
893
+
894
+ update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
895
+ }
896
+ }
897
+
898
+ }
899
+
900
+ /**
901
+ * Enable Logo In Header Of Checkout Page
902
+ *
903
+ * @return void
904
+ */
905
+ public function enable_logo_in_header() {
906
+ global $post;
907
+
908
+ if ( _is_wcf_checkout_type() ) {
909
+ $checkout_id = $post->ID;
910
+ } else {
911
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
912
+ }
913
+
914
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
915
+ $add_image_markup = '';
916
+
917
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
918
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
919
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
920
+ $add_image_markup .= '</div>';
921
+ }
922
+
923
+ echo $add_image_markup;
924
+ }
925
+
926
+ /**
927
+ * Add text to the bootom of the checkout page.
928
+ *
929
+ * @return void
930
+ */
931
+ public function show_cartflows_copyright_message() {
932
+ $output_string = '';
933
+
934
+ $output_string .= '<div class="wcf-footer-primary">';
935
+ $output_string .= '<div class="wcf-footer-content">';
936
+ $output_string .= '<p class="wcf-footer-message">';
937
+ $output_string .= 'Checkout powered by CartFlows';
938
+ $output_string .= '</p>';
939
+ $output_string .= '</div>';
940
+ $output_string .= '</div>';
941
+
942
+ echo $output_string;
943
+ }
944
+
945
+ /**
946
+ * Redirect users to our checkout if hidden param
947
+ *
948
+ * @param string $redirect redirect url.
949
+ * @param object $user user.
950
+ * @return string
951
+ */
952
+ public function after_login_redirect( $redirect, $user ) {
953
+
954
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
955
+
956
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
957
+
958
+ $redirect = get_permalink( $checkout_id );
959
+ }
960
+
961
+ return $redirect;
962
+ }
963
+
964
+ /**
965
+ * Display coupon code field after review order fields.
966
+ */
967
+ public function display_custom_coupon_field() {
968
+
969
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
970
+ $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
971
+
972
+ if ( ! ( $coupon_enabled && $show_coupon ) ) {
973
+ return;
974
+
975
+ }
976
+
977
+ $coupon_field = array(
978
+ 'field_text' => __( 'Coupon Code', 'cartflows' ),
979
+ 'button_text' => __( 'Apply', 'cartflows' ),
980
+ 'class' => '',
981
+ );
982
+
983
+ $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
984
+
985
+ ob_start();
986
+ ?>
987
+ <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
988
+ <div class="wcf-coupon-col-1">
989
+ <span>
990
+ <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
991
+ </span>
992
+ </div>
993
+ <div class="wcf-coupon-col-2">
994
+ <span>
995
+ <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
996
+ </span>
997
+ </div>
998
+ </div>
999
+ <?php
1000
+ echo ob_get_clean();
1001
+ }
1002
+
1003
+ /**
1004
+ * Apply filter to change class of remove coupon field.
1005
+ *
1006
+ * @param string $coupon coupon.
1007
+ * @return string
1008
+ */
1009
+ public function remove_coupon_text( $coupon ) {
1010
+
1011
+ $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1012
+ return $coupon;
1013
+
1014
+ }
1015
+ /**
1016
+ * Apply filter to change the placeholder text of coupon field.
1017
+ *
1018
+ * @return string
1019
+ */
1020
+ public function coupon_field_placeholder() {
1021
+ return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1022
+ }
1023
+
1024
+ /**
1025
+ * Apply filter to change the button text of coupon field.
1026
+ *
1027
+ * @return string
1028
+ */
1029
+ public function coupon_button_text() {
1030
+ return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1031
+ }
1032
+
1033
+ /**
1034
+ * Apply coupon on submit of custom coupon form.
1035
+ */
1036
+ public function apply_coupon() {
1037
+
1038
+ $response = '';
1039
+
1040
+ check_ajax_referer( 'wcf-apply-coupon', 'security' );
1041
+ if ( ! empty( $_POST['coupon_code'] ) ) {
1042
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1043
+ } else {
1044
+ wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1045
+ }
1046
+
1047
+ $response = array(
1048
+ 'status' => $result,
1049
+ 'msg' => wc_print_notices( true ),
1050
+ );
1051
+
1052
+ echo wp_json_encode( $response );
1053
+
1054
+ die();
1055
+ }
1056
+
1057
+
1058
+ /**
1059
+ * Added ajax nonce to localize variable.
1060
+ *
1061
+ * @param array $vars localize variables.
1062
+ */
1063
+ public function add_localize_vars( $vars ) {
1064
+
1065
+ $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1066
+
1067
+ $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1068
+
1069
+ $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1070
+
1071
+ $vars['allow_persistence'] = wcf_apply_filters_deprecated( 'cartflows_allow_persistace', array( 'yes' ), '1.6.0', 'cartflows_allow_persistence' );
1072
+
1073
+ return $vars;
1074
+ }
1075
+
1076
+ /**
1077
+ * Add custom class to the fields to change the UI to three column.
1078
+ *
1079
+ * @param array $fields fields.
1080
+ */
1081
+ public function add_three_column_layout_fields( $fields ) {
1082
+
1083
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
1084
+
1085
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1086
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1087
+ }
1088
+ }
1089
+
1090
+ if ( ! empty( $fields['billing']['billing_company'] ) ) {
1091
+
1092
+ if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1093
+ $fields['billing']['billing_company']['class'][] = 'form-row-full';
1094
+ }
1095
+ }
1096
+
1097
+ if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1098
+
1099
+ if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1100
+ $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1101
+ }
1102
+ }
1103
+
1104
+ if ( ! empty( $fields['billing']['billing_country'] ) ) {
1105
+
1106
+ if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1107
+ $fields['billing']['billing_country']['class'][] = 'form-row-full';
1108
+ }
1109
+ }
1110
+
1111
+ if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1112
+
1113
+ if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1114
+ $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1115
+ }
1116
+ }
1117
+
1118
+ if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1119
+
1120
+ if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1121
+ $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1122
+ }
1123
+ }
1124
+
1125
+ if ( ! empty( $fields['billing']['billing_email'] ) ) {
1126
+
1127
+ if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1128
+ $fields['billing']['billing_email']['class'][] = 'form-row-full';
1129
+ }
1130
+ }
1131
+
1132
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1133
+
1134
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1135
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1136
+ }
1137
+ }
1138
+
1139
+ if ( isset( $fields['billing']['billing_city'] ) &&
1140
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1141
+
1142
+ $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1143
+ $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1144
+ $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1145
+ }
1146
+
1147
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
1148
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1149
+
1150
+ $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1151
+ $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1152
+ $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1153
+ }
1154
+
1155
+ return $fields;
1156
+ }
1157
+
1158
+ /**
1159
+ * Add opening dev
1160
+ *
1161
+ * @since 1.0.0
1162
+ */
1163
+ public function order_wrap_div_start() {
1164
+
1165
+ echo "<div class='wcf-order-wrap'> ";
1166
+ }
1167
+
1168
+ /**
1169
+ * Add closing dev
1170
+ *
1171
+ * @since 1.0.0
1172
+ */
1173
+ public function order_wrap_div_end() {
1174
+
1175
+ echo '</div> ';
1176
+ }
1177
+ /**
1178
+ * Remove coupon.
1179
+ */
1180
+ public function remove_coupon() {
1181
+
1182
+ check_ajax_referer( 'wcf-remove-coupon', 'security' );
1183
+ $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1184
+
1185
+ if ( empty( $coupon ) ) {
1186
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1187
+ } else {
1188
+ WC()->cart->remove_coupon( $coupon );
1189
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1190
+ }
1191
+ wc_print_notices();
1192
+ wp_die();
1193
+ }
1194
+
1195
+ /**
1196
+ * Remove cart item.
1197
+ */
1198
+ public function wcf_woo_remove_cart_product() {
1199
+
1200
+ check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1201
+ $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1202
+ $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1203
+ $product_title = get_the_title( $product_id );
1204
+
1205
+ $needs_shipping = false;
1206
+
1207
+ if ( empty( $product_key ) ) {
1208
+ $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1209
+ } else {
1210
+ WC()->cart->remove_cart_item( $product_key );
1211
+ $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1212
+ }
1213
+
1214
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1215
+ if ( $values['data']->needs_shipping() ) {
1216
+ $needs_shipping = true;
1217
+ break;
1218
+ }
1219
+ }
1220
+
1221
+ $response = array(
1222
+ 'need_shipping' => $needs_shipping,
1223
+ 'msg' => $msg,
1224
+ );
1225
+
1226
+ echo wp_json_encode( $response );
1227
+ wp_die();
1228
+ }
1229
+
1230
+ /**
1231
+ * Calculate discount for product.
1232
+ *
1233
+ * @param string $discount_coupon discount coupon.
1234
+ * @param string $discount_type discount type.
1235
+ * @param int $discount_value discount value.
1236
+ * @param int $_product_price product price.
1237
+ * @return int
1238
+ * @since 1.1.5
1239
+ */
1240
+ public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1241
+
1242
+ $custom_price = '';
1243
+
1244
+ if ( ! empty( $discount_type ) ) {
1245
+ if ( 'discount_percent' === $discount_type ) {
1246
+
1247
+ if ( $discount_value > 0 ) {
1248
+ $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1249
+ }
1250
+ } elseif ( 'discount_price' === $discount_type ) {
1251
+
1252
+ if ( $discount_value > 0 ) {
1253
+ $custom_price = $_product_price - $discount_value;
1254
+ }
1255
+ } elseif ( 'coupon' === $discount_type ) {
1256
+
1257
+ if ( ! empty( $discount_coupon ) ) {
1258
+ WC()->cart->add_discount( $discount_coupon );
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ return $custom_price;
1264
+ }
1265
+
1266
+ /**
1267
+ * Preserve the custom item price added by Variations & Quantity feature
1268
+ *
1269
+ * @param array $cart_object cart object.
1270
+ * @since 1.0.0
1271
+ */
1272
+ public function custom_price_to_cart_item( $cart_object ) {
1273
+
1274
+ if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1275
+
1276
+ foreach ( $cart_object->cart_contents as $key => $value ) {
1277
+
1278
+ if ( isset( $value['custom_price'] ) ) {
1279
+
1280
+ $custom_price = floatval( $value['custom_price'] );
1281
+ $value['data']->set_price( $custom_price );
1282
+ }
1283
+ }
1284
+ }
1285
+ }
1286
+
1287
+ }
1288
+
1289
+ /**
1290
+ * Kicking this off by calling 'get_instance()' method
1291
+ */
1292
+ Cartflows_Checkout_Markup::get_instance();
modules/landing/classes/class-cartflows-landing-markup.php CHANGED
@@ -1,143 +1,147 @@
1
- <?php
2
- /**
3
- * Markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Landing_Markup {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- add_action( 'pre_get_posts', array( $this, 'wcf_pre_get_posts' ) );
39
- add_action( 'template_redirect', array( $this, 'template_redirect' ) );
40
-
41
- if ( is_admin() ) {
42
- add_filter( 'wp_dropdown_pages', array( $this, 'wp_dropdown_pages' ) );
43
- }
44
- }
45
-
46
- /**
47
- * Add landing pages in WordPress reading section.
48
- *
49
- * @param array $output output.
50
- */
51
- public function wp_dropdown_pages( $output ) {
52
-
53
- global $pagenow;
54
-
55
- if ( ( 'options-reading.php' === $pagenow || 'customize.php' === $pagenow ) && preg_match( '#page_on_front#', $output ) ) {
56
-
57
- $args = array(
58
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
59
- 'numberposts' => 100,
60
- 'meta_query' => array( //phpcs:ignore
61
- 'relation' => 'OR',
62
- array(
63
- 'key' => 'wcf-step-type',
64
- 'value' => 'landing',
65
- ),
66
- array(
67
- 'key' => 'wcf-step-type',
68
- 'value' => 'checkout',
69
- ),
70
- array(
71
- 'key' => 'wcf-step-type',
72
- 'value' => 'optin',
73
- ),
74
- ),
75
- );
76
-
77
- $landing_pages = get_posts( $args );
78
-
79
- if ( is_array( $landing_pages ) && ! empty( $landing_pages ) ) {
80
-
81
- $cartflows_custom_option = '';
82
-
83
- $front_page_id = get_option( 'page_on_front' );
84
-
85
- foreach ( $landing_pages as $key => $landing_page ) {
86
-
87
- $selected = selected( $front_page_id, $landing_page->ID, false );
88
-
89
- $cartflows_custom_option .= "<option value=\"{$landing_page->ID}\"{$selected}>{$landing_page->post_title} ( #{$landing_page->ID} - CartFlows )</option>";
90
- }
91
-
92
- $cartflows_custom_option .= '</select>';
93
-
94
- $output = str_replace( '</select>', $cartflows_custom_option, $output );
95
- }
96
- }
97
-
98
- return $output;
99
- }
100
-
101
- /**
102
- * Set post query.
103
- *
104
- * @param string $query post query.
105
- */
106
- public function wcf_pre_get_posts( $query ) {
107
-
108
- if ( $query->is_main_query() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
109
-
110
- $post_type = $query->get( 'post_type' );
111
-
112
- $page_id = $query->get( 'page_id' );
113
-
114
- if ( empty( $post_type ) && ! empty( $page_id ) ) {
115
- $query->set( 'post_type', get_post_type( $page_id ) );
116
- }
117
- }
118
- }
119
-
120
- /**
121
- * Redirect to homepage if landing page set as home page.
122
- */
123
- public function template_redirect() {
124
-
125
- $compatibiliy = Cartflows_Compatibility::get_instance();
126
-
127
- // Do not redirect for page builder preview.
128
- if ( $compatibiliy->is_page_builder_preview() ) {
129
- return;
130
- }
131
-
132
- global $post;
133
-
134
- if ( is_singular() && ! is_front_page() && get_option( 'page_on_front' ) == $post->ID ) {
135
- wp_safe_redirect( site_url(), 301 );
136
- }
137
- }
138
- }
139
-
140
- /**
141
- * Kicking this off by calling 'get_instance()' method
142
- */
143
- Cartflows_Landing_Markup::get_instance();
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Landing_Markup {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ add_action( 'pre_get_posts', array( $this, 'wcf_pre_get_posts' ) );
39
+ add_action( 'template_redirect', array( $this, 'template_redirect' ) );
40
+
41
+ if ( is_admin() ) {
42
+ add_filter( 'wp_dropdown_pages', array( $this, 'wp_dropdown_pages' ) );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Add landing pages in WordPress reading section.
48
+ *
49
+ * @param array $output output.
50
+ */
51
+ public function wp_dropdown_pages( $output ) {
52
+
53
+ global $pagenow;
54
+
55
+ if ( ( 'options-reading.php' === $pagenow || 'customize.php' === $pagenow ) && preg_match( '#page_on_front#', $output ) ) {
56
+
57
+ $args = array(
58
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
59
+ 'numberposts' => 100,
60
+ 'meta_query' => array( //phpcs:ignore
61
+ 'relation' => 'OR',
62
+ array(
63
+ 'key' => 'wcf-step-type',
64
+ 'value' => 'landing',
65
+ ),
66
+ array(
67
+ 'key' => 'wcf-step-type',
68
+ 'value' => 'checkout',
69
+ ),
70
+ array(
71
+ 'key' => 'wcf-step-type',
72
+ 'value' => 'optin',
73
+ ),
74
+ ),
75
+ );
76
+
77
+ $landing_pages = get_posts( $args );
78
+
79
+ if ( is_array( $landing_pages ) && ! empty( $landing_pages ) ) {
80
+
81
+ $cartflows_custom_option = '';
82
+
83
+ $front_page_id = get_option( 'page_on_front' );
84
+
85
+ foreach ( $landing_pages as $key => $landing_page ) {
86
+
87
+ $selected = selected( $front_page_id, $landing_page->ID, false );
88
+
89
+ $cartflows_custom_option .= "<option value=\"{$landing_page->ID}\"{$selected}>{$landing_page->post_title} ( #{$landing_page->ID} - CartFlows )</option>";
90
+ }
91
+
92
+ $cartflows_custom_option .= '</select>';
93
+
94
+ $output = str_replace( '</select>', $cartflows_custom_option, $output );
95
+ }
96
+ }
97
+
98
+ return $output;
99
+ }
100
+
101
+ /**
102
+ * Set post query.
103
+ *
104
+ * @param string $query post query.
105
+ */
106
+ public function wcf_pre_get_posts( $query ) {
107
+
108
+ if ( $query->is_main_query() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
109
+
110
+ $post_type = $query->get( 'post_type' );
111
+
112
+ $page_id = $query->get( 'page_id' );
113
+
114
+ if ( empty( $post_type ) && ! empty( $page_id ) ) {
115
+ $query->set( 'post_type', get_post_type( $page_id ) );
116
+ }
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Redirect to homepage if landing page set as home page.
122
+ */
123
+ public function template_redirect() {
124
+
125
+ if ( ! wcf()->utils->is_step_post_type() ) {
126
+ return;
127
+ }
128
+
129
+ $compatibiliy = Cartflows_Compatibility::get_instance();
130
+
131
+ // Do not redirect for page builder preview.
132
+ if ( $compatibiliy->is_page_builder_preview() ) {
133
+ return;
134
+ }
135
+
136
+ global $post;
137
+
138
+ if ( is_singular() && ! is_front_page() && get_option( 'page_on_front' ) == $post->ID ) {
139
+ wp_safe_redirect( site_url(), 301 );
140
+ }
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Kicking this off by calling 'get_instance()' method
146
+ */
147
+ Cartflows_Landing_Markup::get_instance();
modules/optin/classes/class-cartflows-optin-markup.php CHANGED
@@ -1,736 +1,736 @@
1
- <?php
2
- /**
3
- * Checkout markup.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Optin_Markup {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var object instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- */
25
- public static function get_instance() {
26
- if ( ! isset( self::$instance ) ) {
27
- self::$instance = new self();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Set is checkout flag */
38
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
-
40
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_optin_fields' ), 10, 2 );
41
-
42
- /* Optin Shortcode */
43
- add_shortcode( 'cartflows_optin', array( $this, 'optin_shortcode_markup' ) );
44
-
45
- /* Preconfigured cart data */
46
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
47
-
48
- /* Optin shortcode data */
49
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 1000 );
50
-
51
- /* Ajax Endpoint */
52
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
53
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
54
-
55
- /* Optin Fields */
56
- add_filter( 'woocommerce_default_address_fields', array( $this, 'set_optin_default_fields' ), 1000 );
57
- /**
58
- * It may required later
59
- * add_filter( 'woocommerce_checkout_fields', array( $this, 'set_optin_fields' ) );
60
- */
61
- add_filter( 'woocommerce_billing_fields', array( $this, 'billing_optin_fields' ), 1000, 2 );
62
-
63
- add_filter( 'woocommerce_checkout_required_field_notice', array( $this, 'change_field_label_in_required_notice' ), 100, 2 );
64
-
65
- add_action( 'init', array( $this, 'remove_login_actions' ) );
66
-
67
- $this->elementor_editor_compatibility();
68
- }
69
-
70
- /**
71
- * Elementor editor compatibility.
72
- */
73
- public function elementor_editor_compatibility() {
74
-
75
- if ( ! empty( $_REQUEST['action'] ) && 'elementor' === $_REQUEST['action'] && is_admin() ) { //phpcs:ignore
76
-
77
- if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) { //phpcs:ignore
78
-
79
- if ( _wcf_check_is_optin_by_id( intval( $_GET['post'] ) ) ) { //phpcs:ignore
80
-
81
- /* Submit Button */
82
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
83
- }
84
- }
85
- }
86
- }
87
-
88
- /**
89
- * Remove login and registration actions.
90
- */
91
- public function remove_login_actions() {
92
-
93
- if ( _is_wcf_doing_optin_ajax() ) {
94
-
95
- if ( isset( $_POST['billing_email'] ) && ! empty( $_POST['billing_email'] ) ) { //phpcs:ignore
96
-
97
- if ( email_exists( sanitize_email( wp_unslash( $_POST['billing_email'] ) ) ) ) { // phpcs:ignore
98
- add_filter( 'woocommerce_checkout_registration_required', '__return_false' );
99
- }
100
- }
101
-
102
- add_filter( 'woocommerce_checkout_registration_enabled', '__return_false' );
103
- }
104
- }
105
-
106
- /**
107
- * Change order button text .
108
- *
109
- * @param string $woo_button_text place order.
110
- * @return string
111
- */
112
- public function place_order_button_text( $woo_button_text ) {
113
-
114
- $optin_id = get_the_ID();
115
-
116
- $wcf_order_button_text = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-text' );
117
-
118
- if ( ! empty( $wcf_order_button_text ) ) {
119
- $woo_button_text = $wcf_order_button_text;
120
- }
121
-
122
- return $woo_button_text;
123
- }
124
-
125
- /**
126
- * Display all WooCommerce notices.
127
- *
128
- * @since 1.1.5
129
- */
130
- public function display_woo_notices() {
131
-
132
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
133
- woocommerce_output_all_notices();
134
- }
135
- }
136
-
137
- /**
138
- * Check for checkout flag
139
- *
140
- * @param bool $is_checkout is checkout.
141
- *
142
- * @return bool
143
- */
144
- public function woo_checkout_flag( $is_checkout ) {
145
-
146
- if ( ! is_admin() ) {
147
-
148
- if ( _is_wcf_optin_type() ) {
149
-
150
- $is_checkout = true;
151
- }
152
- }
153
-
154
- return $is_checkout;
155
- }
156
-
157
- /**
158
- * Render checkout shortcode markup.
159
- *
160
- * @param array $atts attributes.
161
- * @return string
162
- */
163
- public function optin_shortcode_markup( $atts ) {
164
-
165
- if ( ! function_exists( 'wc_print_notices' ) ) {
166
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
167
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
168
-
169
- return $notice_out;
170
- }
171
-
172
- $atts = shortcode_atts(
173
- array(
174
- 'id' => 0,
175
- ),
176
- $atts
177
- );
178
-
179
- $optin_id = intval( $atts['id'] );
180
-
181
- if ( empty( $optin_id ) ) {
182
-
183
- if ( ! _is_wcf_optin_type() ) {
184
-
185
- return '<h4>' . __( 'Please place shortcode on Optin step-type only.', 'cartflows' ) . '</h4>';
186
- }
187
-
188
- global $post;
189
-
190
- $optin_id = intval( $post->ID );
191
- }
192
-
193
- $output = '';
194
-
195
- ob_start();
196
-
197
- do_action( 'cartflows_optin_form_before', $optin_id );
198
-
199
- $optin_layout = 'default';
200
-
201
- $template_default = CARTFLOWS_OPTIN_DIR . 'templates/optin-template-simple.php';
202
-
203
- include $template_default;
204
-
205
- $output .= ob_get_clean();
206
-
207
- return $output;
208
- }
209
-
210
- /**
211
- * Configure Cart Data.
212
- *
213
- * @since 1.0.0
214
- *
215
- * @return void
216
- */
217
- public function preconfigured_cart_data() {
218
-
219
- if ( is_admin() ) {
220
- return;
221
- }
222
-
223
- global $post;
224
-
225
- if ( _is_wcf_optin_type() ) {
226
-
227
- if ( wp_doing_ajax() ) {
228
- return;
229
- } else {
230
-
231
- $optin_id = $post->ID;
232
-
233
- do_action( 'cartflows_optin_before_configure_cart', $optin_id );
234
-
235
- $products = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-product' );
236
-
237
- if ( ! is_array( $products ) ) {
238
- return;
239
- }
240
-
241
- /* Empty the current cart */
242
- WC()->cart->empty_cart();
243
-
244
- if ( is_array( $products ) && count( $products ) < 1 ) {
245
- wc_add_notice( __( 'No product is selected. Please select a Simple, Virtual and Free product from the meta settings.', 'cartflows' ), 'error' );
246
- return;
247
- }
248
-
249
- /* Set customer session if not set */
250
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
251
- WC()->session->set_customer_session_cookie( true );
252
- }
253
-
254
- $product_id = reset( $products );
255
- $_product = wc_get_product( $product_id );
256
-
257
- if ( ! empty( $_product ) ) {
258
-
259
- if ( $_product->is_type( 'simple' ) && $_product->is_virtual() ) {
260
-
261
- if ( $_product->get_price() > 0 ) {
262
- wc_add_notice( __( 'Please update the selected product\'s price to zero (0).', 'cartflows' ), 'error' );
263
- } else {
264
-
265
- $quantity = 1;
266
-
267
- WC()->cart->add_to_cart( $product_id, $quantity );
268
- }
269
- } else {
270
-
271
- wc_add_notice( __( 'Please select a Simple, Virtual and Free product.', 'cartflows' ), 'error' );
272
- }
273
- } else {
274
-
275
- wc_add_notice( __( 'Please select a Simple, Virtual and Free product.', 'cartflows' ), 'error' );
276
- }
277
-
278
- do_action( 'cartflows_optin_after_configure_cart', $optin_id );
279
- }
280
- }
281
- }
282
-
283
- /**
284
- * Load shortcode data.
285
- *
286
- * @return void
287
- */
288
- public function shortcode_load_data() {
289
-
290
- if ( _is_wcf_optin_type() ) {
291
-
292
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
293
-
294
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
295
-
296
- /* Show notices if cart has errors */
297
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
298
-
299
- // Outputting the hidden field in checkout page.
300
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
301
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
302
-
303
- /* Remove unnecessary option */
304
- add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
305
- add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false' );
306
-
307
- remove_all_actions( 'woocommerce_before_checkout_form' );
308
- remove_all_actions( 'woocommerce_checkout_billing' );
309
- remove_all_actions( 'woocommerce_checkout_shipping' );
310
- remove_all_actions( 'woocommerce_checkout_before_order_review' );
311
- remove_all_actions( 'woocommerce_checkout_order_review' );
312
- remove_all_actions( 'woocommerce_checkout_after_order_review' );
313
- add_filter( 'woocommerce_cart_needs_payment', '__return_false' );
314
- add_filter( 'woocommerce_available_payment_gateways', array( $this, 'disable_payment_gateways' ) );
315
-
316
- /* Paypal Expresss remove */
317
-
318
- if ( function_exists( 'wc_gateway_ppec' ) ) {
319
- remove_action( 'wp_enqueue_scripts', array( wc_gateway_ppec()->cart, 'enqueue_scripts' ) );
320
- }
321
-
322
- // Hook in actions once.
323
- add_action( 'woocommerce_before_checkout_form', 'woocommerce_output_all_notices', 10 );
324
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
325
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
326
- add_action( 'woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 20 );
327
-
328
- /* Submit Button */
329
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
330
-
331
- add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', '__return_false' );
332
-
333
- /* Remove login actions */
334
- add_filter( 'woocommerce_checkout_registration_enabled', '__return_false' );
335
- add_filter( 'woocommerce_checkout_registration_required', '__return_false' );
336
-
337
- global $post;
338
-
339
- $optin_id = $post->ID;
340
-
341
- do_action( 'cartflows_optin_before_shortcode', $optin_id );
342
- }
343
- }
344
-
345
- /**
346
- * Disable payment gateways.
347
- *
348
- * @param array $available_gateways gateways.
349
- * @return array
350
- */
351
- public function disable_payment_gateways( $available_gateways ) {
352
-
353
- if ( ! is_admin() ) {
354
-
355
- $available_gateways = array();
356
- }
357
-
358
- return $available_gateways;
359
- }
360
-
361
- /**
362
- * Render checkout ID hidden field.
363
- *
364
- * @param array $checkout checkout session data.
365
- * @return void
366
- */
367
- public function checkout_shortcode_post_id( $checkout ) {
368
-
369
- if ( ! _is_wcf_optin_type() ) {
370
- return;
371
- }
372
-
373
- global $post;
374
-
375
- $optin_id = $post->ID;
376
-
377
- $flow_id = get_post_meta( $optin_id, 'wcf-flow-id', true );
378
-
379
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
380
- echo '<input type="hidden" class="input-hidden _wcf_optin_id" name="_wcf_optin_id" value="' . intval( $optin_id ) . '">';
381
- }
382
-
383
- /**
384
- * Load shortcode scripts.
385
- *
386
- * @return void
387
- */
388
- public function shortcode_scripts() {
389
-
390
- wp_enqueue_style( 'wcf-optin-template', wcf()->utils->get_css_url( 'optin-template' ), '', CARTFLOWS_VER );
391
-
392
- wp_enqueue_script(
393
- 'wcf-optin-template',
394
- wcf()->utils->get_js_url( 'optin-template' ),
395
- array( 'jquery' ),
396
- CARTFLOWS_VER,
397
- true
398
- );
399
-
400
- do_action( 'cartflows_optin_scripts' );
401
-
402
- $style = $this->generate_style();
403
-
404
- wp_add_inline_style( 'wcf-optin-template', $style );
405
- }
406
-
407
- /**
408
- * Load compatibility scripts.
409
- *
410
- * @return void
411
- */
412
- public function compatibility_scripts() {
413
-
414
- global $post;
415
-
416
- $optin_id = $post->ID;
417
-
418
- // Add DIVI Compatibility css if DIVI theme is enabled.
419
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
420
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $optin_id )
421
- ) {
422
- wp_enqueue_style( 'wcf-optin-template-divi', wcf()->utils->get_css_url( 'optin-template-divi' ), '', CARTFLOWS_VER );
423
- }
424
- }
425
-
426
- /**
427
- * Generate styles.
428
- *
429
- * @return string
430
- */
431
- public function generate_style() {
432
-
433
- global $post;
434
-
435
- $optin_id = $post->ID;
436
-
437
- /* Load all fonts */
438
- CartFlows_Font_Families::render_fonts( $optin_id );
439
-
440
- $r = '';
441
- $g = '';
442
- $b = '';
443
- $output = '';
444
-
445
- /* Global */
446
- $primary_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-primary-color' );
447
- $base_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-base-font-family' );
448
-
449
- /* Input Fields */
450
- $input_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-font-family' );
451
- $input_font_weight = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-font-weight' );
452
- $field_input_size = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-field-size' );
453
- $field_tb_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-tb-padding' );
454
- $field_lr_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-lr-padding' );
455
- $field_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-color' );
456
- $field_bg_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-bg-color' );
457
- $field_border_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-border-color' );
458
- $field_label_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-label-color' );
459
-
460
- if ( 'custom' == $field_input_size ) {
461
- $field_input_size = '38px';
462
- }
463
-
464
- /* Submit Button */
465
- $submit_button_width = '100%';
466
- $optin_button_position = '';
467
- $button_font_size = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-font-size' );
468
- $button_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-button-font-family' );
469
- $button_font_weight = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-button-font-weight' );
470
- $submit_button_height = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-size' );
471
- $submit_tb_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-tb-padding' );
472
- $submit_lr_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-lr-padding' );
473
- $submit_button_position = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-position' );
474
- $submit_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-color' );
475
- $submit_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-hover-color' );
476
- $submit_bg_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-bg-color', $primary_color );
477
- $submit_bg_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-bg-hover-color', $primary_color );
478
- $submit_border_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-border-color', $primary_color );
479
- $submit_border_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-border-hover-color', $primary_color );
480
-
481
- if ( 'custom' == $submit_button_height ) {
482
- $submit_button_height = '38px';
483
- $submit_button_width = 'auto';
484
-
485
- switch ( $submit_button_position ) {
486
- case 'left':
487
- $optin_button_position = '0 auto 0 0';
488
- break;
489
- case 'center':
490
- $optin_button_position = '0 auto';
491
- break;
492
- case 'right':
493
- $optin_button_position = '0 0 0 auto';
494
- break;
495
-
496
- default:
497
- $optin_button_position = '0 auto';
498
- break;
499
- }
500
- }
501
-
502
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
503
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $optin_id ) ) {
504
-
505
- include CARTFLOWS_OPTIN_DIR . 'includes/optin-dynamic-divi-css.php';
506
-
507
- } else {
508
- include CARTFLOWS_OPTIN_DIR . 'includes/optin-dynamic-css.php';
509
- }
510
-
511
- return $output;
512
- }
513
-
514
- /**
515
- * Get ajax end points.
516
- *
517
- * @param string $endpoint_url end point URL.
518
- * @param string $request end point request.
519
- * @return string
520
- */
521
- public function get_ajax_endpoint( $endpoint_url, $request ) {
522
-
523
- global $post;
524
-
525
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
526
-
527
- if ( _is_wcf_optin_type() ) {
528
-
529
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
530
-
531
- if ( '' === $request ) {
532
- $query_args = array(
533
- 'wc-ajax' => '%%endpoint%%',
534
- );
535
- } else {
536
- $query_args = array(
537
- 'wc-ajax' => $request,
538
- );
539
- }
540
-
541
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
542
- $uri = $uri[0];
543
-
544
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
545
- }
546
- }
547
- }
548
-
549
- return $endpoint_url;
550
- }
551
-
552
-
553
- /**
554
- * Save checkout fields.
555
- *
556
- * @param int $order_id order id.
557
- * @param array $posted posted data.
558
- * @return void
559
- */
560
- public function save_optin_fields( $order_id, $posted ) {
561
-
562
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
563
-
564
- $optin_id = wc_clean( wp_unslash( $_POST['_wcf_optin_id'] ) ); //phpcs:ignore
565
-
566
- update_post_meta( $order_id, '_wcf_optin_id', $optin_id );
567
-
568
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
569
-
570
- $flow_id = wc_clean( wp_unslash( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
571
-
572
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
573
- }
574
- }
575
-
576
- }
577
-
578
- /**
579
- * Redirect users to our checkout if hidden param
580
- *
581
- * @param string $redirect redirect url.
582
- * @param object $user user.
583
- * @return string
584
- */
585
- public function after_login_redirect( $redirect, $user ) {
586
-
587
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
588
-
589
- $optin_id = intval( $_POST['_wcf_optin_id'] ); //phpcs:ignore
590
-
591
- $redirect = get_permalink( $optin_id );
592
- }
593
-
594
- return $redirect;
595
- }
596
-
597
-
598
- /**
599
- * Add custom class to the fields to change the UI to three column.
600
- *
601
- * @param array $fields fields.
602
- */
603
- public function set_optin_default_fields( $fields ) {
604
-
605
- if ( _is_wcf_optin_type() ) {
606
-
607
- global $post;
608
-
609
- $optin_id = $post->ID;
610
- } else {
611
-
612
- if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
613
-
614
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
615
- } else {
616
- return $fields;
617
- }
618
- }
619
-
620
- $first_name = $fields['first_name'];
621
- $last_name = $fields['last_name'];
622
-
623
- /* Make fields required */
624
- $first_name['required'] = true;
625
- $last_name['required'] = true;
626
-
627
- $fields = array(
628
- 'first_name' => $first_name,
629
- 'last_name' => $last_name,
630
- );
631
-
632
- return apply_filters( 'cartflows_optin_default_fields', $fields, $optin_id );
633
- }
634
-
635
- /**
636
- * Add custom class to the fields to change the UI to three column.
637
- *
638
- * @param array $fields fields.
639
- */
640
- public function set_optin_fields( $fields ) {
641
-
642
- if ( _is_wcf_optin_type() ) {
643
-
644
- global $post;
645
-
646
- $optin_id = $post->ID;
647
- } else {
648
-
649
- if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
650
-
651
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
652
- } else {
653
- return $fields;
654
- }
655
- }
656
-
657
- $billing_first_name = $fields['billing']['billing_first_name'];
658
- $billing_last_name = $fields['billing']['billing_last_name'];
659
- $billing_email = $fields['billing']['billing_email'];
660
-
661
- $fields['billing'] = array(
662
- 'billing_first_name' => $billing_first_name,
663
- 'billing_last_name' => $billing_last_name,
664
- 'billing_email' => $billing_email,
665
- );
666
-
667
- return apply_filters( 'cartflows_optin_fields', $fields, $optin_id );
668
- }
669
-
670
- /**
671
- * Billing field customization.
672
- *
673
- * @param array $fields fields data.
674
- * @param string $country country name.
675
- * @return array
676
- */
677
- public function billing_optin_fields( $fields, $country ) {
678
-
679
- if ( _is_wcf_optin_type() ) {
680
-
681
- global $post;
682
-
683
- $optin_id = $post->ID;
684
- } else {
685
-
686
- if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
687
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
688
- } else {
689
- return $fields;
690
- }
691
- }
692
-
693
- if ( is_wc_endpoint_url( 'edit-address' ) ) {
694
- return $fields;
695
- }
696
-
697
- $billing_first_name = $fields['billing_first_name'];
698
- $billing_last_name = $fields['billing_last_name'];
699
- $billing_email = $fields['billing_email'];
700
-
701
- /* Make fields required */
702
- $billing_first_name['required'] = true;
703
- $billing_last_name['required'] = true;
704
-
705
- $fields = array(
706
- 'billing_first_name' => $billing_first_name,
707
- 'billing_last_name' => $billing_last_name,
708
- 'billing_email' => $billing_email,
709
- );
710
-
711
- return apply_filters( 'cartflows_billing_optin_fields', $fields, $country, $optin_id );
712
- }
713
-
714
-
715
- /**
716
- * Replace billing label.
717
- *
718
- * @param string $notice Notice.
719
- * @param string $field_label Field name.
720
- * @return string
721
- */
722
- public function change_field_label_in_required_notice( $notice, $field_label ) {
723
-
724
- if ( _is_wcf_doing_optin_ajax() ) {
725
-
726
- $notice = str_replace( 'Billing ', '', $notice );
727
- }
728
-
729
- return $notice;
730
- }
731
- }
732
-
733
- /**
734
- * Kicking this off by calling 'get_instance()' method
735
- */
736
- Cartflows_Optin_Markup::get_instance();
1
+ <?php
2
+ /**
3
+ * Checkout markup.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Optin_Markup {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var object instance
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Initiator
24
+ */
25
+ public static function get_instance() {
26
+ if ( ! isset( self::$instance ) ) {
27
+ self::$instance = new self();
28
+ }
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Set is checkout flag */
38
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
+
40
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_optin_fields' ), 10, 2 );
41
+
42
+ /* Optin Shortcode */
43
+ add_shortcode( 'cartflows_optin', array( $this, 'optin_shortcode_markup' ) );
44
+
45
+ /* Preconfigured cart data */
46
+ add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
47
+
48
+ /* Optin shortcode data */
49
+ add_action( 'wp', array( $this, 'shortcode_load_data' ), 1000 );
50
+
51
+ /* Ajax Endpoint */
52
+ add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
53
+ add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
54
+
55
+ /* Optin Fields */
56
+ add_filter( 'woocommerce_default_address_fields', array( $this, 'set_optin_default_fields' ), 1000 );
57
+ /**
58
+ * It may required later
59
+ * add_filter( 'woocommerce_checkout_fields', array( $this, 'set_optin_fields' ) );
60
+ */
61
+ add_filter( 'woocommerce_billing_fields', array( $this, 'billing_optin_fields' ), 1000, 2 );
62
+
63
+ add_filter( 'woocommerce_checkout_required_field_notice', array( $this, 'change_field_label_in_required_notice' ), 100, 2 );
64
+
65
+ add_action( 'init', array( $this, 'remove_login_actions' ) );
66
+
67
+ $this->elementor_editor_compatibility();
68
+ }
69
+
70
+ /**
71
+ * Elementor editor compatibility.
72
+ */
73
+ public function elementor_editor_compatibility() {
74
+
75
+ if ( ! empty( $_REQUEST['action'] ) && 'elementor' === $_REQUEST['action'] && is_admin() ) { //phpcs:ignore
76
+
77
+ if ( isset( $_GET['post'] ) && ! empty( $_GET['post'] ) ) { //phpcs:ignore
78
+
79
+ if ( _wcf_check_is_optin_by_id( intval( $_GET['post'] ) ) ) { //phpcs:ignore
80
+
81
+ /* Submit Button */
82
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Remove login and registration actions.
90
+ */
91
+ public function remove_login_actions() {
92
+
93
+ if ( _is_wcf_doing_optin_ajax() ) {
94
+
95
+ if ( isset( $_POST['billing_email'] ) && ! empty( $_POST['billing_email'] ) ) { //phpcs:ignore
96
+
97
+ if ( email_exists( sanitize_email( wp_unslash( $_POST['billing_email'] ) ) ) ) { // phpcs:ignore
98
+ add_filter( 'woocommerce_checkout_registration_required', '__return_false' );
99
+ }
100
+ }
101
+
102
+ add_filter( 'woocommerce_checkout_registration_enabled', '__return_false' );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Change order button text .
108
+ *
109
+ * @param string $woo_button_text place order.
110
+ * @return string
111
+ */
112
+ public function place_order_button_text( $woo_button_text ) {
113
+
114
+ $optin_id = get_the_ID();
115
+
116
+ $wcf_order_button_text = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-text' );
117
+
118
+ if ( ! empty( $wcf_order_button_text ) ) {
119
+ $woo_button_text = $wcf_order_button_text;
120
+ }
121
+
122
+ return $woo_button_text;
123
+ }
124
+
125
+ /**
126
+ * Display all WooCommerce notices.
127
+ *
128
+ * @since 1.1.5
129
+ */
130
+ public function display_woo_notices() {
131
+
132
+ if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
133
+ woocommerce_output_all_notices();
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Check for checkout flag
139
+ *
140
+ * @param bool $is_checkout is checkout.
141
+ *
142
+ * @return bool
143
+ */
144
+ public function woo_checkout_flag( $is_checkout ) {
145
+
146
+ if ( ! is_admin() ) {
147
+
148
+ if ( _is_wcf_optin_type() ) {
149
+
150
+ $is_checkout = true;
151
+ }
152
+ }
153
+
154
+ return $is_checkout;
155
+ }
156
+
157
+ /**
158
+ * Render checkout shortcode markup.
159
+ *
160
+ * @param array $atts attributes.
161
+ * @return string
162
+ */
163
+ public function optin_shortcode_markup( $atts ) {
164
+
165
+ if ( ! function_exists( 'wc_print_notices' ) ) {
166
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
167
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
168
+
169
+ return $notice_out;
170
+ }
171
+
172
+ $atts = shortcode_atts(
173
+ array(
174
+ 'id' => 0,
175
+ ),
176
+ $atts
177
+ );
178
+
179
+ $optin_id = intval( $atts['id'] );
180
+
181
+ if ( empty( $optin_id ) ) {
182
+
183
+ if ( ! _is_wcf_optin_type() ) {
184
+
185
+ return '<h4>' . __( 'Please place shortcode on Optin step-type only.', 'cartflows' ) . '</h4>';
186
+ }
187
+
188
+ global $post;
189
+
190
+ $optin_id = intval( $post->ID );
191
+ }
192
+
193
+ $output = '';
194
+
195
+ ob_start();
196
+
197
+ do_action( 'cartflows_optin_form_before', $optin_id );
198
+
199
+ $optin_layout = 'default';
200
+
201
+ $template_default = CARTFLOWS_OPTIN_DIR . 'templates/optin-template-simple.php';
202
+
203
+ include $template_default;
204
+
205
+ $output .= ob_get_clean();
206
+
207
+ return $output;
208
+ }
209
+
210
+ /**
211
+ * Configure Cart Data.
212
+ *
213
+ * @since 1.0.0
214
+ *
215
+ * @return void
216
+ */
217
+ public function preconfigured_cart_data() {
218
+
219
+ if ( is_admin() ) {
220
+ return;
221
+ }
222
+
223
+ global $post;
224
+
225
+ if ( _is_wcf_optin_type() ) {
226
+
227
+ if ( wp_doing_ajax() ) {
228
+ return;
229
+ } else {
230
+
231
+ $optin_id = $post->ID;
232
+
233
+ do_action( 'cartflows_optin_before_configure_cart', $optin_id );
234
+
235
+ $products = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-product' );
236
+
237
+ if ( ! is_array( $products ) ) {
238
+ return;
239
+ }
240
+
241
+ /* Empty the current cart */
242
+ WC()->cart->empty_cart();
243
+
244
+ if ( is_array( $products ) && count( $products ) < 1 ) {
245
+ wc_add_notice( __( 'No product is selected. Please select a Simple, Virtual and Free product from the meta settings.', 'cartflows' ), 'error' );
246
+ return;
247
+ }
248
+
249
+ /* Set customer session if not set */
250
+ if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
251
+ WC()->session->set_customer_session_cookie( true );
252
+ }
253
+
254
+ $product_id = reset( $products );
255
+ $_product = wc_get_product( $product_id );
256
+
257
+ if ( ! empty( $_product ) ) {
258
+
259
+ if ( $_product->is_type( 'simple' ) && $_product->is_virtual() ) {
260
+
261
+ if ( $_product->get_price() > 0 ) {
262
+ wc_add_notice( __( 'Please update the selected product\'s price to zero (0).', 'cartflows' ), 'error' );
263
+ } else {
264
+
265
+ $quantity = 1;
266
+
267
+ WC()->cart->add_to_cart( $product_id, $quantity );
268
+ }
269
+ } else {
270
+
271
+ wc_add_notice( __( 'Please select a Simple, Virtual and Free product.', 'cartflows' ), 'error' );
272
+ }
273
+ } else {
274
+
275
+ wc_add_notice( __( 'Please select a Simple, Virtual and Free product.', 'cartflows' ), 'error' );
276
+ }
277
+
278
+ do_action( 'cartflows_optin_after_configure_cart', $optin_id );
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Load shortcode data.
285
+ *
286
+ * @return void
287
+ */
288
+ public function shortcode_load_data() {
289
+
290
+ if ( _is_wcf_optin_type() ) {
291
+
292
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
293
+
294
+ add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
295
+
296
+ /* Show notices if cart has errors */
297
+ add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
298
+
299
+ // Outputting the hidden field in checkout page.
300
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
301
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
302
+
303
+ /* Remove unnecessary option */
304
+ add_filter( 'woocommerce_enable_order_notes_field', '__return_false' );
305
+ add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false' );
306
+
307
+ remove_all_actions( 'woocommerce_before_checkout_form' );
308
+ remove_all_actions( 'woocommerce_checkout_billing' );
309
+ remove_all_actions( 'woocommerce_checkout_shipping' );
310
+ remove_all_actions( 'woocommerce_checkout_before_order_review' );
311
+ remove_all_actions( 'woocommerce_checkout_order_review' );
312
+ remove_all_actions( 'woocommerce_checkout_after_order_review' );
313
+ add_filter( 'woocommerce_cart_needs_payment', '__return_false' );
314
+ add_filter( 'woocommerce_available_payment_gateways', array( $this, 'disable_payment_gateways' ) );
315
+
316
+ /* Paypal Expresss remove */
317
+
318
+ if ( function_exists( 'wc_gateway_ppec' ) ) {
319
+ remove_action( 'wp_enqueue_scripts', array( wc_gateway_ppec()->cart, 'enqueue_scripts' ) );
320
+ }
321
+
322
+ // Hook in actions once.
323
+ add_action( 'woocommerce_before_checkout_form', 'woocommerce_output_all_notices', 10 );
324
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
325
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
326
+ add_action( 'woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 20 );
327
+
328
+ /* Submit Button */
329
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
330
+
331
+ add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', '__return_false' );
332
+
333
+ /* Remove login actions */
334
+ add_filter( 'woocommerce_checkout_registration_enabled', '__return_false' );
335
+ add_filter( 'woocommerce_checkout_registration_required', '__return_false' );
336
+
337
+ global $post;
338
+
339
+ $optin_id = $post->ID;
340
+
341
+ do_action( 'cartflows_optin_before_shortcode', $optin_id );
342
+ }
343
+ }
344
+
345
+ /**
346
+ * Disable payment gateways.
347
+ *
348
+ * @param array $available_gateways gateways.
349
+ * @return array
350
+ */
351
+ public function disable_payment_gateways( $available_gateways ) {
352
+
353
+ if ( ! is_admin() ) {
354
+
355
+ $available_gateways = array();
356
+ }
357
+
358
+ return $available_gateways;
359
+ }
360
+
361
+ /**
362
+ * Render checkout ID hidden field.
363
+ *
364
+ * @param array $checkout checkout session data.
365
+ * @return void
366
+ */
367
+ public function checkout_shortcode_post_id( $checkout ) {
368
+
369
+ if ( ! _is_wcf_optin_type() ) {
370
+ return;
371
+ }
372
+
373
+ global $post;
374
+
375
+ $optin_id = $post->ID;
376
+
377
+ $flow_id = get_post_meta( $optin_id, 'wcf-flow-id', true );
378
+
379
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
380
+ echo '<input type="hidden" class="input-hidden _wcf_optin_id" name="_wcf_optin_id" value="' . intval( $optin_id ) . '">';
381
+ }
382
+
383
+ /**
384
+ * Load shortcode scripts.
385
+ *
386
+ * @return void
387
+ */
388
+ public function shortcode_scripts() {
389
+
390
+ wp_enqueue_style( 'wcf-optin-template', wcf()->utils->get_css_url( 'optin-template' ), '', CARTFLOWS_VER );
391
+
392
+ wp_enqueue_script(
393
+ 'wcf-optin-template',
394
+ wcf()->utils->get_js_url( 'optin-template' ),
395
+ array( 'jquery' ),
396
+ CARTFLOWS_VER,
397
+ true
398
+ );
399
+
400
+ do_action( 'cartflows_optin_scripts' );
401
+
402
+ $style = $this->generate_style();
403
+
404
+ wp_add_inline_style( 'wcf-optin-template', $style );
405
+ }
406
+
407
+ /**
408
+ * Load compatibility scripts.
409
+ *
410
+ * @return void
411
+ */
412
+ public function compatibility_scripts() {
413
+
414
+ global $post;
415
+
416
+ $optin_id = $post->ID;
417
+
418
+ // Add DIVI Compatibility css if DIVI theme is enabled.
419
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
420
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $optin_id )
421
+ ) {
422
+ wp_enqueue_style( 'wcf-optin-template-divi', wcf()->utils->get_css_url( 'optin-template-divi' ), '', CARTFLOWS_VER );
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Generate styles.
428
+ *
429
+ * @return string
430
+ */
431
+ public function generate_style() {
432
+
433
+ global $post;
434
+
435
+ $optin_id = $post->ID;
436
+
437
+ /* Load all fonts */
438
+ CartFlows_Font_Families::render_fonts( $optin_id );
439
+
440
+ $r = '';
441
+ $g = '';
442
+ $b = '';
443
+ $output = '';
444
+
445
+ /* Global */
446
+ $primary_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-primary-color' );
447
+ $base_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-base-font-family' );
448
+
449
+ /* Input Fields */
450
+ $input_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-font-family' );
451
+ $input_font_weight = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-font-weight' );
452
+ $field_input_size = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-input-field-size' );
453
+ $field_tb_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-tb-padding' );
454
+ $field_lr_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-lr-padding' );
455
+ $field_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-color' );
456
+ $field_bg_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-bg-color' );
457
+ $field_border_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-border-color' );
458
+ $field_label_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-field-label-color' );
459
+
460
+ if ( 'custom' == $field_input_size ) {
461
+ $field_input_size = '38px';
462
+ }
463
+
464
+ /* Submit Button */
465
+ $submit_button_width = '100%';
466
+ $optin_button_position = '';
467
+ $button_font_size = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-font-size' );
468
+ $button_font_family = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-button-font-family' );
469
+ $button_font_weight = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-button-font-weight' );
470
+ $submit_button_height = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-size' );
471
+ $submit_tb_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-tb-padding' );
472
+ $submit_lr_padding = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-lr-padding' );
473
+ $submit_button_position = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-button-position' );
474
+ $submit_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-color' );
475
+ $submit_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-hover-color' );
476
+ $submit_bg_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-bg-color', $primary_color );
477
+ $submit_bg_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-bg-hover-color', $primary_color );
478
+ $submit_border_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-border-color', $primary_color );
479
+ $submit_border_hover_color = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-submit-border-hover-color', $primary_color );
480
+
481
+ if ( 'custom' == $submit_button_height ) {
482
+ $submit_button_height = '38px';
483
+ $submit_button_width = 'auto';
484
+
485
+ switch ( $submit_button_position ) {
486
+ case 'left':
487
+ $optin_button_position = '0 auto 0 0';
488
+ break;
489
+ case 'center':
490
+ $optin_button_position = '0 auto';
491
+ break;
492
+ case 'right':
493
+ $optin_button_position = '0 0 0 auto';
494
+ break;
495
+
496
+ default:
497
+ $optin_button_position = '0 auto';
498
+ break;
499
+ }
500
+ }
501
+
502
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
503
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $optin_id ) ) {
504
+
505
+ include CARTFLOWS_OPTIN_DIR . 'includes/optin-dynamic-divi-css.php';
506
+
507
+ } else {
508
+ include CARTFLOWS_OPTIN_DIR . 'includes/optin-dynamic-css.php';
509
+ }
510
+
511
+ return $output;
512
+ }
513
+
514
+ /**
515
+ * Get ajax end points.
516
+ *
517
+ * @param string $endpoint_url end point URL.
518
+ * @param string $request end point request.
519
+ * @return string
520
+ */
521
+ public function get_ajax_endpoint( $endpoint_url, $request ) {
522
+
523
+ global $post;
524
+
525
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
526
+
527
+ if ( _is_wcf_optin_type() ) {
528
+
529
+ if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
530
+
531
+ if ( '' === $request ) {
532
+ $query_args = array(
533
+ 'wc-ajax' => '%%endpoint%%',
534
+ );
535
+ } else {
536
+ $query_args = array(
537
+ 'wc-ajax' => $request,
538
+ );
539
+ }
540
+
541
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
542
+ $uri = $uri[0];
543
+
544
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
545
+ }
546
+ }
547
+ }
548
+
549
+ return $endpoint_url;
550
+ }
551
+
552
+
553
+ /**
554
+ * Save checkout fields.
555
+ *
556
+ * @param int $order_id order id.
557
+ * @param array $posted posted data.
558
+ * @return void
559
+ */
560
+ public function save_optin_fields( $order_id, $posted ) {
561
+
562
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
563
+
564
+ $optin_id = wc_clean( wp_unslash( $_POST['_wcf_optin_id'] ) ); //phpcs:ignore
565
+
566
+ update_post_meta( $order_id, '_wcf_optin_id', $optin_id );
567
+
568
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
569
+
570
+ $flow_id = wc_clean( wp_unslash( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
571
+
572
+ update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
573
+ }
574
+ }
575
+
576
+ }
577
+
578
+ /**
579
+ * Redirect users to our checkout if hidden param
580
+ *
581
+ * @param string $redirect redirect url.
582
+ * @param object $user user.
583
+ * @return string
584
+ */
585
+ public function after_login_redirect( $redirect, $user ) {
586
+
587
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
588
+
589
+ $optin_id = intval( $_POST['_wcf_optin_id'] ); //phpcs:ignore
590
+
591
+ $redirect = get_permalink( $optin_id );
592
+ }
593
+
594
+ return $redirect;
595
+ }
596
+
597
+
598
+ /**
599
+ * Add custom class to the fields to change the UI to three column.
600
+ *
601
+ * @param array $fields fields.
602
+ */
603
+ public function set_optin_default_fields( $fields ) {
604
+
605
+ if ( _is_wcf_optin_type() ) {
606
+
607
+ global $post;
608
+
609
+ $optin_id = $post->ID;
610
+ } else {
611
+
612
+ if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
613
+
614
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
615
+ } else {
616
+ return $fields;
617
+ }
618
+ }
619
+
620
+ $first_name = $fields['first_name'];
621
+ $last_name = $fields['last_name'];
622
+
623
+ /* Make fields required */
624
+ $first_name['required'] = true;
625
+ $last_name['required'] = true;
626
+
627
+ $fields = array(
628
+ 'first_name' => $first_name,
629
+ 'last_name' => $last_name,
630
+ );
631
+
632
+ return apply_filters( 'cartflows_optin_default_fields', $fields, $optin_id );
633
+ }
634
+
635
+ /**
636
+ * Add custom class to the fields to change the UI to three column.
637
+ *
638
+ * @param array $fields fields.
639
+ */
640
+ public function set_optin_fields( $fields ) {
641
+
642
+ if ( _is_wcf_optin_type() ) {
643
+
644
+ global $post;
645
+
646
+ $optin_id = $post->ID;
647
+ } else {
648
+
649
+ if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
650
+
651
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
652
+ } else {
653
+ return $fields;
654
+ }
655
+ }
656
+
657
+ $billing_first_name = $fields['billing']['billing_first_name'];
658
+ $billing_last_name = $fields['billing']['billing_last_name'];
659
+ $billing_email = $fields['billing']['billing_email'];
660
+
661
+ $fields['billing'] = array(
662
+ 'billing_first_name' => $billing_first_name,
663
+ 'billing_last_name' => $billing_last_name,
664
+ 'billing_email' => $billing_email,
665
+ );
666
+
667
+ return apply_filters( 'cartflows_optin_fields', $fields, $optin_id );
668
+ }
669
+
670
+ /**
671
+ * Billing field customization.
672
+ *
673
+ * @param array $fields fields data.
674
+ * @param string $country country name.
675
+ * @return array
676
+ */
677
+ public function billing_optin_fields( $fields, $country ) {
678
+
679
+ if ( _is_wcf_optin_type() ) {
680
+
681
+ global $post;
682
+
683
+ $optin_id = $post->ID;
684
+ } else {
685
+
686
+ if ( _is_wcf_doing_optin_ajax() && wcf()->utils->get_optin_id_from_post_data() ) {
687
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
688
+ } else {
689
+ return $fields;
690
+ }
691
+ }
692
+
693
+ if ( is_wc_endpoint_url( 'edit-address' ) ) {
694
+ return $fields;
695
+ }
696
+
697
+ $billing_first_name = $fields['billing_first_name'];
698
+ $billing_last_name = $fields['billing_last_name'];
699
+ $billing_email = $fields['billing_email'];
700
+
701
+ /* Make fields required */
702
+ $billing_first_name['required'] = true;
703
+ $billing_last_name['required'] = true;
704
+
705
+ $fields = array(
706
+ 'billing_first_name' => $billing_first_name,
707
+ 'billing_last_name' => $billing_last_name,
708
+ 'billing_email' => $billing_email,
709
+ );
710
+
711
+ return apply_filters( 'cartflows_billing_optin_fields', $fields, $country, $optin_id );
712
+ }
713
+
714
+
715
+ /**
716
+ * Replace billing label.
717
+ *
718
+ * @param string $notice Notice.
719
+ * @param string $field_label Field name.
720
+ * @return string
721
+ */
722
+ public function change_field_label_in_required_notice( $notice, $field_label ) {
723
+
724
+ if ( _is_wcf_doing_optin_ajax() ) {
725
+
726
+ $notice = str_replace( 'Billing ', '', $notice );
727
+ }
728
+
729
+ return $notice;
730
+ }
731
+ }
732
+
733
+ /**
734
+ * Kicking this off by calling 'get_instance()' method
735
+ */
736
+ Cartflows_Optin_Markup::get_instance();
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: brainstormforce, wpcrafter
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
- Tested up to: 5.5
7
- Stable tag: 1.5.16
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -127,6 +127,13 @@ Glad you asked! Most normal users have less than 3 funnels on a single website,
127
 
128
  == Changelog ==
129
 
 
 
 
 
 
 
 
130
  = Version 1.5.16 - Tuesday, 25th August 2020 =
131
  * Improvement: Hardened the security of the plugin.
132
  * Fix: User's account was not getting created from the Optin step.
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
+ Tested up to: 5.5.1
7
+ Stable tag: 1.5.17
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
127
 
128
  == Changelog ==
129
 
130
+ = Version 1.5.17 - Tuesday, 8th September 2020 =
131
+ * New: Added Braintree subscription product compatibility. Now, you can select it on the checkout page meta setting.
132
+ * Improvement: Added compatibility for a future release of CartFlows Pro.
133
+ * Fix: CartFlows meta boxes were stuck in the side panel.
134
+ * Fix: Groups Menu was getting redirected to the home page in BuddyBoss Theme.
135
+ * Fix: Checkout page was not displaying the rest of the product if one product goes out of stock.
136
+
137
  = Version 1.5.16 - Tuesday, 25th August 2020 =
138
  * Improvement: Hardened the security of the plugin.
139
  * Fix: User's account was not getting created from the Optin step.
woocommerce/template/checkout/thankyou.php CHANGED
@@ -40,6 +40,9 @@ if ( ! defined( 'ABSPATH' ) ) {
40
 
41
  <p class="woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', __( 'Thank you. Your order has been received.', 'woocommerce' ), $order ); ?></p>
42
 
 
 
 
43
  <ul class="woocommerce-order-overview woocommerce-thankyou-order-details order_details">
44
 
45
  <li class="woocommerce-order-overview__order order">
@@ -59,10 +62,12 @@ if ( ! defined( 'ABSPATH' ) ) {
59
  </li>
60
  <?php endif; ?>
61
 
 
62
  <li class="woocommerce-order-overview__total total">
63
  <?php _e( 'Total:', 'woocommerce' ); ?>
64
  <strong><?php echo $order->get_formatted_order_total(); ?></strong>
65
  </li>
 
66
 
67
  <?php if ( $order->get_payment_method_title() ) : ?>
68
  <li class="woocommerce-order-overview__payment-method method">
@@ -70,9 +75,7 @@ if ( ! defined( 'ABSPATH' ) ) {
70
  <strong><?php echo wp_kses_post( $order->get_payment_method_title() ); ?></strong>
71
  </li>
72
  <?php endif; ?>
73
-
74
  </ul>
75
-
76
  <?php endif; ?>
77
 
78
  <?php do_action( 'woocommerce_thankyou_' . $order->get_payment_method(), $order->get_id() ); ?>
40
 
41
  <p class="woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', __( 'Thank you. Your order has been received.', 'woocommerce' ), $order ); ?></p>
42
 
43
+ <?php if ( $order->has_status( 'cancelled' ) ) :
44
+ do_action( 'cartflows_woocommerce_order_overview_cancelled', $order );
45
+ endif; ?>
46
  <ul class="woocommerce-order-overview woocommerce-thankyou-order-details order_details">
47
 
48
  <li class="woocommerce-order-overview__order order">
62
  </li>
63
  <?php endif; ?>
64
 
65
+ <?php if ( ! $order->has_status( 'cancelled' ) ) : ?>
66
  <li class="woocommerce-order-overview__total total">
67
  <?php _e( 'Total:', 'woocommerce' ); ?>
68
  <strong><?php echo $order->get_formatted_order_total(); ?></strong>
69
  </li>
70
+ <?php endif; ?>
71
 
72
  <?php if ( $order->get_payment_method_title() ) : ?>
73
  <li class="woocommerce-order-overview__payment-method method">
75
  <strong><?php echo wp_kses_post( $order->get_payment_method_title() ); ?></strong>
76
  </li>
77
  <?php endif; ?>
 
78
  </ul>
 
79
  <?php endif; ?>
80
 
81
  <?php do_action( 'woocommerce_thankyou_' . $order->get_payment_method(), $order->get_id() ); ?>
woocommerce/template/order/order-details.php CHANGED
@@ -29,76 +29,86 @@ $show_customer_details = is_user_logged_in() && $order->get_user_id() === get_cu
29
  $downloads = $order->get_downloadable_items();
30
  $show_downloads = $order->has_downloadable_item() && $order->is_download_permitted();
31
 
32
- if ( $show_downloads ) {
33
- wc_get_template(
34
- 'order/order-downloads.php',
35
- array(
36
- 'downloads' => $downloads,
37
- 'show_title' => true,
38
- )
39
- );
40
- }
41
- ?>
42
- <section class="woocommerce-order-details">
43
- <?php do_action( 'woocommerce_order_details_before_order_table', $order ); ?>
44
-
45
- <h2 class="woocommerce-order-details__title"><?php esc_html_e( 'Order details', 'woocommerce' ); ?></h2>
46
-
47
- <table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
48
-
49
- <thead>
50
- <tr>
51
- <th class="woocommerce-table__product-name product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
52
- <th class="woocommerce-table__product-table product-total"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
53
- </tr>
54
- </thead>
55
-
56
- <tbody>
57
- <?php
58
- do_action( 'woocommerce_order_details_before_order_table_items', $order );
59
-
60
- foreach ( $order_items as $item_id => $item ) {
61
- $product = $item->get_product();
62
-
63
- wc_get_template(
64
- 'order/order-details-item.php',
65
- array(
66
- 'order' => $order,
67
- 'item_id' => $item_id,
68
- 'item' => $item,
69
- 'show_purchase_note' => $show_purchase_note,
70
- 'purchase_note' => $product ? $product->get_purchase_note() : '',
71
- 'product' => $product,
72
- )
73
- );
74
- }
75
-
76
- do_action( 'woocommerce_order_details_after_order_table_items', $order );
77
- ?>
78
- </tbody>
79
-
80
- <tfoot>
81
- <?php
82
- foreach ( $order->get_order_item_totals() as $key => $total ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  ?>
 
84
  <tr>
85
- <th scope="row"><?php echo esc_html( $total['label'] ); ?></th>
86
- <td><?php echo ( 'payment_method' === $key ) ? esc_html( $total['value'] ) : wp_kses_post( $total['value'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
87
  </tr>
88
- <?php
89
- }
90
- ?>
91
- <?php if ( $order->get_customer_note() ) : ?>
92
- <tr>
93
- <th><?php esc_html_e( 'Note:', 'woocommerce' ); ?></th>
94
- <td><?php echo wp_kses_post( nl2br( wptexturize( $order->get_customer_note() ) ) ); ?></td>
95
- </tr>
96
- <?php endif; ?>
97
- </tfoot>
98
- </table>
99
 
100
- <?php do_action( 'woocommerce_order_details_after_order_table', $order ); ?>
101
- </section>
 
 
 
 
102
 
103
  <?php do_action( 'woocommerce_after_order_details', $order ); ?>
104
 
29
  $downloads = $order->get_downloadable_items();
30
  $show_downloads = $order->has_downloadable_item() && $order->is_download_permitted();
31
 
32
+ // If main order is cancelled then show the new order details.
33
+ if( $order->has_status( 'cancelled' ) ){
34
+ do_action( 'cartflows_woocommerce_order_details_cancelled', $order );
35
+ }else{
36
+
37
+ if ( $show_downloads ) {
38
+ wc_get_template(
39
+ 'order/order-downloads.php',
40
+ array(
41
+ 'downloads' => $downloads,
42
+ 'show_title' => true,
43
+ )
44
+ );
45
+ }
46
+
47
+ ?>
48
+ <section class="woocommerce-order-details">
49
+ <?php do_action( 'woocommerce_order_details_before_order_table', $order ); ?>
50
+
51
+ <h2 class="woocommerce-order-details__title"><?php esc_html_e( 'Order details', 'woocommerce' ); ?></h2>
52
+
53
+ <table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
54
+
55
+ <thead>
56
+ <tr>
57
+ <th class="woocommerce-table__product-name product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
58
+ <th class="woocommerce-table__product-table product-total"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
59
+ </tr>
60
+ </thead>
61
+
62
+ <tbody>
63
+ <?php
64
+ do_action( 'woocommerce_order_details_before_order_table_items', $order );
65
+
66
+ foreach ( $order_items as $item_id => $item ) {
67
+ $product = $item->get_product();
68
+
69
+ wc_get_template(
70
+ 'order/order-details-item.php',
71
+ array(
72
+ 'order' => $order,
73
+ 'item_id' => $item_id,
74
+ 'item' => $item,
75
+ 'show_purchase_note' => $show_purchase_note,
76
+ 'purchase_note' => $product ? $product->get_purchase_note() : '',
77
+ 'product' => $product,
78
+ )
79
+ );
80
+ }
81
+
82
+ do_action( 'woocommerce_order_details_after_order_table_items', $order );
83
+ ?>
84
+ </tbody>
85
+
86
+ <tfoot>
87
+ <?php
88
+ foreach ( $order->get_order_item_totals() as $key => $total ) {
89
+ ?>
90
+ <tr>
91
+ <th scope="row"><?php echo esc_html( $total['label'] ); ?></th>
92
+ <td><?php echo ( 'payment_method' === $key ) ? esc_html( $total['value'] ) : wp_kses_post( $total['value'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></td>
93
+ </tr>
94
+ <?php
95
+ }
96
  ?>
97
+ <?php if ( $order->get_customer_note() ) : ?>
98
  <tr>
99
+ <th><?php esc_html_e( 'Note:', 'woocommerce' ); ?></th>
100
+ <td><?php echo wp_kses_post( nl2br( wptexturize( $order->get_customer_note() ) ) ); ?></td>
101
  </tr>
102
+ <?php endif; ?>
103
+ </tfoot>
104
+ </table>
 
 
 
 
 
 
 
 
105
 
106
+ <?php do_action( 'woocommerce_order_details_after_order_table', $order ); ?>
107
+ </section>
108
+ <?php
109
+ }
110
+
111
+ ?>
112
 
113
  <?php do_action( 'woocommerce_after_order_details', $order ); ?>
114