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

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.14
Comparing to
See all releases

Code changes from version 1.5.13 to 1.5.14

admin/bsf-analytics/class-bsf-analytics-loader.php CHANGED
@@ -1,115 +1,115 @@
1
- <?php
2
- /**
3
- * BSF analytics loader file.
4
- *
5
- * @version 1.0.0
6
- *
7
- * @package bsf-analytics
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) {
11
- exit();
12
- }
13
-
14
- /**
15
- * Class BSF_Analytics_Loader.
16
- */
17
- class BSF_Analytics_Loader {
18
-
19
- /**
20
- * Analytics Entities.
21
- *
22
- * @access private
23
- * @var array Entities array.
24
- */
25
- private $entities = array();
26
-
27
- /**
28
- * Analytics Version.
29
- *
30
- * @access private
31
- * @var float analytics version.
32
- */
33
- private $analytics_version = '';
34
-
35
- /**
36
- * Analytics path.
37
- *
38
- * @access private
39
- * @var string path array.
40
- */
41
- private $analytics_path = '';
42
-
43
- /**
44
- * Instance
45
- *
46
- * @access private
47
- * @var object Class object.
48
- */
49
- private static $instance = null;
50
-
51
- /**
52
- * Get instace of class.
53
- *
54
- * @return object
55
- */
56
- public static function get_instance() {
57
- if ( null === self::$instance ) {
58
- self::$instance = new self();
59
- }
60
-
61
- return self::$instance;
62
- }
63
-
64
- /**
65
- * Constructor
66
- */
67
- public function __construct() {
68
- add_action( 'init', array( $this, 'load_analytics' ) );
69
- }
70
-
71
- /**
72
- * Set entity for analytics.
73
- *
74
- * @param string $data Entity attributes data.
75
- * @return void
76
- */
77
- public function set_entity( $data ) {
78
- array_push( $this->entities, $data );
79
- }
80
-
81
- /**
82
- * Load Analytics library.
83
- *
84
- * @return void
85
- */
86
- public function load_analytics() {
87
- $unique_entities = array();
88
-
89
- if ( ! empty( $this->entities ) ) {
90
- foreach ( $this->entities as $entity ) {
91
- foreach ( $entity as $key => $data ) {
92
-
93
- if ( isset( $data['path'] ) ) {
94
- if ( file_exists( $data['path'] . '/version.json' ) ) {
95
- $analytics_version = file_get_contents( $data['path'] . '/version.json' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
96
- if ( version_compare( $analytics_version, $this->analytics_version, '>' ) ) {
97
- $this->analytics_version = $analytics_version;
98
- $this->analytics_path = $data['path'];
99
- }
100
- }
101
- }
102
-
103
- if ( ! isset( $unique_entities[ $key ] ) ) {
104
- $unique_entities[ $key ] = $data;
105
- }
106
- }
107
- }
108
-
109
- if ( file_exists( $this->analytics_path ) && ! class_exists( 'BSF_Analytics' ) ) {
110
- require_once $this->analytics_path . '/class-bsf-analytics.php';
111
- new BSF_Analytics( $unique_entities );
112
- }
113
- }
114
- }
115
- }
1
+ <?php
2
+ /**
3
+ * BSF analytics loader file.
4
+ *
5
+ * @version 1.0.0
6
+ *
7
+ * @package bsf-analytics
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit();
12
+ }
13
+
14
+ /**
15
+ * Class BSF_Analytics_Loader.
16
+ */
17
+ class BSF_Analytics_Loader {
18
+
19
+ /**
20
+ * Analytics Entities.
21
+ *
22
+ * @access private
23
+ * @var array Entities array.
24
+ */
25
+ private $entities = array();
26
+
27
+ /**
28
+ * Analytics Version.
29
+ *
30
+ * @access private
31
+ * @var float analytics version.
32
+ */
33
+ private $analytics_version = '';
34
+
35
+ /**
36
+ * Analytics path.
37
+ *
38
+ * @access private
39
+ * @var string path array.
40
+ */
41
+ private $analytics_path = '';
42
+
43
+ /**
44
+ * Instance
45
+ *
46
+ * @access private
47
+ * @var object Class object.
48
+ */
49
+ private static $instance = null;
50
+
51
+ /**
52
+ * Get instace of class.
53
+ *
54
+ * @return object
55
+ */
56
+ public static function get_instance() {
57
+ if ( null === self::$instance ) {
58
+ self::$instance = new self();
59
+ }
60
+
61
+ return self::$instance;
62
+ }
63
+
64
+ /**
65
+ * Constructor
66
+ */
67
+ public function __construct() {
68
+ add_action( 'init', array( $this, 'load_analytics' ) );
69
+ }
70
+
71
+ /**
72
+ * Set entity for analytics.
73
+ *
74
+ * @param string $data Entity attributes data.
75
+ * @return void
76
+ */
77
+ public function set_entity( $data ) {
78
+ array_push( $this->entities, $data );
79
+ }
80
+
81
+ /**
82
+ * Load Analytics library.
83
+ *
84
+ * @return void
85
+ */
86
+ public function load_analytics() {
87
+ $unique_entities = array();
88
+
89
+ if ( ! empty( $this->entities ) ) {
90
+ foreach ( $this->entities as $entity ) {
91
+ foreach ( $entity as $key => $data ) {
92
+
93
+ if ( isset( $data['path'] ) ) {
94
+ if ( file_exists( $data['path'] . '/version.json' ) ) {
95
+ $analytics_version = file_get_contents( $data['path'] . '/version.json' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
96
+ if ( version_compare( $analytics_version, $this->analytics_version, '>' ) ) {
97
+ $this->analytics_version = $analytics_version;
98
+ $this->analytics_path = $data['path'];
99
+ }
100
+ }
101
+ }
102
+
103
+ if ( ! isset( $unique_entities[ $key ] ) ) {
104
+ $unique_entities[ $key ] = $data;
105
+ }
106
+ }
107
+ }
108
+
109
+ if ( file_exists( $this->analytics_path ) && ! class_exists( 'BSF_Analytics' ) ) {
110
+ require_once $this->analytics_path . '/class-bsf-analytics.php';
111
+ new BSF_Analytics( $unique_entities );
112
+ }
113
+ }
114
+ }
115
+ }
admin/bsf-analytics/class-bsf-analytics.php CHANGED
@@ -1,560 +1,560 @@
1
- <?php
2
- /**
3
- * BSF analytics class file.
4
- *
5
- * @version 1.0.0
6
- *
7
- * @package bsf-analytics
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly.
12
- }
13
-
14
- if ( ! class_exists( 'BSF_Analytics' ) ) {
15
-
16
- /**
17
- * BSF analytics
18
- */
19
- class BSF_Analytics {
20
-
21
- /**
22
- * Member Variable
23
- *
24
- * @var string Product name
25
- */
26
- public $product_name = '';
27
-
28
- /**
29
- * Member Variable
30
- *
31
- * @var array Entities data.
32
- */
33
- private $entities;
34
-
35
- /**
36
- * Member Variable
37
- *
38
- * @var string Usage tracking document URL
39
- */
40
- public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
41
-
42
- /**
43
- * Setup actions, load files.
44
- *
45
- * @param array $args entity data for analytics.
46
- * @since 1.0.0
47
- */
48
- public function __construct( $args ) {
49
-
50
- // Bail when no analytics entities are registered.
51
- if ( empty( $args ) ) {
52
- return;
53
- }
54
-
55
- $this->entities = $args;
56
-
57
- define( 'BSF_ANALYTICS_FILE', __FILE__ );
58
- define( 'BSF_ANALYTICS_URI', $this->bsf_analytics_url() );
59
-
60
- add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
61
- add_action( 'cron_schedules', array( $this, 'every_two_days_schedule' ) );
62
- add_action( 'admin_notices', array( $this, 'option_notice' ) );
63
- add_action( 'init', array( $this, 'schedule_unschedule_event' ), 99 );
64
-
65
- $this->set_actions();
66
-
67
- if ( ! has_action( 'bsf_analytics_send', array( $this, 'send' ) ) ) {
68
- add_action( 'bsf_analytics_send', array( $this, 'send' ) );
69
- }
70
-
71
- add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
72
-
73
- $this->includes();
74
- }
75
-
76
- /**
77
- * Setup actions for admin notice style and analytics cron event.
78
- *
79
- * @since 1.0.4
80
- */
81
- public function set_actions() {
82
-
83
- foreach ( $this->entities as $key => $data ) {
84
- add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) );
85
- add_action( 'update_option_' . $key . '_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
86
- add_action( 'add_option_' . $key . '_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
87
- }
88
- }
89
-
90
- /**
91
- * BSF Analytics URL
92
- *
93
- * @return String URL of bsf-analytics directory.
94
- * @since 1.0.0
95
- */
96
- public function bsf_analytics_url() {
97
-
98
- $path = wp_normalize_path( dirname( __FILE__ ) );
99
- $theme_dir = wp_normalize_path( get_template_directory() );
100
-
101
- if ( strpos( $path, $theme_dir ) !== false ) {
102
- return rtrim( get_template_directory_uri() . '/admin/bsf-analytics/', '/' );
103
- } else {
104
- return rtrim( plugin_dir_url( BSF_ANALYTICS_FILE ), '/' );
105
- }
106
- }
107
-
108
- /**
109
- * Get API URL for sending analytics.
110
- *
111
- * @return string API URL.
112
- * @since 1.0.0
113
- */
114
- private function get_api_url() {
115
- return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
116
- }
117
-
118
- /**
119
- * Enqueue Scripts.
120
- *
121
- * @since 1.0.0
122
- * @return void
123
- */
124
- public function enqueue_assets() {
125
-
126
- global $bsf_analytics_version;
127
- /**
128
- * Load unminified if SCRIPT_DEBUG is true.
129
- *
130
- * Directory and Extensions.
131
- */
132
- $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
133
- $file_rtl = ( is_rtl() ) ? '-rtl' : '';
134
- $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
135
-
136
- $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
137
-
138
- wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, $bsf_analytics_version, 'all' );
139
- }
140
-
141
- /**
142
- * Send analytics API call.
143
- *
144
- * @since 1.0.0
145
- */
146
- public function send() {
147
- wp_remote_post(
148
- $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
149
- array(
150
- 'body' => BSF_Analytics_Stats::instance()->get_stats(),
151
- 'timeout' => 5,
152
- 'blocking' => false,
153
- )
154
- );
155
- }
156
-
157
- /**
158
- * Check if usage tracking is enabled.
159
- *
160
- * @return bool
161
- * @since 1.0.0
162
- */
163
- public function is_tracking_enabled() {
164
-
165
- foreach ( $this->entities as $key => $data ) {
166
-
167
- $is_enabled = get_site_option( $key . '_analytics_optin' ) === 'yes' ? true : false;
168
- $is_enabled = $this->is_white_label_enabled( $key ) ? false : $is_enabled;
169
-
170
- if ( apply_filters( $key . '_tracking_enabled', $is_enabled ) ) {
171
- return true;
172
- }
173
- }
174
-
175
- return false;
176
- }
177
-
178
- /**
179
- * Check if WHITE label is enabled for BSF products.
180
- *
181
- * @param string $source source of analytics.
182
- * @return bool
183
- * @since 1.0.0
184
- */
185
- public function is_white_label_enabled( $source ) {
186
-
187
- $options = apply_filters( $source . '_white_label_options', array() );
188
- $is_enabled = false;
189
-
190
- if ( is_array( $options ) ) {
191
- foreach ( $options as $option ) {
192
- if ( true === $option ) {
193
- $is_enabled = true;
194
- break;
195
- }
196
- }
197
- }
198
-
199
- return $is_enabled;
200
- }
201
-
202
- /**
203
- * Display admin notice for usage tracking.
204
- *
205
- * @since 1.0.0
206
- */
207
- public function option_notice() {
208
-
209
- if ( ! current_user_can( 'manage_options' ) ) {
210
- return;
211
- }
212
-
213
- foreach ( $this->entities as $key => $data ) {
214
-
215
- $time_to_display = isset( $data['time_to_display'] ) ? $data['time_to_display'] : '+24 hours';
216
- $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
217
-
218
- // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
219
- if ( false !== get_site_option( $key . '_analytics_optin', false ) || $this->is_white_label_enabled( $key ) ) {
220
- continue;
221
- }
222
-
223
- // Show tracker consent notice after 24 hours from installed time.
224
- if ( strtotime( $time_to_display, $this->get_analytics_install_time( $key ) ) > time() ) {
225
- continue;
226
- }
227
-
228
- /* translators: %s product name */
229
- $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'cartflows' );
230
-
231
- if ( is_multisite() ) {
232
- $notice_string .= __( 'This will be applicable for all sites from the network.', 'cartflows' );
233
- }
234
-
235
- $language_dir = is_rtl() ? 'rtl' : 'ltr';
236
-
237
- Astra_Notices::add_notice(
238
- array(
239
- 'id' => $key . '-optin-notice',
240
- 'type' => '',
241
- 'message' => sprintf(
242
- '<div class="notice-content">
243
- <div class="notice-heading">
244
- %1$s
245
- </div>
246
- <div class="astra-notices-container">
247
- <a href="%2$s" class="astra-notices button-primary">
248
- %3$s
249
- </a>
250
- <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
251
- %6$s
252
- </a>
253
- </div>
254
- </div>',
255
- /* translators: %s usage doc link */
256
- sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $data['product_name'] ), $language_dir, esc_url( $usage_doc_link ), __( ' Know More.', 'cartflows' ) ),
257
- add_query_arg(
258
- array(
259
- $key . '_analytics_optin' => 'yes',
260
- $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
261
- 'bsf_analytics_source' => $key,
262
- )
263
- ),
264
- __( 'Yes! Allow it', 'cartflows' ),
265
- add_query_arg(
266
- array(
267
- $key . '_analytics_optin' => 'no',
268
- $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
269
- 'bsf_analytics_source' => $key,
270
- )
271
- ),
272
- MONTH_IN_SECONDS,
273
- __( 'No Thanks', 'cartflows' )
274
- ),
275
- 'show_if' => true,
276
- 'repeat-notice-after' => false,
277
- 'priority' => 18,
278
- 'display-with-other-notices' => true,
279
- )
280
- );
281
- }
282
- }
283
-
284
- /**
285
- * Process usage tracking opt out.
286
- *
287
- * @since 1.0.0
288
- */
289
- public function handle_optin_optout() {
290
-
291
- if ( ! current_user_can( 'manage_options' ) ) {
292
- return;
293
- }
294
-
295
- $source = isset( $_GET['bsf_analytics_source'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_source'] ) ) : '';
296
-
297
- if ( ! isset( $_GET[ $source . '_analytics_nonce' ] ) ) {
298
- return;
299
- }
300
-
301
- if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_nonce' ] ) ), $source . '_analytics_optin' ) ) {
302
- return;
303
- }
304
-
305
- $optin_status = isset( $_GET[ $source . '_analytics_optin' ] ) ? sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_optin' ] ) ) : '';
306
-
307
- if ( 'yes' === $optin_status ) {
308
- $this->optin( $source );
309
- } elseif ( 'no' === $optin_status ) {
310
- $this->optout( $source );
311
- }
312
-
313
- wp_safe_redirect(
314
- remove_query_arg(
315
- array(
316
- $source . '_analytics_optin',
317
- $source . '_analytics_nonce',
318
- 'bsf_analytics_source',
319
- )
320
- )
321
- );
322
- }
323
-
324
- /**
325
- * Opt in to usage tracking.
326
- *
327
- * @param string $source source of analytics.
328
- * @since 1.0.0
329
- */
330
- private function optin( $source ) {
331
- update_site_option( $source . '_analytics_optin', 'yes' );
332
- }
333
-
334
- /**
335
- * Opt out to usage tracking.
336
- *
337
- * @param string $source source of analytics.
338
- * @since 1.0.0
339
- */
340
- private function optout( $source ) {
341
- update_site_option( $source . '_analytics_optin', 'no' );
342
- }
343
-
344
- /**
345
- * Add two days event schedule variables.
346
- *
347
- * @param array $schedules scheduled array data.
348
- * @since 1.0.0
349
- */
350
- public function every_two_days_schedule( $schedules ) {
351
- $schedules['every_two_days'] = array(
352
- 'interval' => 2 * DAY_IN_SECONDS,
353
- 'display' => __( 'Every two days', 'cartflows' ),
354
- );
355
-
356
- return $schedules;
357
- }
358
-
359
- /**
360
- * Schedule usage tracking event.
361
- *
362
- * @since 1.0.0
363
- */
364
- private function schedule_event() {
365
- if ( ! wp_next_scheduled( 'bsf_analytics_send' ) && $this->is_tracking_enabled() ) {
366
- wp_schedule_event( time(), 'every_two_days', 'bsf_analytics_send' );
367
- }
368
- }
369
-
370
- /**
371
- * Unschedule usage tracking event.
372
- *
373
- * @since 1.0.0
374
- */
375
- private function unschedule_event() {
376
- wp_clear_scheduled_hook( 'bsf_analytics_send' );
377
- }
378
-
379
- /**
380
- * Load analytics stat class.
381
- *
382
- * @since 1.0.0
383
- */
384
- private function includes() {
385
- require_once __DIR__ . '/class-bsf-analytics-stats.php';
386
- }
387
-
388
- /**
389
- * Register usage tracking option in General settings page.
390
- *
391
- * @since 1.0.0
392
- */
393
- public function register_usage_tracking_setting() {
394
-
395
- foreach ( $this->entities as $key => $data ) {
396
-
397
- if ( ! apply_filters( $key . 'tracking_enabled', true ) || $this->is_white_label_enabled( $key ) ) {
398
- return;
399
- }
400
-
401
- $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
402
- $author = isset( $data['author'] ) ? $data['author'] : 'Brainstorm Force';
403
-
404
- register_setting(
405
- 'general', // Options group.
406
- $key . '_analytics_optin', // Option name/database.
407
- array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
408
- );
409
-
410
- add_settings_field(
411
- $key . '-analytics-optin', // Field ID.
412
- __( 'Usage Tracking', 'cartflows' ), // Field title.
413
- array( $this, 'render_settings_field_html' ), // Field callback function.
414
- 'general',
415
- 'default', // Settings page slug.
416
- array(
417
- 'type' => 'checkbox',
418
- 'title' => $author,
419
- 'name' => $key . '_analytics_optin',
420
- 'label_for' => $key . '-analytics-optin',
421
- 'id' => $key . '-analytics-optin',
422
- 'usage_doc_link' => $usage_doc_link,
423
- )
424
- );
425
- }
426
- }
427
-
428
- /**
429
- * Sanitize Callback Function
430
- *
431
- * @param bool $input Option value.
432
- * @since 1.0.0
433
- */
434
- public function sanitize_option( $input ) {
435
-
436
- if ( ! $input || 'no' === $input ) {
437
- return 'no';
438
- }
439
-
440
- return 'yes';
441
- }
442
-
443
- /**
444
- * Print settings field HTML.
445
- *
446
- * @param array $args arguments to field.
447
- * @since 1.0.0
448
- */
449
- public function render_settings_field_html( $args ) {
450
- ?>
451
- <fieldset>
452
- <label for="<?php echo esc_attr( $args['label_for'] ); ?>">
453
- <input id="<?php echo esc_attr( $args['id'] ); ?>" type="checkbox" value="1" name="<?php echo esc_attr( $args['name'] ); ?>" <?php checked( get_site_option( $args['name'], 'no' ), 'yes' ); ?>>
454
- <?php
455
- /* translators: %s Product title */
456
- esc_html_e( sprintf( 'Allow %s products to track non-sensitive usage tracking data.', $args['cartflows'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
457
-
458
- if ( is_multisite() ) {
459
- esc_html_e( ' This will be applicable for all sites from the network.', 'cartflows' );
460
- }
461
- ?>
462
- </label>
463
- <?php
464
- echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $args['usage_doc_link'] ), __( 'Learn More.', 'cartflows' ) ) );
465
- ?>
466
- </fieldset>
467
- <?php
468
- }
469
-
470
- /**
471
- * Set analytics installed time in option.
472
- *
473
- * @param string $source source of analytics.
474
- * @return string $time analytics installed time.
475
- * @since 1.0.0
476
- */
477
- private function get_analytics_install_time( $source ) {
478
-
479
- $time = get_site_option( $source . '_analytics_installed_time' );
480
-
481
- if ( ! $time ) {
482
- $time = time();
483
- update_site_option( $source . '_analytics_installed_time', time() );
484
- }
485
-
486
- return $time;
487
- }
488
-
489
- /**
490
- * Schedule/unschedule cron event on updation of option.
491
- *
492
- * @param string $old_value old value of option.
493
- * @param string $value value of option.
494
- * @param string $option Option name.
495
- * @since 1.0.0
496
- */
497
- public function update_analytics_option_callback( $old_value, $value, $option ) {
498
- if ( is_multisite() ) {
499
- $this->add_option_to_network( $option, $value );
500
- }
501
- }
502
-
503
- /**
504
- * Analytics option add callback.
505
- *
506
- * @param string $option Option name.
507
- * @param string $value value of option.
508
- * @since 1.0.0
509
- */
510
- public function add_analytics_option_callback( $option, $value ) {
511
- if ( is_multisite() ) {
512
- $this->add_option_to_network( $option, $value );
513
- }
514
- }
515
-
516
- /**
517
- * Schedule or unschedule event based on analytics option value.
518
- *
519
- * @since 1.0.0
520
- */
521
- public function schedule_unschedule_event() {
522
-
523
- foreach ( $this->entities as $key => $source ) {
524
-
525
- if ( true === $this->is_white_label_enabled( $key ) ) {
526
- $this->unschedule_event();
527
- return;
528
- }
529
-
530
- $analytics_option = get_site_option( $key . '_analytics_optin' );
531
-
532
- if ( 'yes' === $analytics_option ) {
533
- $this->schedule_event();
534
- } else {
535
- $this->unschedule_event();
536
- }
537
- }
538
- }
539
-
540
- /**
541
- * Save analytics option to network.
542
- *
543
- * @param string $option name of option.
544
- * @param string $value value of option.
545
- * @since 1.0.0
546
- */
547
- public function add_option_to_network( $option, $value ) {
548
-
549
- // If action coming from general settings page.
550
- if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
551
-
552
- if ( get_site_option( $option ) ) {
553
- update_site_option( $option, $value );
554
- } else {
555
- add_site_option( $option, $value );
556
- }
557
- }
558
- }
559
- }
560
- }
1
+ <?php
2
+ /**
3
+ * BSF analytics class file.
4
+ *
5
+ * @version 1.0.0
6
+ *
7
+ * @package bsf-analytics
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly.
12
+ }
13
+
14
+ if ( ! class_exists( 'BSF_Analytics' ) ) {
15
+
16
+ /**
17
+ * BSF analytics
18
+ */
19
+ class BSF_Analytics {
20
+
21
+ /**
22
+ * Member Variable
23
+ *
24
+ * @var string Product name
25
+ */
26
+ public $product_name = '';
27
+
28
+ /**
29
+ * Member Variable
30
+ *
31
+ * @var array Entities data.
32
+ */
33
+ private $entities;
34
+
35
+ /**
36
+ * Member Variable
37
+ *
38
+ * @var string Usage tracking document URL
39
+ */
40
+ public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
41
+
42
+ /**
43
+ * Setup actions, load files.
44
+ *
45
+ * @param array $args entity data for analytics.
46
+ * @since 1.0.0
47
+ */
48
+ public function __construct( $args ) {
49
+
50
+ // Bail when no analytics entities are registered.
51
+ if ( empty( $args ) ) {
52
+ return;
53
+ }
54
+
55
+ $this->entities = $args;
56
+
57
+ define( 'BSF_ANALYTICS_FILE', __FILE__ );
58
+ define( 'BSF_ANALYTICS_URI', $this->bsf_analytics_url() );
59
+
60
+ add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
61
+ add_action( 'cron_schedules', array( $this, 'every_two_days_schedule' ) );
62
+ add_action( 'admin_notices', array( $this, 'option_notice' ) );
63
+ add_action( 'init', array( $this, 'schedule_unschedule_event' ), 99 );
64
+
65
+ $this->set_actions();
66
+
67
+ if ( ! has_action( 'bsf_analytics_send', array( $this, 'send' ) ) ) {
68
+ add_action( 'bsf_analytics_send', array( $this, 'send' ) );
69
+ }
70
+
71
+ add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
72
+
73
+ $this->includes();
74
+ }
75
+
76
+ /**
77
+ * Setup actions for admin notice style and analytics cron event.
78
+ *
79
+ * @since 1.0.4
80
+ */
81
+ public function set_actions() {
82
+
83
+ foreach ( $this->entities as $key => $data ) {
84
+ add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) );
85
+ add_action( 'update_option_' . $key . '_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
86
+ add_action( 'add_option_' . $key . '_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
87
+ }
88
+ }
89
+
90
+ /**
91
+ * BSF Analytics URL
92
+ *
93
+ * @return String URL of bsf-analytics directory.
94
+ * @since 1.0.0
95
+ */
96
+ public function bsf_analytics_url() {
97
+
98
+ $path = wp_normalize_path( dirname( __FILE__ ) );
99
+ $theme_dir = wp_normalize_path( get_template_directory() );
100
+
101
+ if ( strpos( $path, $theme_dir ) !== false ) {
102
+ return rtrim( get_template_directory_uri() . '/admin/bsf-analytics/', '/' );
103
+ } else {
104
+ return rtrim( plugin_dir_url( BSF_ANALYTICS_FILE ), '/' );
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Get API URL for sending analytics.
110
+ *
111
+ * @return string API URL.
112
+ * @since 1.0.0
113
+ */
114
+ private function get_api_url() {
115
+ return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
116
+ }
117
+
118
+ /**
119
+ * Enqueue Scripts.
120
+ *
121
+ * @since 1.0.0
122
+ * @return void
123
+ */
124
+ public function enqueue_assets() {
125
+
126
+ global $bsf_analytics_version;
127
+ /**
128
+ * Load unminified if SCRIPT_DEBUG is true.
129
+ *
130
+ * Directory and Extensions.
131
+ */
132
+ $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
133
+ $file_rtl = ( is_rtl() ) ? '-rtl' : '';
134
+ $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
135
+
136
+ $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
137
+
138
+ wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, $bsf_analytics_version, 'all' );
139
+ }
140
+
141
+ /**
142
+ * Send analytics API call.
143
+ *
144
+ * @since 1.0.0
145
+ */
146
+ public function send() {
147
+ wp_remote_post(
148
+ $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
149
+ array(
150
+ 'body' => BSF_Analytics_Stats::instance()->get_stats(),
151
+ 'timeout' => 5,
152
+ 'blocking' => false,
153
+ )
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Check if usage tracking is enabled.
159
+ *
160
+ * @return bool
161
+ * @since 1.0.0
162
+ */
163
+ public function is_tracking_enabled() {
164
+
165
+ foreach ( $this->entities as $key => $data ) {
166
+
167
+ $is_enabled = get_site_option( $key . '_analytics_optin' ) === 'yes' ? true : false;
168
+ $is_enabled = $this->is_white_label_enabled( $key ) ? false : $is_enabled;
169
+
170
+ if ( apply_filters( $key . '_tracking_enabled', $is_enabled ) ) {
171
+ return true;
172
+ }
173
+ }
174
+
175
+ return false;
176
+ }
177
+
178
+ /**
179
+ * Check if WHITE label is enabled for BSF products.
180
+ *
181
+ * @param string $source source of analytics.
182
+ * @return bool
183
+ * @since 1.0.0
184
+ */
185
+ public function is_white_label_enabled( $source ) {
186
+
187
+ $options = apply_filters( $source . '_white_label_options', array() );
188
+ $is_enabled = false;
189
+
190
+ if ( is_array( $options ) ) {
191
+ foreach ( $options as $option ) {
192
+ if ( true === $option ) {
193
+ $is_enabled = true;
194
+ break;
195
+ }
196
+ }
197
+ }
198
+
199
+ return $is_enabled;
200
+ }
201
+
202
+ /**
203
+ * Display admin notice for usage tracking.
204
+ *
205
+ * @since 1.0.0
206
+ */
207
+ public function option_notice() {
208
+
209
+ if ( ! current_user_can( 'manage_options' ) ) {
210
+ return;
211
+ }
212
+
213
+ foreach ( $this->entities as $key => $data ) {
214
+
215
+ $time_to_display = isset( $data['time_to_display'] ) ? $data['time_to_display'] : '+24 hours';
216
+ $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
217
+
218
+ // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
219
+ if ( false !== get_site_option( $key . '_analytics_optin', false ) || $this->is_white_label_enabled( $key ) ) {
220
+ continue;
221
+ }
222
+
223
+ // Show tracker consent notice after 24 hours from installed time.
224
+ if ( strtotime( $time_to_display, $this->get_analytics_install_time( $key ) ) > time() ) {
225
+ continue;
226
+ }
227
+
228
+ /* translators: %s product name */
229
+ $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'cartflows' );
230
+
231
+ if ( is_multisite() ) {
232
+ $notice_string .= __( 'This will be applicable for all sites from the network.', 'cartflows' );
233
+ }
234
+
235
+ $language_dir = is_rtl() ? 'rtl' : 'ltr';
236
+
237
+ Astra_Notices::add_notice(
238
+ array(
239
+ 'id' => $key . '-optin-notice',
240
+ 'type' => '',
241
+ 'message' => sprintf(
242
+ '<div class="notice-content">
243
+ <div class="notice-heading">
244
+ %1$s
245
+ </div>
246
+ <div class="astra-notices-container">
247
+ <a href="%2$s" class="astra-notices button-primary">
248
+ %3$s
249
+ </a>
250
+ <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
251
+ %6$s
252
+ </a>
253
+ </div>
254
+ </div>',
255
+ /* translators: %s usage doc link */
256
+ sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $data['product_name'] ), $language_dir, esc_url( $usage_doc_link ), __( ' Know More.', 'cartflows' ) ),
257
+ add_query_arg(
258
+ array(
259
+ $key . '_analytics_optin' => 'yes',
260
+ $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
261
+ 'bsf_analytics_source' => $key,
262
+ )
263
+ ),
264
+ __( 'Yes! Allow it', 'cartflows' ),
265
+ add_query_arg(
266
+ array(
267
+ $key . '_analytics_optin' => 'no',
268
+ $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
269
+ 'bsf_analytics_source' => $key,
270
+ )
271
+ ),
272
+ MONTH_IN_SECONDS,
273
+ __( 'No Thanks', 'cartflows' )
274
+ ),
275
+ 'show_if' => true,
276
+ 'repeat-notice-after' => false,
277
+ 'priority' => 18,
278
+ 'display-with-other-notices' => true,
279
+ )
280
+ );
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Process usage tracking opt out.
286
+ *
287
+ * @since 1.0.0
288
+ */
289
+ public function handle_optin_optout() {
290
+
291
+ if ( ! current_user_can( 'manage_options' ) ) {
292
+ return;
293
+ }
294
+
295
+ $source = isset( $_GET['bsf_analytics_source'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_source'] ) ) : '';
296
+
297
+ if ( ! isset( $_GET[ $source . '_analytics_nonce' ] ) ) {
298
+ return;
299
+ }
300
+
301
+ if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_nonce' ] ) ), $source . '_analytics_optin' ) ) {
302
+ return;
303
+ }
304
+
305
+ $optin_status = isset( $_GET[ $source . '_analytics_optin' ] ) ? sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_optin' ] ) ) : '';
306
+
307
+ if ( 'yes' === $optin_status ) {
308
+ $this->optin( $source );
309
+ } elseif ( 'no' === $optin_status ) {
310
+ $this->optout( $source );
311
+ }
312
+
313
+ wp_safe_redirect(
314
+ remove_query_arg(
315
+ array(
316
+ $source . '_analytics_optin',
317
+ $source . '_analytics_nonce',
318
+ 'bsf_analytics_source',
319
+ )
320
+ )
321
+ );
322
+ }
323
+
324
+ /**
325
+ * Opt in to usage tracking.
326
+ *
327
+ * @param string $source source of analytics.
328
+ * @since 1.0.0
329
+ */
330
+ private function optin( $source ) {
331
+ update_site_option( $source . '_analytics_optin', 'yes' );
332
+ }
333
+
334
+ /**
335
+ * Opt out to usage tracking.
336
+ *
337
+ * @param string $source source of analytics.
338
+ * @since 1.0.0
339
+ */
340
+ private function optout( $source ) {
341
+ update_site_option( $source . '_analytics_optin', 'no' );
342
+ }
343
+
344
+ /**
345
+ * Add two days event schedule variables.
346
+ *
347
+ * @param array $schedules scheduled array data.
348
+ * @since 1.0.0
349
+ */
350
+ public function every_two_days_schedule( $schedules ) {
351
+ $schedules['every_two_days'] = array(
352
+ 'interval' => 2 * DAY_IN_SECONDS,
353
+ 'display' => __( 'Every two days', 'cartflows' ),
354
+ );
355
+
356
+ return $schedules;
357
+ }
358
+
359
+ /**
360
+ * Schedule usage tracking event.
361
+ *
362
+ * @since 1.0.0
363
+ */
364
+ private function schedule_event() {
365
+ if ( ! wp_next_scheduled( 'bsf_analytics_send' ) && $this->is_tracking_enabled() ) {
366
+ wp_schedule_event( time(), 'every_two_days', 'bsf_analytics_send' );
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Unschedule usage tracking event.
372
+ *
373
+ * @since 1.0.0
374
+ */
375
+ private function unschedule_event() {
376
+ wp_clear_scheduled_hook( 'bsf_analytics_send' );
377
+ }
378
+
379
+ /**
380
+ * Load analytics stat class.
381
+ *
382
+ * @since 1.0.0
383
+ */
384
+ private function includes() {
385
+ require_once __DIR__ . '/class-bsf-analytics-stats.php';
386
+ }
387
+
388
+ /**
389
+ * Register usage tracking option in General settings page.
390
+ *
391
+ * @since 1.0.0
392
+ */
393
+ public function register_usage_tracking_setting() {
394
+
395
+ foreach ( $this->entities as $key => $data ) {
396
+
397
+ if ( ! apply_filters( $key . 'tracking_enabled', true ) || $this->is_white_label_enabled( $key ) ) {
398
+ return;
399
+ }
400
+
401
+ $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
402
+ $author = isset( $data['author'] ) ? $data['author'] : 'Brainstorm Force';
403
+
404
+ register_setting(
405
+ 'general', // Options group.
406
+ $key . '_analytics_optin', // Option name/database.
407
+ array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
408
+ );
409
+
410
+ add_settings_field(
411
+ $key . '-analytics-optin', // Field ID.
412
+ __( 'Usage Tracking', 'cartflows' ), // Field title.
413
+ array( $this, 'render_settings_field_html' ), // Field callback function.
414
+ 'general',
415
+ 'default', // Settings page slug.
416
+ array(
417
+ 'type' => 'checkbox',
418
+ 'title' => $author,
419
+ 'name' => $key . '_analytics_optin',
420
+ 'label_for' => $key . '-analytics-optin',
421
+ 'id' => $key . '-analytics-optin',
422
+ 'usage_doc_link' => $usage_doc_link,
423
+ )
424
+ );
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Sanitize Callback Function
430
+ *
431
+ * @param bool $input Option value.
432
+ * @since 1.0.0
433
+ */
434
+ public function sanitize_option( $input ) {
435
+
436
+ if ( ! $input || 'no' === $input ) {
437
+ return 'no';
438
+ }
439
+
440
+ return 'yes';
441
+ }
442
+
443
+ /**
444
+ * Print settings field HTML.
445
+ *
446
+ * @param array $args arguments to field.
447
+ * @since 1.0.0
448
+ */
449
+ public function render_settings_field_html( $args ) {
450
+ ?>
451
+ <fieldset>
452
+ <label for="<?php echo esc_attr( $args['label_for'] ); ?>">
453
+ <input id="<?php echo esc_attr( $args['id'] ); ?>" type="checkbox" value="1" name="<?php echo esc_attr( $args['name'] ); ?>" <?php checked( get_site_option( $args['name'], 'no' ), 'yes' ); ?>>
454
+ <?php
455
+ /* translators: %s Product title */
456
+ esc_html_e( sprintf( 'Allow %s products to track non-sensitive usage tracking data.', $args['cartflows'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
457
+
458
+ if ( is_multisite() ) {
459
+ esc_html_e( ' This will be applicable for all sites from the network.', 'cartflows' );
460
+ }
461
+ ?>
462
+ </label>
463
+ <?php
464
+ echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $args['usage_doc_link'] ), __( 'Learn More.', 'cartflows' ) ) );
465
+ ?>
466
+ </fieldset>
467
+ <?php
468
+ }
469
+
470
+ /**
471
+ * Set analytics installed time in option.
472
+ *
473
+ * @param string $source source of analytics.
474
+ * @return string $time analytics installed time.
475
+ * @since 1.0.0
476
+ */
477
+ private function get_analytics_install_time( $source ) {
478
+
479
+ $time = get_site_option( $source . '_analytics_installed_time' );
480
+
481
+ if ( ! $time ) {
482
+ $time = time();
483
+ update_site_option( $source . '_analytics_installed_time', time() );
484
+ }
485
+
486
+ return $time;
487
+ }
488
+
489
+ /**
490
+ * Schedule/unschedule cron event on updation of option.
491
+ *
492
+ * @param string $old_value old value of option.
493
+ * @param string $value value of option.
494
+ * @param string $option Option name.
495
+ * @since 1.0.0
496
+ */
497
+ public function update_analytics_option_callback( $old_value, $value, $option ) {
498
+ if ( is_multisite() ) {
499
+ $this->add_option_to_network( $option, $value );
500
+ }
501
+ }
502
+
503
+ /**
504
+ * Analytics option add callback.
505
+ *
506
+ * @param string $option Option name.
507
+ * @param string $value value of option.
508
+ * @since 1.0.0
509
+ */
510
+ public function add_analytics_option_callback( $option, $value ) {
511
+ if ( is_multisite() ) {
512
+ $this->add_option_to_network( $option, $value );
513
+ }
514
+ }
515
+
516
+ /**
517
+ * Schedule or unschedule event based on analytics option value.
518
+ *
519
+ * @since 1.0.0
520
+ */
521
+ public function schedule_unschedule_event() {
522
+
523
+ foreach ( $this->entities as $key => $source ) {
524
+
525
+ if ( true === $this->is_white_label_enabled( $key ) ) {
526
+ $this->unschedule_event();
527
+ return;
528
+ }
529
+
530
+ $analytics_option = get_site_option( $key . '_analytics_optin' );
531
+
532
+ if ( 'yes' === $analytics_option ) {
533
+ $this->schedule_event();
534
+ } else {
535
+ $this->unschedule_event();
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Save analytics option to network.
542
+ *
543
+ * @param string $option name of option.
544
+ * @param string $value value of option.
545
+ * @since 1.0.0
546
+ */
547
+ public function add_option_to_network( $option, $value ) {
548
+
549
+ // If action coming from general settings page.
550
+ if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
551
+
552
+ if ( get_site_option( $option ) ) {
553
+ update_site_option( $option, $value );
554
+ } else {
555
+ add_site_option( $option, $value );
556
+ }
557
+ }
558
+ }
559
+ }
560
+ }
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.13
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.14
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  Version 1.5.13 - Tuesday, 21st July 2020
2
  - Improvement: Improved the product search query of meta options.
3
  - Improvement: Added compatibility for a future release of CartFlows Pro.
1
+ Version 1.5.14 - Thursday, 30th July 2020
2
+ - Fix: Not able to search & select the course type of product.
3
+
4
  Version 1.5.13 - Tuesday, 21st July 2020
5
  - Improvement: Improved the product search query of meta options.
6
  - Improvement: Added compatibility for a future release of CartFlows Pro.
classes/class-cartflows-admin.php CHANGED
@@ -1,657 +1,657 @@
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
- }
62
-
63
- /**
64
- * After save of permalinks.
65
- */
66
- public static function cartflows_after_save_permalinks() {
67
-
68
- $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
69
- if ( $has_saved_permalinks ) {
70
- flush_rewrite_rules();
71
- delete_option( 'cartflows_permalink_saved' );
72
- }
73
- }
74
-
75
-
76
- /**
77
- * Initialize after Cartflows pro get loaded.
78
- */
79
- public static function settings_admin_scripts() {
80
- // Enqueue admin scripts.
81
- if ( isset( $_GET['page'] ) && false !== strpos( $_GET['page'], 'cartflows_' ) ) { //phpcs:ignore
82
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
83
-
84
- self::save_settings();
85
- }
86
- }
87
- /**
88
- * Show action on plugin page.
89
- *
90
- * @param array $links links.
91
- * @return array
92
- */
93
- public static function add_action_links( $links ) {
94
- $mylinks = array(
95
- '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
96
- '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
97
- );
98
-
99
- if ( ! _is_cartflows_pro() ) {
100
- array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
101
- }
102
-
103
- return array_merge( $links, $mylinks );
104
- }
105
-
106
- /**
107
- * Initialises the Plugin Name.
108
- *
109
- * @since 1.0.0
110
- * @return void
111
- */
112
- public static function initialise_plugin() {
113
-
114
- $name = 'Cartflows';
115
- $short_name = 'Cflows';
116
-
117
- define( 'CARTFLOWS_PLUGIN_NAME', $name );
118
- define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
119
- }
120
-
121
- /**
122
- * Renders the admin settings menu.
123
- *
124
- * @since 1.0.0
125
- * @return void
126
- */
127
- public static function menu() {
128
-
129
- if ( ! current_user_can( 'manage_options' ) ) {
130
- return;
131
- }
132
-
133
- add_menu_page(
134
- 'CartFlows',
135
- 'CartFlows',
136
- 'manage_options',
137
- CARTFLOWS_SLUG,
138
- __CLASS__ . '::render',
139
- 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
140
- 39.7
141
- );
142
-
143
- }
144
-
145
- /**
146
- * Add submenu to admin menu.
147
- *
148
- * @since 1.0.0
149
- */
150
- public static function submenu() {
151
-
152
- $parent_slug = CARTFLOWS_SLUG;
153
- $page_title = __( 'Settings', 'cartflows' );
154
- $menu_title = __( 'Settings', 'cartflows' );
155
- $capability = 'manage_options';
156
- $menu_slug = 'cartflows_settings';
157
- $callback = __CLASS__ . '::render';
158
-
159
- add_submenu_page(
160
- $parent_slug,
161
- $page_title,
162
- $menu_title,
163
- $capability,
164
- $menu_slug,
165
- $callback
166
- );
167
- }
168
-
169
- /**
170
- * Renders the admin settings.
171
- *
172
- * @since 1.0.0
173
- * @return void
174
- */
175
- public static function render() {
176
- $menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore
177
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
178
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
179
- $action = str_replace( '_', '-', $action );
180
-
181
- // Enable header icon filter below.
182
- $header_wrapper_class = apply_filters( 'cartflows_admin_header_wrapper_class', array( $action, $menu_page_slug ) );
183
-
184
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
185
- }
186
-
187
- /**
188
- * Renders the admin settings content.
189
- *
190
- * @since 1.0.0
191
- * @param sting $menu_page_slug current page name.
192
- *
193
- * @return void
194
- */
195
- public static function render_content( $menu_page_slug ) {
196
-
197
- if ( CARTFLOWS_SETTINGS === $menu_page_slug ) {
198
-
199
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
200
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
201
- $action = str_replace( '_', '-', $action );
202
- $action = 'general';
203
-
204
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
205
- }
206
- }
207
-
208
- /**
209
- * Save Global Setting options.
210
- *
211
- * @since 1.0.0
212
- */
213
- public static function save_common_settings() {
214
-
215
- if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
216
-
217
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
218
- $new_settings = array();
219
-
220
- if ( isset( $_POST['_cartflows_common'] ) ) {
221
- // Loop through the input and sanitize each of the values.
222
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
223
- }
224
-
225
- Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
226
-
227
- $query = array(
228
- 'message' => 'saved',
229
- );
230
-
231
- $redirect_to = add_query_arg( $query, $url );
232
-
233
- wp_safe_redirect( $redirect_to );
234
- exit;
235
- } // End if statement.
236
- }
237
-
238
- /**
239
- * Save Debug Setting options.
240
- *
241
- * @since 1.1.14
242
- */
243
- public static function save_debug_settings() {
244
-
245
- if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
246
-
247
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
248
- $new_settings = array();
249
-
250
- if ( isset( $_POST['_cartflows_debug_data'] ) ) {
251
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
252
- }
253
-
254
- Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
255
-
256
- $query = array(
257
- 'message' => 'saved',
258
- );
259
-
260
- $redirect_to = add_query_arg( $query, $url );
261
-
262
- wp_safe_redirect( $redirect_to );
263
- exit;
264
-
265
- }
266
- }
267
-
268
-
269
- /**
270
- * Save permalink Setting options.
271
- *
272
- * @since 1.1.14
273
- */
274
- public static function save_permalink_settings() {
275
-
276
- if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
277
-
278
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
279
- $new_settings = array();
280
-
281
- if ( isset( $_POST['reset'] ) ) {
282
- $_POST['_cartflows_permalink'] = array(
283
- 'permalink' => CARTFLOWS_STEP_POST_TYPE,
284
- 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
285
- 'permalink_structure' => '',
286
- );
287
-
288
- }
289
-
290
- if ( isset( $_POST['_cartflows_permalink'] ) ) {
291
- $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
292
-
293
- if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
294
- $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
295
- } else {
296
- $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
297
- }
298
-
299
- if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
300
- $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
301
- } else {
302
- $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
303
- }
304
-
305
- $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
306
-
307
- }
308
-
309
- Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
310
-
311
- $query = array(
312
- 'message' => 'saved',
313
- );
314
-
315
- $redirect_to = add_query_arg( $query, $url );
316
-
317
- update_option( 'cartflows_permalink_saved', true );
318
-
319
- wp_safe_redirect( $redirect_to );
320
- exit;
321
-
322
- }
323
- }
324
-
325
- /**
326
- * Save google analytics Setting options.
327
- *
328
- * @since 1.1.14
329
- */
330
- public static function save_google_analytics_settings() {
331
-
332
- 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' ) ) {
333
-
334
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
335
- $new_settings = array();
336
-
337
- if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
338
- $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
339
-
340
- }
341
-
342
- Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
343
-
344
- $query = array(
345
- 'message' => 'saved',
346
- );
347
-
348
- $redirect_to = add_query_arg( $query, $url );
349
-
350
- wp_safe_redirect( $redirect_to );
351
- exit;
352
-
353
- }
354
- }
355
-
356
- /**
357
- * Loop through the input and sanitize each of the values.
358
- *
359
- * @param array $input_settings input settings.
360
- * @return array
361
- */
362
- public static function sanitize_form_inputs( $input_settings = array() ) {
363
- $new_settings = array();
364
- foreach ( $input_settings as $key => $val ) {
365
-
366
- if ( is_array( $val ) ) {
367
- foreach ( $val as $k => $v ) {
368
- $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
369
- }
370
- } else {
371
- $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
372
- }
373
- }
374
- return $new_settings;
375
- }
376
-
377
- /**
378
- * Check is cartflows admin.
379
- *
380
- * @since 1.0.0
381
- * @return boolean
382
- */
383
- public static function is_global_admin() {
384
-
385
- $current_screen = get_current_screen();
386
-
387
- if (
388
- is_object( $current_screen ) &&
389
- isset( $current_screen->post_type ) &&
390
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
391
- CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
392
- )
393
- ) {
394
- return true;
395
- }
396
- return false;
397
- }
398
-
399
- /**
400
- * Check is flow admin.
401
- *
402
- * @since 1.0.0
403
- * @return boolean
404
- */
405
- public static function is_flow_edit_admin() {
406
-
407
- $current_screen = get_current_screen();
408
-
409
- if (
410
- is_object( $current_screen ) &&
411
- isset( $current_screen->post_type ) &&
412
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
413
- isset( $current_screen->base ) &&
414
- ( 'post' === $current_screen->base )
415
- ) {
416
- return true;
417
- }
418
- return false;
419
- }
420
-
421
- /**
422
- * Global Admin Scripts.
423
- *
424
- * @since 1.0.0
425
- */
426
- public static function global_admin_scripts() {
427
-
428
- $installed_plugins = get_plugins();
429
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
430
- $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
431
- $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
432
-
433
- $localize = array(
434
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
435
- 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
436
- 'wc_status' => array(
437
- 'installed' => $is_wc_installed,
438
- 'active' => wcf()->is_woo_active,
439
- ),
440
- 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
441
- 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
442
- 'wcf_edit_test_mode' => $edit_test_mode,
443
- );
444
-
445
- wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
446
-
447
- if ( self::is_global_admin() ) {
448
-
449
- // Styles.
450
- wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
451
- wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
452
-
453
- wp_enqueue_script(
454
- 'wcf-global-admin',
455
- CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
456
- array( 'jquery' ),
457
- CARTFLOWS_VER,
458
- true
459
- );
460
-
461
- do_action( 'cartflows_global_admin_scripts' );
462
- }
463
- }
464
-
465
- /**
466
- * Global Admin Data.
467
- *
468
- * @since 1.0.0
469
- */
470
- public static function global_admin_data() {
471
-
472
- $current_screen = get_current_screen();
473
-
474
- if ( ! $current_screen ) {
475
- return;
476
- }
477
-
478
- if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
479
- return;
480
- }
481
-
482
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
483
- ?>
484
-
485
- <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
486
- <div class="wcf-templates-popup-content">
487
- <div class="spinner"></div>
488
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
489
-
490
- <div id="wcf-remote-flow-actions" class="wcf-template-header">
491
- <div class="wcf-template-logo-wrap">
492
- <span class="wcf-cartflows-logo-img">
493
- <span class="cartflows-logo-icon"></span>
494
- </span>
495
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
496
- </div>
497
- <div class="wcf-tab-wrapper">
498
- <?php if ( 'other' !== $default_page_builder ) { ?>
499
- <div id="wcf-get-started-steps">
500
- <ul class="filter-links ">
501
- <li>
502
- <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>
503
- </li>
504
- <li>
505
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
506
- </li>
507
- </ul>
508
- </div>
509
- <?php } ?>
510
- </div>
511
- <div class="wcf-popup-close-wrap">
512
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
513
- </div>
514
- </div>
515
- <!-- <div class="wcf-search-form">
516
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
517
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
518
- </div> -->
519
-
520
- <div id="wcf-remote-content">
521
- <?php if ( 'other' !== $default_page_builder ) { ?>
522
- <div id="wcf-ready-templates">
523
- <div id="wcf-remote-filters">
524
- <div id="wcf-page-builders"></div>
525
- <div id="wcf-categories"></div>
526
- </div>
527
- <div class="wcf-page-builder-notice"></div>
528
- <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
529
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
530
- </div>
531
- <?php } ?>
532
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
533
- <div class="inner">
534
- <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
535
- <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>
536
- </div>
537
- </div>
538
- </div>
539
- </div>
540
- </div>
541
- </div>
542
-
543
- <?php
544
- }
545
-
546
- /**
547
- * Enqueues the needed CSS/JS for the builder's admin settings page.
548
- *
549
- * @since 1.0.0
550
- */
551
- public static function styles_scripts() {
552
-
553
- // Styles.
554
- wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
555
- wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
556
-
557
- // Script.
558
- wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
559
-
560
- $localize = array(
561
- 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
562
- );
563
-
564
- wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
565
-
566
- do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
567
- }
568
-
569
- /**
570
- * Save All admin settings here
571
- */
572
- public static function save_settings() {
573
-
574
- // Only admins can save settings.
575
- if ( ! current_user_can( 'manage_options' ) ) {
576
- return;
577
- }
578
-
579
- self::save_common_settings();
580
- self::save_debug_settings();
581
- self::save_permalink_settings();
582
-
583
- self::save_google_analytics_settings();
584
- self::save_facebook_settings();
585
-
586
- // Let extensions hook into saving.
587
- do_action( 'cartflows_admin_settings_save' );
588
- }
589
-
590
- /**
591
- * Get and return page URL
592
- *
593
- * @param string $menu_slug Menu name.
594
- * @since 1.0.0
595
- * @return string page url
596
- */
597
- public static function get_page_url( $menu_slug ) {
598
-
599
- $parent_page = self::$default_menu_position;
600
-
601
- if ( strpos( $parent_page, '?' ) !== false ) {
602
- $query_var = '&page=' . self::$plugin_slug;
603
- } else {
604
- $query_var = '?page=' . self::$plugin_slug;
605
- }
606
-
607
- $parent_page_url = admin_url( $parent_page . $query_var );
608
-
609
- $url = $parent_page_url . '&action=' . $menu_slug;
610
-
611
- return esc_url( $url );
612
- }
613
-
614
- /**
615
- * Admin body classes.
616
- *
617
- * Body classes to be added to <body> tag in admin page
618
- *
619
- * @param String $classes body classes returned from the filter.
620
- * @return String body classes to be added to <body> tag in admin page
621
- */
622
- public static function add_admin_body_class( $classes ) {
623
-
624
- $classes .= ' cartflows-' . CARTFLOWS_VER;
625
-
626
- return $classes;
627
- }
628
-
629
- /**
630
- * Save Global Setting options.
631
- *
632
- * @since 1.0.0
633
- */
634
- public static function save_facebook_settings() {
635
-
636
- if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
637
-
638
- $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
639
- $new_settings = array();
640
-
641
- if ( isset( $_POST['_cartflows_facebook'] ) ) {
642
- $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
643
- }
644
-
645
- Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
646
- $query = array(
647
- 'message' => 'saved',
648
- );
649
- $redirect_to = add_query_arg( $query, $url );
650
- wp_safe_redirect( $redirect_to );
651
- exit;
652
- }
653
- }
654
-
655
- }
656
-
657
- 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
+ }
62
+
63
+ /**
64
+ * After save of permalinks.
65
+ */
66
+ public static function cartflows_after_save_permalinks() {
67
+
68
+ $has_saved_permalinks = get_option( 'cartflows_permalink_saved' );
69
+ if ( $has_saved_permalinks ) {
70
+ flush_rewrite_rules();
71
+ delete_option( 'cartflows_permalink_saved' );
72
+ }
73
+ }
74
+
75
+
76
+ /**
77
+ * Initialize after Cartflows pro get loaded.
78
+ */
79
+ public static function settings_admin_scripts() {
80
+ // Enqueue admin scripts.
81
+ if ( isset( $_GET['page'] ) && false !== strpos( $_GET['page'], 'cartflows_' ) ) { //phpcs:ignore
82
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
83
+
84
+ self::save_settings();
85
+ }
86
+ }
87
+ /**
88
+ * Show action on plugin page.
89
+ *
90
+ * @param array $links links.
91
+ * @return array
92
+ */
93
+ public static function add_action_links( $links ) {
94
+ $mylinks = array(
95
+ '<a href="' . admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS ) . '">Settings</a>',
96
+ '<a target="_blank" href="' . esc_url( 'https://cartflows.com/docs' ) . '">Docs</a>',
97
+ );
98
+
99
+ if ( ! _is_cartflows_pro() ) {
100
+ array_push( $mylinks, '<a style="color: #39b54a; font-weight: bold;" target="_blank" href="' . esc_url( 'https://cartflows.com/pricing/' ) . '"> Go Pro </a>' );
101
+ }
102
+
103
+ return array_merge( $links, $mylinks );
104
+ }
105
+
106
+ /**
107
+ * Initialises the Plugin Name.
108
+ *
109
+ * @since 1.0.0
110
+ * @return void
111
+ */
112
+ public static function initialise_plugin() {
113
+
114
+ $name = 'Cartflows';
115
+ $short_name = 'Cflows';
116
+
117
+ define( 'CARTFLOWS_PLUGIN_NAME', $name );
118
+ define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
119
+ }
120
+
121
+ /**
122
+ * Renders the admin settings menu.
123
+ *
124
+ * @since 1.0.0
125
+ * @return void
126
+ */
127
+ public static function menu() {
128
+
129
+ if ( ! current_user_can( 'manage_options' ) ) {
130
+ return;
131
+ }
132
+
133
+ add_menu_page(
134
+ 'CartFlows',
135
+ 'CartFlows',
136
+ 'manage_options',
137
+ CARTFLOWS_SLUG,
138
+ __CLASS__ . '::render',
139
+ 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),//phpcs:ignore
140
+ 39.7
141
+ );
142
+
143
+ }
144
+
145
+ /**
146
+ * Add submenu to admin menu.
147
+ *
148
+ * @since 1.0.0
149
+ */
150
+ public static function submenu() {
151
+
152
+ $parent_slug = CARTFLOWS_SLUG;
153
+ $page_title = __( 'Settings', 'cartflows' );
154
+ $menu_title = __( 'Settings', 'cartflows' );
155
+ $capability = 'manage_options';
156
+ $menu_slug = 'cartflows_settings';
157
+ $callback = __CLASS__ . '::render';
158
+
159
+ add_submenu_page(
160
+ $parent_slug,
161
+ $page_title,
162
+ $menu_title,
163
+ $capability,
164
+ $menu_slug,
165
+ $callback
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Renders the admin settings.
171
+ *
172
+ * @since 1.0.0
173
+ * @return void
174
+ */
175
+ public static function render() {
176
+ $menu_page_slug = ( isset( $_GET['page'] ) ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : CARTFLOWS_SETTINGS; //phpcs:ignore
177
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
178
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
179
+ $action = str_replace( '_', '-', $action );
180
+
181
+ // Enable header icon filter below.
182
+ $header_wrapper_class = apply_filters( 'cartflows_admin_header_wrapper_class', array( $action, $menu_page_slug ) );
183
+
184
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
185
+ }
186
+
187
+ /**
188
+ * Renders the admin settings content.
189
+ *
190
+ * @since 1.0.0
191
+ * @param sting $menu_page_slug current page name.
192
+ *
193
+ * @return void
194
+ */
195
+ public static function render_content( $menu_page_slug ) {
196
+
197
+ if ( CARTFLOWS_SETTINGS === $menu_page_slug ) {
198
+
199
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; //phpcs:ignore
200
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
201
+ $action = str_replace( '_', '-', $action );
202
+ $action = 'general';
203
+
204
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Save Global Setting options.
210
+ *
211
+ * @since 1.0.0
212
+ */
213
+ public static function save_common_settings() {
214
+
215
+ if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-common-settings-nonce'] ) ), 'cartflows-common-settings' ) ) {
216
+
217
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
218
+ $new_settings = array();
219
+
220
+ if ( isset( $_POST['_cartflows_common'] ) ) {
221
+ // Loop through the input and sanitize each of the values.
222
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_common'] ) ); //phpcs:ignore
223
+ }
224
+
225
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, false );
226
+
227
+ $query = array(
228
+ 'message' => 'saved',
229
+ );
230
+
231
+ $redirect_to = add_query_arg( $query, $url );
232
+
233
+ wp_safe_redirect( $redirect_to );
234
+ exit;
235
+ } // End if statement.
236
+ }
237
+
238
+ /**
239
+ * Save Debug Setting options.
240
+ *
241
+ * @since 1.1.14
242
+ */
243
+ public static function save_debug_settings() {
244
+
245
+ if ( isset( $_POST['cartflows-debug-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-debug-settings-nonce'] ) ), 'cartflows-debug-settings' ) ) {
246
+
247
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
248
+ $new_settings = array();
249
+
250
+ if ( isset( $_POST['_cartflows_debug_data'] ) ) {
251
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_debug_data'] ) ); //phpcs:ignore
252
+ }
253
+
254
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_debug_data', $new_settings, false );
255
+
256
+ $query = array(
257
+ 'message' => 'saved',
258
+ );
259
+
260
+ $redirect_to = add_query_arg( $query, $url );
261
+
262
+ wp_safe_redirect( $redirect_to );
263
+ exit;
264
+
265
+ }
266
+ }
267
+
268
+
269
+ /**
270
+ * Save permalink Setting options.
271
+ *
272
+ * @since 1.1.14
273
+ */
274
+ public static function save_permalink_settings() {
275
+
276
+ if ( isset( $_POST['cartflows-permalink-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-permalink-settings-nonce'] ) ), 'cartflows-permalink-settings' ) ) {
277
+
278
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
279
+ $new_settings = array();
280
+
281
+ if ( isset( $_POST['reset'] ) ) {
282
+ $_POST['_cartflows_permalink'] = array(
283
+ 'permalink' => CARTFLOWS_STEP_POST_TYPE,
284
+ 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
285
+ 'permalink_structure' => '',
286
+ );
287
+
288
+ }
289
+
290
+ if ( isset( $_POST['_cartflows_permalink'] ) ) {
291
+ $cartflows_permalink_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_permalink'] ) ); //phpcs:ignore
292
+
293
+ if ( empty( $cartflows_permalink_settings['permalink'] ) ) {
294
+ $new_settings['permalink'] = CARTFLOWS_STEP_POST_TYPE;
295
+ } else {
296
+ $new_settings['permalink'] = $cartflows_permalink_settings['permalink'];
297
+ }
298
+
299
+ if ( empty( $cartflows_permalink_settings['permalink_flow_base'] ) ) {
300
+ $new_settings['permalink_flow_base'] = CARTFLOWS_FLOW_POST_TYPE;
301
+ } else {
302
+ $new_settings['permalink_flow_base'] = $cartflows_permalink_settings['permalink_flow_base'];
303
+ }
304
+
305
+ $new_settings['permalink_structure'] = $cartflows_permalink_settings['permalink_structure'];
306
+
307
+ }
308
+
309
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_permalink', $new_settings, false );
310
+
311
+ $query = array(
312
+ 'message' => 'saved',
313
+ );
314
+
315
+ $redirect_to = add_query_arg( $query, $url );
316
+
317
+ update_option( 'cartflows_permalink_saved', true );
318
+
319
+ wp_safe_redirect( $redirect_to );
320
+ exit;
321
+
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Save google analytics Setting options.
327
+ *
328
+ * @since 1.1.14
329
+ */
330
+ public static function save_google_analytics_settings() {
331
+
332
+ 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' ) ) {
333
+
334
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
335
+ $new_settings = array();
336
+
337
+ if ( isset( $_POST['_cartflows_google_analytics'] ) ) {
338
+ $new_settings = self::sanitize_form_inputs( $_POST['_cartflows_google_analytics'] ); //phpcs:ignore
339
+
340
+ }
341
+
342
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_google_analytics', $new_settings, true );
343
+
344
+ $query = array(
345
+ 'message' => 'saved',
346
+ );
347
+
348
+ $redirect_to = add_query_arg( $query, $url );
349
+
350
+ wp_safe_redirect( $redirect_to );
351
+ exit;
352
+
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Loop through the input and sanitize each of the values.
358
+ *
359
+ * @param array $input_settings input settings.
360
+ * @return array
361
+ */
362
+ public static function sanitize_form_inputs( $input_settings = array() ) {
363
+ $new_settings = array();
364
+ foreach ( $input_settings as $key => $val ) {
365
+
366
+ if ( is_array( $val ) ) {
367
+ foreach ( $val as $k => $v ) {
368
+ $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
369
+ }
370
+ } else {
371
+ $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
372
+ }
373
+ }
374
+ return $new_settings;
375
+ }
376
+
377
+ /**
378
+ * Check is cartflows admin.
379
+ *
380
+ * @since 1.0.0
381
+ * @return boolean
382
+ */
383
+ public static function is_global_admin() {
384
+
385
+ $current_screen = get_current_screen();
386
+
387
+ if (
388
+ is_object( $current_screen ) &&
389
+ isset( $current_screen->post_type ) &&
390
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
391
+ CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
392
+ )
393
+ ) {
394
+ return true;
395
+ }
396
+ return false;
397
+ }
398
+
399
+ /**
400
+ * Check is flow admin.
401
+ *
402
+ * @since 1.0.0
403
+ * @return boolean
404
+ */
405
+ public static function is_flow_edit_admin() {
406
+
407
+ $current_screen = get_current_screen();
408
+
409
+ if (
410
+ is_object( $current_screen ) &&
411
+ isset( $current_screen->post_type ) &&
412
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
413
+ isset( $current_screen->base ) &&
414
+ ( 'post' === $current_screen->base )
415
+ ) {
416
+ return true;
417
+ }
418
+ return false;
419
+ }
420
+
421
+ /**
422
+ * Global Admin Scripts.
423
+ *
424
+ * @since 1.0.0
425
+ */
426
+ public static function global_admin_scripts() {
427
+
428
+ $installed_plugins = get_plugins();
429
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? true : false;
430
+ $edit_test_mode = filter_input( INPUT_GET, 'edit_test_mode', FILTER_SANITIZE_STRING );
431
+ $edit_test_mode = 'yes' === $edit_test_mode ? true : false;
432
+
433
+ $localize = array(
434
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
435
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
436
+ 'wc_status' => array(
437
+ 'installed' => $is_wc_installed,
438
+ 'active' => wcf()->is_woo_active,
439
+ ),
440
+ 'wc_activating_message' => __( 'Installing and activating..', 'cartflows' ),
441
+ 'wc_install_error' => __( 'There was an error with the installation of plugin.', 'cartflows' ),
442
+ 'wcf_edit_test_mode' => $edit_test_mode,
443
+ );
444
+
445
+ wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
446
+
447
+ if ( self::is_global_admin() ) {
448
+
449
+ // Styles.
450
+ wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
451
+ wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
452
+
453
+ wp_enqueue_script(
454
+ 'wcf-global-admin',
455
+ CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
456
+ array( 'jquery' ),
457
+ CARTFLOWS_VER,
458
+ true
459
+ );
460
+
461
+ do_action( 'cartflows_global_admin_scripts' );
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Global Admin Data.
467
+ *
468
+ * @since 1.0.0
469
+ */
470
+ public static function global_admin_data() {
471
+
472
+ $current_screen = get_current_screen();
473
+
474
+ if ( ! $current_screen ) {
475
+ return;
476
+ }
477
+
478
+ if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
479
+ return;
480
+ }
481
+
482
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
483
+ ?>
484
+
485
+ <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
486
+ <div class="wcf-templates-popup-content">
487
+ <div class="spinner"></div>
488
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
489
+
490
+ <div id="wcf-remote-flow-actions" class="wcf-template-header">
491
+ <div class="wcf-template-logo-wrap">
492
+ <span class="wcf-cartflows-logo-img">
493
+ <span class="cartflows-logo-icon"></span>
494
+ </span>
495
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Flows Library', 'cartflows' ); ?></span>
496
+ </div>
497
+ <div class="wcf-tab-wrapper">
498
+ <?php if ( 'other' !== $default_page_builder ) { ?>
499
+ <div id="wcf-get-started-steps">
500
+ <ul class="filter-links ">
501
+ <li>
502
+ <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>
503
+ </li>
504
+ <li>
505
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
506
+ </li>
507
+ </ul>
508
+ </div>
509
+ <?php } ?>
510
+ </div>
511
+ <div class="wcf-popup-close-wrap">
512
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
513
+ </div>
514
+ </div>
515
+ <!-- <div class="wcf-search-form">
516
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
517
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
518
+ </div> -->
519
+
520
+ <div id="wcf-remote-content">
521
+ <?php if ( 'other' !== $default_page_builder ) { ?>
522
+ <div id="wcf-ready-templates">
523
+ <div id="wcf-remote-filters">
524
+ <div id="wcf-page-builders"></div>
525
+ <div id="wcf-categories"></div>
526
+ </div>
527
+ <div class="wcf-page-builder-notice"></div>
528
+ <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
529
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
530
+ </div>
531
+ <?php } ?>
532
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
533
+ <div class="inner">
534
+ <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php esc_html_e( 'Design Your Flow', 'cartflows' ); ?></a>
535
+ <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>
536
+ </div>
537
+ </div>
538
+ </div>
539
+ </div>
540
+ </div>
541
+ </div>
542
+
543
+ <?php
544
+ }
545
+
546
+ /**
547
+ * Enqueues the needed CSS/JS for the builder's admin settings page.
548
+ *
549
+ * @since 1.0.0
550
+ */
551
+ public static function styles_scripts() {
552
+
553
+ // Styles.
554
+ wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
555
+ wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
556
+
557
+ // Script.
558
+ wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
559
+
560
+ $localize = array(
561
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
562
+ );
563
+
564
+ wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
565
+
566
+ do_action( 'cartflows_admin_settings_after_enqueue_scripts' );
567
+ }
568
+
569
+ /**
570
+ * Save All admin settings here
571
+ */
572
+ public static function save_settings() {
573
+
574
+ // Only admins can save settings.
575
+ if ( ! current_user_can( 'manage_options' ) ) {
576
+ return;
577
+ }
578
+
579
+ self::save_common_settings();
580
+ self::save_debug_settings();
581
+ self::save_permalink_settings();
582
+
583
+ self::save_google_analytics_settings();
584
+ self::save_facebook_settings();
585
+
586
+ // Let extensions hook into saving.
587
+ do_action( 'cartflows_admin_settings_save' );
588
+ }
589
+
590
+ /**
591
+ * Get and return page URL
592
+ *
593
+ * @param string $menu_slug Menu name.
594
+ * @since 1.0.0
595
+ * @return string page url
596
+ */
597
+ public static function get_page_url( $menu_slug ) {
598
+
599
+ $parent_page = self::$default_menu_position;
600
+
601
+ if ( strpos( $parent_page, '?' ) !== false ) {
602
+ $query_var = '&page=' . self::$plugin_slug;
603
+ } else {
604
+ $query_var = '?page=' . self::$plugin_slug;
605
+ }
606
+
607
+ $parent_page_url = admin_url( $parent_page . $query_var );
608
+
609
+ $url = $parent_page_url . '&action=' . $menu_slug;
610
+
611
+ return esc_url( $url );
612
+ }
613
+
614
+ /**
615
+ * Admin body classes.
616
+ *
617
+ * Body classes to be added to <body> tag in admin page
618
+ *
619
+ * @param String $classes body classes returned from the filter.
620
+ * @return String body classes to be added to <body> tag in admin page
621
+ */
622
+ public static function add_admin_body_class( $classes ) {
623
+
624
+ $classes .= ' cartflows-' . CARTFLOWS_VER;
625
+
626
+ return $classes;
627
+ }
628
+
629
+ /**
630
+ * Save Global Setting options.
631
+ *
632
+ * @since 1.0.0
633
+ */
634
+ public static function save_facebook_settings() {
635
+
636
+ if ( isset( $_POST['cartflows-facebook-settings-nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-facebook-settings-nonce'] ) ), 'cartflows-facebook-settings' ) ) {
637
+
638
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
639
+ $new_settings = array();
640
+
641
+ if ( isset( $_POST['_cartflows_facebook'] ) ) {
642
+ $new_settings = self::sanitize_form_inputs( wp_unslash( $_POST['_cartflows_facebook'] ) ); //phpcs:ignore
643
+ }
644
+
645
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_facebook', $new_settings, false );
646
+ $query = array(
647
+ 'message' => 'saved',
648
+ );
649
+ $redirect_to = add_query_arg( $query, $url );
650
+ wp_safe_redirect( $redirect_to );
651
+ exit;
652
+ }
653
+ }
654
+
655
+ }
656
+
657
+ Cartflows_Admin::init();
classes/class-cartflows-default-meta.php CHANGED
@@ -1,871 +1,871 @@
1
- <?php
2
- /**
3
- * Cartflow default options.
4
- *
5
- * @package Cartflows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Default_Meta {
14
-
15
-
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_fields
28
- */
29
- private static $checkout_fields = null;
30
-
31
- /**
32
- * Member Variable
33
- *
34
- * @var checkout_fields
35
- */
36
- private static $thankyou_fields = null;
37
-
38
- /**
39
- * Member Variable
40
- *
41
- * @var flow_fields
42
- */
43
- private static $flow_fields = null;
44
-
45
- /**
46
- * Member Variable
47
- *
48
- * @var landing_fields
49
- */
50
- private static $landing_fields = null;
51
-
52
- /**
53
- * Member Variable
54
- *
55
- * @var optin_fields
56
- */
57
- private static $optin_fields = null;
58
-
59
- /**
60
- * Initiator
61
- */
62
- public static function get_instance() {
63
- if ( ! isset( self::$instance ) ) {
64
- self::$instance = new self();
65
- }
66
- return self::$instance;
67
- }
68
-
69
- /**
70
- * Constructor
71
- */
72
- public function __construct() {
73
- }
74
-
75
- /**
76
- * Checkout Default fields.
77
- *
78
- * @param int $post_id post id.
79
- * @return array
80
- */
81
- public function get_checkout_fields( $post_id ) {
82
-
83
- if ( null === self::$checkout_fields ) {
84
- self::$checkout_fields = array(
85
- 'wcf-field-google-font-url' => array(
86
- 'default' => '',
87
- 'sanitize' => 'FILTER_DEFAULT',
88
- ),
89
- 'wcf-checkout-products' => array(
90
- 'default' => array(),
91
- 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
- ),
93
- 'wcf-checkout-layout' => array(
94
- 'default' => 'two-column',
95
- 'sanitize' => 'FILTER_DEFAULT',
96
- ),
97
- 'wcf-input-font-family' => array(
98
- 'default' => '',
99
- 'sanitize' => 'FILTER_DEFAULT',
100
- ),
101
- 'wcf-input-font-weight' => array(
102
- 'default' => '',
103
- 'sanitize' => 'FILTER_DEFAULT',
104
- ),
105
- 'wcf-heading-font-family' => array(
106
- 'default' => '',
107
- 'sanitize' => 'FILTER_DEFAULT',
108
- ),
109
- 'wcf-heading-font-weight' => array(
110
- 'default' => '',
111
- 'sanitize' => 'FILTER_DEFAULT',
112
- ),
113
- 'wcf-base-font-family' => array(
114
- 'default' => '',
115
- 'sanitize' => 'FILTER_DEFAULT',
116
- ),
117
- 'wcf-advance-options-fields' => array(
118
- 'default' => '',
119
- 'sanitize' => 'FILTER_DEFAULT',
120
- ),
121
- 'wcf-remove-product-field' => array(
122
- 'default' => '',
123
- 'sanitize' => 'FILTER_DEFAULT',
124
- ),
125
- 'wcf-checkout-place-order-button-text' => array(
126
- 'default' => '',
127
- 'sanitize' => 'FILTER_SANITIZE_STRING',
128
- ),
129
- 'wcf-base-font-weight' => array(
130
- 'default' => '',
131
- 'sanitize' => 'FILTER_DEFAULT',
132
- ),
133
- 'wcf-button-font-family' => array(
134
- 'default' => '',
135
- 'sanitize' => 'FILTER_DEFAULT',
136
- ),
137
- 'wcf-button-font-weight' => array(
138
- 'default' => '',
139
- 'sanitize' => 'FILTER_DEFAULT',
140
- ),
141
- 'wcf-primary-color' => array(
142
- 'default' => '',
143
- 'sanitize' => 'FILTER_DEFAULT',
144
- ),
145
- 'wcf-heading-color' => array(
146
- 'default' => '',
147
- 'sanitize' => 'FILTER_DEFAULT',
148
- ),
149
- 'wcf-section-bg-color' => array(
150
- 'default' => '',
151
- 'sanitize' => 'FILTER_DEFAULT',
152
- ),
153
- 'wcf-hl-bg-color' => array(
154
- 'default' => '',
155
- 'sanitize' => 'FILTER_DEFAULT',
156
- ),
157
- 'wcf-field-tb-padding' => array(
158
- 'default' => '',
159
- 'sanitize' => 'FILTER_DEFAULT',
160
- ),
161
- 'wcf-field-lr-padding' => array(
162
- 'default' => '',
163
- 'sanitize' => 'FILTER_DEFAULT',
164
- ),
165
- 'wcf-fields-skins' => array(
166
- 'default' => '',
167
- 'sanitize' => 'FILTER_DEFAULT',
168
- ),
169
- 'wcf-input-field-size' => array(
170
- 'default' => '33px',
171
- 'sanitize' => 'FILTER_DEFAULT',
172
- ),
173
- 'wcf-field-color' => array(
174
- 'default' => '',
175
- 'sanitize' => 'FILTER_DEFAULT',
176
- ),
177
- 'wcf-field-bg-color' => array(
178
- 'default' => '',
179
- 'sanitize' => 'FILTER_DEFAULT',
180
- ),
181
- 'wcf-field-border-color' => array(
182
- 'default' => '',
183
- 'sanitize' => 'FILTER_DEFAULT',
184
- ),
185
- 'wcf-box-border-color' => array(
186
- 'default' => '',
187
- 'sanitize' => 'FILTER_DEFAULT',
188
- ),
189
- 'wcf-field-label-color' => array(
190
- 'default' => '',
191
- 'sanitize' => 'FILTER_DEFAULT',
192
- ),
193
- 'wcf-submit-tb-padding' => array(
194
- 'default' => '',
195
- 'sanitize' => 'FILTER_DEFAULT',
196
- ),
197
- 'wcf-submit-lr-padding' => array(
198
- 'default' => '',
199
- 'sanitize' => 'FILTER_DEFAULT',
200
- ),
201
- 'wcf-input-button-size' => array(
202
- 'default' => '33px',
203
- 'sanitize' => 'FILTER_DEFAULT',
204
- ),
205
- 'wcf-submit-color' => array(
206
- 'default' => '',
207
- 'sanitize' => 'FILTER_DEFAULT',
208
- ),
209
- 'wcf-submit-hover-color' => array(
210
- 'default' => '',
211
- 'sanitize' => 'FILTER_DEFAULT',
212
- ),
213
- 'wcf-submit-bg-color' => array(
214
- 'default' => '',
215
- 'sanitize' => 'FILTER_DEFAULT',
216
- ),
217
- 'wcf-submit-bg-hover-color' => array(
218
- 'default' => '',
219
- 'sanitize' => 'FILTER_DEFAULT',
220
- ),
221
- 'wcf-submit-border-color' => array(
222
- 'default' => '',
223
- 'sanitize' => 'FILTER_DEFAULT',
224
- ),
225
- 'wcf-submit-border-hover-color' => array(
226
- 'default' => '',
227
- 'sanitize' => 'FILTER_DEFAULT',
228
- ),
229
- 'wcf-active-tab' => array(
230
- 'default' => '',
231
- 'sanitize' => 'FILTER_DEFAULT',
232
- ),
233
- 'wcf-header-logo-image' => array(
234
- 'default' => '',
235
- 'sanitize' => 'FILTER_DEFAULT',
236
- ),
237
- 'wcf-header-logo-width' => array(
238
- 'default' => '',
239
- 'sanitize' => 'FILTER_DEFAULT',
240
- ),
241
- 'wcf-custom-script' => array(
242
- 'default' => '',
243
- 'sanitize' => 'FILTER_DEFAULT',
244
- ),
245
- );
246
-
247
- self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
- }
249
-
250
- return self::$checkout_fields;
251
- }
252
-
253
- /**
254
- * Save Checkout Meta fields.
255
- *
256
- * @param int $post_id post id.
257
- * @return void
258
- */
259
- public function save_checkout_fields( $post_id ) {
260
-
261
- $post_meta = $this->get_checkout_fields( $post_id );
262
-
263
- $this->save_meta_fields( $post_id, $post_meta );
264
- }
265
-
266
- /**
267
- * Save Landing Meta fields.
268
- *
269
- * @param int $post_id post id.
270
- * @return void
271
- */
272
- public function save_landing_fields( $post_id ) {
273
-
274
- $post_meta = $this->get_landing_fields( $post_id );
275
-
276
- $this->save_meta_fields( $post_id, $post_meta );
277
- }
278
-
279
- /**
280
- * Save ThankYou Meta fields.
281
- *
282
- * @param int $post_id post id.
283
- * @return void
284
- */
285
- public function save_thankyou_fields( $post_id ) {
286
-
287
- $post_meta = $this->get_thankyou_fields( $post_id );
288
-
289
- $this->save_meta_fields( $post_id, $post_meta );
290
- }
291
-
292
- /**
293
- * Flow Default fields.
294
- *
295
- * @param int $post_id post id.
296
- * @return array
297
- */
298
- public function get_flow_fields( $post_id ) {
299
-
300
- if ( null === self::$flow_fields ) {
301
- self::$flow_fields = array(
302
- 'wcf-steps' => array(
303
- 'default' => array(),
304
- 'sanitize' => 'FILTER_DEFAULT',
305
- ),
306
-
307
- 'wcf-testing' => array(
308
- 'default' => 'no',
309
- 'sanitize' => 'FILTER_DEFAULT',
310
- ),
311
- );
312
- }
313
-
314
- return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
- }
316
-
317
- /**
318
- * Save Flow Meta fields.
319
- *
320
- * @param int $post_id post id.
321
- * @return void
322
- */
323
- public function save_flow_fields( $post_id ) {
324
-
325
- $post_meta = $this->get_flow_fields( $post_id );
326
-
327
- if ( isset( $post_meta['wcf-steps'] ) ) {
328
- unset( $post_meta['wcf-steps'] );
329
- }
330
-
331
- $this->save_meta_fields( $post_id, $post_meta );
332
- }
333
-
334
- /**
335
- * Save Meta fields - Common Function.
336
- *
337
- * @param int $post_id post id.
338
- * @param array $post_meta options to store.
339
- * @return void
340
- */
341
- public function save_meta_fields( $post_id, $post_meta ) {
342
-
343
- if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
- return;
345
- }
346
-
347
- foreach ( $post_meta as $key => $data ) {
348
- $meta_value = false;
349
-
350
- // Sanitize values.
351
- $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
-
353
- switch ( $sanitize_filter ) {
354
- case 'FILTER_SANITIZE_STRING':
355
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
- break;
357
-
358
- case 'FILTER_SANITIZE_URL':
359
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
- break;
361
-
362
- case 'FILTER_SANITIZE_NUMBER_INT':
363
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
- break;
365
-
366
- case 'FILTER_CARTFLOWS_ARRAY':
367
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
- $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
- }
370
- break;
371
-
372
- case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
- $i = 0;
375
- $q = 0;
376
-
377
- foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
- if ( ! array_key_exists( 'product', $p_data ) ) {
379
- continue;
380
- }
381
- foreach ( $p_data as $i_key => $i_value ) {
382
-
383
- if ( is_array( $i_value ) ) {
384
- foreach ( $i_value as $q_key => $q_value ) {
385
- $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
-
387
- $q++;
388
- }
389
- } else {
390
- $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
- }
392
- }
393
-
394
- $i++;
395
- }
396
- }
397
- break;
398
-
399
- case 'FILTER_CARTFLOWS_IMAGES':
400
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
-
402
- if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
-
404
- if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
-
406
- $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
- $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
-
409
- $image_data = array(
410
- 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
- 'url' => array(
412
- 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
- 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
- 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
- ),
416
- );
417
-
418
- $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
- update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
- }
421
- }
422
-
423
- break;
424
-
425
- default:
426
- if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
- } else {
429
- $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
- }
431
-
432
- break;
433
- }
434
-
435
- if ( false !== $meta_value ) {
436
- update_post_meta( $post_id, $key, $meta_value );
437
- } else {
438
- delete_post_meta( $post_id, $key );
439
- }
440
- }
441
- }
442
-
443
- /**
444
- * Get checkout meta.
445
- *
446
- * @param int $post_id post id.
447
- * @param string $key options key.
448
- * @param mix $default options default value.
449
- * @return string
450
- */
451
- public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
-
453
- $value = $this->get_save_meta( $post_id, $key );
454
-
455
- if ( ! $value ) {
456
- if ( $default ) {
457
- $value = $default;
458
- } else {
459
- $fields = $this->get_flow_fields( $post_id );
460
-
461
- if ( isset( $fields[ $key ]['default'] ) ) {
462
- $value = $fields[ $key ]['default'];
463
- }
464
- }
465
- }
466
-
467
- return $value;
468
- }
469
-
470
- /**
471
- * Get checkout meta.
472
- *
473
- * @param int $post_id post id.
474
- * @param string $key options key.
475
- * @param mix $default options default value.
476
- * @return string
477
- */
478
- public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
-
480
- $value = $this->get_save_meta( $post_id, $key );
481
-
482
- if ( ! $value ) {
483
- if ( false !== $default ) {
484
- $value = $default;
485
- } else {
486
- $fields = $this->get_checkout_fields( $post_id );
487
-
488
- if ( isset( $fields[ $key ]['default'] ) ) {
489
- $value = $fields[ $key ]['default'];
490
- }
491
- }
492
- }
493
-
494
- return $value;
495
- }
496
-
497
- /**
498
- * Get post meta.
499
- *
500
- * @param int $post_id post id.
501
- * @param string $key options key.
502
- * @return string
503
- */
504
- public function get_save_meta( $post_id, $key ) {
505
-
506
- $value = get_post_meta( $post_id, $key, true );
507
-
508
- return $value;
509
- }
510
-
511
- /**
512
- * Thank You Default fields.
513
- *
514
- * @param int $post_id post id.
515
- * @return array
516
- */
517
- public function get_thankyou_fields( $post_id ) {
518
-
519
- if ( null === self::$thankyou_fields ) {
520
- self::$thankyou_fields = array(
521
- 'wcf-field-google-font-url' => array(
522
- 'default' => '',
523
- 'sanitize' => 'FILTER_DEFAULT',
524
- ),
525
- 'wcf-active-tab' => array(
526
- 'default' => '',
527
- 'sanitize' => 'FILTER_DEFAULT',
528
- ),
529
- 'wcf-tq-text-color' => array(
530
- 'default' => '',
531
- 'sanitize' => 'FILTER_DEFAULT',
532
- ),
533
- 'wcf-tq-font-family' => array(
534
- 'default' => '',
535
- 'sanitize' => 'FILTER_DEFAULT',
536
- ),
537
- 'wcf-tq-font-size' => array(
538
- 'default' => '',
539
- 'sanitize' => 'FILTER_DEFAULT',
540
- ),
541
- 'wcf-tq-heading-color' => array(
542
- 'default' => '',
543
- 'sanitize' => 'FILTER_DEFAULT',
544
- ),
545
- 'wcf-tq-heading-font-family' => array(
546
- 'default' => '',
547
- 'sanitize' => 'FILTER_DEFAULT',
548
- ),
549
- 'wcf-tq-heading-font-wt' => array(
550
- 'default' => '',
551
- 'sanitize' => 'FILTER_DEFAULT',
552
- ),
553
- 'wcf-tq-container-width' => array(
554
- 'default' => '',
555
- 'sanitize' => 'FILTER_DEFAULT',
556
- ),
557
- 'wcf-tq-section-bg-color' => array(
558
- 'default' => '',
559
- 'sanitize' => 'FILTER_DEFAULT',
560
- ),
561
- 'wcf-tq-advance-options-fields' => array(
562
- 'default' => '',
563
- 'sanitize' => 'FILTER_DEFAULT',
564
- ),
565
- 'wcf-show-overview-section' => array(
566
- 'default' => 'yes',
567
- 'sanitize' => 'FILTER_DEFAULT',
568
- ),
569
- 'wcf-show-details-section' => array(
570
- 'default' => 'yes',
571
- 'sanitize' => 'FILTER_DEFAULT',
572
- ),
573
- 'wcf-show-billing-section' => array(
574
- 'default' => 'yes',
575
- 'sanitize' => 'FILTER_DEFAULT',
576
- ),
577
- 'wcf-show-shipping-section' => array(
578
- 'default' => 'yes',
579
- 'sanitize' => 'FILTER_DEFAULT',
580
- ),
581
- 'wcf-show-tq-redirect-section' => array(
582
- 'default' => '',
583
- 'sanitize' => 'FILTER_DEFAULT',
584
- ),
585
- 'wcf-tq-redirect-link' => array(
586
- 'default' => '',
587
- 'sanitize' => 'FILTER_SANITIZE_URL',
588
- ),
589
- 'wcf-tq-text' => array(
590
- 'default' => '',
591
- 'sanitize' => 'FILTER_DEFAULT',
592
- ),
593
- 'wcf-custom-script' => array(
594
- 'default' => '',
595
- 'sanitize' => 'FILTER_DEFAULT',
596
- ),
597
- );
598
- }
599
-
600
- return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
- }
602
-
603
- /**
604
- * Get Thank you section meta.
605
- *
606
- * @param int $post_id post id.
607
- * @param string $key options key.
608
- * @param mix $default options default value.
609
- * @return string
610
- */
611
- public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
-
613
- $value = $this->get_save_meta( $post_id, $key );
614
-
615
- if ( ! $value ) {
616
- if ( $default ) {
617
- $value = $default;
618
- } else {
619
- $fields = $this->get_thankyou_fields( $post_id );
620
-
621
- if ( isset( $fields[ $key ]['default'] ) ) {
622
- $value = $fields[ $key ]['default'];
623
- }
624
- }
625
- }
626
-
627
- return $value;
628
- }
629
-
630
- /**
631
- * Get Landing section meta.
632
- *
633
- * @param int $post_id post id.
634
- * @param string $key options key.
635
- * @param mix $default options default value.
636
- * @return string
637
- */
638
- public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
-
640
- $value = $this->get_save_meta( $post_id, $key );
641
- if ( ! $value ) {
642
- if ( $default ) {
643
- $value = $default;
644
- } else {
645
- $fields = $this->get_landing_fields( $post_id );
646
-
647
- if ( isset( $fields[ $key ]['default'] ) ) {
648
- $value = $fields[ $key ]['default'];
649
- }
650
- }
651
- }
652
-
653
- return $value;
654
- }
655
-
656
- /**
657
- * Landing Default fields.
658
- *
659
- * @param int $post_id post id.
660
- * @return array
661
- */
662
- public function get_landing_fields( $post_id ) {
663
-
664
- if ( null === self::$landing_fields ) {
665
- self::$landing_fields = array(
666
- 'wcf-custom-script' => array(
667
- 'default' => '',
668
- 'sanitize' => 'FILTER_DEFAULT',
669
- ),
670
- );
671
- }
672
- return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
- }
674
-
675
- /**
676
- * Optin Default fields.
677
- *
678
- * @param int $post_id post id.
679
- * @return array
680
- */
681
- public function get_optin_fields( $post_id ) {
682
-
683
- if ( null === self::$optin_fields ) {
684
- self::$optin_fields = array(
685
-
686
- 'wcf-optin-product' => array(
687
- 'default' => array(),
688
- 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
- ),
690
-
691
- /* Style */
692
- 'wcf-field-google-font-url' => array(
693
- 'default' => '',
694
- 'sanitize' => 'FILTER_DEFAULT',
695
- ),
696
- 'wcf-primary-color' => array(
697
- 'default' => '',
698
- 'sanitize' => 'FILTER_DEFAULT',
699
- ),
700
- 'wcf-base-font-family' => array(
701
- 'default' => '',
702
- 'sanitize' => 'FILTER_DEFAULT',
703
- ),
704
- 'wcf-input-fields-skins' => array(
705
- 'default' => '',
706
- 'sanitize' => 'FILTER_DEFAULT',
707
- ),
708
- 'wcf-input-font-family' => array(
709
- 'default' => '',
710
- 'sanitize' => 'FILTER_DEFAULT',
711
- ),
712
- 'wcf-input-font-weight' => array(
713
- 'default' => '',
714
- 'sanitize' => 'FILTER_DEFAULT',
715
- ),
716
- 'wcf-input-field-size' => array(
717
- 'default' => '33px',
718
- 'sanitize' => 'FILTER_DEFAULT',
719
- ),
720
- 'wcf-field-tb-padding' => array(
721
- 'default' => '',
722
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
- ),
724
- 'wcf-field-lr-padding' => array(
725
- 'default' => '',
726
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
- ),
728
- 'wcf-field-color' => array(
729
- 'default' => '',
730
- 'sanitize' => 'FILTER_DEFAULT',
731
- ),
732
- 'wcf-field-bg-color' => array(
733
- 'default' => '',
734
- 'sanitize' => 'FILTER_DEFAULT',
735
- ),
736
- 'wcf-field-border-color' => array(
737
- 'default' => '',
738
- 'sanitize' => 'FILTER_DEFAULT',
739
- ),
740
- 'wcf-field-label-color' => array(
741
- 'default' => '',
742
- 'sanitize' => 'FILTER_DEFAULT',
743
- ),
744
- 'wcf-submit-button-text' => array(
745
- 'default' => __( 'Submit', 'cartflows' ),
746
- 'sanitize' => 'FILTER_DEFAULT',
747
- ),
748
- 'wcf-submit-font-size' => array(
749
- 'default' => '',
750
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
- ),
752
- 'wcf-button-font-family' => array(
753
- 'default' => '',
754
- 'sanitize' => 'FILTER_DEFAULT',
755
- ),
756
- 'wcf-button-font-weight' => array(
757
- 'default' => '',
758
- 'sanitize' => 'FILTER_DEFAULT',
759
- ),
760
- 'wcf-submit-button-size' => array(
761
- 'default' => '33px',
762
- 'sanitize' => 'FILTER_DEFAULT',
763
- ),
764
- 'wcf-submit-tb-padding' => array(
765
- 'default' => '',
766
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
- ),
768
- 'wcf-submit-lr-padding' => array(
769
- 'default' => '',
770
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
- ),
772
- 'wcf-submit-button-position' => array(
773
- 'default' => 'center',
774
- 'sanitize' => 'FILTER_DEFAULT',
775
- ),
776
- 'wcf-submit-color' => array(
777
- 'default' => '',
778
- 'sanitize' => 'FILTER_DEFAULT',
779
- ),
780
- 'wcf-submit-hover-color' => array(
781
- 'default' => '',
782
- 'sanitize' => 'FILTER_DEFAULT',
783
- ),
784
- 'wcf-submit-bg-color' => array(
785
- 'default' => '',
786
- 'sanitize' => 'FILTER_DEFAULT',
787
- ),
788
- 'wcf-submit-bg-hover-color' => array(
789
- 'default' => '',
790
- 'sanitize' => 'FILTER_DEFAULT',
791
- ),
792
- 'wcf-submit-border-color' => array(
793
- 'default' => '',
794
- 'sanitize' => 'FILTER_DEFAULT',
795
- ),
796
- 'wcf-submit-border-hover-color' => array(
797
- 'default' => '',
798
- 'sanitize' => 'FILTER_DEFAULT',
799
- ),
800
-
801
- /* Settings */
802
- 'wcf-optin-pass-fields' => array(
803
- 'default' => '',
804
- 'sanitize' => 'FILTER_DEFAULT',
805
- ),
806
- 'wcf-optin-pass-specific-fields' => array(
807
- 'default' => 'first_name',
808
- 'sanitize' => 'FILTER_DEFAULT',
809
- ),
810
-
811
- /* Script */
812
- 'wcf-custom-script' => array(
813
- 'default' => '',
814
- 'sanitize' => 'FILTER_DEFAULT',
815
- ),
816
-
817
- /* Hidden */
818
- 'wcf-active-tab' => array(
819
- 'default' => '',
820
- 'sanitize' => 'FILTER_DEFAULT',
821
- ),
822
- );
823
- }
824
- return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
- }
826
-
827
- /**
828
- * Save Optin Meta fields.
829
- *
830
- * @param int $post_id post id.
831
- * @return void
832
- */
833
- public function save_optin_fields( $post_id ) {
834
-
835
- $post_meta = $this->get_optin_fields( $post_id );
836
-
837
- $this->save_meta_fields( $post_id, $post_meta );
838
- }
839
-
840
- /**
841
- * Get optin meta.
842
- *
843
- * @param int $post_id post id.
844
- * @param string $key options key.
845
- * @param mix $default options default value.
846
- * @return string
847
- */
848
- public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
-
850
- $value = $this->get_save_meta( $post_id, $key );
851
-
852
- if ( ! $value ) {
853
- if ( false !== $default ) {
854
- $value = $default;
855
- } else {
856
- $fields = $this->get_optin_fields( $post_id );
857
-
858
- if ( isset( $fields[ $key ]['default'] ) ) {
859
- $value = $fields[ $key ]['default'];
860
- }
861
- }
862
- }
863
-
864
- return $value;
865
- }
866
- }
867
-
868
- /**
869
- * Kicking this off by calling 'get_instance()' method
870
- */
871
- Cartflows_Default_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Cartflow default options.
4
+ *
5
+ * @package Cartflows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Default_Meta {
14
+
15
+
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_fields
28
+ */
29
+ private static $checkout_fields = null;
30
+
31
+ /**
32
+ * Member Variable
33
+ *
34
+ * @var checkout_fields
35
+ */
36
+ private static $thankyou_fields = null;
37
+
38
+ /**
39
+ * Member Variable
40
+ *
41
+ * @var flow_fields
42
+ */
43
+ private static $flow_fields = null;
44
+
45
+ /**
46
+ * Member Variable
47
+ *
48
+ * @var landing_fields
49
+ */
50
+ private static $landing_fields = null;
51
+
52
+ /**
53
+ * Member Variable
54
+ *
55
+ * @var optin_fields
56
+ */
57
+ private static $optin_fields = null;
58
+
59
+ /**
60
+ * Initiator
61
+ */
62
+ public static function get_instance() {
63
+ if ( ! isset( self::$instance ) ) {
64
+ self::$instance = new self();
65
+ }
66
+ return self::$instance;
67
+ }
68
+
69
+ /**
70
+ * Constructor
71
+ */
72
+ public function __construct() {
73
+ }
74
+
75
+ /**
76
+ * Checkout Default fields.
77
+ *
78
+ * @param int $post_id post id.
79
+ * @return array
80
+ */
81
+ public function get_checkout_fields( $post_id ) {
82
+
83
+ if ( null === self::$checkout_fields ) {
84
+ self::$checkout_fields = array(
85
+ 'wcf-field-google-font-url' => array(
86
+ 'default' => '',
87
+ 'sanitize' => 'FILTER_DEFAULT',
88
+ ),
89
+ 'wcf-checkout-products' => array(
90
+ 'default' => array(),
91
+ 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
+ ),
93
+ 'wcf-checkout-layout' => array(
94
+ 'default' => 'two-column',
95
+ 'sanitize' => 'FILTER_DEFAULT',
96
+ ),
97
+ 'wcf-input-font-family' => array(
98
+ 'default' => '',
99
+ 'sanitize' => 'FILTER_DEFAULT',
100
+ ),
101
+ 'wcf-input-font-weight' => array(
102
+ 'default' => '',
103
+ 'sanitize' => 'FILTER_DEFAULT',
104
+ ),
105
+ 'wcf-heading-font-family' => array(
106
+ 'default' => '',
107
+ 'sanitize' => 'FILTER_DEFAULT',
108
+ ),
109
+ 'wcf-heading-font-weight' => array(
110
+ 'default' => '',
111
+ 'sanitize' => 'FILTER_DEFAULT',
112
+ ),
113
+ 'wcf-base-font-family' => array(
114
+ 'default' => '',
115
+ 'sanitize' => 'FILTER_DEFAULT',
116
+ ),
117
+ 'wcf-advance-options-fields' => array(
118
+ 'default' => '',
119
+ 'sanitize' => 'FILTER_DEFAULT',
120
+ ),
121
+ 'wcf-remove-product-field' => array(
122
+ 'default' => '',
123
+ 'sanitize' => 'FILTER_DEFAULT',
124
+ ),
125
+ 'wcf-checkout-place-order-button-text' => array(
126
+ 'default' => '',
127
+ 'sanitize' => 'FILTER_SANITIZE_STRING',
128
+ ),
129
+ 'wcf-base-font-weight' => array(
130
+ 'default' => '',
131
+ 'sanitize' => 'FILTER_DEFAULT',
132
+ ),
133
+ 'wcf-button-font-family' => array(
134
+ 'default' => '',
135
+ 'sanitize' => 'FILTER_DEFAULT',
136
+ ),
137
+ 'wcf-button-font-weight' => array(
138
+ 'default' => '',
139
+ 'sanitize' => 'FILTER_DEFAULT',
140
+ ),
141
+ 'wcf-primary-color' => array(
142
+ 'default' => '',
143
+ 'sanitize' => 'FILTER_DEFAULT',
144
+ ),
145
+ 'wcf-heading-color' => array(
146
+ 'default' => '',
147
+ 'sanitize' => 'FILTER_DEFAULT',
148
+ ),
149
+ 'wcf-section-bg-color' => array(
150
+ 'default' => '',
151
+ 'sanitize' => 'FILTER_DEFAULT',
152
+ ),
153
+ 'wcf-hl-bg-color' => array(
154
+ 'default' => '',
155
+ 'sanitize' => 'FILTER_DEFAULT',
156
+ ),
157
+ 'wcf-field-tb-padding' => array(
158
+ 'default' => '',
159
+ 'sanitize' => 'FILTER_DEFAULT',
160
+ ),
161
+ 'wcf-field-lr-padding' => array(
162
+ 'default' => '',
163
+ 'sanitize' => 'FILTER_DEFAULT',
164
+ ),
165
+ 'wcf-fields-skins' => array(
166
+ 'default' => '',
167
+ 'sanitize' => 'FILTER_DEFAULT',
168
+ ),
169
+ 'wcf-input-field-size' => array(
170
+ 'default' => '33px',
171
+ 'sanitize' => 'FILTER_DEFAULT',
172
+ ),
173
+ 'wcf-field-color' => array(
174
+ 'default' => '',
175
+ 'sanitize' => 'FILTER_DEFAULT',
176
+ ),
177
+ 'wcf-field-bg-color' => array(
178
+ 'default' => '',
179
+ 'sanitize' => 'FILTER_DEFAULT',
180
+ ),
181
+ 'wcf-field-border-color' => array(
182
+ 'default' => '',
183
+ 'sanitize' => 'FILTER_DEFAULT',
184
+ ),
185
+ 'wcf-box-border-color' => array(
186
+ 'default' => '',
187
+ 'sanitize' => 'FILTER_DEFAULT',
188
+ ),
189
+ 'wcf-field-label-color' => array(
190
+ 'default' => '',
191
+ 'sanitize' => 'FILTER_DEFAULT',
192
+ ),
193
+ 'wcf-submit-tb-padding' => array(
194
+ 'default' => '',
195
+ 'sanitize' => 'FILTER_DEFAULT',
196
+ ),
197
+ 'wcf-submit-lr-padding' => array(
198
+ 'default' => '',
199
+ 'sanitize' => 'FILTER_DEFAULT',
200
+ ),
201
+ 'wcf-input-button-size' => array(
202
+ 'default' => '33px',
203
+ 'sanitize' => 'FILTER_DEFAULT',
204
+ ),
205
+ 'wcf-submit-color' => array(
206
+ 'default' => '',
207
+ 'sanitize' => 'FILTER_DEFAULT',
208
+ ),
209
+ 'wcf-submit-hover-color' => array(
210
+ 'default' => '',
211
+ 'sanitize' => 'FILTER_DEFAULT',
212
+ ),
213
+ 'wcf-submit-bg-color' => array(
214
+ 'default' => '',
215
+ 'sanitize' => 'FILTER_DEFAULT',
216
+ ),
217
+ 'wcf-submit-bg-hover-color' => array(
218
+ 'default' => '',
219
+ 'sanitize' => 'FILTER_DEFAULT',
220
+ ),
221
+ 'wcf-submit-border-color' => array(
222
+ 'default' => '',
223
+ 'sanitize' => 'FILTER_DEFAULT',
224
+ ),
225
+ 'wcf-submit-border-hover-color' => array(
226
+ 'default' => '',
227
+ 'sanitize' => 'FILTER_DEFAULT',
228
+ ),
229
+ 'wcf-active-tab' => array(
230
+ 'default' => '',
231
+ 'sanitize' => 'FILTER_DEFAULT',
232
+ ),
233
+ 'wcf-header-logo-image' => array(
234
+ 'default' => '',
235
+ 'sanitize' => 'FILTER_DEFAULT',
236
+ ),
237
+ 'wcf-header-logo-width' => array(
238
+ 'default' => '',
239
+ 'sanitize' => 'FILTER_DEFAULT',
240
+ ),
241
+ 'wcf-custom-script' => array(
242
+ 'default' => '',
243
+ 'sanitize' => 'FILTER_DEFAULT',
244
+ ),
245
+ );
246
+
247
+ self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
+ }
249
+
250
+ return self::$checkout_fields;
251
+ }
252
+
253
+ /**
254
+ * Save Checkout Meta fields.
255
+ *
256
+ * @param int $post_id post id.
257
+ * @return void
258
+ */
259
+ public function save_checkout_fields( $post_id ) {
260
+
261
+ $post_meta = $this->get_checkout_fields( $post_id );
262
+
263
+ $this->save_meta_fields( $post_id, $post_meta );
264
+ }
265
+
266
+ /**
267
+ * Save Landing Meta fields.
268
+ *
269
+ * @param int $post_id post id.
270
+ * @return void
271
+ */
272
+ public function save_landing_fields( $post_id ) {
273
+
274
+ $post_meta = $this->get_landing_fields( $post_id );
275
+
276
+ $this->save_meta_fields( $post_id, $post_meta );
277
+ }
278
+
279
+ /**
280
+ * Save ThankYou Meta fields.
281
+ *
282
+ * @param int $post_id post id.
283
+ * @return void
284
+ */
285
+ public function save_thankyou_fields( $post_id ) {
286
+
287
+ $post_meta = $this->get_thankyou_fields( $post_id );
288
+
289
+ $this->save_meta_fields( $post_id, $post_meta );
290
+ }
291
+
292
+ /**
293
+ * Flow Default fields.
294
+ *
295
+ * @param int $post_id post id.
296
+ * @return array
297
+ */
298
+ public function get_flow_fields( $post_id ) {
299
+
300
+ if ( null === self::$flow_fields ) {
301
+ self::$flow_fields = array(
302
+ 'wcf-steps' => array(
303
+ 'default' => array(),
304
+ 'sanitize' => 'FILTER_DEFAULT',
305
+ ),
306
+
307
+ 'wcf-testing' => array(
308
+ 'default' => 'no',
309
+ 'sanitize' => 'FILTER_DEFAULT',
310
+ ),
311
+ );
312
+ }
313
+
314
+ return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
+ }
316
+
317
+ /**
318
+ * Save Flow Meta fields.
319
+ *
320
+ * @param int $post_id post id.
321
+ * @return void
322
+ */
323
+ public function save_flow_fields( $post_id ) {
324
+
325
+ $post_meta = $this->get_flow_fields( $post_id );
326
+
327
+ if ( isset( $post_meta['wcf-steps'] ) ) {
328
+ unset( $post_meta['wcf-steps'] );
329
+ }
330
+
331
+ $this->save_meta_fields( $post_id, $post_meta );
332
+ }
333
+
334
+ /**
335
+ * Save Meta fields - Common Function.
336
+ *
337
+ * @param int $post_id post id.
338
+ * @param array $post_meta options to store.
339
+ * @return void
340
+ */
341
+ public function save_meta_fields( $post_id, $post_meta ) {
342
+
343
+ if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
+ return;
345
+ }
346
+
347
+ foreach ( $post_meta as $key => $data ) {
348
+ $meta_value = false;
349
+
350
+ // Sanitize values.
351
+ $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
+
353
+ switch ( $sanitize_filter ) {
354
+ case 'FILTER_SANITIZE_STRING':
355
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
+ break;
357
+
358
+ case 'FILTER_SANITIZE_URL':
359
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
+ break;
361
+
362
+ case 'FILTER_SANITIZE_NUMBER_INT':
363
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
+ break;
365
+
366
+ case 'FILTER_CARTFLOWS_ARRAY':
367
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
+ $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
+ }
370
+ break;
371
+
372
+ case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
+ $i = 0;
375
+ $q = 0;
376
+
377
+ foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
+ if ( ! array_key_exists( 'product', $p_data ) ) {
379
+ continue;
380
+ }
381
+ foreach ( $p_data as $i_key => $i_value ) {
382
+
383
+ if ( is_array( $i_value ) ) {
384
+ foreach ( $i_value as $q_key => $q_value ) {
385
+ $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
+
387
+ $q++;
388
+ }
389
+ } else {
390
+ $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
+ }
392
+ }
393
+
394
+ $i++;
395
+ }
396
+ }
397
+ break;
398
+
399
+ case 'FILTER_CARTFLOWS_IMAGES':
400
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
+
402
+ if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
+
404
+ if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
+
406
+ $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
+ $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
+
409
+ $image_data = array(
410
+ 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
+ 'url' => array(
412
+ 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
+ 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
+ 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
+ ),
416
+ );
417
+
418
+ $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
+ update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
+ }
421
+ }
422
+
423
+ break;
424
+
425
+ default:
426
+ if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
+ } else {
429
+ $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
+ }
431
+
432
+ break;
433
+ }
434
+
435
+ if ( false !== $meta_value ) {
436
+ update_post_meta( $post_id, $key, $meta_value );
437
+ } else {
438
+ delete_post_meta( $post_id, $key );
439
+ }
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Get checkout meta.
445
+ *
446
+ * @param int $post_id post id.
447
+ * @param string $key options key.
448
+ * @param mix $default options default value.
449
+ * @return string
450
+ */
451
+ public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
+
453
+ $value = $this->get_save_meta( $post_id, $key );
454
+
455
+ if ( ! $value ) {
456
+ if ( $default ) {
457
+ $value = $default;
458
+ } else {
459
+ $fields = $this->get_flow_fields( $post_id );
460
+
461
+ if ( isset( $fields[ $key ]['default'] ) ) {
462
+ $value = $fields[ $key ]['default'];
463
+ }
464
+ }
465
+ }
466
+
467
+ return $value;
468
+ }
469
+
470
+ /**
471
+ * Get checkout meta.
472
+ *
473
+ * @param int $post_id post id.
474
+ * @param string $key options key.
475
+ * @param mix $default options default value.
476
+ * @return string
477
+ */
478
+ public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
+
480
+ $value = $this->get_save_meta( $post_id, $key );
481
+
482
+ if ( ! $value ) {
483
+ if ( false !== $default ) {
484
+ $value = $default;
485
+ } else {
486
+ $fields = $this->get_checkout_fields( $post_id );
487
+
488
+ if ( isset( $fields[ $key ]['default'] ) ) {
489
+ $value = $fields[ $key ]['default'];
490
+ }
491
+ }
492
+ }
493
+
494
+ return $value;
495
+ }
496
+
497
+ /**
498
+ * Get post meta.
499
+ *
500
+ * @param int $post_id post id.
501
+ * @param string $key options key.
502
+ * @return string
503
+ */
504
+ public function get_save_meta( $post_id, $key ) {
505
+
506
+ $value = get_post_meta( $post_id, $key, true );
507
+
508
+ return $value;
509
+ }
510
+
511
+ /**
512
+ * Thank You Default fields.
513
+ *
514
+ * @param int $post_id post id.
515
+ * @return array
516
+ */
517
+ public function get_thankyou_fields( $post_id ) {
518
+
519
+ if ( null === self::$thankyou_fields ) {
520
+ self::$thankyou_fields = array(
521
+ 'wcf-field-google-font-url' => array(
522
+ 'default' => '',
523
+ 'sanitize' => 'FILTER_DEFAULT',
524
+ ),
525
+ 'wcf-active-tab' => array(
526
+ 'default' => '',
527
+ 'sanitize' => 'FILTER_DEFAULT',
528
+ ),
529
+ 'wcf-tq-text-color' => array(
530
+ 'default' => '',
531
+ 'sanitize' => 'FILTER_DEFAULT',
532
+ ),
533
+ 'wcf-tq-font-family' => array(
534
+ 'default' => '',
535
+ 'sanitize' => 'FILTER_DEFAULT',
536
+ ),
537
+ 'wcf-tq-font-size' => array(
538
+ 'default' => '',
539
+ 'sanitize' => 'FILTER_DEFAULT',
540
+ ),
541
+ 'wcf-tq-heading-color' => array(
542
+ 'default' => '',
543
+ 'sanitize' => 'FILTER_DEFAULT',
544
+ ),
545
+ 'wcf-tq-heading-font-family' => array(
546
+ 'default' => '',
547
+ 'sanitize' => 'FILTER_DEFAULT',
548
+ ),
549
+ 'wcf-tq-heading-font-wt' => array(
550
+ 'default' => '',
551
+ 'sanitize' => 'FILTER_DEFAULT',
552
+ ),
553
+ 'wcf-tq-container-width' => array(
554
+ 'default' => '',
555
+ 'sanitize' => 'FILTER_DEFAULT',
556
+ ),
557
+ 'wcf-tq-section-bg-color' => array(
558
+ 'default' => '',
559
+ 'sanitize' => 'FILTER_DEFAULT',
560
+ ),
561
+ 'wcf-tq-advance-options-fields' => array(
562
+ 'default' => '',
563
+ 'sanitize' => 'FILTER_DEFAULT',
564
+ ),
565
+ 'wcf-show-overview-section' => array(
566
+ 'default' => 'yes',
567
+ 'sanitize' => 'FILTER_DEFAULT',
568
+ ),
569
+ 'wcf-show-details-section' => array(
570
+ 'default' => 'yes',
571
+ 'sanitize' => 'FILTER_DEFAULT',
572
+ ),
573
+ 'wcf-show-billing-section' => array(
574
+ 'default' => 'yes',
575
+ 'sanitize' => 'FILTER_DEFAULT',
576
+ ),
577
+ 'wcf-show-shipping-section' => array(
578
+ 'default' => 'yes',
579
+ 'sanitize' => 'FILTER_DEFAULT',
580
+ ),
581
+ 'wcf-show-tq-redirect-section' => array(
582
+ 'default' => '',
583
+ 'sanitize' => 'FILTER_DEFAULT',
584
+ ),
585
+ 'wcf-tq-redirect-link' => array(
586
+ 'default' => '',
587
+ 'sanitize' => 'FILTER_SANITIZE_URL',
588
+ ),
589
+ 'wcf-tq-text' => array(
590
+ 'default' => '',
591
+ 'sanitize' => 'FILTER_DEFAULT',
592
+ ),
593
+ 'wcf-custom-script' => array(
594
+ 'default' => '',
595
+ 'sanitize' => 'FILTER_DEFAULT',
596
+ ),
597
+ );
598
+ }
599
+
600
+ return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
+ }
602
+
603
+ /**
604
+ * Get Thank you section meta.
605
+ *
606
+ * @param int $post_id post id.
607
+ * @param string $key options key.
608
+ * @param mix $default options default value.
609
+ * @return string
610
+ */
611
+ public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
+
613
+ $value = $this->get_save_meta( $post_id, $key );
614
+
615
+ if ( ! $value ) {
616
+ if ( $default ) {
617
+ $value = $default;
618
+ } else {
619
+ $fields = $this->get_thankyou_fields( $post_id );
620
+
621
+ if ( isset( $fields[ $key ]['default'] ) ) {
622
+ $value = $fields[ $key ]['default'];
623
+ }
624
+ }
625
+ }
626
+
627
+ return $value;
628
+ }
629
+
630
+ /**
631
+ * Get Landing section meta.
632
+ *
633
+ * @param int $post_id post id.
634
+ * @param string $key options key.
635
+ * @param mix $default options default value.
636
+ * @return string
637
+ */
638
+ public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
+
640
+ $value = $this->get_save_meta( $post_id, $key );
641
+ if ( ! $value ) {
642
+ if ( $default ) {
643
+ $value = $default;
644
+ } else {
645
+ $fields = $this->get_landing_fields( $post_id );
646
+
647
+ if ( isset( $fields[ $key ]['default'] ) ) {
648
+ $value = $fields[ $key ]['default'];
649
+ }
650
+ }
651
+ }
652
+
653
+ return $value;
654
+ }
655
+
656
+ /**
657
+ * Landing Default fields.
658
+ *
659
+ * @param int $post_id post id.
660
+ * @return array
661
+ */
662
+ public function get_landing_fields( $post_id ) {
663
+
664
+ if ( null === self::$landing_fields ) {
665
+ self::$landing_fields = array(
666
+ 'wcf-custom-script' => array(
667
+ 'default' => '',
668
+ 'sanitize' => 'FILTER_DEFAULT',
669
+ ),
670
+ );
671
+ }
672
+ return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
+ }
674
+
675
+ /**
676
+ * Optin Default fields.
677
+ *
678
+ * @param int $post_id post id.
679
+ * @return array
680
+ */
681
+ public function get_optin_fields( $post_id ) {
682
+
683
+ if ( null === self::$optin_fields ) {
684
+ self::$optin_fields = array(
685
+
686
+ 'wcf-optin-product' => array(
687
+ 'default' => array(),
688
+ 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
+ ),
690
+
691
+ /* Style */
692
+ 'wcf-field-google-font-url' => array(
693
+ 'default' => '',
694
+ 'sanitize' => 'FILTER_DEFAULT',
695
+ ),
696
+ 'wcf-primary-color' => array(
697
+ 'default' => '',
698
+ 'sanitize' => 'FILTER_DEFAULT',
699
+ ),
700
+ 'wcf-base-font-family' => array(
701
+ 'default' => '',
702
+ 'sanitize' => 'FILTER_DEFAULT',
703
+ ),
704
+ 'wcf-input-fields-skins' => array(
705
+ 'default' => '',
706
+ 'sanitize' => 'FILTER_DEFAULT',
707
+ ),
708
+ 'wcf-input-font-family' => array(
709
+ 'default' => '',
710
+ 'sanitize' => 'FILTER_DEFAULT',
711
+ ),
712
+ 'wcf-input-font-weight' => array(
713
+ 'default' => '',
714
+ 'sanitize' => 'FILTER_DEFAULT',
715
+ ),
716
+ 'wcf-input-field-size' => array(
717
+ 'default' => '33px',
718
+ 'sanitize' => 'FILTER_DEFAULT',
719
+ ),
720
+ 'wcf-field-tb-padding' => array(
721
+ 'default' => '',
722
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
+ ),
724
+ 'wcf-field-lr-padding' => array(
725
+ 'default' => '',
726
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
+ ),
728
+ 'wcf-field-color' => array(
729
+ 'default' => '',
730
+ 'sanitize' => 'FILTER_DEFAULT',
731
+ ),
732
+ 'wcf-field-bg-color' => array(
733
+ 'default' => '',
734
+ 'sanitize' => 'FILTER_DEFAULT',
735
+ ),
736
+ 'wcf-field-border-color' => array(
737
+ 'default' => '',
738
+ 'sanitize' => 'FILTER_DEFAULT',
739
+ ),
740
+ 'wcf-field-label-color' => array(
741
+ 'default' => '',
742
+ 'sanitize' => 'FILTER_DEFAULT',
743
+ ),
744
+ 'wcf-submit-button-text' => array(
745
+ 'default' => __( 'Submit', 'cartflows' ),
746
+ 'sanitize' => 'FILTER_DEFAULT',
747
+ ),
748
+ 'wcf-submit-font-size' => array(
749
+ 'default' => '',
750
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
+ ),
752
+ 'wcf-button-font-family' => array(
753
+ 'default' => '',
754
+ 'sanitize' => 'FILTER_DEFAULT',
755
+ ),
756
+ 'wcf-button-font-weight' => array(
757
+ 'default' => '',
758
+ 'sanitize' => 'FILTER_DEFAULT',
759
+ ),
760
+ 'wcf-submit-button-size' => array(
761
+ 'default' => '33px',
762
+ 'sanitize' => 'FILTER_DEFAULT',
763
+ ),
764
+ 'wcf-submit-tb-padding' => array(
765
+ 'default' => '',
766
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
+ ),
768
+ 'wcf-submit-lr-padding' => array(
769
+ 'default' => '',
770
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
+ ),
772
+ 'wcf-submit-button-position' => array(
773
+ 'default' => 'center',
774
+ 'sanitize' => 'FILTER_DEFAULT',
775
+ ),
776
+ 'wcf-submit-color' => array(
777
+ 'default' => '',
778
+ 'sanitize' => 'FILTER_DEFAULT',
779
+ ),
780
+ 'wcf-submit-hover-color' => array(
781
+ 'default' => '',
782
+ 'sanitize' => 'FILTER_DEFAULT',
783
+ ),
784
+ 'wcf-submit-bg-color' => array(
785
+ 'default' => '',
786
+ 'sanitize' => 'FILTER_DEFAULT',
787
+ ),
788
+ 'wcf-submit-bg-hover-color' => array(
789
+ 'default' => '',
790
+ 'sanitize' => 'FILTER_DEFAULT',
791
+ ),
792
+ 'wcf-submit-border-color' => array(
793
+ 'default' => '',
794
+ 'sanitize' => 'FILTER_DEFAULT',
795
+ ),
796
+ 'wcf-submit-border-hover-color' => array(
797
+ 'default' => '',
798
+ 'sanitize' => 'FILTER_DEFAULT',
799
+ ),
800
+
801
+ /* Settings */
802
+ 'wcf-optin-pass-fields' => array(
803
+ 'default' => '',
804
+ 'sanitize' => 'FILTER_DEFAULT',
805
+ ),
806
+ 'wcf-optin-pass-specific-fields' => array(
807
+ 'default' => 'first_name',
808
+ 'sanitize' => 'FILTER_DEFAULT',
809
+ ),
810
+
811
+ /* Script */
812
+ 'wcf-custom-script' => array(
813
+ 'default' => '',
814
+ 'sanitize' => 'FILTER_DEFAULT',
815
+ ),
816
+
817
+ /* Hidden */
818
+ 'wcf-active-tab' => array(
819
+ 'default' => '',
820
+ 'sanitize' => 'FILTER_DEFAULT',
821
+ ),
822
+ );
823
+ }
824
+ return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
+ }
826
+
827
+ /**
828
+ * Save Optin Meta fields.
829
+ *
830
+ * @param int $post_id post id.
831
+ * @return void
832
+ */
833
+ public function save_optin_fields( $post_id ) {
834
+
835
+ $post_meta = $this->get_optin_fields( $post_id );
836
+
837
+ $this->save_meta_fields( $post_id, $post_meta );
838
+ }
839
+
840
+ /**
841
+ * Get optin meta.
842
+ *
843
+ * @param int $post_id post id.
844
+ * @param string $key options key.
845
+ * @param mix $default options default value.
846
+ * @return string
847
+ */
848
+ public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
+
850
+ $value = $this->get_save_meta( $post_id, $key );
851
+
852
+ if ( ! $value ) {
853
+ if ( false !== $default ) {
854
+ $value = $default;
855
+ } else {
856
+ $fields = $this->get_optin_fields( $post_id );
857
+
858
+ if ( isset( $fields[ $key ]['default'] ) ) {
859
+ $value = $fields[ $key ]['default'];
860
+ }
861
+ }
862
+ }
863
+
864
+ return $value;
865
+ }
866
+ }
867
+
868
+ /**
869
+ * Kicking this off by calling 'get_instance()' method
870
+ */
871
+ Cartflows_Default_Meta::get_instance();
classes/class-cartflows-flow-frontend.php CHANGED
@@ -1,247 +1,247 @@
1
- <?php
2
- /**
3
- * Frontend & Markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Frontend {
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
- /* Analytics */
39
- add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
- }
41
-
42
- /**
43
- * Footer markup
44
- */
45
- public function footer_markup() {
46
-
47
- if ( wcf()->utils->is_step_post_type() ) {
48
- // @codingStandardsIgnoreStart
49
- $flow_id = wcf()->utils->get_flow_id();
50
- ?>
51
- <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
- <div class="wcf-preview-mode">
53
- <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
- <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
- <?php
56
- $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
- ?>
58
- <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
- <?php } ?>
60
- </div>
61
- <?php } ?>
62
- <?php
63
- // @codingStandardsIgnoreEnd
64
- }
65
- }
66
-
67
- /**
68
- * Check if flow test mode is enable.
69
- *
70
- * @since 1.0.0
71
- * @param int $flow_id flow ID.
72
- *
73
- * @return boolean
74
- */
75
- public function is_flow_testmode( $flow_id = '' ) {
76
-
77
- if ( ! $flow_id ) {
78
- $flow_id = wcf()->utils->get_flow_id();
79
- }
80
-
81
- $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
-
83
- if ( 'no' === $test_mode ) {
84
- return false;
85
- }
86
-
87
- return true;
88
- }
89
-
90
- /**
91
- * Get steps data.
92
- *
93
- * @since 1.0.0
94
- * @param int $flow_id flow ID.
95
- *
96
- * @return array
97
- */
98
- public function get_steps( $flow_id ) {
99
-
100
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
-
102
- if ( ! is_array( $steps ) ) {
103
-
104
- $steps = array();
105
- }
106
-
107
- return $steps;
108
- }
109
-
110
- /**
111
- * Check thank you page exists.
112
- *
113
- * @since 1.0.0
114
- * @param array $order order data.
115
- *
116
- * @return bool
117
- */
118
- public function is_thankyou_page_exists( $order ) {
119
-
120
- $thankyou_step_exist = false;
121
-
122
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
-
124
- if ( $flow_id ) {
125
-
126
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
-
129
- if ( is_array( $flow_steps ) ) {
130
-
131
- $current_step_found = false;
132
-
133
- foreach ( $flow_steps as $index => $data ) {
134
-
135
- if ( $current_step_found ) {
136
-
137
- if ( 'thankyou' === $data['type'] ) {
138
-
139
- $thankyou_step_exist = true;
140
- break;
141
- }
142
- } else {
143
-
144
- if ( intval( $data['id'] ) === $step_id ) {
145
-
146
- $current_step_found = true;
147
- }
148
- }
149
- }
150
- }
151
- }
152
-
153
- return $thankyou_step_exist;
154
- }
155
-
156
- /**
157
- * Check thank you page exists.
158
- *
159
- * @since 1.0.0
160
- * @param array $order order data.
161
- *
162
- * @return bool
163
- */
164
- public function get_thankyou_page_id( $order ) {
165
-
166
- $thankyou_step_id = false;
167
-
168
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
-
170
- if ( $flow_id ) {
171
-
172
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
-
175
- if ( is_array( $flow_steps ) ) {
176
-
177
- $current_step_found = false;
178
-
179
- foreach ( $flow_steps as $index => $data ) {
180
-
181
- if ( $current_step_found ) {
182
-
183
- if ( 'thankyou' === $data['type'] ) {
184
-
185
- $thankyou_step_id = intval( $data['id'] );
186
- break;
187
- }
188
- } else {
189
-
190
- if ( intval( $data['id'] ) === $step_id ) {
191
-
192
- $current_step_found = true;
193
- }
194
- }
195
- }
196
- }
197
- }
198
-
199
- return $thankyou_step_id;
200
- }
201
-
202
- /**
203
- * Check thank you page exists.
204
- *
205
- * @since 1.0.0
206
- * @param array $order order data.
207
- *
208
- * @return bool
209
- */
210
- public function get_next_step_id( $order ) {
211
-
212
- $next_step_id = false;
213
-
214
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
-
216
- if ( $flow_id ) {
217
-
218
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
- $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
-
221
- if ( is_array( $flow_steps ) ) {
222
-
223
- foreach ( $flow_steps as $index => $data ) {
224
-
225
- if ( intval( $data['id'] ) === $step_id ) {
226
-
227
- $next_step_index = $index + 1;
228
-
229
- if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
-
231
- $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
- }
233
-
234
- break;
235
- }
236
- }
237
- }
238
- }
239
-
240
- return $next_step_id;
241
- }
242
- }
243
-
244
- /**
245
- * Kicking this off by calling 'get_instance()' method
246
- */
247
- Cartflows_Flow_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * Frontend & Markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Frontend {
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
+ /* Analytics */
39
+ add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
+ }
41
+
42
+ /**
43
+ * Footer markup
44
+ */
45
+ public function footer_markup() {
46
+
47
+ if ( wcf()->utils->is_step_post_type() ) {
48
+ // @codingStandardsIgnoreStart
49
+ $flow_id = wcf()->utils->get_flow_id();
50
+ ?>
51
+ <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
+ <div class="wcf-preview-mode">
53
+ <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
+ <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
+ <?php
56
+ $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
+ ?>
58
+ <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
+ <?php } ?>
60
+ </div>
61
+ <?php } ?>
62
+ <?php
63
+ // @codingStandardsIgnoreEnd
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Check if flow test mode is enable.
69
+ *
70
+ * @since 1.0.0
71
+ * @param int $flow_id flow ID.
72
+ *
73
+ * @return boolean
74
+ */
75
+ public function is_flow_testmode( $flow_id = '' ) {
76
+
77
+ if ( ! $flow_id ) {
78
+ $flow_id = wcf()->utils->get_flow_id();
79
+ }
80
+
81
+ $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
+
83
+ if ( 'no' === $test_mode ) {
84
+ return false;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ /**
91
+ * Get steps data.
92
+ *
93
+ * @since 1.0.0
94
+ * @param int $flow_id flow ID.
95
+ *
96
+ * @return array
97
+ */
98
+ public function get_steps( $flow_id ) {
99
+
100
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
+
102
+ if ( ! is_array( $steps ) ) {
103
+
104
+ $steps = array();
105
+ }
106
+
107
+ return $steps;
108
+ }
109
+
110
+ /**
111
+ * Check thank you page exists.
112
+ *
113
+ * @since 1.0.0
114
+ * @param array $order order data.
115
+ *
116
+ * @return bool
117
+ */
118
+ public function is_thankyou_page_exists( $order ) {
119
+
120
+ $thankyou_step_exist = false;
121
+
122
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
+
124
+ if ( $flow_id ) {
125
+
126
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
+
129
+ if ( is_array( $flow_steps ) ) {
130
+
131
+ $current_step_found = false;
132
+
133
+ foreach ( $flow_steps as $index => $data ) {
134
+
135
+ if ( $current_step_found ) {
136
+
137
+ if ( 'thankyou' === $data['type'] ) {
138
+
139
+ $thankyou_step_exist = true;
140
+ break;
141
+ }
142
+ } else {
143
+
144
+ if ( intval( $data['id'] ) === $step_id ) {
145
+
146
+ $current_step_found = true;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ return $thankyou_step_exist;
154
+ }
155
+
156
+ /**
157
+ * Check thank you page exists.
158
+ *
159
+ * @since 1.0.0
160
+ * @param array $order order data.
161
+ *
162
+ * @return bool
163
+ */
164
+ public function get_thankyou_page_id( $order ) {
165
+
166
+ $thankyou_step_id = false;
167
+
168
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
+
170
+ if ( $flow_id ) {
171
+
172
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
+
175
+ if ( is_array( $flow_steps ) ) {
176
+
177
+ $current_step_found = false;
178
+
179
+ foreach ( $flow_steps as $index => $data ) {
180
+
181
+ if ( $current_step_found ) {
182
+
183
+ if ( 'thankyou' === $data['type'] ) {
184
+
185
+ $thankyou_step_id = intval( $data['id'] );
186
+ break;
187
+ }
188
+ } else {
189
+
190
+ if ( intval( $data['id'] ) === $step_id ) {
191
+
192
+ $current_step_found = true;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ return $thankyou_step_id;
200
+ }
201
+
202
+ /**
203
+ * Check thank you page exists.
204
+ *
205
+ * @since 1.0.0
206
+ * @param array $order order data.
207
+ *
208
+ * @return bool
209
+ */
210
+ public function get_next_step_id( $order ) {
211
+
212
+ $next_step_id = false;
213
+
214
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
+
216
+ if ( $flow_id ) {
217
+
218
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
+ $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
+
221
+ if ( is_array( $flow_steps ) ) {
222
+
223
+ foreach ( $flow_steps as $index => $data ) {
224
+
225
+ if ( intval( $data['id'] ) === $step_id ) {
226
+
227
+ $next_step_index = $index + 1;
228
+
229
+ if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
+
231
+ $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
+ }
233
+
234
+ break;
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ return $next_step_id;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Kicking this off by calling 'get_instance()' method
246
+ */
247
+ Cartflows_Flow_Frontend::get_instance();
classes/class-cartflows-frontend.php CHANGED
@@ -1,654 +1,654 @@
1
- <?php
2
- /**
3
- * CartFlows Frontend.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Frontend.
10
- */
11
- class Cartflows_Frontend {
12
-
13
- /**
14
- * Member Variable
15
- *
16
- * @var instance
17
- */
18
- private static $instance;
19
-
20
- /**
21
- * Initiator
22
- */
23
- public static function get_instance() {
24
- if ( ! isset( self::$instance ) ) {
25
- self::$instance = new self();
26
- }
27
- return self::$instance;
28
- }
29
-
30
- /**
31
- * Constructor
32
- */
33
- public function __construct() {
34
-
35
- /* Set / Destroy Flow Sessions. Set data */
36
- add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
-
38
- add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
- add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
- /* Enqueue global required scripts */
41
- add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
-
43
- /* Modify the checkout order received url to go thank you page in our flow */
44
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
-
46
- add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
-
48
- }
49
-
50
- /**
51
- * Redirect to thank page if upsell not exists
52
- *
53
- * @param string $order_recieve_url url.
54
- * @param object $order order object.
55
- * @since 1.0.0
56
- */
57
- public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
-
59
- /* Only for thank you page */
60
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
- wcf()->logger->log( 'Only for thank you page' );
62
-
63
- if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
-
65
- if ( _is_wcf_doing_checkout_ajax() ) {
66
-
67
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
-
69
- if ( ! $checkout_id ) {
70
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
- }
72
- } else {
73
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
- }
75
-
76
- wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
-
78
- if ( $checkout_id ) {
79
-
80
- $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
-
82
- if ( $thankyou_step_id ) {
83
-
84
- $order_recieve_url = get_permalink( $thankyou_step_id );
85
-
86
- $order_recieve_url = add_query_arg(
87
- array(
88
- 'wcf-key' => $order->get_order_key(),
89
- 'wcf-order' => $order->get_id(),
90
- ),
91
- $order_recieve_url
92
- );
93
- }
94
- }
95
- }
96
-
97
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
-
99
- Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
-
101
- Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
-
103
- return $order_recieve_url;
104
- }
105
-
106
- /**
107
- * Cancel and redirect to checkout
108
- *
109
- * @param string $return_url url.
110
- * @since 1.0.0
111
- */
112
- public function redirect_to_checkout_on_cancel( $return_url ) {
113
-
114
- if ( _is_wcf_doing_checkout_ajax() ) {
115
-
116
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
-
118
- if ( ! $checkout_id ) {
119
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
- }
121
- } else {
122
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
- }
124
-
125
- if ( $checkout_id ) {
126
-
127
- $return_url = add_query_arg(
128
- array(
129
- 'cancel_order' => 'true',
130
- '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
- ),
132
- get_permalink( $checkout_id )
133
- );
134
- }
135
-
136
- return $return_url;
137
- }
138
-
139
-
140
- /**
141
- * Remove theme styles.
142
- *
143
- * @since 1.0.0
144
- */
145
- public function remove_theme_styles() {
146
-
147
- if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
- return;
149
- }
150
-
151
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
-
153
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
-
155
- if ( ! _wcf_supported_template( $page_template ) ) {
156
- return;
157
- }
158
-
159
- // get all styles data.
160
- global $wp_styles;
161
- global $wp_scripts;
162
-
163
- $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
- $get_template = 'themes/' . get_template() . '/';
165
-
166
- $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
-
168
- if ( $remove_styles ) {
169
-
170
- // loop over all of the registered scripts..
171
- foreach ( $wp_styles->registered as $handle => $data ) {
172
-
173
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
-
175
- // remove it.
176
- wp_deregister_style( $handle );
177
- wp_dequeue_style( $handle );
178
- }
179
- }
180
- }
181
-
182
- $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
-
184
- if ( $remove_scripts ) {
185
-
186
- // loop over all of the registered scripts.
187
- foreach ( $wp_scripts->registered as $handle => $data ) {
188
-
189
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
-
191
- // remove it.
192
- wp_deregister_script( $handle );
193
- wp_dequeue_script( $handle );
194
- }
195
- }
196
- }
197
-
198
- }
199
-
200
- /**
201
- * Update main order data in transient.
202
- *
203
- * @param array $woo_styles new styles array.
204
- * @since 1.0.0
205
- * @return array.
206
- */
207
- public function woo_default_css( $woo_styles ) {
208
-
209
- $woo_styles = array(
210
- 'woocommerce-layout' => array(
211
- 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
- 'deps' => '',
213
- 'version' => WC_VERSION,
214
- 'media' => 'all',
215
- 'has_rtl' => true,
216
- ),
217
- 'woocommerce-smallscreen' => array(
218
- 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
- 'deps' => 'woocommerce-layout',
220
- 'version' => WC_VERSION,
221
- 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
- 'has_rtl' => true,
223
- ),
224
- 'woocommerce-general' => array(
225
- 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
- 'deps' => '',
227
- 'version' => WC_VERSION,
228
- 'media' => 'all',
229
- 'has_rtl' => true,
230
- ),
231
- );
232
-
233
- return $woo_styles;
234
- }
235
-
236
- /**
237
- * Init Actions.
238
- *
239
- * @since 1.0.0
240
- */
241
- public function init_actions() {
242
-
243
- $this->set_flow_session();
244
- }
245
-
246
- /**
247
- * Set flow session.
248
- *
249
- * @since 1.0.0
250
- */
251
- public function set_flow_session() {
252
-
253
- if ( wcf()->utils->is_step_post_type() ) {
254
- global $wp;
255
- add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
-
257
- wcf()->utils->do_not_cache();
258
-
259
- if ( _is_wcf_thankyou_type() ) {
260
- /* Set key to support pixel */
261
- if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
-
263
- $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
-
265
- $_GET['key'] = $wcf_key;
266
- $_REQUEST['key'] = $wcf_key;
267
- }
268
-
269
- if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
-
271
- $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
-
273
- $_GET['order'] = $wcf_order;
274
- $_REQUEST['order'] = $wcf_order;
275
- $_GET['order-received'] = $wcf_order;
276
- $_REQUEST['order-received'] = $wcf_order;
277
-
278
- $wp->set_query_var( 'order-received', $wcf_order );
279
- }
280
- }
281
- }
282
- }
283
-
284
- /**
285
- * Add noindex, nofollow.
286
- *
287
- * @since 1.0.0
288
- */
289
- public function noindex_flow() {
290
-
291
- $common = Cartflows_Helper::get_common_settings();
292
-
293
- if ( 'enable' === $common['disallow_indexing'] ) {
294
- echo '<meta name="robots" content="noindex,nofollow">';
295
- }
296
- }
297
-
298
- /**
299
- * WP Actions.
300
- *
301
- * @since 1.0.0
302
- */
303
- public function wp_actions() {
304
-
305
- if ( wcf()->utils->is_step_post_type() ) {
306
-
307
- if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
- wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
- }
310
-
311
- /* CSS Compatibility for All theme */
312
- add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
-
314
- add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
- add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
-
317
- /* Load woo templates from plugin */
318
- add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
-
320
- /* Add version class to body in frontend. */
321
- add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
-
323
- /* Custom Script Option */
324
- add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
-
326
- /* Remove the action applied by the Flatsome theme */
327
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
- $this->remove_flatsome_action();
329
- }
330
- }
331
- }
332
-
333
- /**
334
- * Function for facebook pixel.
335
- */
336
- public function facebook_pixel_init() {
337
-
338
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
-
341
- $facebook_id = $facebook_settings['facebook_pixel_id'];
342
- echo '<!-- Facebook Pixel Script By CartFlows -->';
343
- $fb_script = "<script type='text/javascript'>
344
- !function(f,b,e,v,n,t,s)
345
- {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
- n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
- if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
- n.queue=[];t=b.createElement(e);t.async=!0;
349
- t.src=v;s=b.getElementsByTagName(e)[0];
350
- s.parentNode.insertBefore(t,s)}(window, document,'script',
351
- 'https://connect.facebook.net/en_US/fbevents.js');
352
- </script>
353
- <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
-
355
- $fb_page_view = "<script type='text/javascript'>
356
- fbq('init', $facebook_id);
357
- fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
- </script>";
359
-
360
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
- echo $fb_script;
362
- echo $fb_page_view;
363
- } else {
364
- echo $fb_script;
365
- }
366
- echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
- }
368
-
369
- }
370
-
371
- /**
372
- * Debug Data Setting Actions.
373
- *
374
- * @since 1.1.14
375
- */
376
- public function debug_data_setting_actions() {
377
-
378
- add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
- }
380
-
381
- /**
382
- * Get/Set the allow minify option.
383
- *
384
- * @since 1.1.14
385
- */
386
- public function allow_load_minify() {
387
- $debug_data = Cartflows_Helper::get_debug_settings();
388
- $allow_minified = $debug_data['allow_minified_files'];
389
- $allow_minify = false;
390
-
391
- if ( 'enable' === $allow_minified ) {
392
- $allow_minify = true;
393
- }
394
-
395
- return $allow_minify;
396
- }
397
-
398
- /**
399
- * Global flow scripts.
400
- *
401
- * @since 1.0.0
402
- */
403
- public function global_flow_scripts() {
404
-
405
- global $post;
406
-
407
- $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
- $current_step = $post->ID;
409
- $next_step_link = '';
410
- $compatibility = Cartflows_Compatibility::get_instance();
411
-
412
- if ( _is_wcf_landing_type() ) {
413
-
414
- $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
- $next_step_link = get_permalink( $next_step_id );
416
- }
417
-
418
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
-
420
- $fb_active = Cartflows_Helper::get_facebook_settings();
421
- $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
- $params = array();
423
- $ga_param = array();
424
-
425
- if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
-
427
- $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
- }
429
-
430
- if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
- $ga_param = Cartflows_Tracking::get_ga_items_list();
432
- }
433
-
434
- $localize = array(
435
- 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
- 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
- 'current_theme' => $compatibility->get_current_theme(),
438
- 'current_flow' => $flow,
439
- 'current_step' => $current_step,
440
- 'next_step' => $next_step_link,
441
- 'page_template' => $page_template,
442
- 'is_checkout_page' => _is_wcf_checkout_type(),
443
- 'params' => $params,
444
- 'fb_active' => $fb_active,
445
- 'wcf_ga_active' => $wcf_ga_active,
446
- 'ga_param' => $ga_param,
447
- );
448
-
449
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
-
451
- if ( _wcf_supported_template( $page_template ) ) {
452
-
453
- wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
- }
455
-
456
- wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
-
458
- wp_enqueue_script(
459
- 'wcf-frontend-global',
460
- wcf()->utils->get_js_url( 'frontend' ),
461
- array( 'jquery', 'jquery-cookie' ),
462
- CARTFLOWS_VER,
463
- false
464
- );
465
- }
466
-
467
- /**
468
- * Custom Script in head.
469
- *
470
- * @since 1.0.0
471
- */
472
- public function custom_script_option() {
473
-
474
- /* Add custom script to header in frontend. */
475
- $script = $this->get_custom_script();
476
- if ( '' !== $script ) {
477
- if ( false === strpos( $script, '<script' ) ) {
478
- $script = '<script>' . $script . '</script>';
479
- }
480
- echo '<!-- Custom CartFlows Script -->';
481
- echo $script;
482
- echo '<!-- End Custom CartFlows Script -->';
483
- }
484
- }
485
-
486
- /**
487
- * Override woo templates.
488
- *
489
- * @param string $template new Template full path.
490
- * @param string $template_name Template name.
491
- * @param string $template_path Template Path.
492
- * @since 1.1.5
493
- * @return string.
494
- */
495
- public function override_woo_template( $template, $template_name, $template_path ) {
496
-
497
- global $woocommerce;
498
-
499
- $_template = $template;
500
-
501
- $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
-
503
- if ( file_exists( $plugin_path . $template_name ) ) {
504
- $template = $plugin_path . $template_name;
505
- }
506
-
507
- if ( ! $template ) {
508
- $template = $_template;
509
- }
510
-
511
- return $template;
512
- }
513
-
514
- /**
515
- * Remove the action applied by the Flatsome theme.
516
- *
517
- * @since 1.1.5
518
- * @return void.
519
- */
520
- public function remove_flatsome_action() {
521
-
522
- // Remove action where flatsome dequeued the woocommerce's default styles.
523
- remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
- }
525
-
526
- /**
527
- * Add version class to body in frontend.
528
- *
529
- * @since 1.1.5
530
- * @param array $classes classes.
531
- * @return array $classes classes.
532
- */
533
- public function add_cartflows_lite_version_to_body( $classes ) {
534
-
535
- $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
-
537
- return $classes;
538
-
539
- }
540
-
541
- /**
542
- * Get custom script data.
543
- *
544
- * @since 1.0.0
545
- */
546
- public function get_custom_script() {
547
-
548
- global $post;
549
-
550
- $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
-
552
- return $script;
553
- }
554
-
555
-
556
- /**
557
- * Set appropriate filter sctions.
558
- *
559
- * @since 1.1.14
560
- */
561
- public function setup_optin_checkout_filter() {
562
-
563
- if ( _is_wcf_doing_optin_ajax() ) {
564
- /* Modify the optin order received url to go next step */
565
- remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
- }
568
- }
569
-
570
- /**
571
- * Redirect to thank page if upsell not exists
572
- *
573
- * @param string $order_recieve_url url.
574
- * @param object $order order object.
575
- * @since 1.0.0
576
- */
577
- public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
-
579
- /* Only for optin page */
580
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
- wcf()->logger->log( 'Only for optin page' );
582
-
583
- if ( _is_wcf_doing_optin_ajax() ) {
584
-
585
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
-
587
- if ( ! $optin_id ) {
588
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
- }
590
- } else {
591
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
- }
593
-
594
- wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
-
596
- if ( $optin_id ) {
597
-
598
- $next_step_id = wcf()->flow->get_next_step_id( $order );
599
-
600
- if ( $next_step_id ) {
601
-
602
- $order_recieve_url = get_permalink( $next_step_id );
603
- $query_param = array(
604
- 'wcf-key' => $order->get_order_key(),
605
- 'wcf-order' => $order->get_id(),
606
- );
607
-
608
- if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
-
610
- $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
-
612
- $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
-
614
- if ( is_array( $fields ) ) {
615
-
616
- $order_id = $order->get_id();
617
-
618
- foreach ( $fields as $in => $key ) {
619
- switch ( $key ) {
620
- case 'first_name':
621
- $query_param[ $key ] = $order->get_billing_first_name();
622
- break;
623
- case 'last_name':
624
- $query_param[ $key ] = $order->get_billing_last_name();
625
- break;
626
- case 'email':
627
- $query_param[ $key ] = $order->get_billing_email();
628
- break;
629
- default:
630
- $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
- break;
632
- }
633
- }
634
- }
635
- }
636
-
637
- $order_recieve_url = add_query_arg(
638
- $query_param,
639
- $order_recieve_url
640
- );
641
- }
642
- }
643
-
644
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
-
646
- return $order_recieve_url;
647
- }
648
- }
649
-
650
- /**
651
- * Prepare if class 'Cartflows_Frontend' exist.
652
- * Kicking this off by calling 'get_instance()' method
653
- */
654
- Cartflows_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * CartFlows Frontend.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Frontend.
10
+ */
11
+ class Cartflows_Frontend {
12
+
13
+ /**
14
+ * Member Variable
15
+ *
16
+ * @var instance
17
+ */
18
+ private static $instance;
19
+
20
+ /**
21
+ * Initiator
22
+ */
23
+ public static function get_instance() {
24
+ if ( ! isset( self::$instance ) ) {
25
+ self::$instance = new self();
26
+ }
27
+ return self::$instance;
28
+ }
29
+
30
+ /**
31
+ * Constructor
32
+ */
33
+ public function __construct() {
34
+
35
+ /* Set / Destroy Flow Sessions. Set data */
36
+ add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
+
38
+ add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
+ add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
+ /* Enqueue global required scripts */
41
+ add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
+
43
+ /* Modify the checkout order received url to go thank you page in our flow */
44
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
+
46
+ add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
+
48
+ }
49
+
50
+ /**
51
+ * Redirect to thank page if upsell not exists
52
+ *
53
+ * @param string $order_recieve_url url.
54
+ * @param object $order order object.
55
+ * @since 1.0.0
56
+ */
57
+ public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
+
59
+ /* Only for thank you page */
60
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
+ wcf()->logger->log( 'Only for thank you page' );
62
+
63
+ if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
+
65
+ if ( _is_wcf_doing_checkout_ajax() ) {
66
+
67
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
+
69
+ if ( ! $checkout_id ) {
70
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
+ }
72
+ } else {
73
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
+ }
75
+
76
+ wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
+
78
+ if ( $checkout_id ) {
79
+
80
+ $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
+
82
+ if ( $thankyou_step_id ) {
83
+
84
+ $order_recieve_url = get_permalink( $thankyou_step_id );
85
+
86
+ $order_recieve_url = add_query_arg(
87
+ array(
88
+ 'wcf-key' => $order->get_order_key(),
89
+ 'wcf-order' => $order->get_id(),
90
+ ),
91
+ $order_recieve_url
92
+ );
93
+ }
94
+ }
95
+ }
96
+
97
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
+
99
+ Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
+
101
+ Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
+
103
+ return $order_recieve_url;
104
+ }
105
+
106
+ /**
107
+ * Cancel and redirect to checkout
108
+ *
109
+ * @param string $return_url url.
110
+ * @since 1.0.0
111
+ */
112
+ public function redirect_to_checkout_on_cancel( $return_url ) {
113
+
114
+ if ( _is_wcf_doing_checkout_ajax() ) {
115
+
116
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
+
118
+ if ( ! $checkout_id ) {
119
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
+ }
121
+ } else {
122
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
+ }
124
+
125
+ if ( $checkout_id ) {
126
+
127
+ $return_url = add_query_arg(
128
+ array(
129
+ 'cancel_order' => 'true',
130
+ '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
+ ),
132
+ get_permalink( $checkout_id )
133
+ );
134
+ }
135
+
136
+ return $return_url;
137
+ }
138
+
139
+
140
+ /**
141
+ * Remove theme styles.
142
+ *
143
+ * @since 1.0.0
144
+ */
145
+ public function remove_theme_styles() {
146
+
147
+ if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
+ return;
149
+ }
150
+
151
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
+
153
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
+
155
+ if ( ! _wcf_supported_template( $page_template ) ) {
156
+ return;
157
+ }
158
+
159
+ // get all styles data.
160
+ global $wp_styles;
161
+ global $wp_scripts;
162
+
163
+ $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
+ $get_template = 'themes/' . get_template() . '/';
165
+
166
+ $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
+
168
+ if ( $remove_styles ) {
169
+
170
+ // loop over all of the registered scripts..
171
+ foreach ( $wp_styles->registered as $handle => $data ) {
172
+
173
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
+
175
+ // remove it.
176
+ wp_deregister_style( $handle );
177
+ wp_dequeue_style( $handle );
178
+ }
179
+ }
180
+ }
181
+
182
+ $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
+
184
+ if ( $remove_scripts ) {
185
+
186
+ // loop over all of the registered scripts.
187
+ foreach ( $wp_scripts->registered as $handle => $data ) {
188
+
189
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
+
191
+ // remove it.
192
+ wp_deregister_script( $handle );
193
+ wp_dequeue_script( $handle );
194
+ }
195
+ }
196
+ }
197
+
198
+ }
199
+
200
+ /**
201
+ * Update main order data in transient.
202
+ *
203
+ * @param array $woo_styles new styles array.
204
+ * @since 1.0.0
205
+ * @return array.
206
+ */
207
+ public function woo_default_css( $woo_styles ) {
208
+
209
+ $woo_styles = array(
210
+ 'woocommerce-layout' => array(
211
+ 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
+ 'deps' => '',
213
+ 'version' => WC_VERSION,
214
+ 'media' => 'all',
215
+ 'has_rtl' => true,
216
+ ),
217
+ 'woocommerce-smallscreen' => array(
218
+ 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
+ 'deps' => 'woocommerce-layout',
220
+ 'version' => WC_VERSION,
221
+ 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
+ 'has_rtl' => true,
223
+ ),
224
+ 'woocommerce-general' => array(
225
+ 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
+ 'deps' => '',
227
+ 'version' => WC_VERSION,
228
+ 'media' => 'all',
229
+ 'has_rtl' => true,
230
+ ),
231
+ );
232
+
233
+ return $woo_styles;
234
+ }
235
+
236
+ /**
237
+ * Init Actions.
238
+ *
239
+ * @since 1.0.0
240
+ */
241
+ public function init_actions() {
242
+
243
+ $this->set_flow_session();
244
+ }
245
+
246
+ /**
247
+ * Set flow session.
248
+ *
249
+ * @since 1.0.0
250
+ */
251
+ public function set_flow_session() {
252
+
253
+ if ( wcf()->utils->is_step_post_type() ) {
254
+ global $wp;
255
+ add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
+
257
+ wcf()->utils->do_not_cache();
258
+
259
+ if ( _is_wcf_thankyou_type() ) {
260
+ /* Set key to support pixel */
261
+ if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
+
263
+ $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
+
265
+ $_GET['key'] = $wcf_key;
266
+ $_REQUEST['key'] = $wcf_key;
267
+ }
268
+
269
+ if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
+
271
+ $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
+
273
+ $_GET['order'] = $wcf_order;
274
+ $_REQUEST['order'] = $wcf_order;
275
+ $_GET['order-received'] = $wcf_order;
276
+ $_REQUEST['order-received'] = $wcf_order;
277
+
278
+ $wp->set_query_var( 'order-received', $wcf_order );
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Add noindex, nofollow.
286
+ *
287
+ * @since 1.0.0
288
+ */
289
+ public function noindex_flow() {
290
+
291
+ $common = Cartflows_Helper::get_common_settings();
292
+
293
+ if ( 'enable' === $common['disallow_indexing'] ) {
294
+ echo '<meta name="robots" content="noindex,nofollow">';
295
+ }
296
+ }
297
+
298
+ /**
299
+ * WP Actions.
300
+ *
301
+ * @since 1.0.0
302
+ */
303
+ public function wp_actions() {
304
+
305
+ if ( wcf()->utils->is_step_post_type() ) {
306
+
307
+ if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
+ wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
+ }
310
+
311
+ /* CSS Compatibility for All theme */
312
+ add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
+
314
+ add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
+ add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
+
317
+ /* Load woo templates from plugin */
318
+ add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
+
320
+ /* Add version class to body in frontend. */
321
+ add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
+
323
+ /* Custom Script Option */
324
+ add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
+
326
+ /* Remove the action applied by the Flatsome theme */
327
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
+ $this->remove_flatsome_action();
329
+ }
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Function for facebook pixel.
335
+ */
336
+ public function facebook_pixel_init() {
337
+
338
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
+
341
+ $facebook_id = $facebook_settings['facebook_pixel_id'];
342
+ echo '<!-- Facebook Pixel Script By CartFlows -->';
343
+ $fb_script = "<script type='text/javascript'>
344
+ !function(f,b,e,v,n,t,s)
345
+ {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
+ if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
+ n.queue=[];t=b.createElement(e);t.async=!0;
349
+ t.src=v;s=b.getElementsByTagName(e)[0];
350
+ s.parentNode.insertBefore(t,s)}(window, document,'script',
351
+ 'https://connect.facebook.net/en_US/fbevents.js');
352
+ </script>
353
+ <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
+
355
+ $fb_page_view = "<script type='text/javascript'>
356
+ fbq('init', $facebook_id);
357
+ fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
+ </script>";
359
+
360
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
+ echo $fb_script;
362
+ echo $fb_page_view;
363
+ } else {
364
+ echo $fb_script;
365
+ }
366
+ echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
+ }
368
+
369
+ }
370
+
371
+ /**
372
+ * Debug Data Setting Actions.
373
+ *
374
+ * @since 1.1.14
375
+ */
376
+ public function debug_data_setting_actions() {
377
+
378
+ add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
+ }
380
+
381
+ /**
382
+ * Get/Set the allow minify option.
383
+ *
384
+ * @since 1.1.14
385
+ */
386
+ public function allow_load_minify() {
387
+ $debug_data = Cartflows_Helper::get_debug_settings();
388
+ $allow_minified = $debug_data['allow_minified_files'];
389
+ $allow_minify = false;
390
+
391
+ if ( 'enable' === $allow_minified ) {
392
+ $allow_minify = true;
393
+ }
394
+
395
+ return $allow_minify;
396
+ }
397
+
398
+ /**
399
+ * Global flow scripts.
400
+ *
401
+ * @since 1.0.0
402
+ */
403
+ public function global_flow_scripts() {
404
+
405
+ global $post;
406
+
407
+ $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
+ $current_step = $post->ID;
409
+ $next_step_link = '';
410
+ $compatibility = Cartflows_Compatibility::get_instance();
411
+
412
+ if ( _is_wcf_landing_type() ) {
413
+
414
+ $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
+ $next_step_link = get_permalink( $next_step_id );
416
+ }
417
+
418
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
+
420
+ $fb_active = Cartflows_Helper::get_facebook_settings();
421
+ $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
+ $params = array();
423
+ $ga_param = array();
424
+
425
+ if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
+
427
+ $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
+ }
429
+
430
+ if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
+ $ga_param = Cartflows_Tracking::get_ga_items_list();
432
+ }
433
+
434
+ $localize = array(
435
+ 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
+ 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
+ 'current_theme' => $compatibility->get_current_theme(),
438
+ 'current_flow' => $flow,
439
+ 'current_step' => $current_step,
440
+ 'next_step' => $next_step_link,
441
+ 'page_template' => $page_template,
442
+ 'is_checkout_page' => _is_wcf_checkout_type(),
443
+ 'params' => $params,
444
+ 'fb_active' => $fb_active,
445
+ 'wcf_ga_active' => $wcf_ga_active,
446
+ 'ga_param' => $ga_param,
447
+ );
448
+
449
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
+
451
+ if ( _wcf_supported_template( $page_template ) ) {
452
+
453
+ wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
+ }
455
+
456
+ wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
+
458
+ wp_enqueue_script(
459
+ 'wcf-frontend-global',
460
+ wcf()->utils->get_js_url( 'frontend' ),
461
+ array( 'jquery', 'jquery-cookie' ),
462
+ CARTFLOWS_VER,
463
+ false
464
+ );
465
+ }
466
+
467
+ /**
468
+ * Custom Script in head.
469
+ *
470
+ * @since 1.0.0
471
+ */
472
+ public function custom_script_option() {
473
+
474
+ /* Add custom script to header in frontend. */
475
+ $script = $this->get_custom_script();
476
+ if ( '' !== $script ) {
477
+ if ( false === strpos( $script, '<script' ) ) {
478
+ $script = '<script>' . $script . '</script>';
479
+ }
480
+ echo '<!-- Custom CartFlows Script -->';
481
+ echo $script;
482
+ echo '<!-- End Custom CartFlows Script -->';
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Override woo templates.
488
+ *
489
+ * @param string $template new Template full path.
490
+ * @param string $template_name Template name.
491
+ * @param string $template_path Template Path.
492
+ * @since 1.1.5
493
+ * @return string.
494
+ */
495
+ public function override_woo_template( $template, $template_name, $template_path ) {
496
+
497
+ global $woocommerce;
498
+
499
+ $_template = $template;
500
+
501
+ $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
+
503
+ if ( file_exists( $plugin_path . $template_name ) ) {
504
+ $template = $plugin_path . $template_name;
505
+ }
506
+
507
+ if ( ! $template ) {
508
+ $template = $_template;
509
+ }
510
+
511
+ return $template;
512
+ }
513
+
514
+ /**
515
+ * Remove the action applied by the Flatsome theme.
516
+ *
517
+ * @since 1.1.5
518
+ * @return void.
519
+ */
520
+ public function remove_flatsome_action() {
521
+
522
+ // Remove action where flatsome dequeued the woocommerce's default styles.
523
+ remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
+ }
525
+
526
+ /**
527
+ * Add version class to body in frontend.
528
+ *
529
+ * @since 1.1.5
530
+ * @param array $classes classes.
531
+ * @return array $classes classes.
532
+ */
533
+ public function add_cartflows_lite_version_to_body( $classes ) {
534
+
535
+ $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
+
537
+ return $classes;
538
+
539
+ }
540
+
541
+ /**
542
+ * Get custom script data.
543
+ *
544
+ * @since 1.0.0
545
+ */
546
+ public function get_custom_script() {
547
+
548
+ global $post;
549
+
550
+ $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
+
552
+ return $script;
553
+ }
554
+
555
+
556
+ /**
557
+ * Set appropriate filter sctions.
558
+ *
559
+ * @since 1.1.14
560
+ */
561
+ public function setup_optin_checkout_filter() {
562
+
563
+ if ( _is_wcf_doing_optin_ajax() ) {
564
+ /* Modify the optin order received url to go next step */
565
+ remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
+ }
568
+ }
569
+
570
+ /**
571
+ * Redirect to thank page if upsell not exists
572
+ *
573
+ * @param string $order_recieve_url url.
574
+ * @param object $order order object.
575
+ * @since 1.0.0
576
+ */
577
+ public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
+
579
+ /* Only for optin page */
580
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
+ wcf()->logger->log( 'Only for optin page' );
582
+
583
+ if ( _is_wcf_doing_optin_ajax() ) {
584
+
585
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
+
587
+ if ( ! $optin_id ) {
588
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
+ }
590
+ } else {
591
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
+ }
593
+
594
+ wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
+
596
+ if ( $optin_id ) {
597
+
598
+ $next_step_id = wcf()->flow->get_next_step_id( $order );
599
+
600
+ if ( $next_step_id ) {
601
+
602
+ $order_recieve_url = get_permalink( $next_step_id );
603
+ $query_param = array(
604
+ 'wcf-key' => $order->get_order_key(),
605
+ 'wcf-order' => $order->get_id(),
606
+ );
607
+
608
+ if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
+
610
+ $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
+
612
+ $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
+
614
+ if ( is_array( $fields ) ) {
615
+
616
+ $order_id = $order->get_id();
617
+
618
+ foreach ( $fields as $in => $key ) {
619
+ switch ( $key ) {
620
+ case 'first_name':
621
+ $query_param[ $key ] = $order->get_billing_first_name();
622
+ break;
623
+ case 'last_name':
624
+ $query_param[ $key ] = $order->get_billing_last_name();
625
+ break;
626
+ case 'email':
627
+ $query_param[ $key ] = $order->get_billing_email();
628
+ break;
629
+ default:
630
+ $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
+ break;
632
+ }
633
+ }
634
+ }
635
+ }
636
+
637
+ $order_recieve_url = add_query_arg(
638
+ $query_param,
639
+ $order_recieve_url
640
+ );
641
+ }
642
+ }
643
+
644
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
+
646
+ return $order_recieve_url;
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Prepare if class 'Cartflows_Frontend' exist.
652
+ * Kicking this off by calling 'get_instance()' method
653
+ */
654
+ Cartflows_Frontend::get_instance();
classes/class-cartflows-functions.php CHANGED
@@ -1,539 +1,539 @@
1
- <?php
2
- /**
3
- * CartFlows Functions.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Fatal error mb_strpos fallback.
14
- *
15
- * @param string $string string where to find.
16
- * @param string $search string to search.
17
- * @since 1.0.0
18
- */
19
- function wcf_mb_strpos( $string, $search ) {
20
-
21
- if ( function_exists( 'mb_strpos' ) ) {
22
- return mb_strpos( $string, $search, 0, 'utf-8' );
23
- } else {
24
- return strpos( $string, $search );
25
- }
26
- }
27
-
28
- /**
29
- * Check if cartflows pro activated.
30
- *
31
- * @since 1.0.0
32
- */
33
- function _is_cartflows_pro() {
34
-
35
- if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
- return true;
37
- }
38
-
39
- return false;
40
-
41
- }
42
-
43
- /**
44
- * Returns pro version number.
45
- *
46
- * @param int $version version number.
47
- * @since 1.0.0
48
- */
49
- function _is_cartflows_pro_ver_less_than( $version ) {
50
-
51
- if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
- return true;
53
- }
54
-
55
- return false;
56
- }
57
-
58
- /**
59
- * Returns step id.
60
- *
61
- * @since 1.0.0
62
- */
63
- function _get_wcf_post_id() {
64
-
65
- global $post;
66
-
67
- if ( isset( $post->ID ) ) {
68
- return $post->ID;
69
- }
70
-
71
- return 0;
72
- }
73
-
74
- /**
75
- * Returns step id.
76
- *
77
- * @since 1.0.0
78
- */
79
- function _get_wcf_step_id() {
80
-
81
- if ( wcf()->utils->is_step_post_type() ) {
82
-
83
- global $post;
84
-
85
- return $post->ID;
86
- }
87
-
88
- return false;
89
- }
90
-
91
- /**
92
- * Check if it is a landing page?
93
- *
94
- * @since 1.0.0
95
- */
96
- function _is_wcf_landing_type() {
97
-
98
- if ( wcf()->utils->is_step_post_type() ) {
99
-
100
- global $post;
101
-
102
- if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
-
104
- return true;
105
- }
106
- }
107
-
108
- return false;
109
- }
110
-
111
- /**
112
- * Returns landing id.
113
- *
114
- * @since 1.0.0
115
- */
116
- function _get_wcf_landing_id() {
117
-
118
- if ( _is_wcf_landing_type() ) {
119
-
120
- global $post;
121
-
122
- return $post->ID;
123
- }
124
-
125
- return false;
126
- }
127
-
128
- /**
129
- * Is custom checkout?
130
- *
131
- * @param int $checkout_id checkout ID.
132
- * @since 1.0.0
133
- */
134
- function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
-
136
- $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
-
138
- if ( 'yes' === $is_custom ) {
139
-
140
- return true;
141
- }
142
-
143
- return false;
144
- }
145
-
146
- /**
147
- * Check if page is cartflow checkout.
148
- *
149
- * @since 1.0.0
150
- * @return bool
151
- */
152
- function _is_wcf_checkout_type() {
153
-
154
- if ( wcf()->utils->is_step_post_type() ) {
155
-
156
- global $post;
157
-
158
- if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
-
160
- return true;
161
- }
162
- }
163
-
164
- return false;
165
- }
166
-
167
- /**
168
- * Check if AJAX call is in progress.
169
- *
170
- * @since 1.0.0
171
- * @return bool
172
- */
173
- function _is_wcf_doing_checkout_ajax() {
174
-
175
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
-
177
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
- isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
- ) {
180
- return true;
181
- }
182
- }
183
-
184
- return false;
185
- }
186
-
187
- /**
188
- * Check if optin AJAX call is in progress.
189
- *
190
- * @since 1.0.0
191
- * @return bool
192
- */
193
- function _is_wcf_doing_optin_ajax() {
194
-
195
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
-
197
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
- isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
- ) {
200
- return true;
201
- }
202
- }
203
-
204
- return false;
205
- }
206
-
207
- /**
208
- * Returns checkout ID.
209
- *
210
- * @since 1.0.0
211
- * @return int/bool
212
- */
213
- function _get_wcf_checkout_id() {
214
-
215
- if ( _is_wcf_checkout_type() ) {
216
-
217
- global $post;
218
-
219
- return $post->ID;
220
- }
221
-
222
- return false;
223
- }
224
-
225
- /**
226
- * Check if it is checkout shortcode.
227
- *
228
- * @since 1.0.0
229
- * @return bool
230
- */
231
- function _is_wcf_checkout_shortcode() {
232
-
233
- global $post;
234
-
235
- if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
-
237
- return true;
238
- }
239
-
240
- return false;
241
- }
242
-
243
- /**
244
- * Check if it is checkout shortcode.
245
- *
246
- * @since 1.0.0
247
- * @param string $content shortcode content.
248
- * @return bool
249
- */
250
- function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
-
252
- $checkout_id = 0;
253
-
254
- if ( ! empty( $content ) ) {
255
-
256
- $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
-
258
- preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
-
260
- if ( ! empty( $regex_matches ) ) {
261
-
262
- if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
-
264
- $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
- $attribure_str = str_replace( '"', '', $attribure_str );
266
-
267
- $attributes = wp_parse_args( $attribure_str );
268
-
269
- if ( isset( $attributes['id'] ) ) {
270
- $checkout_id = $attributes['id'];
271
- }
272
- }
273
- }
274
- }
275
-
276
- return $checkout_id;
277
- }
278
-
279
- /**
280
- * Check if post type is upsell.
281
- *
282
- * @since 1.0.0
283
- * @return bool
284
- */
285
- function _is_wcf_upsell_type() {
286
-
287
- if ( wcf()->utils->is_step_post_type() ) {
288
-
289
- global $post;
290
-
291
- if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
-
293
- return true;
294
- }
295
- }
296
-
297
- return false;
298
- }
299
-
300
- /**
301
- * Returns upsell ID.
302
- *
303
- * @since 1.0.0
304
- * @return int/bool
305
- */
306
- function _get_wcf_upsell_id() {
307
-
308
- if ( _is_wcf_upsell_type() ) {
309
-
310
- global $post;
311
-
312
- return $post->ID;
313
- }
314
-
315
- return false;
316
- }
317
-
318
- /**
319
- * Check if post is of type downsell.
320
- *
321
- * @since 1.0.0
322
- * @return int/bool
323
- */
324
- function _is_wcf_downsell_type() {
325
-
326
- if ( wcf()->utils->is_step_post_type() ) {
327
-
328
- global $post;
329
-
330
- if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
-
332
- return true;
333
- }
334
- }
335
-
336
- return false;
337
- }
338
-
339
- /**
340
- * Get downsell page ID.
341
- *
342
- * @since 1.0.0
343
- * @return int/bool
344
- */
345
- function _get_wcf_downsell_id() {
346
-
347
- if ( _is_wcf_downsell_type() ) {
348
-
349
- global $post;
350
-
351
- return $post->ID;
352
- }
353
-
354
- return false;
355
- }
356
-
357
- /**
358
- * Check if page is of thank you type.
359
- *
360
- * @since 1.0.0
361
- * @return int/bool
362
- */
363
- function _is_wcf_thankyou_type() {
364
-
365
- if ( wcf()->utils->is_step_post_type() ) {
366
-
367
- global $post;
368
-
369
- if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
-
371
- return true;
372
- }
373
- }
374
-
375
- return false;
376
- }
377
-
378
- /**
379
- * Get thank you page ID.
380
- *
381
- * @since 1.0.0
382
- * @return int/bool
383
- */
384
- function _get_wcf_thankyou_id() {
385
-
386
- if ( _is_wcf_thankyou_type() ) {
387
-
388
- global $post;
389
-
390
- return $post->ID;
391
- }
392
-
393
- return false;
394
- }
395
-
396
-
397
- /**
398
- * Check if post type is upsell.
399
- *
400
- * @since 1.0.0
401
- * @return bool
402
- */
403
- function _is_wcf_base_offer_type() {
404
-
405
- if ( wcf()->utils->is_step_post_type() ) {
406
-
407
- global $post;
408
-
409
- $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
-
411
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
-
413
- return true;
414
- }
415
- }
416
-
417
- return false;
418
- }
419
-
420
- /**
421
- * Returns upsell ID.
422
- *
423
- * @since 1.0.0
424
- * @return int/bool
425
- */
426
- function _get_wcf_base_offer_id() {
427
-
428
- if ( _is_wcf_base_offer_type() ) {
429
-
430
- global $post;
431
-
432
- return $post->ID;
433
- }
434
-
435
- return false;
436
- }
437
-
438
- /**
439
- * Check if page is of optin type.
440
- *
441
- * @since 1.0.0
442
- * @return int/bool
443
- */
444
- function _is_wcf_optin_type() {
445
-
446
- if ( wcf()->utils->is_step_post_type() ) {
447
-
448
- global $post;
449
-
450
- if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
-
452
- return true;
453
- }
454
- }
455
-
456
- return false;
457
- }
458
-
459
- /**
460
- * Get optin page ID.
461
- *
462
- * @since 1.0.0
463
- * @return int/bool
464
- */
465
- function _get_wcf_optin_id() {
466
-
467
- if ( _is_wcf_optin_type() ) {
468
-
469
- global $post;
470
-
471
- return $post->ID;
472
- }
473
-
474
- return false;
475
- }
476
-
477
- /**
478
- * Define a constant if it is not already defined.
479
- *
480
- * @since 3.0.0
481
- * @param string $name Constant name.
482
- * @param mixed $value Value.
483
- */
484
- function wcf_maybe_define_constant( $name, $value ) {
485
- if ( ! defined( $name ) ) {
486
- define( $name, $value );
487
- }
488
- }
489
-
490
-
491
- if ( ! function_exists( 'wp_body_open' ) ) {
492
- /**
493
- * Fire the wp_body_open action.
494
- *
495
- * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
- */
497
- function wp_body_open() {
498
- /**
499
- * Triggered after the opening <body> tag.
500
- */
501
- do_action( 'wp_body_open' );
502
- }
503
- }
504
-
505
- /**
506
- * Check if type is optin by id.
507
- *
508
- * @param int $post_id post id.
509
- *
510
- * @return int/bool
511
- * @since 1.0.0
512
- */
513
- function _wcf_check_is_optin_by_id( $post_id ) {
514
-
515
- if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
-
517
- return true;
518
- }
519
-
520
- return false;
521
- }
522
-
523
- /**
524
- * Supported Page Template
525
- *
526
- * @param string $page_template current page template.
527
- *
528
- * @return int/bool
529
- * @since 1.5.7
530
- */
531
- function _wcf_supported_template( $page_template ) {
532
-
533
- if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
-
535
- return true;
536
- }
537
-
538
- return false;
539
- }
1
+ <?php
2
+ /**
3
+ * CartFlows Functions.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Fatal error mb_strpos fallback.
14
+ *
15
+ * @param string $string string where to find.
16
+ * @param string $search string to search.
17
+ * @since 1.0.0
18
+ */
19
+ function wcf_mb_strpos( $string, $search ) {
20
+
21
+ if ( function_exists( 'mb_strpos' ) ) {
22
+ return mb_strpos( $string, $search, 0, 'utf-8' );
23
+ } else {
24
+ return strpos( $string, $search );
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Check if cartflows pro activated.
30
+ *
31
+ * @since 1.0.0
32
+ */
33
+ function _is_cartflows_pro() {
34
+
35
+ if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Returns pro version number.
45
+ *
46
+ * @param int $version version number.
47
+ * @since 1.0.0
48
+ */
49
+ function _is_cartflows_pro_ver_less_than( $version ) {
50
+
51
+ if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
+ return true;
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Returns step id.
60
+ *
61
+ * @since 1.0.0
62
+ */
63
+ function _get_wcf_post_id() {
64
+
65
+ global $post;
66
+
67
+ if ( isset( $post->ID ) ) {
68
+ return $post->ID;
69
+ }
70
+
71
+ return 0;
72
+ }
73
+
74
+ /**
75
+ * Returns step id.
76
+ *
77
+ * @since 1.0.0
78
+ */
79
+ function _get_wcf_step_id() {
80
+
81
+ if ( wcf()->utils->is_step_post_type() ) {
82
+
83
+ global $post;
84
+
85
+ return $post->ID;
86
+ }
87
+
88
+ return false;
89
+ }
90
+
91
+ /**
92
+ * Check if it is a landing page?
93
+ *
94
+ * @since 1.0.0
95
+ */
96
+ function _is_wcf_landing_type() {
97
+
98
+ if ( wcf()->utils->is_step_post_type() ) {
99
+
100
+ global $post;
101
+
102
+ if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
+
104
+ return true;
105
+ }
106
+ }
107
+
108
+ return false;
109
+ }
110
+
111
+ /**
112
+ * Returns landing id.
113
+ *
114
+ * @since 1.0.0
115
+ */
116
+ function _get_wcf_landing_id() {
117
+
118
+ if ( _is_wcf_landing_type() ) {
119
+
120
+ global $post;
121
+
122
+ return $post->ID;
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Is custom checkout?
130
+ *
131
+ * @param int $checkout_id checkout ID.
132
+ * @since 1.0.0
133
+ */
134
+ function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
+
136
+ $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
+
138
+ if ( 'yes' === $is_custom ) {
139
+
140
+ return true;
141
+ }
142
+
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Check if page is cartflow checkout.
148
+ *
149
+ * @since 1.0.0
150
+ * @return bool
151
+ */
152
+ function _is_wcf_checkout_type() {
153
+
154
+ if ( wcf()->utils->is_step_post_type() ) {
155
+
156
+ global $post;
157
+
158
+ if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
+
160
+ return true;
161
+ }
162
+ }
163
+
164
+ return false;
165
+ }
166
+
167
+ /**
168
+ * Check if AJAX call is in progress.
169
+ *
170
+ * @since 1.0.0
171
+ * @return bool
172
+ */
173
+ function _is_wcf_doing_checkout_ajax() {
174
+
175
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
+
177
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
+ isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
+ ) {
180
+ return true;
181
+ }
182
+ }
183
+
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * Check if optin AJAX call is in progress.
189
+ *
190
+ * @since 1.0.0
191
+ * @return bool
192
+ */
193
+ function _is_wcf_doing_optin_ajax() {
194
+
195
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
+
197
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
+ isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
+ ) {
200
+ return true;
201
+ }
202
+ }
203
+
204
+ return false;
205
+ }
206
+
207
+ /**
208
+ * Returns checkout ID.
209
+ *
210
+ * @since 1.0.0
211
+ * @return int/bool
212
+ */
213
+ function _get_wcf_checkout_id() {
214
+
215
+ if ( _is_wcf_checkout_type() ) {
216
+
217
+ global $post;
218
+
219
+ return $post->ID;
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Check if it is checkout shortcode.
227
+ *
228
+ * @since 1.0.0
229
+ * @return bool
230
+ */
231
+ function _is_wcf_checkout_shortcode() {
232
+
233
+ global $post;
234
+
235
+ if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
+
237
+ return true;
238
+ }
239
+
240
+ return false;
241
+ }
242
+
243
+ /**
244
+ * Check if it is checkout shortcode.
245
+ *
246
+ * @since 1.0.0
247
+ * @param string $content shortcode content.
248
+ * @return bool
249
+ */
250
+ function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
+
252
+ $checkout_id = 0;
253
+
254
+ if ( ! empty( $content ) ) {
255
+
256
+ $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
+
258
+ preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
+
260
+ if ( ! empty( $regex_matches ) ) {
261
+
262
+ if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
+
264
+ $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
+ $attribure_str = str_replace( '"', '', $attribure_str );
266
+
267
+ $attributes = wp_parse_args( $attribure_str );
268
+
269
+ if ( isset( $attributes['id'] ) ) {
270
+ $checkout_id = $attributes['id'];
271
+ }
272
+ }
273
+ }
274
+ }
275
+
276
+ return $checkout_id;
277
+ }
278
+
279
+ /**
280
+ * Check if post type is upsell.
281
+ *
282
+ * @since 1.0.0
283
+ * @return bool
284
+ */
285
+ function _is_wcf_upsell_type() {
286
+
287
+ if ( wcf()->utils->is_step_post_type() ) {
288
+
289
+ global $post;
290
+
291
+ if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
+
293
+ return true;
294
+ }
295
+ }
296
+
297
+ return false;
298
+ }
299
+
300
+ /**
301
+ * Returns upsell ID.
302
+ *
303
+ * @since 1.0.0
304
+ * @return int/bool
305
+ */
306
+ function _get_wcf_upsell_id() {
307
+
308
+ if ( _is_wcf_upsell_type() ) {
309
+
310
+ global $post;
311
+
312
+ return $post->ID;
313
+ }
314
+
315
+ return false;
316
+ }
317
+
318
+ /**
319
+ * Check if post is of type downsell.
320
+ *
321
+ * @since 1.0.0
322
+ * @return int/bool
323
+ */
324
+ function _is_wcf_downsell_type() {
325
+
326
+ if ( wcf()->utils->is_step_post_type() ) {
327
+
328
+ global $post;
329
+
330
+ if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
+
332
+ return true;
333
+ }
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ /**
340
+ * Get downsell page ID.
341
+ *
342
+ * @since 1.0.0
343
+ * @return int/bool
344
+ */
345
+ function _get_wcf_downsell_id() {
346
+
347
+ if ( _is_wcf_downsell_type() ) {
348
+
349
+ global $post;
350
+
351
+ return $post->ID;
352
+ }
353
+
354
+ return false;
355
+ }
356
+
357
+ /**
358
+ * Check if page is of thank you type.
359
+ *
360
+ * @since 1.0.0
361
+ * @return int/bool
362
+ */
363
+ function _is_wcf_thankyou_type() {
364
+
365
+ if ( wcf()->utils->is_step_post_type() ) {
366
+
367
+ global $post;
368
+
369
+ if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
+
371
+ return true;
372
+ }
373
+ }
374
+
375
+ return false;
376
+ }
377
+
378
+ /**
379
+ * Get thank you page ID.
380
+ *
381
+ * @since 1.0.0
382
+ * @return int/bool
383
+ */
384
+ function _get_wcf_thankyou_id() {
385
+
386
+ if ( _is_wcf_thankyou_type() ) {
387
+
388
+ global $post;
389
+
390
+ return $post->ID;
391
+ }
392
+
393
+ return false;
394
+ }
395
+
396
+
397
+ /**
398
+ * Check if post type is upsell.
399
+ *
400
+ * @since 1.0.0
401
+ * @return bool
402
+ */
403
+ function _is_wcf_base_offer_type() {
404
+
405
+ if ( wcf()->utils->is_step_post_type() ) {
406
+
407
+ global $post;
408
+
409
+ $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
+
411
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
+
413
+ return true;
414
+ }
415
+ }
416
+
417
+ return false;
418
+ }
419
+
420
+ /**
421
+ * Returns upsell ID.
422
+ *
423
+ * @since 1.0.0
424
+ * @return int/bool
425
+ */
426
+ function _get_wcf_base_offer_id() {
427
+
428
+ if ( _is_wcf_base_offer_type() ) {
429
+
430
+ global $post;
431
+
432
+ return $post->ID;
433
+ }
434
+
435
+ return false;
436
+ }
437
+
438
+ /**
439
+ * Check if page is of optin type.
440
+ *
441
+ * @since 1.0.0
442
+ * @return int/bool
443
+ */
444
+ function _is_wcf_optin_type() {
445
+
446
+ if ( wcf()->utils->is_step_post_type() ) {
447
+
448
+ global $post;
449
+
450
+ if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
+
452
+ return true;
453
+ }
454
+ }
455
+
456
+ return false;
457
+ }
458
+
459
+ /**
460
+ * Get optin page ID.
461
+ *
462
+ * @since 1.0.0
463
+ * @return int/bool
464
+ */
465
+ function _get_wcf_optin_id() {
466
+
467
+ if ( _is_wcf_optin_type() ) {
468
+
469
+ global $post;
470
+
471
+ return $post->ID;
472
+ }
473
+
474
+ return false;
475
+ }
476
+
477
+ /**
478
+ * Define a constant if it is not already defined.
479
+ *
480
+ * @since 3.0.0
481
+ * @param string $name Constant name.
482
+ * @param mixed $value Value.
483
+ */
484
+ function wcf_maybe_define_constant( $name, $value ) {
485
+ if ( ! defined( $name ) ) {
486
+ define( $name, $value );
487
+ }
488
+ }
489
+
490
+
491
+ if ( ! function_exists( 'wp_body_open' ) ) {
492
+ /**
493
+ * Fire the wp_body_open action.
494
+ *
495
+ * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
+ */
497
+ function wp_body_open() {
498
+ /**
499
+ * Triggered after the opening <body> tag.
500
+ */
501
+ do_action( 'wp_body_open' );
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Check if type is optin by id.
507
+ *
508
+ * @param int $post_id post id.
509
+ *
510
+ * @return int/bool
511
+ * @since 1.0.0
512
+ */
513
+ function _wcf_check_is_optin_by_id( $post_id ) {
514
+
515
+ if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
+
517
+ return true;
518
+ }
519
+
520
+ return false;
521
+ }
522
+
523
+ /**
524
+ * Supported Page Template
525
+ *
526
+ * @param string $page_template current page template.
527
+ *
528
+ * @return int/bool
529
+ * @since 1.5.7
530
+ */
531
+ function _wcf_supported_template( $page_template ) {
532
+
533
+ if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
+
535
+ return true;
536
+ }
537
+
538
+ return false;
539
+ }
classes/class-cartflows-loader.php CHANGED
@@ -125,7 +125,7 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
- define( 'CARTFLOWS_VER', '1.5.13' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
+ define( 'CARTFLOWS_VER', '1.5.14' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
classes/class-cartflows-meta-fields.php CHANGED
@@ -116,7 +116,7 @@ class Cartflows_Meta_Fields {
116
  }
117
 
118
  // CartFlows supported product types.
119
- $supported_product_types = array( 'simple', 'variable', 'variation', 'subscription', 'variable-subscription', 'subscription_variation' );
120
 
121
  // Allowed product types.
122
  if ( isset( $_GET['allowed'] ) && ! empty( $_GET['allowed'] ) ) {
116
  }
117
 
118
  // CartFlows supported product types.
119
+ $supported_product_types = array( 'simple', 'variable', 'variation', 'subscription', 'variable-subscription', 'subscription_variation', 'course' );
120
 
121
  // Allowed product types.
122
  if ( isset( $_GET['allowed'] ) && ! empty( $_GET['allowed'] ) ) {
classes/class-cartflows-update.php CHANGED
@@ -1,168 +1,168 @@
1
- <?php
2
- /**
3
- * Update Compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- if ( ! class_exists( 'Cartflows_Update' ) ) :
9
-
10
- /**
11
- * CartFlows Update initial setup
12
- *
13
- * @since 1.0.0
14
- */
15
- class Cartflows_Update {
16
-
17
- /**
18
- * Class instance.
19
- *
20
- * @access private
21
- * @var $instance Class instance.
22
- */
23
- private static $instance;
24
-
25
- /**
26
- * Initiator
27
- */
28
- public static function get_instance() {
29
- if ( ! isset( self::$instance ) ) {
30
- self::$instance = new self();
31
- }
32
- return self::$instance;
33
- }
34
-
35
- /**
36
- * Constructor
37
- */
38
- public function __construct() {
39
- add_action( 'admin_init', array( $this, 'init' ) );
40
- }
41
-
42
- /**
43
- * Init
44
- *
45
- * @since 1.0.0
46
- * @return void
47
- */
48
- public function init() {
49
-
50
- do_action( 'cartflows_update_before' );
51
-
52
- // Get auto saved version number.
53
- $saved_version = get_option( 'cartflows-version', false );
54
-
55
- // Update auto saved version number.
56
- if ( ! $saved_version ) {
57
- update_option( 'cartflows-version', CARTFLOWS_VER );
58
- return;
59
- }
60
-
61
- // If equals then return.
62
- if ( version_compare( $saved_version, CARTFLOWS_VER, '=' ) ) {
63
- return;
64
- }
65
-
66
- $this->logger_files();
67
-
68
- if ( version_compare( $saved_version, '1.1.22', '<' ) ) {
69
- update_option( 'wcf_setup_skipped', true );
70
- }
71
-
72
- if ( version_compare( $saved_version, '1.2.0', '<' ) ) {
73
-
74
- $this->changed_wp_templates();
75
- }
76
-
77
- if ( version_compare( $saved_version, '1.5.13', '<' ) ) {
78
- $this->update_usage_tracking_option();
79
- }
80
-
81
- // Update auto saved version number.
82
- update_option( 'cartflows-version', CARTFLOWS_VER );
83
-
84
- do_action( 'cartflows_update_after' );
85
- }
86
-
87
-
88
- /**
89
- * Loading logger files.
90
- *
91
- * @since 1.0.0
92
- * @return void
93
- */
94
- public function logger_files() {
95
-
96
- if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
97
-
98
- $upload_dir = wp_upload_dir( null, false );
99
-
100
- define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
101
- }
102
-
103
- wcf()->create_files();
104
- }
105
-
106
- /**
107
- * Update usage tracking option.
108
- *
109
- * @since 1.0.0
110
- * @return void
111
- */
112
- public function update_usage_tracking_option() {
113
-
114
- $bsf_usage_tracking = get_site_option( 'bsf_analytics_optin' );
115
-
116
- $cf_usage_tracking = get_site_option( 'cf_analytics_optin' );
117
-
118
- if ( isset( $bsf_usage_tracking ) && 'yes' === $bsf_usage_tracking && false === $cf_usage_tracking ) {
119
- update_site_option( 'cf_analytics_optin', 'yes' );
120
- }
121
-
122
- }
123
-
124
- /**
125
- * Init
126
- *
127
- * @since 1.0.0
128
- * @return void
129
- */
130
- public function changed_wp_templates() {
131
-
132
- global $wpdb;
133
-
134
- $query_results = $wpdb->get_results(
135
- $wpdb->prepare(
136
- "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )
137
- where {$wpdb->posts}.post_type = %s AND {$wpdb->postmeta}.meta_key = %s AND {$wpdb->postmeta}.meta_value != %s AND {$wpdb->postmeta}.meta_value != %s",
138
- 'cartflows_step',
139
- '_wp_page_template',
140
- 'cartflows-canvas',
141
- 'cartflows-default'
142
- )
143
- ); // db call ok; no-cache ok.
144
-
145
- if ( is_array( $query_results ) && ! empty( $query_results ) ) {
146
-
147
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-change-template-batch.php';
148
-
149
- wcf()->logger->log( '(✓) Update Templates BATCH Started!' );
150
-
151
- $change_template_batch = new Cartflows_Change_Template_Batch();
152
-
153
- foreach ( $query_results as $query_result ) {
154
-
155
- wcf()->logger->log( '(✓) POST ID ' . $query_result->ID );
156
- $change_template_batch->push_to_queue( $query_result->ID );
157
- }
158
-
159
- $change_template_batch->save()->dispatch();
160
- }
161
- }
162
- }
163
- /**
164
- * Kicking this off by calling 'get_instance()' method
165
- */
166
- Cartflows_Update::get_instance();
167
-
168
- endif;
1
+ <?php
2
+ /**
3
+ * Update Compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ if ( ! class_exists( 'Cartflows_Update' ) ) :
9
+
10
+ /**
11
+ * CartFlows Update initial setup
12
+ *
13
+ * @since 1.0.0
14
+ */
15
+ class Cartflows_Update {
16
+
17
+ /**
18
+ * Class instance.
19
+ *
20
+ * @access private
21
+ * @var $instance Class instance.
22
+ */
23
+ private static $instance;
24
+
25
+ /**
26
+ * Initiator
27
+ */
28
+ public static function get_instance() {
29
+ if ( ! isset( self::$instance ) ) {
30
+ self::$instance = new self();
31
+ }
32
+ return self::$instance;
33
+ }
34
+
35
+ /**
36
+ * Constructor
37
+ */
38
+ public function __construct() {
39
+ add_action( 'admin_init', array( $this, 'init' ) );
40
+ }
41
+
42
+ /**
43
+ * Init
44
+ *
45
+ * @since 1.0.0
46
+ * @return void
47
+ */
48
+ public function init() {
49
+
50
+ do_action( 'cartflows_update_before' );
51
+
52
+ // Get auto saved version number.
53
+ $saved_version = get_option( 'cartflows-version', false );
54
+
55
+ // Update auto saved version number.
56
+ if ( ! $saved_version ) {
57
+ update_option( 'cartflows-version', CARTFLOWS_VER );
58
+ return;
59
+ }
60
+
61
+ // If equals then return.
62
+ if ( version_compare( $saved_version, CARTFLOWS_VER, '=' ) ) {
63
+ return;
64
+ }
65
+
66
+ $this->logger_files();
67
+
68
+ if ( version_compare( $saved_version, '1.1.22', '<' ) ) {
69
+ update_option( 'wcf_setup_skipped', true );
70
+ }
71
+
72
+ if ( version_compare( $saved_version, '1.2.0', '<' ) ) {
73
+
74
+ $this->changed_wp_templates();
75
+ }
76
+
77
+ if ( version_compare( $saved_version, '1.5.13', '<' ) ) {
78
+ $this->update_usage_tracking_option();
79
+ }
80
+
81
+ // Update auto saved version number.
82
+ update_option( 'cartflows-version', CARTFLOWS_VER );
83
+
84
+ do_action( 'cartflows_update_after' );
85
+ }
86
+
87
+
88
+ /**
89
+ * Loading logger files.
90
+ *
91
+ * @since 1.0.0
92
+ * @return void
93
+ */
94
+ public function logger_files() {
95
+
96
+ if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
97
+
98
+ $upload_dir = wp_upload_dir( null, false );
99
+
100
+ define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
101
+ }
102
+
103
+ wcf()->create_files();
104
+ }
105
+
106
+ /**
107
+ * Update usage tracking option.
108
+ *
109
+ * @since 1.0.0
110
+ * @return void
111
+ */
112
+ public function update_usage_tracking_option() {
113
+
114
+ $bsf_usage_tracking = get_site_option( 'bsf_analytics_optin' );
115
+
116
+ $cf_usage_tracking = get_site_option( 'cf_analytics_optin' );
117
+
118
+ if ( isset( $bsf_usage_tracking ) && 'yes' === $bsf_usage_tracking && false === $cf_usage_tracking ) {
119
+ update_site_option( 'cf_analytics_optin', 'yes' );
120
+ }
121
+
122
+ }
123
+
124
+ /**
125
+ * Init
126
+ *
127
+ * @since 1.0.0
128
+ * @return void
129
+ */
130
+ public function changed_wp_templates() {
131
+
132
+ global $wpdb;
133
+
134
+ $query_results = $wpdb->get_results(
135
+ $wpdb->prepare(
136
+ "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )
137
+ where {$wpdb->posts}.post_type = %s AND {$wpdb->postmeta}.meta_key = %s AND {$wpdb->postmeta}.meta_value != %s AND {$wpdb->postmeta}.meta_value != %s",
138
+ 'cartflows_step',
139
+ '_wp_page_template',
140
+ 'cartflows-canvas',
141
+ 'cartflows-default'
142
+ )
143
+ ); // db call ok; no-cache ok.
144
+
145
+ if ( is_array( $query_results ) && ! empty( $query_results ) ) {
146
+
147
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-change-template-batch.php';
148
+
149
+ wcf()->logger->log( '(✓) Update Templates BATCH Started!' );
150
+
151
+ $change_template_batch = new Cartflows_Change_Template_Batch();
152
+
153
+ foreach ( $query_results as $query_result ) {
154
+
155
+ wcf()->logger->log( '(✓) POST ID ' . $query_result->ID );
156
+ $change_template_batch->push_to_queue( $query_result->ID );
157
+ }
158
+
159
+ $change_template_batch->save()->dispatch();
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * Kicking this off by calling 'get_instance()' method
165
+ */
166
+ Cartflows_Update::get_instance();
167
+
168
+ endif;
classes/class-cartflows-utils.php CHANGED
@@ -1,591 +1,591 @@
1
- <?php
2
- /**
3
- * Utils.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Utils.
14
- */
15
- class Cartflows_Utils {
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_products
28
- */
29
- public $checkout_products = array();
30
-
31
-
32
- /**
33
- * Initiator
34
- */
35
- public static function get_instance() {
36
- if ( ! isset( self::$instance ) ) {
37
- self::$instance = new self();
38
- }
39
- return self::$instance;
40
- }
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get current post type
50
- *
51
- * @param string $post_type post type.
52
- * @return string
53
- */
54
- public function current_post_type( $post_type = '' ) {
55
-
56
- if ( '' === $post_type ) {
57
- $post_type = get_post_type();
58
- }
59
-
60
- return $post_type;
61
- }
62
-
63
- /**
64
- * Check if post type is of step.
65
- *
66
- * @param string $post_type post type.
67
- * @return bool
68
- */
69
- public function is_step_post_type( $post_type = '' ) {
70
-
71
- if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
-
73
- return true;
74
- }
75
-
76
- return false;
77
- }
78
-
79
- /**
80
- * Check if post type is of flow.
81
- *
82
- * @param string $post_type post type.
83
- * @return bool
84
- */
85
- public function is_flow_post_type( $post_type = '' ) {
86
-
87
- if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
-
89
- return true;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Get post type of step.
97
- *
98
- * @return string
99
- */
100
- public function get_step_post_type() {
101
-
102
- return CARTFLOWS_STEP_POST_TYPE;
103
- }
104
-
105
- /**
106
- * Get post type of flow.
107
- *
108
- * @return string
109
- */
110
- public function get_flow_post_type() {
111
-
112
- return CARTFLOWS_FLOW_POST_TYPE;
113
- }
114
-
115
- /**
116
- * Get flow id
117
- *
118
- * @return int
119
- */
120
- public function get_flow_id() {
121
-
122
- global $post;
123
-
124
- return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
- }
126
-
127
- /**
128
- * Get flow id by step
129
- *
130
- * @param int $step_id step ID.
131
- * @return int
132
- */
133
- public function get_flow_id_from_step_id( $step_id ) {
134
-
135
- return get_post_meta( $step_id, 'wcf-flow-id', true );
136
- }
137
-
138
- /**
139
- * Get flow steps by id
140
- *
141
- * @param int $flow_id flow ID.
142
- * @return int
143
- */
144
- public function get_flow_steps( $flow_id ) {
145
-
146
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
-
148
- if ( is_array( $steps ) && ! empty( $steps ) ) {
149
- return $steps;
150
- }
151
-
152
- return false;
153
- }
154
-
155
- /**
156
- * Get template type of step
157
- *
158
- * @param int $step_id step ID.
159
- * @return int
160
- */
161
- public function get_step_type( $step_id ) {
162
-
163
- return get_post_meta( $step_id, 'wcf-step-type', true );
164
- }
165
-
166
- /**
167
- * Get next id for step
168
- *
169
- * @param int $flow_id flow ID.
170
- * @param int $step_id step ID.
171
- * @return bool
172
- */
173
- public function get_next_step_id( $flow_id, $step_id ) {
174
-
175
- $steps = $this->get_flow_steps( $flow_id );
176
- $step_id = intval( $step_id );
177
-
178
- if ( ! $steps ) {
179
- return false;
180
- }
181
-
182
- foreach ( $steps as $i => $step ) {
183
-
184
- if ( intval( $step['id'] ) === $step_id ) {
185
-
186
- $next_i = $i + 1;
187
-
188
- if ( isset( $steps[ $next_i ] ) ) {
189
-
190
- $navigation = $steps[ $next_i ];
191
-
192
- return intval( $navigation['id'] );
193
- }
194
-
195
- break;
196
- }
197
- }
198
-
199
- return false;
200
- }
201
-
202
- /**
203
- * Get next id for step
204
- *
205
- * @param int $order_id order ID.
206
- * @return int
207
- */
208
- public function get_flow_id_from_order( $order_id ) {
209
-
210
- $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
-
212
- return intval( $flow_id );
213
- }
214
-
215
- /**
216
- * Get checkout id for order
217
- *
218
- * @param int $order_id order ID.
219
- * @return int
220
- */
221
- public function get_checkout_id_from_order( $order_id ) {
222
-
223
- $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
-
225
- return intval( $checkout_id );
226
- }
227
-
228
- /**
229
- * We are using this function mostly in ajax on checkout page
230
- *
231
- * @return bool
232
- */
233
- public function get_checkout_id_from_post_data() {
234
-
235
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
-
237
- $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
-
239
- return intval( $checkout_id );
240
- }
241
-
242
- return false;
243
- }
244
-
245
- /**
246
- * We are using this function mostly in ajax on checkout page
247
- *
248
- * @return bool
249
- */
250
- public function get_flow_id_from_post_data() {
251
-
252
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
-
254
- $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
-
256
- return intval( $flow_id );
257
- }
258
-
259
- return false;
260
- }
261
-
262
- /**
263
- * Get optin id for order
264
- *
265
- * @param int $order_id order ID.
266
- * @return int
267
- */
268
- public function get_optin_id_from_order( $order_id ) {
269
-
270
- $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
-
272
- return intval( $optin_id );
273
- }
274
-
275
- /**
276
- * We are using this function mostly in ajax on checkout page
277
- *
278
- * @return bool
279
- */
280
- public function get_optin_id_from_post_data() {
281
-
282
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
-
284
- $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
-
286
- return intval( $optin_id );
287
- }
288
-
289
- return false;
290
- }
291
-
292
- /**
293
- * Check for thank you page
294
- *
295
- * @param int $step_id step ID.
296
- * @return bool
297
- */
298
- public function check_is_thankyou_page( $step_id ) {
299
-
300
- $step_type = $this->get_step_type( $step_id );
301
-
302
- if ( 'thankyou' === $step_type ) {
303
-
304
- return true;
305
- }
306
-
307
- return false;
308
- }
309
-
310
- /**
311
- * Check for offer page
312
- *
313
- * @param int $step_id step ID.
314
- * @return bool
315
- */
316
- public function check_is_offer_page( $step_id ) {
317
-
318
- $step_type = $this->get_step_type( $step_id );
319
-
320
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
-
322
- return true;
323
- }
324
-
325
- return false;
326
- }
327
-
328
- /**
329
- * Check if loaded page requires woo.
330
- *
331
- * @return bool
332
- */
333
- public function check_is_woo_required_page() {
334
-
335
- global $post;
336
- $step_id = $post->ID;
337
- $woo_not_required_type = array( 'landing' );
338
- $step_type = $this->get_step_type( $step_id );
339
- return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
- }
341
-
342
- /**
343
- * Define constant for cache
344
- *
345
- * @return void
346
- */
347
- public function do_not_cache() {
348
-
349
- global $post;
350
-
351
- if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
- return;
353
- }
354
-
355
- wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
- wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
- wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
-
359
- nocache_headers();
360
- }
361
-
362
- /**
363
- * Get linking url
364
- *
365
- * @param array $args query args.
366
- * @return string
367
- */
368
- public function get_linking_url( $args = array() ) {
369
-
370
- $url = get_home_url();
371
-
372
- $url = add_query_arg( $args, $url );
373
-
374
- return $url;
375
- }
376
-
377
- /**
378
- * Get assets urls
379
- *
380
- * @return array
381
- * @since 1.1.6
382
- */
383
- public function get_assets_path() {
384
-
385
- $rtl = '';
386
-
387
- if ( is_rtl() ) {
388
- $rtl = '-rtl';
389
- }
390
-
391
- $file_prefix = '';
392
- $dir_name = '';
393
-
394
- $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
-
396
- if ( $is_min ) {
397
- $file_prefix = '.min';
398
- $dir_name = 'min-';
399
- }
400
-
401
- $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
- $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
-
404
- return array(
405
- 'css' => $css_gen_path,
406
- 'js' => $js_gen_path,
407
- 'file_prefix' => $file_prefix,
408
- 'rtl' => $rtl,
409
- );
410
- }
411
-
412
- /**
413
- * Get assets css url
414
- *
415
- * @param string $file file name.
416
- * @return string
417
- * @since 1.1.6
418
- */
419
- public function get_css_url( $file ) {
420
-
421
- $assets_vars = wcf()->assets_vars;
422
-
423
- $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
-
425
- return $url;
426
- }
427
-
428
- /**
429
- * Get assets js url
430
- *
431
- * @param string $file file name.
432
- * @return string
433
- * @since 1.1.6
434
- */
435
- public function get_js_url( $file ) {
436
-
437
- $assets_vars = wcf()->assets_vars;
438
-
439
- $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
-
441
- return $url;
442
- }
443
-
444
- /**
445
- * Get unique id.
446
- *
447
- * @param int $length Length.
448
- *
449
- * @return string
450
- */
451
- public function get_unique_id( $length = 8 ) {
452
-
453
- return substr( md5( microtime() ), 0, $length );
454
- }
455
-
456
- /**
457
- * Get selected checkout products and data
458
- *
459
- * @param int $checkout_id Checkout id..
460
- * @param array $saved_products Saved product.
461
- *
462
- * @return array
463
- */
464
- public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
-
466
- if ( empty( $checkout_id ) ) {
467
-
468
- global $post;
469
-
470
- $checkout_id = $post->ID;
471
- }
472
-
473
- if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
-
475
- if ( ! empty( $saved_products ) ) {
476
-
477
- $products = $saved_products;
478
- } else {
479
-
480
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
- }
482
-
483
- $verify_url_data = false;
484
- $default_add_to_cart = false;
485
- $default_ids = array();
486
- $default_add_to_cart = true;
487
-
488
- if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
- //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
- $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
- $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
- $verify_url_data = true;
493
- }
494
-
495
- if ( is_array( $products ) ) {
496
-
497
- foreach ( $products as $in => $data ) {
498
-
499
- if ( $verify_url_data ) {
500
-
501
- $default_add_to_cart = false;
502
- $sequence = $in + 1;
503
-
504
- if ( in_array( $sequence, $default_ids, true ) ) {
505
- $default_add_to_cart = true;
506
- }
507
- }
508
-
509
- $default_data = array(
510
- 'quantity' => 1,
511
- 'discount_type' => '',
512
- 'discount_value' => '',
513
- 'unique_id' => $this->get_unique_id(),
514
- 'add_to_cart' => $default_add_to_cart,
515
- );
516
-
517
- $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
- }
519
- }
520
-
521
- $this->checkout_products[ $checkout_id ] = $products;
522
- }
523
-
524
- return $this->checkout_products[ $checkout_id ];
525
- }
526
-
527
- /**
528
- * Get selected checkout products and data
529
- *
530
- * @param int $checkout_id Checkout id..
531
- * @param array $products_data Saved product.
532
- *
533
- * @return array
534
- */
535
- public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
-
537
- if ( empty( $checkout_id ) ) {
538
-
539
- global $post;
540
-
541
- $checkout_id = $post->ID;
542
- }
543
-
544
- if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
-
546
- $products = $this->checkout_products[ $checkout_id ];
547
- } else {
548
- $products = $this->get_selected_checkout_products( $checkout_id );
549
- }
550
-
551
- if ( is_array( $products ) && ! empty( $products_data ) ) {
552
-
553
- foreach ( $products as $in => $data ) {
554
-
555
- if ( isset( $products_data[ $in ] ) ) {
556
- $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
- }
558
- }
559
- }
560
-
561
- $this->checkout_products[ $checkout_id ] = $products;
562
-
563
- return $this->checkout_products[ $checkout_id ];
564
- }
565
- }
566
-
567
- /**
568
- * Get a specific property of an array without needing to check if that property exists.
569
- *
570
- * Provide a default value if you want to return a specific value if the property is not set.
571
- *
572
- * @param array $array Array from which the property's value should be retrieved.
573
- * @param string $prop Name of the property to be retrieved.
574
- * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
- *
576
- * @return null|string|mixed The value
577
- */
578
- function wcf_get_prop( $array, $prop, $default = null ) {
579
-
580
- if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
- return $default;
582
- }
583
-
584
- if ( isset( $array[ $prop ] ) ) {
585
- $value = $array[ $prop ];
586
- } else {
587
- $value = '';
588
- }
589
-
590
- return empty( $value ) && null !== $default ? $default : $value;
591
- }
1
+ <?php
2
+ /**
3
+ * Utils.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Utils.
14
+ */
15
+ class Cartflows_Utils {
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_products
28
+ */
29
+ public $checkout_products = array();
30
+
31
+
32
+ /**
33
+ * Initiator
34
+ */
35
+ public static function get_instance() {
36
+ if ( ! isset( self::$instance ) ) {
37
+ self::$instance = new self();
38
+ }
39
+ return self::$instance;
40
+ }
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get current post type
50
+ *
51
+ * @param string $post_type post type.
52
+ * @return string
53
+ */
54
+ public function current_post_type( $post_type = '' ) {
55
+
56
+ if ( '' === $post_type ) {
57
+ $post_type = get_post_type();
58
+ }
59
+
60
+ return $post_type;
61
+ }
62
+
63
+ /**
64
+ * Check if post type is of step.
65
+ *
66
+ * @param string $post_type post type.
67
+ * @return bool
68
+ */
69
+ public function is_step_post_type( $post_type = '' ) {
70
+
71
+ if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
+
73
+ return true;
74
+ }
75
+
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * Check if post type is of flow.
81
+ *
82
+ * @param string $post_type post type.
83
+ * @return bool
84
+ */
85
+ public function is_flow_post_type( $post_type = '' ) {
86
+
87
+ if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
+
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Get post type of step.
97
+ *
98
+ * @return string
99
+ */
100
+ public function get_step_post_type() {
101
+
102
+ return CARTFLOWS_STEP_POST_TYPE;
103
+ }
104
+
105
+ /**
106
+ * Get post type of flow.
107
+ *
108
+ * @return string
109
+ */
110
+ public function get_flow_post_type() {
111
+
112
+ return CARTFLOWS_FLOW_POST_TYPE;
113
+ }
114
+
115
+ /**
116
+ * Get flow id
117
+ *
118
+ * @return int
119
+ */
120
+ public function get_flow_id() {
121
+
122
+ global $post;
123
+
124
+ return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
+ }
126
+
127
+ /**
128
+ * Get flow id by step
129
+ *
130
+ * @param int $step_id step ID.
131
+ * @return int
132
+ */
133
+ public function get_flow_id_from_step_id( $step_id ) {
134
+
135
+ return get_post_meta( $step_id, 'wcf-flow-id', true );
136
+ }
137
+
138
+ /**
139
+ * Get flow steps by id
140
+ *
141
+ * @param int $flow_id flow ID.
142
+ * @return int
143
+ */
144
+ public function get_flow_steps( $flow_id ) {
145
+
146
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
+
148
+ if ( is_array( $steps ) && ! empty( $steps ) ) {
149
+ return $steps;
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * Get template type of step
157
+ *
158
+ * @param int $step_id step ID.
159
+ * @return int
160
+ */
161
+ public function get_step_type( $step_id ) {
162
+
163
+ return get_post_meta( $step_id, 'wcf-step-type', true );
164
+ }
165
+
166
+ /**
167
+ * Get next id for step
168
+ *
169
+ * @param int $flow_id flow ID.
170
+ * @param int $step_id step ID.
171
+ * @return bool
172
+ */
173
+ public function get_next_step_id( $flow_id, $step_id ) {
174
+
175
+ $steps = $this->get_flow_steps( $flow_id );
176
+ $step_id = intval( $step_id );
177
+
178
+ if ( ! $steps ) {
179
+ return false;
180
+ }
181
+
182
+ foreach ( $steps as $i => $step ) {
183
+
184
+ if ( intval( $step['id'] ) === $step_id ) {
185
+
186
+ $next_i = $i + 1;
187
+
188
+ if ( isset( $steps[ $next_i ] ) ) {
189
+
190
+ $navigation = $steps[ $next_i ];
191
+
192
+ return intval( $navigation['id'] );
193
+ }
194
+
195
+ break;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Get next id for step
204
+ *
205
+ * @param int $order_id order ID.
206
+ * @return int
207
+ */
208
+ public function get_flow_id_from_order( $order_id ) {
209
+
210
+ $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
+
212
+ return intval( $flow_id );
213
+ }
214
+
215
+ /**
216
+ * Get checkout id for order
217
+ *
218
+ * @param int $order_id order ID.
219
+ * @return int
220
+ */
221
+ public function get_checkout_id_from_order( $order_id ) {
222
+
223
+ $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
+
225
+ return intval( $checkout_id );
226
+ }
227
+
228
+ /**
229
+ * We are using this function mostly in ajax on checkout page
230
+ *
231
+ * @return bool
232
+ */
233
+ public function get_checkout_id_from_post_data() {
234
+
235
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
+
237
+ $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
+
239
+ return intval( $checkout_id );
240
+ }
241
+
242
+ return false;
243
+ }
244
+
245
+ /**
246
+ * We are using this function mostly in ajax on checkout page
247
+ *
248
+ * @return bool
249
+ */
250
+ public function get_flow_id_from_post_data() {
251
+
252
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
+
254
+ $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
+
256
+ return intval( $flow_id );
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Get optin id for order
264
+ *
265
+ * @param int $order_id order ID.
266
+ * @return int
267
+ */
268
+ public function get_optin_id_from_order( $order_id ) {
269
+
270
+ $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
+
272
+ return intval( $optin_id );
273
+ }
274
+
275
+ /**
276
+ * We are using this function mostly in ajax on checkout page
277
+ *
278
+ * @return bool
279
+ */
280
+ public function get_optin_id_from_post_data() {
281
+
282
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
+
284
+ $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
+
286
+ return intval( $optin_id );
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ /**
293
+ * Check for thank you page
294
+ *
295
+ * @param int $step_id step ID.
296
+ * @return bool
297
+ */
298
+ public function check_is_thankyou_page( $step_id ) {
299
+
300
+ $step_type = $this->get_step_type( $step_id );
301
+
302
+ if ( 'thankyou' === $step_type ) {
303
+
304
+ return true;
305
+ }
306
+
307
+ return false;
308
+ }
309
+
310
+ /**
311
+ * Check for offer page
312
+ *
313
+ * @param int $step_id step ID.
314
+ * @return bool
315
+ */
316
+ public function check_is_offer_page( $step_id ) {
317
+
318
+ $step_type = $this->get_step_type( $step_id );
319
+
320
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
+
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * Check if loaded page requires woo.
330
+ *
331
+ * @return bool
332
+ */
333
+ public function check_is_woo_required_page() {
334
+
335
+ global $post;
336
+ $step_id = $post->ID;
337
+ $woo_not_required_type = array( 'landing' );
338
+ $step_type = $this->get_step_type( $step_id );
339
+ return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
+ }
341
+
342
+ /**
343
+ * Define constant for cache
344
+ *
345
+ * @return void
346
+ */
347
+ public function do_not_cache() {
348
+
349
+ global $post;
350
+
351
+ if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
+ return;
353
+ }
354
+
355
+ wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
+ wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
+ wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
+
359
+ nocache_headers();
360
+ }
361
+
362
+ /**
363
+ * Get linking url
364
+ *
365
+ * @param array $args query args.
366
+ * @return string
367
+ */
368
+ public function get_linking_url( $args = array() ) {
369
+
370
+ $url = get_home_url();
371
+
372
+ $url = add_query_arg( $args, $url );
373
+
374
+ return $url;
375
+ }
376
+
377
+ /**
378
+ * Get assets urls
379
+ *
380
+ * @return array
381
+ * @since 1.1.6
382
+ */
383
+ public function get_assets_path() {
384
+
385
+ $rtl = '';
386
+
387
+ if ( is_rtl() ) {
388
+ $rtl = '-rtl';
389
+ }
390
+
391
+ $file_prefix = '';
392
+ $dir_name = '';
393
+
394
+ $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
+
396
+ if ( $is_min ) {
397
+ $file_prefix = '.min';
398
+ $dir_name = 'min-';
399
+ }
400
+
401
+ $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
+ $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
+
404
+ return array(
405
+ 'css' => $css_gen_path,
406
+ 'js' => $js_gen_path,
407
+ 'file_prefix' => $file_prefix,
408
+ 'rtl' => $rtl,
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Get assets css url
414
+ *
415
+ * @param string $file file name.
416
+ * @return string
417
+ * @since 1.1.6
418
+ */
419
+ public function get_css_url( $file ) {
420
+
421
+ $assets_vars = wcf()->assets_vars;
422
+
423
+ $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
+
425
+ return $url;
426
+ }
427
+
428
+ /**
429
+ * Get assets js url
430
+ *
431
+ * @param string $file file name.
432
+ * @return string
433
+ * @since 1.1.6
434
+ */
435
+ public function get_js_url( $file ) {
436
+
437
+ $assets_vars = wcf()->assets_vars;
438
+
439
+ $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
+
441
+ return $url;
442
+ }
443
+
444
+ /**
445
+ * Get unique id.
446
+ *
447
+ * @param int $length Length.
448
+ *
449
+ * @return string
450
+ */
451
+ public function get_unique_id( $length = 8 ) {
452
+
453
+ return substr( md5( microtime() ), 0, $length );
454
+ }
455
+
456
+ /**
457
+ * Get selected checkout products and data
458
+ *
459
+ * @param int $checkout_id Checkout id..
460
+ * @param array $saved_products Saved product.
461
+ *
462
+ * @return array
463
+ */
464
+ public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
+
466
+ if ( empty( $checkout_id ) ) {
467
+
468
+ global $post;
469
+
470
+ $checkout_id = $post->ID;
471
+ }
472
+
473
+ if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
+
475
+ if ( ! empty( $saved_products ) ) {
476
+
477
+ $products = $saved_products;
478
+ } else {
479
+
480
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
+ }
482
+
483
+ $verify_url_data = false;
484
+ $default_add_to_cart = false;
485
+ $default_ids = array();
486
+ $default_add_to_cart = true;
487
+
488
+ if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
+ $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
+ $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
+ $verify_url_data = true;
493
+ }
494
+
495
+ if ( is_array( $products ) ) {
496
+
497
+ foreach ( $products as $in => $data ) {
498
+
499
+ if ( $verify_url_data ) {
500
+
501
+ $default_add_to_cart = false;
502
+ $sequence = $in + 1;
503
+
504
+ if ( in_array( $sequence, $default_ids, true ) ) {
505
+ $default_add_to_cart = true;
506
+ }
507
+ }
508
+
509
+ $default_data = array(
510
+ 'quantity' => 1,
511
+ 'discount_type' => '',
512
+ 'discount_value' => '',
513
+ 'unique_id' => $this->get_unique_id(),
514
+ 'add_to_cart' => $default_add_to_cart,
515
+ );
516
+
517
+ $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
+ }
519
+ }
520
+
521
+ $this->checkout_products[ $checkout_id ] = $products;
522
+ }
523
+
524
+ return $this->checkout_products[ $checkout_id ];
525
+ }
526
+
527
+ /**
528
+ * Get selected checkout products and data
529
+ *
530
+ * @param int $checkout_id Checkout id..
531
+ * @param array $products_data Saved product.
532
+ *
533
+ * @return array
534
+ */
535
+ public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
+
537
+ if ( empty( $checkout_id ) ) {
538
+
539
+ global $post;
540
+
541
+ $checkout_id = $post->ID;
542
+ }
543
+
544
+ if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
+
546
+ $products = $this->checkout_products[ $checkout_id ];
547
+ } else {
548
+ $products = $this->get_selected_checkout_products( $checkout_id );
549
+ }
550
+
551
+ if ( is_array( $products ) && ! empty( $products_data ) ) {
552
+
553
+ foreach ( $products as $in => $data ) {
554
+
555
+ if ( isset( $products_data[ $in ] ) ) {
556
+ $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
+ }
558
+ }
559
+ }
560
+
561
+ $this->checkout_products[ $checkout_id ] = $products;
562
+
563
+ return $this->checkout_products[ $checkout_id ];
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Get a specific property of an array without needing to check if that property exists.
569
+ *
570
+ * Provide a default value if you want to return a specific value if the property is not set.
571
+ *
572
+ * @param array $array Array from which the property's value should be retrieved.
573
+ * @param string $prop Name of the property to be retrieved.
574
+ * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
+ *
576
+ * @return null|string|mixed The value
577
+ */
578
+ function wcf_get_prop( $array, $prop, $default = null ) {
579
+
580
+ if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
+ return $default;
582
+ }
583
+
584
+ if ( isset( $array[ $prop ] ) ) {
585
+ $value = $array[ $prop ];
586
+ } else {
587
+ $value = '';
588
+ }
589
+
590
+ return empty( $value ) && null !== $default ? $default : $value;
591
+ }
classes/class-cartflows-wizard.php CHANGED
@@ -1,745 +1,745 @@
1
- <?php
2
- /**
3
- * CartFlows- Onboarding Wizard
4
- *
5
- * @package cartflows
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit;
10
- }
11
-
12
- if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
-
14
- /**
15
- * CartFlows_Wizard class.
16
- */
17
- class CartFlows_Wizard {
18
-
19
- /**
20
- * Hook in tabs.
21
- */
22
- public function __construct() {
23
-
24
- if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
- add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
- add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
- add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
- add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
-
31
- add_action( 'wp_ajax_usage_tracking_option', array( $this, 'save_usage_tracking_option' ) );
32
-
33
- add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
34
- add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
35
-
36
- add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
37
-
38
- add_action( 'admin_init', array( $this, 'hide_notices' ) );
39
-
40
- }
41
- }
42
-
43
-
44
- /**
45
- * Hide a notice if the GET variable is set.
46
- */
47
- public function hide_notices() {
48
-
49
- if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
50
- return;
51
- }
52
-
53
- $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
54
- $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
55
-
56
- if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
57
- update_option( 'wcf_setup_skipped', true );
58
- }
59
- }
60
-
61
- /**
62
- * Disable the woo redirect for new setup.
63
- */
64
- public function disable_woo_setup_redirect() {
65
-
66
- delete_transient( '_wc_activation_redirect' );
67
- }
68
-
69
- /**
70
- * Show action links on the plugin screen.
71
- *
72
- * @since 1.0.0
73
- * @return void
74
- */
75
- public function show_setup_wizard() {
76
-
77
- $screen = get_current_screen();
78
- $screen_id = $screen ? $screen->id : '';
79
- $allowed_screens = array(
80
- 'cartflows_page_cartflows_settings',
81
- 'edit-cartflows_flow',
82
- 'dashboard',
83
- 'plugins',
84
- );
85
-
86
- if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
87
- return;
88
- }
89
-
90
- $status = get_option( 'wcf_setup_complete', false );
91
- $skip_setup = get_option( 'wcf_setup_skipped', false );
92
- if ( false === $status && ! $skip_setup ) { ?>
93
- <div class="notice notice-info wcf-notice">
94
- <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
95
- <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
96
- <p>
97
- <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
98
- <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
99
- </p>
100
- </div>
101
- <?php
102
- }
103
- }
104
-
105
- /**
106
- * Add admin menus/screens.
107
- */
108
- public function admin_menus() {
109
-
110
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
111
- return;
112
- }
113
-
114
- add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
115
- }
116
-
117
- /**
118
- * Show the setup wizard.
119
- */
120
- public function setup_wizard() {
121
-
122
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
123
- return;
124
- }
125
-
126
- $this->steps = array(
127
- 'basic-config' => array(
128
- 'name' => __( 'Welcome', 'cartflows' ),
129
- 'view' => array( $this, 'welcome_step' ),
130
- 'handler' => array( $this, 'welcome_step_save' ),
131
- ),
132
- 'page-builder' => array(
133
- 'name' => __( 'Page Builder', 'cartflows' ),
134
- 'view' => array( $this, 'page_builder_step' ),
135
- ),
136
- 'checkout' => array(
137
- 'name' => __( 'Checkout', 'cartflows' ),
138
- 'view' => array( $this, 'checkout_step' ),
139
- ),
140
- 'training' => array(
141
- 'name' => __( 'Training', 'cartflows' ),
142
- 'view' => array( $this, 'training_step' ),
143
- ),
144
- 'setup-ready' => array(
145
- 'name' => __( 'Ready!', 'cartflows' ),
146
- 'view' => array( $this, 'ready_step' ),
147
- 'handler' => '',
148
- ),
149
- );
150
-
151
- $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
152
-
153
- wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
154
- wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
155
-
156
- wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
157
-
158
- wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
159
-
160
- wp_enqueue_media();
161
-
162
- if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
163
- call_user_func( $this->steps[ $this->step ]['handler'] );
164
- }
165
-
166
- ob_start();
167
- $this->setup_wizard_header();
168
- $this->setup_wizard_steps();
169
- $this->setup_wizard_content();
170
- $this->setup_wizard_footer();
171
- exit;
172
- }
173
-
174
- /**
175
- * Get current step slug
176
- */
177
- public function get_current_step_slug() {
178
- $keys = array_keys( $this->steps );
179
- return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
180
- }
181
-
182
- /**
183
- * Get previous step link
184
- */
185
- public function get_prev_step_link() {
186
- $keys = array_keys( $this->steps );
187
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
188
- }
189
-
190
- /**
191
- * Get next step link
192
- */
193
- public function get_next_step_link() {
194
- $keys = array_keys( $this->steps );
195
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
196
- }
197
-
198
- /**
199
- * Get next step link
200
- */
201
- public function get_next_step_plain_link() {
202
- $keys = array_keys( $this->steps );
203
- $step_index = array_search( $this->step, $keys, true );
204
- $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
205
- $step = $keys[ $step_index ];
206
- return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
207
- }
208
-
209
- /**
210
- * Setup Wizard Header.
211
- */
212
- public function setup_wizard_header() {
213
- set_current_screen();
214
- ?>
215
- <html <?php language_attributes(); ?>>
216
- <html>
217
- <head>
218
- <meta name="viewport" content="width=device-width" />
219
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
220
- <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
221
-
222
- <script type="text/javascript">
223
- addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
224
- var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
225
- var pagenow = '';
226
- </script>
227
- <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
228
- <?php do_action( 'admin_print_styles' ); ?>
229
- <?php do_action( 'admin_head' ); ?>
230
- </head>
231
- <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
232
- <div id="cartflows-logo">
233
- <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
234
- </div>
235
- <?php
236
- }
237
-
238
- /**
239
- * Setup Wizard Footer.
240
- */
241
- public function setup_wizard_footer() {
242
-
243
- $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
244
- ?>
245
- <div class="close-button-wrapper">
246
- <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
247
- </div>
248
- </body>
249
- </html>
250
- <?php
251
- }
252
-
253
- /**
254
- * Output the steps.
255
- */
256
- public function setup_wizard_steps() {
257
-
258
- $ouput_steps = $this->steps;
259
- ?>
260
- <ol class="cartflows-setup-steps">
261
- <?php
262
- foreach ( $ouput_steps as $step_key => $step ) :
263
- $classes = '';
264
- $activated = false;
265
- if ( $step_key === $this->step ) {
266
- $classes = 'active';
267
- $activated = true;
268
- } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
269
- $classes = 'done';
270
- $activated = true;
271
- }
272
- ?>
273
- <li class="<?php echo esc_attr( $classes ); ?>">
274
- <span><?php echo esc_html( $step['name'] ); ?></span>
275
- </li>
276
- <?php endforeach; ?>
277
- </ol>
278
- <?php
279
- }
280
-
281
- /**
282
- * Output the content for the current step.
283
- */
284
- public function setup_wizard_content() {
285
- ?>
286
- <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
287
- <?php
288
-
289
- echo '<div class="cartflows-setup-content">';
290
- call_user_func( $this->steps[ $this->step ]['view'] );
291
- echo '</div>';
292
- }
293
-
294
- /**
295
- * Introduction step.
296
- */
297
- public function welcome_step() {
298
- ?>
299
- <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
300
- <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
301
- <form method="post">
302
- <div class="cartflows-usage-tracking cartflows-setup-message">
303
- <div class="usage-tracking-wrap">
304
- <h4><?php esc_html_e( 'Let&#x27;s Build it better!', 'cartflows' ); ?> </h4>
305
- <p><?php esc_html_e( 'Get improved features and faster fixes by sharing non-sensitive data via usage tracking that shows us how CartFlows is used. No personal data is tracked or stored.', 'cartflows' ); ?>
306
- <a href="https://my.cartflows.com/usage-tracking/"> <?php esc_html_e( 'Learn More', 'cartflows' ); ?></a></p>
307
- <input type="hidden" name="cartflows-usage-tracking-option" value="no">
308
- <input type="checkbox" name="cartflows-usage-tracking-option" id="cartflows-usage-tracking-option" value="Yes" checked>
309
- <label><?php esc_html_e( 'Yes, I am in.', 'cartflows' ); ?></label>
310
- </div>
311
- </div>
312
- <div class="cartflows-setup-actions step">
313
- <div class="button-prev-wrap">
314
- </div>
315
- <div class="button-next-wrap">
316
- <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
317
- </div>
318
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
319
- </div>
320
-
321
- </form>
322
- <?php
323
- }
324
-
325
- /**
326
- * Save Locale Settings.
327
- */
328
- public function welcome_step_save() {
329
- check_admin_referer( 'cartflow-setup' );
330
-
331
- // Update site title & tagline.
332
- $redirect_url = $this->get_next_step_link();
333
-
334
- wp_safe_redirect( esc_url_raw( $redirect_url ) );
335
- exit;
336
- }
337
-
338
- /**
339
- * Locale settings
340
- */
341
- public function page_builder_step() {
342
- ?>
343
-
344
- <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
345
- <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
346
- <form method="post">
347
- <table class="cartflows-table widefat">
348
- <tr class="cartflows-row">
349
- <td class="cartflows-row-heading">
350
- <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
351
- </td>
352
- <td class="cartflows-row-content">
353
- <?php
354
- $installed_plugins = get_plugins();
355
- $plugins = array(
356
- array(
357
- 'title' => __( 'Elementor', 'cartflows' ),
358
- 'value' => 'elementor',
359
- 'data' => array(
360
- 'slug' => 'elementor',
361
- 'init' => 'elementor/elementor.php',
362
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
363
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
364
- ),
365
- ),
366
- array(
367
- 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
368
- 'value' => 'beaver-builder',
369
- 'data' => array(
370
- 'slug' => 'beaver-builder-lite-version',
371
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
372
- 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
373
- 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
374
- ),
375
- ),
376
- array(
377
- 'title' => __( 'Divi', 'cartflows' ),
378
- 'value' => 'divi',
379
- 'data' => array(
380
- 'slug' => 'divi',
381
- 'init' => 'divi',
382
- 'active' => 'yes',
383
- 'install' => 'NA',
384
- ),
385
- ),
386
- array(
387
- 'title' => __( 'Gutenberg', 'cartflows' ),
388
- 'value' => 'gutenberg',
389
- 'data' => array(
390
- 'slug' => 'ultimate-addons-for-gutenberg',
391
- 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
392
- 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
393
- 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
394
- ),
395
- ),
396
- array(
397
- 'title' => __( 'Other', 'cartflows' ),
398
- 'value' => 'other',
399
- 'data' => array(
400
- 'slug' => 'other',
401
- 'init' => false,
402
- 'active' => 'yes',
403
- 'install' => 'NA',
404
- ),
405
- ),
406
- );
407
- ?>
408
- <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
409
- <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
410
- <?php
411
- foreach ( $plugins as $key => $plugin ) {
412
- echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
413
- }
414
- ?>
415
- </select>
416
- </td>
417
- </tr>
418
- </table>
419
- <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
420
-
421
- <div class="cartflows-setup-actions step">
422
- <div class="button-prev-wrap">
423
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
424
- </div>
425
- <div class="button-next-wrap">
426
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
427
- <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
428
- </div>
429
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
430
- </div>
431
- </form>
432
- <?php
433
- }
434
-
435
- /**
436
- * Render checkout step.
437
- */
438
- public function checkout_step() {
439
-
440
- $installed_plugins = get_plugins();
441
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
442
- $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
443
- $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
444
- $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
445
- ?>
446
- <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
447
- <div class="cartflows-setup-message">
448
- <p>
449
- <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
450
- </p>
451
- <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
452
- <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
453
- </div>
454
-
455
- <div class="cartflows-setup-extra-notice">
456
-
457
- <span>
458
- <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
459
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
460
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
461
-
462
- </span>
463
-
464
- </div>
465
-
466
- <div class="cartflows-setup-actions step">
467
- <div class="button-prev-wrap">
468
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
469
- </div>
470
- <div class="button-next-wrap">
471
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
472
- <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
473
- </div>
474
- </div>
475
-
476
- <?php
477
- }
478
-
479
- /**
480
- * Save Locale Settings.
481
- */
482
- public function activate_wc_plugins() {
483
-
484
- check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
485
-
486
- $plugin_slug_arr = array(
487
- 'woocommerce/woocommerce.php' => true,
488
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
489
- );
490
-
491
- $activate = array(
492
- 'woocommerce/woocommerce.php' => false,
493
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
494
- );
495
-
496
- foreach ( $plugin_slug_arr as $slug => $do_silently ) {
497
-
498
- $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
499
- }
500
-
501
- foreach ( $activate as $slug => $data ) {
502
-
503
- if ( is_wp_error( $data ) ) {
504
- wp_send_json_error(
505
- array(
506
- 'success' => false,
507
- 'message' => $data->get_error_message(),
508
- )
509
- );
510
- }
511
- }
512
-
513
- wp_send_json_success();
514
- }
515
-
516
- /**
517
- * Save usage tracking Settings.
518
- */
519
- public function save_usage_tracking_option() {
520
-
521
- if ( ! current_user_can( 'manage_options' ) ) {
522
- return;
523
- }
524
-
525
- check_ajax_referer( 'wcf-usage-tracking-option', 'security' );
526
-
527
- $allow_usage_tracking = isset( $_POST['allow_usage_tracking'] ) && 'true' == $_POST['allow_usage_tracking'] ? 'yes' : 'no';
528
-
529
- $usage_tracking = get_site_option( 'cf_analytics_optin' );
530
-
531
- if ( ( false === $usage_tracking ) || $allow_usage_tracking !== $usage_tracking ) {
532
- update_site_option( 'cf_analytics_optin', $allow_usage_tracking );
533
- }
534
-
535
- wp_send_json_success( get_site_option( 'cf_analytics_optin' ) );
536
- }
537
-
538
-
539
- /**
540
- * Save Locale Settings.
541
- */
542
- public function page_builder_step_save() {
543
-
544
- if ( ! current_user_can( 'manage_options' ) ) {
545
- return;
546
- }
547
-
548
- check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
549
-
550
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
551
- $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
552
- $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
553
-
554
- $do_sliently = true;
555
- if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
556
- $do_sliently = false;
557
- }
558
-
559
- $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
560
-
561
- if ( $save_option ) {
562
- $this->save_page_builder_option();
563
- }
564
-
565
- if ( is_wp_error( $activate ) ) {
566
- wp_send_json_error(
567
- array(
568
- 'success' => false,
569
- 'message' => $activate->get_error_message(),
570
- )
571
- );
572
- }
573
-
574
- wp_send_json_success(
575
- array( 'plugin' => $plugin_slug )
576
- );
577
- }
578
-
579
- /**
580
- * Save selected page builder in options database.
581
- */
582
- public function save_page_builder_option() {
583
-
584
- if ( ! current_user_can( 'manage_options' ) ) {
585
- return;
586
- }
587
-
588
- $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
589
-
590
- $wcf_settings = get_option( '_cartflows_common', array() );
591
-
592
- if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
593
- $page_builder = 'beaver-builder';
594
- }
595
-
596
- $wcf_settings['default_page_builder'] = $page_builder;
597
-
598
- update_option( '_cartflows_common', $wcf_settings );
599
-
600
- wp_send_json_success(
601
- array( 'plugin' => $page_builder )
602
- );
603
-
604
- }
605
-
606
- /**
607
- * Final step.
608
- */
609
- public function ready_step() {
610
-
611
- // Set setup wizard status to complete.
612
- update_option( 'wcf_setup_complete', true );
613
- ?>
614
- <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
615
-
616
- <div class="cartflows-setup-next-steps">
617
- <div class="cartflows-setup-next-steps-last">
618
-
619
- <p class="success">
620
- <?php
621
- esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
622
- ?>
623
- </p>
624
-
625
-
626
- <ul class="wcf-wizard-next-steps">
627
- <li class="wcf-wizard-next-step-item">
628
- <div class="wcf-wizard-next-step-description">
629
- <p class="next-step-heading">Next step</p>
630
- <h3 class="next-step-description">Create First Flow</h3>
631
- <p class="next-step-extra-info">You're ready to add flows to your website.</p>
632
- </div>
633
- <div class="wcf-wizard-next-step-action">
634
- <p class="wc-setup-actions step">
635
- <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
636
- </p>
637
- </div>
638
- </li>
639
- </ul>
640
-
641
- </div>
642
- </div>
643
- <?php
644
- }
645
-
646
- /**
647
- * Training course step.
648
- */
649
- public function training_step() {
650
- $current_user = wp_get_current_user();
651
- ?>
652
- <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
653
-
654
- <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
655
- <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
656
- <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
657
- <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
658
- <div class="mauticform-innerform">
659
- <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
660
- <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
661
- <div class="cartflows-setup-message">
662
- <p>
663
- <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
664
- <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
665
- </p>
666
- <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
667
- </div>
668
- <span class="mauticform-errormsg" style="display: none;"></span>
669
- </div>
670
- </div>
671
- </div>
672
-
673
- <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
674
- <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
675
- <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
676
- <div class="cartflows-setup-actions step">
677
- <div class="button-prev-wrap">
678
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
679
- </div>
680
- <div class="button-next-wrap">
681
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
682
- <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
683
- </div>
684
- </div>
685
- </form>
686
- </div>
687
- <?php
688
- }
689
-
690
- /**
691
- * Localize variables in admin
692
- */
693
- public function localize_vars() {
694
-
695
- $vars = array();
696
-
697
- $ajax_actions = array(
698
- 'wcf_page_builder_step_save',
699
- 'wcf_wc_plugins_activate',
700
- 'wcf_usage_tracking_option',
701
- );
702
-
703
- foreach ( $ajax_actions as $action ) {
704
-
705
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
706
- }
707
-
708
- return $vars;
709
- }
710
-
711
- /**
712
- * Add JS script for mautic form
713
- */
714
- public function add_mautic_form_script() {
715
-
716
- if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
717
- return;
718
- }
719
- ?>
720
-
721
- <script type="text/javascript">
722
- /** This section is only needed once per page if manually copying **/
723
- if (typeof MauticSDKLoaded == 'undefined') {
724
- var MauticSDKLoaded = true;
725
- var head = document.getElementsByTagName('head')[0];
726
- var script = document.createElement('script');
727
- script.type = 'text/javascript';
728
- script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
729
- script.onload = function() {
730
- MauticSDK.onLoad();
731
- };
732
- head.appendChild(script);
733
- var MauticDomain = 'https://go.cartflows.com';
734
- var MauticLang = {
735
- 'submittingMessage': "Please wait..."
736
- };
737
- }
738
- </script>
739
- <?php
740
- }
741
- }
742
-
743
- new CartFlows_Wizard();
744
-
745
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows- Onboarding Wizard
4
+ *
5
+ * @package cartflows
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
+
14
+ /**
15
+ * CartFlows_Wizard class.
16
+ */
17
+ class CartFlows_Wizard {
18
+
19
+ /**
20
+ * Hook in tabs.
21
+ */
22
+ public function __construct() {
23
+
24
+ if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
+ add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
+ add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
+ add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
+ add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
+ add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
+
31
+ add_action( 'wp_ajax_usage_tracking_option', array( $this, 'save_usage_tracking_option' ) );
32
+
33
+ add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
34
+ add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
35
+
36
+ add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
37
+
38
+ add_action( 'admin_init', array( $this, 'hide_notices' ) );
39
+
40
+ }
41
+ }
42
+
43
+
44
+ /**
45
+ * Hide a notice if the GET variable is set.
46
+ */
47
+ public function hide_notices() {
48
+
49
+ if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
50
+ return;
51
+ }
52
+
53
+ $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
54
+ $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
55
+
56
+ if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
57
+ update_option( 'wcf_setup_skipped', true );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Disable the woo redirect for new setup.
63
+ */
64
+ public function disable_woo_setup_redirect() {
65
+
66
+ delete_transient( '_wc_activation_redirect' );
67
+ }
68
+
69
+ /**
70
+ * Show action links on the plugin screen.
71
+ *
72
+ * @since 1.0.0
73
+ * @return void
74
+ */
75
+ public function show_setup_wizard() {
76
+
77
+ $screen = get_current_screen();
78
+ $screen_id = $screen ? $screen->id : '';
79
+ $allowed_screens = array(
80
+ 'cartflows_page_cartflows_settings',
81
+ 'edit-cartflows_flow',
82
+ 'dashboard',
83
+ 'plugins',
84
+ );
85
+
86
+ if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
87
+ return;
88
+ }
89
+
90
+ $status = get_option( 'wcf_setup_complete', false );
91
+ $skip_setup = get_option( 'wcf_setup_skipped', false );
92
+ if ( false === $status && ! $skip_setup ) { ?>
93
+ <div class="notice notice-info wcf-notice">
94
+ <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
95
+ <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
96
+ <p>
97
+ <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
98
+ <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
99
+ </p>
100
+ </div>
101
+ <?php
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Add admin menus/screens.
107
+ */
108
+ public function admin_menus() {
109
+
110
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
111
+ return;
112
+ }
113
+
114
+ add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
115
+ }
116
+
117
+ /**
118
+ * Show the setup wizard.
119
+ */
120
+ public function setup_wizard() {
121
+
122
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
123
+ return;
124
+ }
125
+
126
+ $this->steps = array(
127
+ 'basic-config' => array(
128
+ 'name' => __( 'Welcome', 'cartflows' ),
129
+ 'view' => array( $this, 'welcome_step' ),
130
+ 'handler' => array( $this, 'welcome_step_save' ),
131
+ ),
132
+ 'page-builder' => array(
133
+ 'name' => __( 'Page Builder', 'cartflows' ),
134
+ 'view' => array( $this, 'page_builder_step' ),
135
+ ),
136
+ 'checkout' => array(
137
+ 'name' => __( 'Checkout', 'cartflows' ),
138
+ 'view' => array( $this, 'checkout_step' ),
139
+ ),
140
+ 'training' => array(
141
+ 'name' => __( 'Training', 'cartflows' ),
142
+ 'view' => array( $this, 'training_step' ),
143
+ ),
144
+ 'setup-ready' => array(
145
+ 'name' => __( 'Ready!', 'cartflows' ),
146
+ 'view' => array( $this, 'ready_step' ),
147
+ 'handler' => '',
148
+ ),
149
+ );
150
+
151
+ $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
152
+
153
+ wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
154
+ wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
155
+
156
+ wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
157
+
158
+ wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
159
+
160
+ wp_enqueue_media();
161
+
162
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
163
+ call_user_func( $this->steps[ $this->step ]['handler'] );
164
+ }
165
+
166
+ ob_start();
167
+ $this->setup_wizard_header();
168
+ $this->setup_wizard_steps();
169
+ $this->setup_wizard_content();
170
+ $this->setup_wizard_footer();
171
+ exit;
172
+ }
173
+
174
+ /**
175
+ * Get current step slug
176
+ */
177
+ public function get_current_step_slug() {
178
+ $keys = array_keys( $this->steps );
179
+ return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
180
+ }
181
+
182
+ /**
183
+ * Get previous step link
184
+ */
185
+ public function get_prev_step_link() {
186
+ $keys = array_keys( $this->steps );
187
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
188
+ }
189
+
190
+ /**
191
+ * Get next step link
192
+ */
193
+ public function get_next_step_link() {
194
+ $keys = array_keys( $this->steps );
195
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
196
+ }
197
+
198
+ /**
199
+ * Get next step link
200
+ */
201
+ public function get_next_step_plain_link() {
202
+ $keys = array_keys( $this->steps );
203
+ $step_index = array_search( $this->step, $keys, true );
204
+ $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
205
+ $step = $keys[ $step_index ];
206
+ return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
207
+ }
208
+
209
+ /**
210
+ * Setup Wizard Header.
211
+ */
212
+ public function setup_wizard_header() {
213
+ set_current_screen();
214
+ ?>
215
+ <html <?php language_attributes(); ?>>
216
+ <html>
217
+ <head>
218
+ <meta name="viewport" content="width=device-width" />
219
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
220
+ <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
221
+
222
+ <script type="text/javascript">
223
+ addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
224
+ var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
225
+ var pagenow = '';
226
+ </script>
227
+ <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
228
+ <?php do_action( 'admin_print_styles' ); ?>
229
+ <?php do_action( 'admin_head' ); ?>
230
+ </head>
231
+ <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
232
+ <div id="cartflows-logo">
233
+ <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
234
+ </div>
235
+ <?php
236
+ }
237
+
238
+ /**
239
+ * Setup Wizard Footer.
240
+ */
241
+ public function setup_wizard_footer() {
242
+
243
+ $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
244
+ ?>
245
+ <div class="close-button-wrapper">
246
+ <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
247
+ </div>
248
+ </body>
249
+ </html>
250
+ <?php
251
+ }
252
+
253
+ /**
254
+ * Output the steps.
255
+ */
256
+ public function setup_wizard_steps() {
257
+
258
+ $ouput_steps = $this->steps;
259
+ ?>
260
+ <ol class="cartflows-setup-steps">
261
+ <?php
262
+ foreach ( $ouput_steps as $step_key => $step ) :
263
+ $classes = '';
264
+ $activated = false;
265
+ if ( $step_key === $this->step ) {
266
+ $classes = 'active';
267
+ $activated = true;
268
+ } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
269
+ $classes = 'done';
270
+ $activated = true;
271
+ }
272
+ ?>
273
+ <li class="<?php echo esc_attr( $classes ); ?>">
274
+ <span><?php echo esc_html( $step['name'] ); ?></span>
275
+ </li>
276
+ <?php endforeach; ?>
277
+ </ol>
278
+ <?php
279
+ }
280
+
281
+ /**
282
+ * Output the content for the current step.
283
+ */
284
+ public function setup_wizard_content() {
285
+ ?>
286
+ <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
287
+ <?php
288
+
289
+ echo '<div class="cartflows-setup-content">';
290
+ call_user_func( $this->steps[ $this->step ]['view'] );
291
+ echo '</div>';
292
+ }
293
+
294
+ /**
295
+ * Introduction step.
296
+ */
297
+ public function welcome_step() {
298
+ ?>
299
+ <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
300
+ <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
301
+ <form method="post">
302
+ <div class="cartflows-usage-tracking cartflows-setup-message">
303
+ <div class="usage-tracking-wrap">
304
+ <h4><?php esc_html_e( 'Let&#x27;s Build it better!', 'cartflows' ); ?> </h4>
305
+ <p><?php esc_html_e( 'Get improved features and faster fixes by sharing non-sensitive data via usage tracking that shows us how CartFlows is used. No personal data is tracked or stored.', 'cartflows' ); ?>
306
+ <a href="https://my.cartflows.com/usage-tracking/"> <?php esc_html_e( 'Learn More', 'cartflows' ); ?></a></p>
307
+ <input type="hidden" name="cartflows-usage-tracking-option" value="no">
308
+ <input type="checkbox" name="cartflows-usage-tracking-option" id="cartflows-usage-tracking-option" value="Yes" checked>
309
+ <label><?php esc_html_e( 'Yes, I am in.', 'cartflows' ); ?></label>
310
+ </div>
311
+ </div>
312
+ <div class="cartflows-setup-actions step">
313
+ <div class="button-prev-wrap">
314
+ </div>
315
+ <div class="button-next-wrap">
316
+ <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
317
+ </div>
318
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
319
+ </div>
320
+
321
+ </form>
322
+ <?php
323
+ }
324
+
325
+ /**
326
+ * Save Locale Settings.
327
+ */
328
+ public function welcome_step_save() {
329
+ check_admin_referer( 'cartflow-setup' );
330
+
331
+ // Update site title & tagline.
332
+ $redirect_url = $this->get_next_step_link();
333
+
334
+ wp_safe_redirect( esc_url_raw( $redirect_url ) );
335
+ exit;
336
+ }
337
+
338
+ /**
339
+ * Locale settings
340
+ */
341
+ public function page_builder_step() {
342
+ ?>
343
+
344
+ <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
345
+ <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
346
+ <form method="post">
347
+ <table class="cartflows-table widefat">
348
+ <tr class="cartflows-row">
349
+ <td class="cartflows-row-heading">
350
+ <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
351
+ </td>
352
+ <td class="cartflows-row-content">
353
+ <?php
354
+ $installed_plugins = get_plugins();
355
+ $plugins = array(
356
+ array(
357
+ 'title' => __( 'Elementor', 'cartflows' ),
358
+ 'value' => 'elementor',
359
+ 'data' => array(
360
+ 'slug' => 'elementor',
361
+ 'init' => 'elementor/elementor.php',
362
+ 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
363
+ 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
364
+ ),
365
+ ),
366
+ array(
367
+ 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
368
+ 'value' => 'beaver-builder',
369
+ 'data' => array(
370
+ 'slug' => 'beaver-builder-lite-version',
371
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
372
+ 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
373
+ 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
374
+ ),
375
+ ),
376
+ array(
377
+ 'title' => __( 'Divi', 'cartflows' ),
378
+ 'value' => 'divi',
379
+ 'data' => array(
380
+ 'slug' => 'divi',
381
+ 'init' => 'divi',
382
+ 'active' => 'yes',
383
+ 'install' => 'NA',
384
+ ),
385
+ ),
386
+ array(
387
+ 'title' => __( 'Gutenberg', 'cartflows' ),
388
+ 'value' => 'gutenberg',
389
+ 'data' => array(
390
+ 'slug' => 'ultimate-addons-for-gutenberg',
391
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
392
+ 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
393
+ 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
394
+ ),
395
+ ),
396
+ array(
397
+ 'title' => __( 'Other', 'cartflows' ),
398
+ 'value' => 'other',
399
+ 'data' => array(
400
+ 'slug' => 'other',
401
+ 'init' => false,
402
+ 'active' => 'yes',
403
+ 'install' => 'NA',
404
+ ),
405
+ ),
406
+ );
407
+ ?>
408
+ <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
409
+ <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
410
+ <?php
411
+ foreach ( $plugins as $key => $plugin ) {
412
+ echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
413
+ }
414
+ ?>
415
+ </select>
416
+ </td>
417
+ </tr>
418
+ </table>
419
+ <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
420
+
421
+ <div class="cartflows-setup-actions step">
422
+ <div class="button-prev-wrap">
423
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
424
+ </div>
425
+ <div class="button-next-wrap">
426
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
427
+ <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
428
+ </div>
429
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
430
+ </div>
431
+ </form>
432
+ <?php
433
+ }
434
+
435
+ /**
436
+ * Render checkout step.
437
+ */
438
+ public function checkout_step() {
439
+
440
+ $installed_plugins = get_plugins();
441
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
442
+ $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
443
+ $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
444
+ $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
445
+ ?>
446
+ <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
447
+ <div class="cartflows-setup-message">
448
+ <p>
449
+ <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
450
+ </p>
451
+ <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
452
+ <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
453
+ </div>
454
+
455
+ <div class="cartflows-setup-extra-notice">
456
+
457
+ <span>
458
+ <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
459
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
460
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
461
+
462
+ </span>
463
+
464
+ </div>
465
+
466
+ <div class="cartflows-setup-actions step">
467
+ <div class="button-prev-wrap">
468
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
469
+ </div>
470
+ <div class="button-next-wrap">
471
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
472
+ <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
473
+ </div>
474
+ </div>
475
+
476
+ <?php
477
+ }
478
+
479
+ /**
480
+ * Save Locale Settings.
481
+ */
482
+ public function activate_wc_plugins() {
483
+
484
+ check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
485
+
486
+ $plugin_slug_arr = array(
487
+ 'woocommerce/woocommerce.php' => true,
488
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
489
+ );
490
+
491
+ $activate = array(
492
+ 'woocommerce/woocommerce.php' => false,
493
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
494
+ );
495
+
496
+ foreach ( $plugin_slug_arr as $slug => $do_silently ) {
497
+
498
+ $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
499
+ }
500
+
501
+ foreach ( $activate as $slug => $data ) {
502
+
503
+ if ( is_wp_error( $data ) ) {
504
+ wp_send_json_error(
505
+ array(
506
+ 'success' => false,
507
+ 'message' => $data->get_error_message(),
508
+ )
509
+ );
510
+ }
511
+ }
512
+
513
+ wp_send_json_success();
514
+ }
515
+
516
+ /**
517
+ * Save usage tracking Settings.
518
+ */
519
+ public function save_usage_tracking_option() {
520
+
521
+ if ( ! current_user_can( 'manage_options' ) ) {
522
+ return;
523
+ }
524
+
525
+ check_ajax_referer( 'wcf-usage-tracking-option', 'security' );
526
+
527
+ $allow_usage_tracking = isset( $_POST['allow_usage_tracking'] ) && 'true' == $_POST['allow_usage_tracking'] ? 'yes' : 'no';
528
+
529
+ $usage_tracking = get_site_option( 'cf_analytics_optin' );
530
+
531
+ if ( ( false === $usage_tracking ) || $allow_usage_tracking !== $usage_tracking ) {
532
+ update_site_option( 'cf_analytics_optin', $allow_usage_tracking );
533
+ }
534
+
535
+ wp_send_json_success( get_site_option( 'cf_analytics_optin' ) );
536
+ }
537
+
538
+
539
+ /**
540
+ * Save Locale Settings.
541
+ */
542
+ public function page_builder_step_save() {
543
+
544
+ if ( ! current_user_can( 'manage_options' ) ) {
545
+ return;
546
+ }
547
+
548
+ check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
549
+
550
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
551
+ $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
552
+ $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
553
+
554
+ $do_sliently = true;
555
+ if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
556
+ $do_sliently = false;
557
+ }
558
+
559
+ $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
560
+
561
+ if ( $save_option ) {
562
+ $this->save_page_builder_option();
563
+ }
564
+
565
+ if ( is_wp_error( $activate ) ) {
566
+ wp_send_json_error(
567
+ array(
568
+ 'success' => false,
569
+ 'message' => $activate->get_error_message(),
570
+ )
571
+ );
572
+ }
573
+
574
+ wp_send_json_success(
575
+ array( 'plugin' => $plugin_slug )
576
+ );
577
+ }
578
+
579
+ /**
580
+ * Save selected page builder in options database.
581
+ */
582
+ public function save_page_builder_option() {
583
+
584
+ if ( ! current_user_can( 'manage_options' ) ) {
585
+ return;
586
+ }
587
+
588
+ $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
589
+
590
+ $wcf_settings = get_option( '_cartflows_common', array() );
591
+
592
+ if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
593
+ $page_builder = 'beaver-builder';
594
+ }
595
+
596
+ $wcf_settings['default_page_builder'] = $page_builder;
597
+
598
+ update_option( '_cartflows_common', $wcf_settings );
599
+
600
+ wp_send_json_success(
601
+ array( 'plugin' => $page_builder )
602
+ );
603
+
604
+ }
605
+
606
+ /**
607
+ * Final step.
608
+ */
609
+ public function ready_step() {
610
+
611
+ // Set setup wizard status to complete.
612
+ update_option( 'wcf_setup_complete', true );
613
+ ?>
614
+ <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
615
+
616
+ <div class="cartflows-setup-next-steps">
617
+ <div class="cartflows-setup-next-steps-last">
618
+
619
+ <p class="success">
620
+ <?php
621
+ esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
622
+ ?>
623
+ </p>
624
+
625
+
626
+ <ul class="wcf-wizard-next-steps">
627
+ <li class="wcf-wizard-next-step-item">
628
+ <div class="wcf-wizard-next-step-description">
629
+ <p class="next-step-heading">Next step</p>
630
+ <h3 class="next-step-description">Create First Flow</h3>
631
+ <p class="next-step-extra-info">You're ready to add flows to your website.</p>
632
+ </div>
633
+ <div class="wcf-wizard-next-step-action">
634
+ <p class="wc-setup-actions step">
635
+ <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
636
+ </p>
637
+ </div>
638
+ </li>
639
+ </ul>
640
+
641
+ </div>
642
+ </div>
643
+ <?php
644
+ }
645
+
646
+ /**
647
+ * Training course step.
648
+ */
649
+ public function training_step() {
650
+ $current_user = wp_get_current_user();
651
+ ?>
652
+ <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
653
+
654
+ <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
655
+ <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
656
+ <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
657
+ <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
658
+ <div class="mauticform-innerform">
659
+ <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
660
+ <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
661
+ <div class="cartflows-setup-message">
662
+ <p>
663
+ <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
664
+ <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
665
+ </p>
666
+ <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
667
+ </div>
668
+ <span class="mauticform-errormsg" style="display: none;"></span>
669
+ </div>
670
+ </div>
671
+ </div>
672
+
673
+ <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
674
+ <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
675
+ <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
676
+ <div class="cartflows-setup-actions step">
677
+ <div class="button-prev-wrap">
678
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
679
+ </div>
680
+ <div class="button-next-wrap">
681
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
682
+ <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
683
+ </div>
684
+ </div>
685
+ </form>
686
+ </div>
687
+ <?php
688
+ }
689
+
690
+ /**
691
+ * Localize variables in admin
692
+ */
693
+ public function localize_vars() {
694
+
695
+ $vars = array();
696
+
697
+ $ajax_actions = array(
698
+ 'wcf_page_builder_step_save',
699
+ 'wcf_wc_plugins_activate',
700
+ 'wcf_usage_tracking_option',
701
+ );
702
+
703
+ foreach ( $ajax_actions as $action ) {
704
+
705
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
706
+ }
707
+
708
+ return $vars;
709
+ }
710
+
711
+ /**
712
+ * Add JS script for mautic form
713
+ */
714
+ public function add_mautic_form_script() {
715
+
716
+ if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
717
+ return;
718
+ }
719
+ ?>
720
+
721
+ <script type="text/javascript">
722
+ /** This section is only needed once per page if manually copying **/
723
+ if (typeof MauticSDKLoaded == 'undefined') {
724
+ var MauticSDKLoaded = true;
725
+ var head = document.getElementsByTagName('head')[0];
726
+ var script = document.createElement('script');
727
+ script.type = 'text/javascript';
728
+ script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
729
+ script.onload = function() {
730
+ MauticSDK.onLoad();
731
+ };
732
+ head.appendChild(script);
733
+ var MauticDomain = 'https://go.cartflows.com';
734
+ var MauticLang = {
735
+ 'submittingMessage': "Please wait..."
736
+ };
737
+ }
738
+ </script>
739
+ <?php
740
+ }
741
+ }
742
+
743
+ new CartFlows_Wizard();
744
+
745
+ endif;
classes/deprecated/deprecated-hooks.php CHANGED
@@ -1,51 +1,51 @@
1
- <?php
2
- /**
3
- * Deprecated Hooks of CartFlows Plugin.
4
- *
5
- * @package CartFlows
6
- * @author CartFlows
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- exit;
11
- }
12
-
13
- if ( ! function_exists( 'wcf_do_action_deprecated' ) ) {
14
- /**
15
- * Cartlows Action Deprecated
16
- *
17
- * @since 1.1.1
18
- * @param string $tag The name of the Action hook.
19
- * @param array $args Array of additional function arguments to be passed to apply_filters().
20
- * @param string $version The version of WordPress that deprecated the hook.
21
- * @param string $replacement Optional. The hook that should have been used. Default false.
22
- * @param string $message Optional. A message regarding the change. Default null.
23
- */
24
- function wcf_do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
25
- if ( function_exists( 'do_action_deprecated' ) ) { /* WP >= 4.6 */
26
- do_action_deprecated( $tag, $args, $version, $replacement, $message );
27
- } else {
28
- do_action_ref_array( $tag, $args );
29
- }
30
- }
31
- }
32
-
33
- if ( ! function_exists( 'wcf_apply_filters_deprecated' ) ) {
34
- /**
35
- * Cartlows Apply Filters Deprecated
36
- *
37
- * @since 1.6.0
38
- * @param string $tag The name of the Action hook.
39
- * @param array $args Array of additional function arguments to be passed to apply_filters().
40
- * @param string $version The version of WordPress that deprecated the hook.
41
- * @param string $replacement Optional. The hook that should have been used. Default false.
42
- * @param string $message Optional. A message regarding the change. Default null.
43
- */
44
- function wcf_apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
45
- if ( function_exists( 'apply_filters_deprecated' ) ) { /* WP >= 4.6 */
46
- return apply_filters_deprecated( $tag, $args, $version, $replacement, $message );
47
- } else {
48
- return apply_filters_ref_array( $tag, $args );
49
- }
50
- }
51
- }
1
+ <?php
2
+ /**
3
+ * Deprecated Hooks of CartFlows Plugin.
4
+ *
5
+ * @package CartFlows
6
+ * @author CartFlows
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ if ( ! function_exists( 'wcf_do_action_deprecated' ) ) {
14
+ /**
15
+ * Cartlows Action Deprecated
16
+ *
17
+ * @since 1.1.1
18
+ * @param string $tag The name of the Action hook.
19
+ * @param array $args Array of additional function arguments to be passed to apply_filters().
20
+ * @param string $version The version of WordPress that deprecated the hook.
21
+ * @param string $replacement Optional. The hook that should have been used. Default false.
22
+ * @param string $message Optional. A message regarding the change. Default null.
23
+ */
24
+ function wcf_do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
25
+ if ( function_exists( 'do_action_deprecated' ) ) { /* WP >= 4.6 */
26
+ do_action_deprecated( $tag, $args, $version, $replacement, $message );
27
+ } else {
28
+ do_action_ref_array( $tag, $args );
29
+ }
30
+ }
31
+ }
32
+
33
+ if ( ! function_exists( 'wcf_apply_filters_deprecated' ) ) {
34
+ /**
35
+ * Cartlows Apply Filters Deprecated
36
+ *
37
+ * @since 1.6.0
38
+ * @param string $tag The name of the Action hook.
39
+ * @param array $args Array of additional function arguments to be passed to apply_filters().
40
+ * @param string $version The version of WordPress that deprecated the hook.
41
+ * @param string $replacement Optional. The hook that should have been used. Default false.
42
+ * @param string $message Optional. A message regarding the change. Default null.
43
+ */
44
+ function wcf_apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
45
+ if ( function_exists( 'apply_filters_deprecated' ) ) { /* WP >= 4.6 */
46
+ return apply_filters_deprecated( $tag, $args, $version, $replacement, $message );
47
+ } else {
48
+ return apply_filters_ref_array( $tag, $args );
49
+ }
50
+ }
51
+ }
includes/admin/cartflows-general.php CHANGED
@@ -1,525 +1,525 @@
1
- <?php
2
- /**
3
- * General settings
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $settings = Cartflows_Helper::get_common_settings();
9
-
10
- $debug_data = Cartflows_Helper::get_debug_settings();
11
-
12
- $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
-
14
- $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
-
16
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
-
18
- $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
-
20
- $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
- ?>
22
-
23
-
24
- <?php if ( $error_log ) : ?>
25
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
- <?php Cartflows_Logger::status_logs_file(); ?>
27
- </div>
28
- <?php else : ?>
29
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
- <input type="hidden" name="action" value="wcf_save_common_settings">
31
- <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
-
33
- <div id="poststuff">
34
- <div id="post-body" class="columns-2">
35
- <div id="post-body-content">
36
-
37
- <!-- Getting Started -->
38
- <div class="postbox introduction">
39
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
- <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
- </h2>
42
- <div class="inside">
43
- <div class="iframe-wrap">
44
- <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
- </div>
46
- <p>
47
- <?php
48
- esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
- ?>
50
- </p>
51
- </div>
52
- </div>
53
- <!-- Getting Started -->
54
-
55
- <!-- General Settings -->
56
- <div class="general-settings-form postbox">
57
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
- <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
- </h2>
60
- <div class="inside">
61
- <form method="post" class="wrap wcf-clear" action="" >
62
- <div class="form-wrap">
63
- <?php
64
-
65
- do_action( 'cartflows_before_settings_fields', $settings );
66
-
67
- echo Cartflows_Admin_Fields::checkobox_field(
68
- array(
69
- 'id' => 'wcf_disallow_indexing',
70
- 'name' => '_cartflows_common[disallow_indexing]',
71
- 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
- 'value' => $settings['disallow_indexing'],
73
- )
74
- );
75
-
76
- if ( wcf()->is_woo_active ) {
77
- echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
- array(
79
- 'id' => 'wcf_global_checkout',
80
- 'name' => '_cartflows_common[global_checkout]',
81
- 'title' => __( 'Global Checkout', 'cartflows' ),
82
- 'value' => $settings['global_checkout'],
83
- )
84
- );
85
- }
86
- echo Cartflows_Admin_Fields::select_field(
87
- array(
88
- 'id' => 'wcf_default_page_builder',
89
- 'name' => '_cartflows_common[default_page_builder]',
90
- 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
- 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
- 'value' => $settings['default_page_builder'],
93
- 'options' => array(
94
- 'elementor' => __( 'Elementor', 'cartflows' ),
95
- 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
- 'divi' => __( 'Divi', 'cartflows' ),
97
- 'gutenberg' => __( 'Gutenberg', 'cartflows' ),
98
- 'other' => __( 'Other', 'cartflows' ),
99
- ),
100
- )
101
- );
102
-
103
- do_action( 'cartflows_after_settings_fields', $settings );
104
-
105
- ?>
106
- </div>
107
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
108
- <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
109
- </form>
110
- </div>
111
- </div>
112
- <!-- General Settings -->
113
-
114
- <?php do_action( 'cartflows_after_general_settings' ); ?>
115
-
116
- <!-- Permalink Settings -->
117
- <div class="general-settingss-form postbox">
118
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
119
- <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
120
- </h2>
121
- <div class="inside">
122
- <form method="post" class="wrap wcf-clear" action="" >
123
- <div class="form-wrap wcf_permalink_settings">
124
- <?php
125
-
126
- echo Cartflows_Admin_Fields::radio_field(
127
- array(
128
- 'id' => 'permalink_structure',
129
- 'name' => '_cartflows_permalink[permalink_structure]',
130
- 'value' => $permalink_settings['permalink_structure'],
131
- 'options' => array(
132
- '' =>
133
- array(
134
- 'label' => __( 'Default', 'cartflows' ),
135
- 'description' => 'Default WordPress Permalink',
136
- ),
137
-
138
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
139
- array(
140
- 'label' => __( 'Flow and Step Slug', 'cartflows' ),
141
- 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
142
- ),
143
-
144
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
145
- array(
146
- 'label' => __( 'Flow Slug', 'cartflows' ),
147
- 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
148
- ),
149
-
150
- '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
151
- array(
152
- 'label' => __( 'Step Slug', 'cartflows' ),
153
- 'description' => get_site_url() . '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
154
- ),
155
- ),
156
- )
157
- );
158
- ?>
159
- <hr/>
160
- <?php
161
-
162
- echo Cartflows_Admin_Fields::title_field(
163
- array(
164
- 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
165
- )
166
- );
167
-
168
- echo Cartflows_Admin_Fields::text_field(
169
- array(
170
- 'id' => 'wcf_permalink_step_base',
171
- 'name' => '_cartflows_permalink[permalink]',
172
- 'title' => __( 'Step Base', 'cartflows' ),
173
- 'value' => $permalink_settings['permalink'],
174
- 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
175
- )
176
- );
177
-
178
- echo Cartflows_Admin_Fields::text_field(
179
- array(
180
- 'id' => 'wcf_permalink_flow_base',
181
- 'name' => '_cartflows_permalink[permalink_flow_base]',
182
- 'title' => __( 'Flow Base', 'cartflows' ),
183
- 'value' => $permalink_settings['permalink_flow_base'],
184
- 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
185
- )
186
- );
187
-
188
- ?>
189
-
190
-
191
- </div>
192
- <p>
193
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
194
- <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
195
- <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
196
- </p>
197
-
198
-
199
- </form>
200
- </div>
201
- </div>
202
- <!-- Permalink Settings -->
203
-
204
- <!-- Facebook Pixel Tracking -->
205
- <div class="general-settingss-form postbox">
206
- <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
207
-
208
- <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
209
- </h2>
210
-
211
- <form method="post" class="wrap wcf-clear" action="">
212
- <div class="form-wrap">
213
- <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
214
- <div id="post-body">
215
-
216
- <div class="inside">
217
- <div class="form-wrap">
218
- <?php
219
- echo Cartflows_Admin_Fields::checkobox_field(
220
- array(
221
- 'id' => 'wcf_facebook_pixel_tracking',
222
- 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
223
- 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
224
- 'value' => $facebook_settings['facebook_pixel_tracking'],
225
- )
226
- );
227
-
228
- echo "<div class='wcf-fb-pixel-wrapper'>";
229
- ?>
230
- <hr/>
231
- <?php
232
- echo Cartflows_Admin_Fields::checkobox_field(
233
- array(
234
- 'id' => 'wcf_facebook_pixel_tracking_for_site',
235
- 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
236
- 'title' => __( 'Enable for the whole site', 'cartflows' ),
237
- 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
238
- )
239
- );
240
-
241
- echo Cartflows_Admin_Fields::title_field(
242
- array(
243
- 'title' => '',
244
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
245
- )
246
- );
247
- ?>
248
- <hr/>
249
- <?php
250
- echo Cartflows_Admin_Fields::text_field(
251
- array(
252
- 'id' => 'wcf_facebook_pixel_id',
253
- 'name' => '_cartflows_facebook[facebook_pixel_id]',
254
- 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
255
- 'value' => $facebook_settings['facebook_pixel_id'],
256
- )
257
- );
258
-
259
-
260
- echo Cartflows_Admin_Fields::title_field(
261
- array(
262
- 'title' => __( 'Enable Events:', 'cartflows' ),
263
- )
264
- );
265
-
266
-
267
- echo Cartflows_Admin_Fields::checkobox_field(
268
- array(
269
- 'id' => 'wcf_facebook_pixel_initiate_checkout',
270
- 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
271
- 'title' => __( 'Initiate Checkout', 'cartflows' ),
272
- 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
273
- )
274
- );
275
-
276
- echo Cartflows_Admin_Fields::checkobox_field(
277
- array(
278
- 'id' => 'wcf_facebook_pixel_add_payment_info',
279
- 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
280
- 'title' => __( 'Add Payment Info', 'cartflows' ),
281
- 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
282
- )
283
- );
284
-
285
- echo Cartflows_Admin_Fields::checkobox_field(
286
- array(
287
- 'id' => 'wcf_facebook_pixel_purchase_complete',
288
- 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
289
- 'title' => __( 'Purchase Complete', 'cartflows' ),
290
- 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
291
- )
292
- );
293
-
294
- echo '</div>';
295
-
296
- ?>
297
- </div>
298
-
299
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
300
- <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
301
- </div>
302
- </div>
303
- </div>
304
- </form>
305
- </div>
306
- <!-- Facebook Pixel Tracking -->
307
-
308
- <!-- Google Analytics Tracking -->
309
- <div class="general-settingss-form postbox">
310
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
311
- <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
312
- </h2>
313
- <div class="inside">
314
- <form method="post" class="wrap wcf-clear" action="" >
315
- <div class="form-wrap">
316
- <?php
317
-
318
- echo Cartflows_Admin_Fields::checkobox_field(
319
- array(
320
- 'id' => 'enable_google-analytics-id',
321
- 'name' => '_cartflows_google_analytics[enable_google_analytics]',
322
- 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
323
- 'value' => $google_analytics_settings['enable_google_analytics'],
324
- )
325
- );
326
-
327
- echo "<div class='wcf-google-analytics-wrapper'>";
328
- ?>
329
- <hr/>
330
- <?php
331
- echo Cartflows_Admin_Fields::checkobox_field(
332
- array(
333
- 'id' => 'enable_google_analytics_for_site',
334
- 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
335
- 'title' => __( 'Enable for the whole website', 'cartflows' ),
336
- 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
337
- )
338
- );
339
-
340
- echo Cartflows_Admin_Fields::title_field(
341
- array(
342
- 'title' => '',
343
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
344
- )
345
- );
346
- ?>
347
- <hr/>
348
- <?php
349
- echo Cartflows_Admin_Fields::text_field(
350
- array(
351
- 'id' => 'google-analytics-id',
352
- 'name' => '_cartflows_google_analytics[google_analytics_id]',
353
- 'title' => __( 'Google Analytics ID', 'cartflows' ),
354
- 'value' => $google_analytics_settings['google_analytics_id'],
355
- 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
356
- )
357
- );
358
-
359
- echo Cartflows_Admin_Fields::title_field(
360
- array(
361
- 'title' => __( 'Enable Events:', 'cartflows' ),
362
- )
363
- );
364
-
365
- echo Cartflows_Admin_Fields::checkobox_field(
366
- array(
367
- 'id' => 'enable_begin_checkout',
368
- 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
369
- 'title' => __( 'Begin Checkout', 'cartflows' ),
370
- 'value' => $google_analytics_settings['enable_begin_checkout'],
371
- )
372
- );
373
-
374
- echo Cartflows_Admin_Fields::checkobox_field(
375
- array(
376
- 'id' => 'enable_add_to_cart',
377
- 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
378
- 'title' => __( 'Add To Cart', 'cartflows' ),
379
- 'value' => $google_analytics_settings['enable_add_to_cart'],
380
- )
381
- );
382
-
383
- echo Cartflows_Admin_Fields::checkobox_field(
384
- array(
385
- 'id' => 'enable_add_payment_info',
386
- 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
387
- 'title' => __( 'Add Payment Info', 'cartflows' ),
388
- 'value' => $google_analytics_settings['enable_add_payment_info'],
389
- )
390
- );
391
-
392
- echo Cartflows_Admin_Fields::checkobox_field(
393
- array(
394
- 'id' => 'enable_purchase_event',
395
- 'name' => '_cartflows_google_analytics[enable_purchase_event]',
396
- 'title' => __( 'Purchase', 'cartflows' ),
397
- 'value' => $google_analytics_settings['enable_purchase_event'],
398
- )
399
- );
400
-
401
- echo Cartflows_Admin_Fields::title_field(
402
- array(
403
- 'title' => '',
404
- 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
405
- )
406
- );
407
-
408
- do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
409
-
410
- echo '</div>';
411
- ?>
412
-
413
-
414
- </div>
415
- <p>
416
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
417
- <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
418
- </p>
419
-
420
-
421
- </form>
422
- </div>
423
- </div>
424
- <!-- Google Analytics Tracking -->
425
-
426
- <?php do_action( 'cartflows_register_general_settings' ); ?>
427
-
428
- </div>
429
-
430
- <!-- Right Sidebar -->
431
- <div class="postbox-container" id="postbox-container-1">
432
- <div id="side-sortables">
433
-
434
- <div class="postbox">
435
- <h2 class="hndle">
436
- <span class="dashicons dashicons-book"></span>
437
- <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
438
- </h2>
439
- <div class="inside">
440
- <p>
441
- <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
442
- </p>
443
- <p>
444
- <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
445
- </p>
446
- </div>
447
- </div>
448
-
449
- <div class="postbox">
450
- <h2 class="hndle">
451
- <span class="dashicons dashicons-groups"></span>
452
- <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
453
- </h2>
454
- <div class="inside">
455
- <p>
456
- <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
457
- </p>
458
- <p>
459
- <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
460
- </p>
461
- </div>
462
- </div>
463
-
464
- <div class="postbox">
465
- <h2 class="hndle">
466
- <span class="dashicons dashicons-sos"></span>
467
- <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
468
- </h2>
469
- <div class="inside">
470
- <p>
471
- <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
472
- </p>
473
- <p>
474
- <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
475
- </p>
476
- </div>
477
- </div>
478
- <?php
479
- if ( 'true' == $debug_on ) {
480
- ?>
481
- <div class="postbox">
482
- <h2 class="hndle">
483
- <span class="dashicons dashicons-editor-code"></span>
484
- <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
485
- </h2>
486
- <div class="inside">
487
- <form method="post" class="wrap wcf-clear" action="">
488
- <p>
489
- <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
490
- </p>
491
- <?php
492
- echo Cartflows_Admin_Fields::checkobox_field(
493
- array(
494
- 'id' => 'allow_minified_files',
495
- 'name' => '_cartflows_debug_data[allow_minified_files]',
496
- 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
497
- 'value' => $debug_data['allow_minified_files'],
498
- )
499
- );
500
- ?>
501
- <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
502
- <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
503
- </form>
504
- </div>
505
- </div>
506
- <?php
507
- }
508
- ?>
509
- </div>
510
- </div>
511
- <!-- Right Sidebar -->
512
-
513
- </div>
514
- <!-- /post-body -->
515
- <br class="clear">
516
- </div>
517
- </div>
518
- <?php endif; ?>
519
-
520
- <?php
521
- /**
522
- * Loads Zapier settings admin view.
523
- */
524
- do_action( 'cartflows_after_settings' );
525
- ?>
1
+ <?php
2
+ /**
3
+ * General settings
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $settings = Cartflows_Helper::get_common_settings();
9
+
10
+ $debug_data = Cartflows_Helper::get_debug_settings();
11
+
12
+ $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
+
14
+ $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
+
16
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
+
18
+ $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
+
20
+ $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
+ ?>
22
+
23
+
24
+ <?php if ( $error_log ) : ?>
25
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
+ <?php Cartflows_Logger::status_logs_file(); ?>
27
+ </div>
28
+ <?php else : ?>
29
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
+ <input type="hidden" name="action" value="wcf_save_common_settings">
31
+ <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
+
33
+ <div id="poststuff">
34
+ <div id="post-body" class="columns-2">
35
+ <div id="post-body-content">
36
+
37
+ <!-- Getting Started -->
38
+ <div class="postbox introduction">
39
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
+ <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
+ </h2>
42
+ <div class="inside">
43
+ <div class="iframe-wrap">
44
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
+ </div>
46
+ <p>
47
+ <?php
48
+ esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
+ ?>
50
+ </p>
51
+ </div>
52
+ </div>
53
+ <!-- Getting Started -->
54
+
55
+ <!-- General Settings -->
56
+ <div class="general-settings-form postbox">
57
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
+ <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
+ </h2>
60
+ <div class="inside">
61
+ <form method="post" class="wrap wcf-clear" action="" >
62
+ <div class="form-wrap">
63
+ <?php
64
+
65
+ do_action( 'cartflows_before_settings_fields', $settings );
66
+
67
+ echo Cartflows_Admin_Fields::checkobox_field(
68
+ array(
69
+ 'id' => 'wcf_disallow_indexing',
70
+ 'name' => '_cartflows_common[disallow_indexing]',
71
+ 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
+ 'value' => $settings['disallow_indexing'],
73
+ )
74
+ );
75
+
76
+ if ( wcf()->is_woo_active ) {
77
+ echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
+ array(
79
+ 'id' => 'wcf_global_checkout',
80
+ 'name' => '_cartflows_common[global_checkout]',
81
+ 'title' => __( 'Global Checkout', 'cartflows' ),
82
+ 'value' => $settings['global_checkout'],
83
+ )
84
+ );
85
+ }
86
+ echo Cartflows_Admin_Fields::select_field(
87
+ array(
88
+ 'id' => 'wcf_default_page_builder',
89
+ 'name' => '_cartflows_common[default_page_builder]',
90
+ 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
+ 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
+ 'value' => $settings['default_page_builder'],
93
+ 'options' => array(
94
+ 'elementor' => __( 'Elementor', 'cartflows' ),
95
+ 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
+ 'divi' => __( 'Divi', 'cartflows' ),
97
+ 'gutenberg' => __( 'Gutenberg', 'cartflows' ),
98
+ 'other' => __( 'Other', 'cartflows' ),
99
+ ),
100
+ )
101
+ );
102
+
103
+ do_action( 'cartflows_after_settings_fields', $settings );
104
+
105
+ ?>
106
+ </div>
107
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
108
+ <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
109
+ </form>
110
+ </div>
111
+ </div>
112
+ <!-- General Settings -->
113
+
114
+ <?php do_action( 'cartflows_after_general_settings' ); ?>
115
+
116
+ <!-- Permalink Settings -->
117
+ <div class="general-settingss-form postbox">
118
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
119
+ <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
120
+ </h2>
121
+ <div class="inside">
122
+ <form method="post" class="wrap wcf-clear" action="" >
123
+ <div class="form-wrap wcf_permalink_settings">
124
+ <?php
125
+
126
+ echo Cartflows_Admin_Fields::radio_field(
127
+ array(
128
+ 'id' => 'permalink_structure',
129
+ 'name' => '_cartflows_permalink[permalink_structure]',
130
+ 'value' => $permalink_settings['permalink_structure'],
131
+ 'options' => array(
132
+ '' =>
133
+ array(
134
+ 'label' => __( 'Default', 'cartflows' ),
135
+ 'description' => 'Default WordPress Permalink',
136
+ ),
137
+
138
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
139
+ array(
140
+ 'label' => __( 'Flow and Step Slug', 'cartflows' ),
141
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
142
+ ),
143
+
144
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
145
+ array(
146
+ 'label' => __( 'Flow Slug', 'cartflows' ),
147
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
148
+ ),
149
+
150
+ '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
151
+ array(
152
+ 'label' => __( 'Step Slug', 'cartflows' ),
153
+ 'description' => get_site_url() . '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
154
+ ),
155
+ ),
156
+ )
157
+ );
158
+ ?>
159
+ <hr/>
160
+ <?php
161
+
162
+ echo Cartflows_Admin_Fields::title_field(
163
+ array(
164
+ 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
165
+ )
166
+ );
167
+
168
+ echo Cartflows_Admin_Fields::text_field(
169
+ array(
170
+ 'id' => 'wcf_permalink_step_base',
171
+ 'name' => '_cartflows_permalink[permalink]',
172
+ 'title' => __( 'Step Base', 'cartflows' ),
173
+ 'value' => $permalink_settings['permalink'],
174
+ 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
175
+ )
176
+ );
177
+
178
+ echo Cartflows_Admin_Fields::text_field(
179
+ array(
180
+ 'id' => 'wcf_permalink_flow_base',
181
+ 'name' => '_cartflows_permalink[permalink_flow_base]',
182
+ 'title' => __( 'Flow Base', 'cartflows' ),
183
+ 'value' => $permalink_settings['permalink_flow_base'],
184
+ 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
185
+ )
186
+ );
187
+
188
+ ?>
189
+
190
+
191
+ </div>
192
+ <p>
193
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
194
+ <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
195
+ <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
196
+ </p>
197
+
198
+
199
+ </form>
200
+ </div>
201
+ </div>
202
+ <!-- Permalink Settings -->
203
+
204
+ <!-- Facebook Pixel Tracking -->
205
+ <div class="general-settingss-form postbox">
206
+ <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
207
+
208
+ <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
209
+ </h2>
210
+
211
+ <form method="post" class="wrap wcf-clear" action="">
212
+ <div class="form-wrap">
213
+ <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
214
+ <div id="post-body">
215
+
216
+ <div class="inside">
217
+ <div class="form-wrap">
218
+ <?php
219
+ echo Cartflows_Admin_Fields::checkobox_field(
220
+ array(
221
+ 'id' => 'wcf_facebook_pixel_tracking',
222
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
223
+ 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
224
+ 'value' => $facebook_settings['facebook_pixel_tracking'],
225
+ )
226
+ );
227
+
228
+ echo "<div class='wcf-fb-pixel-wrapper'>";
229
+ ?>
230
+ <hr/>
231
+ <?php
232
+ echo Cartflows_Admin_Fields::checkobox_field(
233
+ array(
234
+ 'id' => 'wcf_facebook_pixel_tracking_for_site',
235
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
236
+ 'title' => __( 'Enable for the whole site', 'cartflows' ),
237
+ 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
238
+ )
239
+ );
240
+
241
+ echo Cartflows_Admin_Fields::title_field(
242
+ array(
243
+ 'title' => '',
244
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
245
+ )
246
+ );
247
+ ?>
248
+ <hr/>
249
+ <?php
250
+ echo Cartflows_Admin_Fields::text_field(
251
+ array(
252
+ 'id' => 'wcf_facebook_pixel_id',
253
+ 'name' => '_cartflows_facebook[facebook_pixel_id]',
254
+ 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
255
+ 'value' => $facebook_settings['facebook_pixel_id'],
256
+ )
257
+ );
258
+
259
+
260
+ echo Cartflows_Admin_Fields::title_field(
261
+ array(
262
+ 'title' => __( 'Enable Events:', 'cartflows' ),
263
+ )
264
+ );
265
+
266
+
267
+ echo Cartflows_Admin_Fields::checkobox_field(
268
+ array(
269
+ 'id' => 'wcf_facebook_pixel_initiate_checkout',
270
+ 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
271
+ 'title' => __( 'Initiate Checkout', 'cartflows' ),
272
+ 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
273
+ )
274
+ );
275
+
276
+ echo Cartflows_Admin_Fields::checkobox_field(
277
+ array(
278
+ 'id' => 'wcf_facebook_pixel_add_payment_info',
279
+ 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
280
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
281
+ 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
282
+ )
283
+ );
284
+
285
+ echo Cartflows_Admin_Fields::checkobox_field(
286
+ array(
287
+ 'id' => 'wcf_facebook_pixel_purchase_complete',
288
+ 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
289
+ 'title' => __( 'Purchase Complete', 'cartflows' ),
290
+ 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
291
+ )
292
+ );
293
+
294
+ echo '</div>';
295
+
296
+ ?>
297
+ </div>
298
+
299
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
300
+ <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
301
+ </div>
302
+ </div>
303
+ </div>
304
+ </form>
305
+ </div>
306
+ <!-- Facebook Pixel Tracking -->
307
+
308
+ <!-- Google Analytics Tracking -->
309
+ <div class="general-settingss-form postbox">
310
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
311
+ <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
312
+ </h2>
313
+ <div class="inside">
314
+ <form method="post" class="wrap wcf-clear" action="" >
315
+ <div class="form-wrap">
316
+ <?php
317
+
318
+ echo Cartflows_Admin_Fields::checkobox_field(
319
+ array(
320
+ 'id' => 'enable_google-analytics-id',
321
+ 'name' => '_cartflows_google_analytics[enable_google_analytics]',
322
+ 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
323
+ 'value' => $google_analytics_settings['enable_google_analytics'],
324
+ )
325
+ );
326
+
327
+ echo "<div class='wcf-google-analytics-wrapper'>";
328
+ ?>
329
+ <hr/>
330
+ <?php
331
+ echo Cartflows_Admin_Fields::checkobox_field(
332
+ array(
333
+ 'id' => 'enable_google_analytics_for_site',
334
+ 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
335
+ 'title' => __( 'Enable for the whole website', 'cartflows' ),
336
+ 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
337
+ )
338
+ );
339
+
340
+ echo Cartflows_Admin_Fields::title_field(
341
+ array(
342
+ 'title' => '',
343
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
344
+ )
345
+ );
346
+ ?>
347
+ <hr/>
348
+ <?php
349
+ echo Cartflows_Admin_Fields::text_field(
350
+ array(
351
+ 'id' => 'google-analytics-id',
352
+ 'name' => '_cartflows_google_analytics[google_analytics_id]',
353
+ 'title' => __( 'Google Analytics ID', 'cartflows' ),
354
+ 'value' => $google_analytics_settings['google_analytics_id'],
355
+ 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
356
+ )
357
+ );
358
+
359
+ echo Cartflows_Admin_Fields::title_field(
360
+ array(
361
+ 'title' => __( 'Enable Events:', 'cartflows' ),
362
+ )
363
+ );
364
+
365
+ echo Cartflows_Admin_Fields::checkobox_field(
366
+ array(
367
+ 'id' => 'enable_begin_checkout',
368
+ 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
369
+ 'title' => __( 'Begin Checkout', 'cartflows' ),
370
+ 'value' => $google_analytics_settings['enable_begin_checkout'],
371
+ )
372
+ );
373
+
374
+ echo Cartflows_Admin_Fields::checkobox_field(
375
+ array(
376
+ 'id' => 'enable_add_to_cart',
377
+ 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
378
+ 'title' => __( 'Add To Cart', 'cartflows' ),
379
+ 'value' => $google_analytics_settings['enable_add_to_cart'],
380
+ )
381
+ );
382
+
383
+ echo Cartflows_Admin_Fields::checkobox_field(
384
+ array(
385
+ 'id' => 'enable_add_payment_info',
386
+ 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
387
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
388
+ 'value' => $google_analytics_settings['enable_add_payment_info'],
389
+ )
390
+ );
391
+
392
+ echo Cartflows_Admin_Fields::checkobox_field(
393
+ array(
394
+ 'id' => 'enable_purchase_event',
395
+ 'name' => '_cartflows_google_analytics[enable_purchase_event]',
396
+ 'title' => __( 'Purchase', 'cartflows' ),
397
+ 'value' => $google_analytics_settings['enable_purchase_event'],
398
+ )
399
+ );
400
+
401
+ echo Cartflows_Admin_Fields::title_field(
402
+ array(
403
+ 'title' => '',
404
+ 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
405
+ )
406
+ );
407
+
408
+ do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
409
+
410
+ echo '</div>';
411
+ ?>
412
+
413
+
414
+ </div>
415
+ <p>
416
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
417
+ <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
418
+ </p>
419
+
420
+
421
+ </form>
422
+ </div>
423
+ </div>
424
+ <!-- Google Analytics Tracking -->
425
+
426
+ <?php do_action( 'cartflows_register_general_settings' ); ?>
427
+
428
+ </div>
429
+
430
+ <!-- Right Sidebar -->
431
+ <div class="postbox-container" id="postbox-container-1">
432
+ <div id="side-sortables">
433
+
434
+ <div class="postbox">
435
+ <h2 class="hndle">
436
+ <span class="dashicons dashicons-book"></span>
437
+ <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
438
+ </h2>
439
+ <div class="inside">
440
+ <p>
441
+ <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
442
+ </p>
443
+ <p>
444
+ <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
445
+ </p>
446
+ </div>
447
+ </div>
448
+
449
+ <div class="postbox">
450
+ <h2 class="hndle">
451
+ <span class="dashicons dashicons-groups"></span>
452
+ <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
453
+ </h2>
454
+ <div class="inside">
455
+ <p>
456
+ <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
457
+ </p>
458
+ <p>
459
+ <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
460
+ </p>
461
+ </div>
462
+ </div>
463
+
464
+ <div class="postbox">
465
+ <h2 class="hndle">
466
+ <span class="dashicons dashicons-sos"></span>
467
+ <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
468
+ </h2>
469
+ <div class="inside">
470
+ <p>
471
+ <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
472
+ </p>
473
+ <p>
474
+ <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
475
+ </p>
476
+ </div>
477
+ </div>
478
+ <?php
479
+ if ( 'true' == $debug_on ) {
480
+ ?>
481
+ <div class="postbox">
482
+ <h2 class="hndle">
483
+ <span class="dashicons dashicons-editor-code"></span>
484
+ <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
485
+ </h2>
486
+ <div class="inside">
487
+ <form method="post" class="wrap wcf-clear" action="">
488
+ <p>
489
+ <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
490
+ </p>
491
+ <?php
492
+ echo Cartflows_Admin_Fields::checkobox_field(
493
+ array(
494
+ 'id' => 'allow_minified_files',
495
+ 'name' => '_cartflows_debug_data[allow_minified_files]',
496
+ 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
497
+ 'value' => $debug_data['allow_minified_files'],
498
+ )
499
+ );
500
+ ?>
501
+ <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
502
+ <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
503
+ </form>
504
+ </div>
505
+ </div>
506
+ <?php
507
+ }
508
+ ?>
509
+ </div>
510
+ </div>
511
+ <!-- Right Sidebar -->
512
+
513
+ </div>
514
+ <!-- /post-body -->
515
+ <br class="clear">
516
+ </div>
517
+ </div>
518
+ <?php endif; ?>
519
+
520
+ <?php
521
+ /**
522
+ * Loads Zapier settings admin view.
523
+ */
524
+ do_action( 'cartflows_after_settings' );
525
+ ?>
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-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>
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1288 +1,1288 @@
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
- if ( ! empty( $custom_price ) ) {
481
-
482
- $cart_item_data = array(
483
- 'custom_price' => $custom_price,
484
- );
485
- }
486
-
487
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
488
-
489
- if ( $_product->is_type( 'variable' ) ) {
490
-
491
- $default_attributes = $_product->get_default_attributes();
492
-
493
- if ( ! empty( $default_attributes ) ) {
494
-
495
- foreach ( $_product->get_children() as $variation_id ) {
496
-
497
- $single_variation = new WC_Product_Variation( $variation_id );
498
-
499
- if ( $default_attributes == $single_variation->get_attributes() ) {
500
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
501
- $cart_product_count++;
502
- }
503
- }
504
- } else {
505
-
506
- $product_childrens = $_product->get_children();
507
-
508
- if ( isset( $product_childrens[0] ) ) {
509
- $variation = wc_get_product( $product_childrens[0] );
510
- $_product_price = $variation->get_price();
511
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
512
- if ( ! empty( $custom_price ) ) {
513
- $cart_item_data = array(
514
- 'custom_price' => $custom_price,
515
- 'data' => $data,
516
- );
517
- }
518
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
519
- $cart_product_count++;
520
- } else {
521
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
522
- }
523
- }
524
- } else {
525
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
526
- $cart_product_count++;
527
- }
528
- } else {
529
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
530
- wc_add_notice( $wrong_product_notice );
531
- /**
532
- WC()->cart->add_to_cart( $product_id, $quantity );.
533
- */
534
- }
535
- }
536
- $products_new[ $index ] = array(
537
- 'cart_item_key' => $cart_key,
538
- );
539
- }
540
-
541
- /* Set checkout products data */
542
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
543
-
544
- /* Since 1.2.2 */
545
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
546
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
547
- }
548
- }
549
- }
550
-
551
- /**
552
- * Load shortcode data.
553
- *
554
- * @return void
555
- */
556
- public function shortcode_load_data() {
557
-
558
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
559
-
560
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
561
-
562
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
563
-
564
- /* Show notices if cart has errors */
565
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
566
-
567
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
568
-
569
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
570
-
571
- // Outputting the hidden field in checkout page.
572
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
573
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
-
575
- remove_all_actions( 'woocommerce_checkout_billing' );
576
- remove_all_actions( 'woocommerce_checkout_shipping' );
577
-
578
- // Hook in actions once.
579
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
580
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
581
-
582
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
583
-
584
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
585
-
586
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
587
-
588
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
589
-
590
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
591
-
592
- global $post;
593
-
594
- if ( _is_wcf_checkout_type() ) {
595
- $checkout_id = $post->ID;
596
- } else {
597
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
598
- }
599
-
600
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
601
- }
602
- }
603
-
604
- /**
605
- * Render checkout ID hidden field.
606
- *
607
- * @param array $checkout checkout session data.
608
- * @return void
609
- */
610
- public function checkout_shortcode_post_id( $checkout ) {
611
-
612
- global $post;
613
-
614
- if ( _is_wcf_checkout_type() ) {
615
- $checkout_id = $post->ID;
616
- } else {
617
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
618
- }
619
-
620
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
621
-
622
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
623
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
624
- }
625
-
626
- /**
627
- * Load shortcode scripts.
628
- *
629
- * @return void
630
- */
631
- public function shortcode_scripts() {
632
-
633
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
634
-
635
- wp_enqueue_script(
636
- 'wcf-checkout-template',
637
- wcf()->utils->get_js_url( 'checkout-template' ),
638
- array( 'jquery' ),
639
- CARTFLOWS_VER,
640
- true
641
- );
642
-
643
- do_action( 'cartflows_checkout_scripts' );
644
-
645
- $style = $this->generate_style();
646
-
647
- wp_add_inline_style( 'wcf-checkout-template', $style );
648
-
649
- }
650
-
651
- /**
652
- * Load compatibility scripts.
653
- *
654
- * @return void
655
- */
656
- public function compatibility_scripts() {
657
-
658
- global $post;
659
-
660
- if ( _is_wcf_checkout_type() ) {
661
- $checkout_id = $post->ID;
662
- } else {
663
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
664
- }
665
-
666
- // Add DIVI Compatibility css if DIVI theme is enabled.
667
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
668
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
669
- ) {
670
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
671
- }
672
-
673
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
674
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
675
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
676
- }
677
-
678
- // Add The7 Compatibility css if The7 theme is enabled.
679
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
680
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
681
- }
682
- }
683
-
684
- /**
685
- * Generate styles.
686
- *
687
- * @return string
688
- */
689
- public function generate_style() {
690
-
691
- global $post;
692
-
693
- if ( _is_wcf_checkout_type() ) {
694
- $checkout_id = $post->ID;
695
- } else {
696
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
697
- }
698
-
699
- /*Output css variable */
700
- $output = '';
701
-
702
- CartFlows_Font_Families::render_fonts( $checkout_id );
703
-
704
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
705
-
706
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
707
-
708
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
709
-
710
- /**
711
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
712
- $r = '';
713
- $g = '';
714
- $b = '';
715
-
716
- $field_tb_padding = '';
717
- $field_lr_padding = '';
718
-
719
- $field_heading_color = '';
720
- $field_color = '';
721
- $field_bg_color = '';
722
- $field_border_color = '';
723
- $field_label_color = '';
724
- $submit_tb_padding = '';
725
- $submit_lr_padding = '';
726
- $hl_bg_color = '';
727
- $field_input_size = '';
728
- $box_border_color = '';
729
- $section_bg_color = '';
730
- $submit_button_height = '';
731
- $submit_color = '';
732
- $submit_bg_color = $primary_color;
733
- $submit_border_color = $primary_color;
734
-
735
- $submit_hover_color = '';
736
- $submit_bg_hover_color = $primary_color;
737
- $submit_border_hover_color = $primary_color;
738
-
739
- $section_heading_color = '';
740
-
741
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
742
-
743
- $button_font_family = '';
744
- $button_font_weight = '';
745
- $input_font_family = '';
746
- $input_font_weight = '';
747
- $heading_font_family = '';
748
- $heading_font_weight = '';
749
- $base_font_family = $base_font_family;
750
- /**
751
- $base_font_weight = $base_font_weight;*/
752
-
753
- if ( 'yes' == $is_advance_option ) {
754
-
755
- /**
756
- * Get Font Family and Font Weight weight values
757
- */
758
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
759
-
760
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
761
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
762
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
763
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
764
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
765
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
766
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
767
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
768
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
769
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
770
-
771
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
772
-
773
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
774
-
775
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
776
-
777
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
778
-
779
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
780
-
781
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
782
-
783
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
784
-
785
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
786
-
787
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
788
-
789
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
790
-
791
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
792
-
793
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
794
-
795
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
796
-
797
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
798
-
799
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
800
-
801
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
802
-
803
- /**
804
- * Get font values
805
- */
806
-
807
- if ( 'custom' == $submit_button_height ) {
808
- $submit_button_height = '38px';
809
- }
810
-
811
- if ( 'custom' == $field_input_size ) {
812
- $field_input_size = '38px';
813
- }
814
- }
815
- if ( isset( $primary_color ) ) {
816
-
817
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
818
- }
819
-
820
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
821
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
822
-
823
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
824
-
825
- } else {
826
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
827
- }
828
-
829
- return $output;
830
- }
831
-
832
- /**
833
- * Get ajax end points.
834
- *
835
- * @param string $endpoint_url end point URL.
836
- * @param string $request end point request.
837
- * @return string
838
- */
839
- public function get_ajax_endpoint( $endpoint_url, $request ) {
840
-
841
- global $post;
842
-
843
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
844
-
845
- if ( _is_wcf_checkout_type() ) {
846
-
847
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
848
-
849
- if ( '' === $request ) {
850
- $query_args = array(
851
- 'wc-ajax' => '%%endpoint%%',
852
- );
853
- } else {
854
- $query_args = array(
855
- 'wc-ajax' => $request,
856
- );
857
- }
858
-
859
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
860
- $uri = $uri[0];
861
-
862
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
863
- }
864
- }
865
- }
866
-
867
- return $endpoint_url;
868
- }
869
-
870
-
871
- /**
872
- * Save checkout fields.
873
- *
874
- * @param int $order_id order id.
875
- * @param array $posted posted data.
876
- * @return void
877
- */
878
- public function save_checkout_fields( $order_id, $posted ) {
879
-
880
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
881
-
882
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
883
-
884
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
885
-
886
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
887
-
888
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
889
-
890
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
891
- }
892
- }
893
-
894
- }
895
-
896
- /**
897
- * Enable Logo In Header Of Checkout Page
898
- *
899
- * @return void
900
- */
901
- public function enable_logo_in_header() {
902
- global $post;
903
-
904
- if ( _is_wcf_checkout_type() ) {
905
- $checkout_id = $post->ID;
906
- } else {
907
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
908
- }
909
-
910
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
911
- $add_image_markup = '';
912
-
913
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
914
- $add_image_markup = '<div class="wcf-checkout-header-image">';
915
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
916
- $add_image_markup .= '</div>';
917
- }
918
-
919
- echo $add_image_markup;
920
- }
921
-
922
- /**
923
- * Add text to the bootom of the checkout page.
924
- *
925
- * @return void
926
- */
927
- public function show_cartflows_copyright_message() {
928
- $output_string = '';
929
-
930
- $output_string .= '<div class="wcf-footer-primary">';
931
- $output_string .= '<div class="wcf-footer-content">';
932
- $output_string .= '<p class="wcf-footer-message">';
933
- $output_string .= 'Checkout powered by CartFlows';
934
- $output_string .= '</p>';
935
- $output_string .= '</div>';
936
- $output_string .= '</div>';
937
-
938
- echo $output_string;
939
- }
940
-
941
- /**
942
- * Redirect users to our checkout if hidden param
943
- *
944
- * @param string $redirect redirect url.
945
- * @param object $user user.
946
- * @return string
947
- */
948
- public function after_login_redirect( $redirect, $user ) {
949
-
950
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
951
-
952
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
953
-
954
- $redirect = get_permalink( $checkout_id );
955
- }
956
-
957
- return $redirect;
958
- }
959
-
960
- /**
961
- * Display coupon code field after review order fields.
962
- */
963
- public function display_custom_coupon_field() {
964
-
965
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
966
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
967
-
968
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
969
- return;
970
-
971
- }
972
-
973
- $coupon_field = array(
974
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
975
- 'button_text' => __( 'Apply', 'cartflows' ),
976
- 'class' => '',
977
- );
978
-
979
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
980
-
981
- ob_start();
982
- ?>
983
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
984
- <div class="wcf-coupon-col-1">
985
- <span>
986
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
987
- </span>
988
- </div>
989
- <div class="wcf-coupon-col-2">
990
- <span>
991
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
992
- </span>
993
- </div>
994
- </div>
995
- <?php
996
- echo ob_get_clean();
997
- }
998
-
999
- /**
1000
- * Apply filter to change class of remove coupon field.
1001
- *
1002
- * @param string $coupon coupon.
1003
- * @return string
1004
- */
1005
- public function remove_coupon_text( $coupon ) {
1006
-
1007
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1008
- return $coupon;
1009
-
1010
- }
1011
- /**
1012
- * Apply filter to change the placeholder text of coupon field.
1013
- *
1014
- * @return string
1015
- */
1016
- public function coupon_field_placeholder() {
1017
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1018
- }
1019
-
1020
- /**
1021
- * Apply filter to change the button text of coupon field.
1022
- *
1023
- * @return string
1024
- */
1025
- public function coupon_button_text() {
1026
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1027
- }
1028
-
1029
- /**
1030
- * Apply coupon on submit of custom coupon form.
1031
- */
1032
- public function apply_coupon() {
1033
-
1034
- $response = '';
1035
-
1036
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1037
- if ( ! empty( $_POST['coupon_code'] ) ) {
1038
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1039
- } else {
1040
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1041
- }
1042
-
1043
- $response = array(
1044
- 'status' => $result,
1045
- 'msg' => wc_print_notices( true ),
1046
- );
1047
-
1048
- echo wp_json_encode( $response );
1049
-
1050
- die();
1051
- }
1052
-
1053
-
1054
- /**
1055
- * Added ajax nonce to localize variable.
1056
- *
1057
- * @param array $vars localize variables.
1058
- */
1059
- public function add_localize_vars( $vars ) {
1060
-
1061
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1062
-
1063
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1064
-
1065
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1066
-
1067
- $vars['allow_persistence'] = wcf_apply_filters_deprecated( 'cartflows_allow_persistace', array( 'yes' ), '1.6.0', 'cartflows_allow_persistence' );
1068
-
1069
- return $vars;
1070
- }
1071
-
1072
- /**
1073
- * Add custom class to the fields to change the UI to three column.
1074
- *
1075
- * @param array $fields fields.
1076
- */
1077
- public function add_three_column_layout_fields( $fields ) {
1078
-
1079
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
1080
-
1081
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1082
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1083
- }
1084
- }
1085
-
1086
- if ( ! empty( $fields['billing']['billing_company'] ) ) {
1087
-
1088
- if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1089
- $fields['billing']['billing_company']['class'][] = 'form-row-full';
1090
- }
1091
- }
1092
-
1093
- if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1094
-
1095
- if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1096
- $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1097
- }
1098
- }
1099
-
1100
- if ( ! empty( $fields['billing']['billing_country'] ) ) {
1101
-
1102
- if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1103
- $fields['billing']['billing_country']['class'][] = 'form-row-full';
1104
- }
1105
- }
1106
-
1107
- if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1108
-
1109
- if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1110
- $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1111
- }
1112
- }
1113
-
1114
- if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1115
-
1116
- if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1117
- $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1118
- }
1119
- }
1120
-
1121
- if ( ! empty( $fields['billing']['billing_email'] ) ) {
1122
-
1123
- if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1124
- $fields['billing']['billing_email']['class'][] = 'form-row-full';
1125
- }
1126
- }
1127
-
1128
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1129
-
1130
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1131
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1132
- }
1133
- }
1134
-
1135
- if ( isset( $fields['billing']['billing_city'] ) &&
1136
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1137
-
1138
- $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1139
- $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1140
- $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1141
- }
1142
-
1143
- if ( isset( $fields['shipping']['shipping_city'] ) &&
1144
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1145
-
1146
- $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1147
- $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1148
- $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1149
- }
1150
-
1151
- return $fields;
1152
- }
1153
-
1154
- /**
1155
- * Add opening dev
1156
- *
1157
- * @since 1.0.0
1158
- */
1159
- public function order_wrap_div_start() {
1160
-
1161
- echo "<div class='wcf-order-wrap'> ";
1162
- }
1163
-
1164
- /**
1165
- * Add closing dev
1166
- *
1167
- * @since 1.0.0
1168
- */
1169
- public function order_wrap_div_end() {
1170
-
1171
- echo '</div> ';
1172
- }
1173
- /**
1174
- * Remove coupon.
1175
- */
1176
- public function remove_coupon() {
1177
-
1178
- check_ajax_referer( 'wcf-remove-coupon', 'security' );
1179
- $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1180
-
1181
- if ( empty( $coupon ) ) {
1182
- echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1183
- } else {
1184
- WC()->cart->remove_coupon( $coupon );
1185
- echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1186
- }
1187
- wc_print_notices();
1188
- wp_die();
1189
- }
1190
-
1191
- /**
1192
- * Remove cart item.
1193
- */
1194
- public function wcf_woo_remove_cart_product() {
1195
-
1196
- check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1197
- $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1198
- $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1199
- $product_title = get_the_title( $product_id );
1200
-
1201
- $needs_shipping = false;
1202
-
1203
- if ( empty( $product_key ) ) {
1204
- $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1205
- } else {
1206
- WC()->cart->remove_cart_item( $product_key );
1207
- $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1208
- }
1209
-
1210
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1211
- if ( $values['data']->needs_shipping() ) {
1212
- $needs_shipping = true;
1213
- break;
1214
- }
1215
- }
1216
-
1217
- $response = array(
1218
- 'need_shipping' => $needs_shipping,
1219
- 'msg' => $msg,
1220
- );
1221
-
1222
- echo wp_json_encode( $response );
1223
- wp_die();
1224
- }
1225
-
1226
- /**
1227
- * Calculate discount for product.
1228
- *
1229
- * @param string $discount_coupon discount coupon.
1230
- * @param string $discount_type discount type.
1231
- * @param int $discount_value discount value.
1232
- * @param int $_product_price product price.
1233
- * @return int
1234
- * @since 1.1.5
1235
- */
1236
- public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1237
-
1238
- $custom_price = '';
1239
-
1240
- if ( ! empty( $discount_type ) ) {
1241
- if ( 'discount_percent' === $discount_type ) {
1242
-
1243
- if ( $discount_value > 0 ) {
1244
- $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1245
- }
1246
- } elseif ( 'discount_price' === $discount_type ) {
1247
-
1248
- if ( $discount_value > 0 ) {
1249
- $custom_price = $_product_price - $discount_value;
1250
- }
1251
- } elseif ( 'coupon' === $discount_type ) {
1252
-
1253
- if ( ! empty( $discount_coupon ) ) {
1254
- WC()->cart->add_discount( $discount_coupon );
1255
- }
1256
- }
1257
- }
1258
-
1259
- return $custom_price;
1260
- }
1261
-
1262
- /**
1263
- * Preserve the custom item price added by Variations & Quantity feature
1264
- *
1265
- * @param array $cart_object cart object.
1266
- * @since 1.0.0
1267
- */
1268
- public function custom_price_to_cart_item( $cart_object ) {
1269
-
1270
- if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1271
-
1272
- foreach ( $cart_object->cart_contents as $key => $value ) {
1273
-
1274
- if ( isset( $value['custom_price'] ) ) {
1275
-
1276
- $custom_price = floatval( $value['custom_price'] );
1277
- $value['data']->set_price( $custom_price );
1278
- }
1279
- }
1280
- }
1281
- }
1282
-
1283
- }
1284
-
1285
- /**
1286
- * Kicking this off by calling 'get_instance()' method
1287
- */
1288
- 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
+ if ( ! empty( $custom_price ) ) {
481
+
482
+ $cart_item_data = array(
483
+ 'custom_price' => $custom_price,
484
+ );
485
+ }
486
+
487
+ if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
488
+
489
+ if ( $_product->is_type( 'variable' ) ) {
490
+
491
+ $default_attributes = $_product->get_default_attributes();
492
+
493
+ if ( ! empty( $default_attributes ) ) {
494
+
495
+ foreach ( $_product->get_children() as $variation_id ) {
496
+
497
+ $single_variation = new WC_Product_Variation( $variation_id );
498
+
499
+ if ( $default_attributes == $single_variation->get_attributes() ) {
500
+ $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
501
+ $cart_product_count++;
502
+ }
503
+ }
504
+ } else {
505
+
506
+ $product_childrens = $_product->get_children();
507
+
508
+ if ( isset( $product_childrens[0] ) ) {
509
+ $variation = wc_get_product( $product_childrens[0] );
510
+ $_product_price = $variation->get_price();
511
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
512
+ if ( ! empty( $custom_price ) ) {
513
+ $cart_item_data = array(
514
+ 'custom_price' => $custom_price,
515
+ 'data' => $data,
516
+ );
517
+ }
518
+ $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
519
+ $cart_product_count++;
520
+ } else {
521
+ echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
522
+ }
523
+ }
524
+ } else {
525
+ $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
526
+ $cart_product_count++;
527
+ }
528
+ } else {
529
+ $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
530
+ wc_add_notice( $wrong_product_notice );
531
+ /**
532
+ WC()->cart->add_to_cart( $product_id, $quantity );.
533
+ */
534
+ }
535
+ }
536
+ $products_new[ $index ] = array(
537
+ 'cart_item_key' => $cart_key,
538
+ );
539
+ }
540
+
541
+ /* Set checkout products data */
542
+ wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
543
+
544
+ /* Since 1.2.2 */
545
+ wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
546
+ do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
547
+ }
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Load shortcode data.
553
+ *
554
+ * @return void
555
+ */
556
+ public function shortcode_load_data() {
557
+
558
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
559
+
560
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
561
+
562
+ add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
563
+
564
+ /* Show notices if cart has errors */
565
+ add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
566
+
567
+ add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
568
+
569
+ add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
570
+
571
+ // Outputting the hidden field in checkout page.
572
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
573
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
+
575
+ remove_all_actions( 'woocommerce_checkout_billing' );
576
+ remove_all_actions( 'woocommerce_checkout_shipping' );
577
+
578
+ // Hook in actions once.
579
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
580
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
581
+
582
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
583
+
584
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
585
+
586
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
587
+
588
+ add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
589
+
590
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
591
+
592
+ global $post;
593
+
594
+ if ( _is_wcf_checkout_type() ) {
595
+ $checkout_id = $post->ID;
596
+ } else {
597
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
598
+ }
599
+
600
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
601
+ }
602
+ }
603
+
604
+ /**
605
+ * Render checkout ID hidden field.
606
+ *
607
+ * @param array $checkout checkout session data.
608
+ * @return void
609
+ */
610
+ public function checkout_shortcode_post_id( $checkout ) {
611
+
612
+ global $post;
613
+
614
+ if ( _is_wcf_checkout_type() ) {
615
+ $checkout_id = $post->ID;
616
+ } else {
617
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
618
+ }
619
+
620
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
621
+
622
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
623
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
624
+ }
625
+
626
+ /**
627
+ * Load shortcode scripts.
628
+ *
629
+ * @return void
630
+ */
631
+ public function shortcode_scripts() {
632
+
633
+ wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
634
+
635
+ wp_enqueue_script(
636
+ 'wcf-checkout-template',
637
+ wcf()->utils->get_js_url( 'checkout-template' ),
638
+ array( 'jquery' ),
639
+ CARTFLOWS_VER,
640
+ true
641
+ );
642
+
643
+ do_action( 'cartflows_checkout_scripts' );
644
+
645
+ $style = $this->generate_style();
646
+
647
+ wp_add_inline_style( 'wcf-checkout-template', $style );
648
+
649
+ }
650
+
651
+ /**
652
+ * Load compatibility scripts.
653
+ *
654
+ * @return void
655
+ */
656
+ public function compatibility_scripts() {
657
+
658
+ global $post;
659
+
660
+ if ( _is_wcf_checkout_type() ) {
661
+ $checkout_id = $post->ID;
662
+ } else {
663
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
664
+ }
665
+
666
+ // Add DIVI Compatibility css if DIVI theme is enabled.
667
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
668
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
669
+ ) {
670
+ wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
671
+ }
672
+
673
+ // Add Flatsome Compatibility css if Flatsome theme is enabled.
674
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
675
+ wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
676
+ }
677
+
678
+ // Add The7 Compatibility css if The7 theme is enabled.
679
+ if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
680
+ wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Generate styles.
686
+ *
687
+ * @return string
688
+ */
689
+ public function generate_style() {
690
+
691
+ global $post;
692
+
693
+ if ( _is_wcf_checkout_type() ) {
694
+ $checkout_id = $post->ID;
695
+ } else {
696
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
697
+ }
698
+
699
+ /*Output css variable */
700
+ $output = '';
701
+
702
+ CartFlows_Font_Families::render_fonts( $checkout_id );
703
+
704
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
705
+
706
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
707
+
708
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
709
+
710
+ /**
711
+ $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
712
+ $r = '';
713
+ $g = '';
714
+ $b = '';
715
+
716
+ $field_tb_padding = '';
717
+ $field_lr_padding = '';
718
+
719
+ $field_heading_color = '';
720
+ $field_color = '';
721
+ $field_bg_color = '';
722
+ $field_border_color = '';
723
+ $field_label_color = '';
724
+ $submit_tb_padding = '';
725
+ $submit_lr_padding = '';
726
+ $hl_bg_color = '';
727
+ $field_input_size = '';
728
+ $box_border_color = '';
729
+ $section_bg_color = '';
730
+ $submit_button_height = '';
731
+ $submit_color = '';
732
+ $submit_bg_color = $primary_color;
733
+ $submit_border_color = $primary_color;
734
+
735
+ $submit_hover_color = '';
736
+ $submit_bg_hover_color = $primary_color;
737
+ $submit_border_hover_color = $primary_color;
738
+
739
+ $section_heading_color = '';
740
+
741
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
742
+
743
+ $button_font_family = '';
744
+ $button_font_weight = '';
745
+ $input_font_family = '';
746
+ $input_font_weight = '';
747
+ $heading_font_family = '';
748
+ $heading_font_weight = '';
749
+ $base_font_family = $base_font_family;
750
+ /**
751
+ $base_font_weight = $base_font_weight;*/
752
+
753
+ if ( 'yes' == $is_advance_option ) {
754
+
755
+ /**
756
+ * Get Font Family and Font Weight weight values
757
+ */
758
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
759
+
760
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
761
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
762
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
763
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
764
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
765
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
766
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
767
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
768
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
769
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
770
+
771
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
772
+
773
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
774
+
775
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
776
+
777
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
778
+
779
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
780
+
781
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
782
+
783
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
784
+
785
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
786
+
787
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
788
+
789
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
790
+
791
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
792
+
793
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
794
+
795
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
796
+
797
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
798
+
799
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
800
+
801
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
802
+
803
+ /**
804
+ * Get font values
805
+ */
806
+
807
+ if ( 'custom' == $submit_button_height ) {
808
+ $submit_button_height = '38px';
809
+ }
810
+
811
+ if ( 'custom' == $field_input_size ) {
812
+ $field_input_size = '38px';
813
+ }
814
+ }
815
+ if ( isset( $primary_color ) ) {
816
+
817
+ list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
818
+ }
819
+
820
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
821
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
822
+
823
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
824
+
825
+ } else {
826
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
827
+ }
828
+
829
+ return $output;
830
+ }
831
+
832
+ /**
833
+ * Get ajax end points.
834
+ *
835
+ * @param string $endpoint_url end point URL.
836
+ * @param string $request end point request.
837
+ * @return string
838
+ */
839
+ public function get_ajax_endpoint( $endpoint_url, $request ) {
840
+
841
+ global $post;
842
+
843
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
844
+
845
+ if ( _is_wcf_checkout_type() ) {
846
+
847
+ if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
848
+
849
+ if ( '' === $request ) {
850
+ $query_args = array(
851
+ 'wc-ajax' => '%%endpoint%%',
852
+ );
853
+ } else {
854
+ $query_args = array(
855
+ 'wc-ajax' => $request,
856
+ );
857
+ }
858
+
859
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
860
+ $uri = $uri[0];
861
+
862
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
863
+ }
864
+ }
865
+ }
866
+
867
+ return $endpoint_url;
868
+ }
869
+
870
+
871
+ /**
872
+ * Save checkout fields.
873
+ *
874
+ * @param int $order_id order id.
875
+ * @param array $posted posted data.
876
+ * @return void
877
+ */
878
+ public function save_checkout_fields( $order_id, $posted ) {
879
+
880
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
881
+
882
+ $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
883
+
884
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
885
+
886
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
887
+
888
+ $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
889
+
890
+ update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
891
+ }
892
+ }
893
+
894
+ }
895
+
896
+ /**
897
+ * Enable Logo In Header Of Checkout Page
898
+ *
899
+ * @return void
900
+ */
901
+ public function enable_logo_in_header() {
902
+ global $post;
903
+
904
+ if ( _is_wcf_checkout_type() ) {
905
+ $checkout_id = $post->ID;
906
+ } else {
907
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
908
+ }
909
+
910
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
911
+ $add_image_markup = '';
912
+
913
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
914
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
915
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
916
+ $add_image_markup .= '</div>';
917
+ }
918
+
919
+ echo $add_image_markup;
920
+ }
921
+
922
+ /**
923
+ * Add text to the bootom of the checkout page.
924
+ *
925
+ * @return void
926
+ */
927
+ public function show_cartflows_copyright_message() {
928
+ $output_string = '';
929
+
930
+ $output_string .= '<div class="wcf-footer-primary">';
931
+ $output_string .= '<div class="wcf-footer-content">';
932
+ $output_string .= '<p class="wcf-footer-message">';
933
+ $output_string .= 'Checkout powered by CartFlows';
934
+ $output_string .= '</p>';
935
+ $output_string .= '</div>';
936
+ $output_string .= '</div>';
937
+
938
+ echo $output_string;
939
+ }
940
+
941
+ /**
942
+ * Redirect users to our checkout if hidden param
943
+ *
944
+ * @param string $redirect redirect url.
945
+ * @param object $user user.
946
+ * @return string
947
+ */
948
+ public function after_login_redirect( $redirect, $user ) {
949
+
950
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
951
+
952
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
953
+
954
+ $redirect = get_permalink( $checkout_id );
955
+ }
956
+
957
+ return $redirect;
958
+ }
959
+
960
+ /**
961
+ * Display coupon code field after review order fields.
962
+ */
963
+ public function display_custom_coupon_field() {
964
+
965
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
966
+ $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
967
+
968
+ if ( ! ( $coupon_enabled && $show_coupon ) ) {
969
+ return;
970
+
971
+ }
972
+
973
+ $coupon_field = array(
974
+ 'field_text' => __( 'Coupon Code', 'cartflows' ),
975
+ 'button_text' => __( 'Apply', 'cartflows' ),
976
+ 'class' => '',
977
+ );
978
+
979
+ $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
980
+
981
+ ob_start();
982
+ ?>
983
+ <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
984
+ <div class="wcf-coupon-col-1">
985
+ <span>
986
+ <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
987
+ </span>
988
+ </div>
989
+ <div class="wcf-coupon-col-2">
990
+ <span>
991
+ <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
992
+ </span>
993
+ </div>
994
+ </div>
995
+ <?php
996
+ echo ob_get_clean();
997
+ }
998
+
999
+ /**
1000
+ * Apply filter to change class of remove coupon field.
1001
+ *
1002
+ * @param string $coupon coupon.
1003
+ * @return string
1004
+ */
1005
+ public function remove_coupon_text( $coupon ) {
1006
+
1007
+ $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1008
+ return $coupon;
1009
+
1010
+ }
1011
+ /**
1012
+ * Apply filter to change the placeholder text of coupon field.
1013
+ *
1014
+ * @return string
1015
+ */
1016
+ public function coupon_field_placeholder() {
1017
+ return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1018
+ }
1019
+
1020
+ /**
1021
+ * Apply filter to change the button text of coupon field.
1022
+ *
1023
+ * @return string
1024
+ */
1025
+ public function coupon_button_text() {
1026
+ return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1027
+ }
1028
+
1029
+ /**
1030
+ * Apply coupon on submit of custom coupon form.
1031
+ */
1032
+ public function apply_coupon() {
1033
+
1034
+ $response = '';
1035
+
1036
+ check_ajax_referer( 'wcf-apply-coupon', 'security' );
1037
+ if ( ! empty( $_POST['coupon_code'] ) ) {
1038
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1039
+ } else {
1040
+ wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1041
+ }
1042
+
1043
+ $response = array(
1044
+ 'status' => $result,
1045
+ 'msg' => wc_print_notices( true ),
1046
+ );
1047
+
1048
+ echo wp_json_encode( $response );
1049
+
1050
+ die();
1051
+ }
1052
+
1053
+
1054
+ /**
1055
+ * Added ajax nonce to localize variable.
1056
+ *
1057
+ * @param array $vars localize variables.
1058
+ */
1059
+ public function add_localize_vars( $vars ) {
1060
+
1061
+ $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1062
+
1063
+ $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1064
+
1065
+ $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1066
+
1067
+ $vars['allow_persistence'] = wcf_apply_filters_deprecated( 'cartflows_allow_persistace', array( 'yes' ), '1.6.0', 'cartflows_allow_persistence' );
1068
+
1069
+ return $vars;
1070
+ }
1071
+
1072
+ /**
1073
+ * Add custom class to the fields to change the UI to three column.
1074
+ *
1075
+ * @param array $fields fields.
1076
+ */
1077
+ public function add_three_column_layout_fields( $fields ) {
1078
+
1079
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
1080
+
1081
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1082
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1083
+ }
1084
+ }
1085
+
1086
+ if ( ! empty( $fields['billing']['billing_company'] ) ) {
1087
+
1088
+ if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1089
+ $fields['billing']['billing_company']['class'][] = 'form-row-full';
1090
+ }
1091
+ }
1092
+
1093
+ if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1094
+
1095
+ if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1096
+ $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1097
+ }
1098
+ }
1099
+
1100
+ if ( ! empty( $fields['billing']['billing_country'] ) ) {
1101
+
1102
+ if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1103
+ $fields['billing']['billing_country']['class'][] = 'form-row-full';
1104
+ }
1105
+ }
1106
+
1107
+ if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1108
+
1109
+ if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1110
+ $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1111
+ }
1112
+ }
1113
+
1114
+ if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1115
+
1116
+ if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1117
+ $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1118
+ }
1119
+ }
1120
+
1121
+ if ( ! empty( $fields['billing']['billing_email'] ) ) {
1122
+
1123
+ if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1124
+ $fields['billing']['billing_email']['class'][] = 'form-row-full';
1125
+ }
1126
+ }
1127
+
1128
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1129
+
1130
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1131
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1132
+ }
1133
+ }
1134
+
1135
+ if ( isset( $fields['billing']['billing_city'] ) &&
1136
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1137
+
1138
+ $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1139
+ $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1140
+ $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1141
+ }
1142
+
1143
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
1144
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1145
+
1146
+ $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1147
+ $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1148
+ $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1149
+ }
1150
+
1151
+ return $fields;
1152
+ }
1153
+
1154
+ /**
1155
+ * Add opening dev
1156
+ *
1157
+ * @since 1.0.0
1158
+ */
1159
+ public function order_wrap_div_start() {
1160
+
1161
+ echo "<div class='wcf-order-wrap'> ";
1162
+ }
1163
+
1164
+ /**
1165
+ * Add closing dev
1166
+ *
1167
+ * @since 1.0.0
1168
+ */
1169
+ public function order_wrap_div_end() {
1170
+
1171
+ echo '</div> ';
1172
+ }
1173
+ /**
1174
+ * Remove coupon.
1175
+ */
1176
+ public function remove_coupon() {
1177
+
1178
+ check_ajax_referer( 'wcf-remove-coupon', 'security' );
1179
+ $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1180
+
1181
+ if ( empty( $coupon ) ) {
1182
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1183
+ } else {
1184
+ WC()->cart->remove_coupon( $coupon );
1185
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1186
+ }
1187
+ wc_print_notices();
1188
+ wp_die();
1189
+ }
1190
+
1191
+ /**
1192
+ * Remove cart item.
1193
+ */
1194
+ public function wcf_woo_remove_cart_product() {
1195
+
1196
+ check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1197
+ $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1198
+ $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1199
+ $product_title = get_the_title( $product_id );
1200
+
1201
+ $needs_shipping = false;
1202
+
1203
+ if ( empty( $product_key ) ) {
1204
+ $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1205
+ } else {
1206
+ WC()->cart->remove_cart_item( $product_key );
1207
+ $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1208
+ }
1209
+
1210
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1211
+ if ( $values['data']->needs_shipping() ) {
1212
+ $needs_shipping = true;
1213
+ break;
1214
+ }
1215
+ }
1216
+
1217
+ $response = array(
1218
+ 'need_shipping' => $needs_shipping,
1219
+ 'msg' => $msg,
1220
+ );
1221
+
1222
+ echo wp_json_encode( $response );
1223
+ wp_die();
1224
+ }
1225
+
1226
+ /**
1227
+ * Calculate discount for product.
1228
+ *
1229
+ * @param string $discount_coupon discount coupon.
1230
+ * @param string $discount_type discount type.
1231
+ * @param int $discount_value discount value.
1232
+ * @param int $_product_price product price.
1233
+ * @return int
1234
+ * @since 1.1.5
1235
+ */
1236
+ public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1237
+
1238
+ $custom_price = '';
1239
+
1240
+ if ( ! empty( $discount_type ) ) {
1241
+ if ( 'discount_percent' === $discount_type ) {
1242
+
1243
+ if ( $discount_value > 0 ) {
1244
+ $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1245
+ }
1246
+ } elseif ( 'discount_price' === $discount_type ) {
1247
+
1248
+ if ( $discount_value > 0 ) {
1249
+ $custom_price = $_product_price - $discount_value;
1250
+ }
1251
+ } elseif ( 'coupon' === $discount_type ) {
1252
+
1253
+ if ( ! empty( $discount_coupon ) ) {
1254
+ WC()->cart->add_discount( $discount_coupon );
1255
+ }
1256
+ }
1257
+ }
1258
+
1259
+ return $custom_price;
1260
+ }
1261
+
1262
+ /**
1263
+ * Preserve the custom item price added by Variations & Quantity feature
1264
+ *
1265
+ * @param array $cart_object cart object.
1266
+ * @since 1.0.0
1267
+ */
1268
+ public function custom_price_to_cart_item( $cart_object ) {
1269
+
1270
+ if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1271
+
1272
+ foreach ( $cart_object->cart_contents as $key => $value ) {
1273
+
1274
+ if ( isset( $value['custom_price'] ) ) {
1275
+
1276
+ $custom_price = floatval( $value['custom_price'] );
1277
+ $value['data']->set_price( $custom_price );
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ }
1284
+
1285
+ /**
1286
+ * Kicking this off by calling 'get_instance()' method
1287
+ */
1288
+ Cartflows_Checkout_Markup::get_instance();
modules/checkout/templates/embed/checkout-template-simple.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
- /**
3
- * Checkout template
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
9
- $fields_skins = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-fields-skins' );
10
- ?>
11
- <div id="wcf-embed-checkout-form" class="wcf-embed-checkout-form wcf-embed-checkout-form-<?php echo $checkout_layout; ?> wcf-field-<?php echo $fields_skins; ?>">
12
- <!-- CHECKOUT SHORTCODE -->
13
- <?php do_action( 'cartflows_add_before_main_section', $checkout_layout ); ?>
14
-
15
- <?php
16
- $checkout_html = do_shortcode( '[woocommerce_checkout]' );
17
-
18
- if (
19
- empty( $checkout_html ) ||
20
- trim( $checkout_html ) == '<div class="woocommerce"></div>'
21
- ) {
22
-
23
- do_action( 'cartflows_checkout_cart_empty', $checkout_id );
24
-
25
- echo esc_html__( 'Your cart is currently empty.', 'cartflows' );
26
- } else {
27
- echo $checkout_html;
28
- }
29
- ?>
30
-
31
- <?php do_action( 'cartflows_add_after_main_section', $arg = '' ); ?>
32
- <!-- END CHECKOUT SHORTCODE -->
33
- </div>
1
+ <?php
2
+ /**
3
+ * Checkout template
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
9
+ $fields_skins = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-fields-skins' );
10
+ ?>
11
+ <div id="wcf-embed-checkout-form" class="wcf-embed-checkout-form wcf-embed-checkout-form-<?php echo $checkout_layout; ?> wcf-field-<?php echo $fields_skins; ?>">
12
+ <!-- CHECKOUT SHORTCODE -->
13
+ <?php do_action( 'cartflows_add_before_main_section', $checkout_layout ); ?>
14
+
15
+ <?php
16
+ $checkout_html = do_shortcode( '[woocommerce_checkout]' );
17
+
18
+ if (
19
+ empty( $checkout_html ) ||
20
+ trim( $checkout_html ) == '<div class="woocommerce"></div>'
21
+ ) {
22
+
23
+ do_action( 'cartflows_checkout_cart_empty', $checkout_id );
24
+
25
+ echo esc_html__( 'Your cart is currently empty.', 'cartflows' );
26
+ } else {
27
+ echo $checkout_html;
28
+ }
29
+ ?>
30
+
31
+ <?php do_action( 'cartflows_add_after_main_section', $arg = '' ); ?>
32
+ <!-- END CHECKOUT SHORTCODE -->
33
+ </div>
modules/flow/classes/class-cartflows-flow-meta.php CHANGED
@@ -1,760 +1,760 @@
1
- <?php
2
- /**
3
- * Flow meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Flow_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option;
27
-
28
- /**
29
- * For Gutenberg
30
- *
31
- * @var $is_gutenberg_editor_active
32
- */
33
- private $is_gutenberg_editor_active = false;
34
-
35
- /**
36
- * Initiator
37
- */
38
- public static function get_instance() {
39
- if ( ! isset( self::$instance ) ) {
40
- self::$instance = new self();
41
- }
42
-
43
- return self::$instance;
44
- }
45
-
46
- /**
47
- * Constructor
48
- */
49
- public function __construct() {
50
-
51
- add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
-
53
- add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
-
55
- /* Init Metabox */
56
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
-
59
- /* Add Scripts */
60
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
-
62
- add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
- add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
-
65
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
-
67
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
-
69
- /* To check the status of gutenberg */
70
- add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
-
72
- /* Add back to edit flow button for gutenberg */
73
- add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
- }
75
-
76
- /**
77
- * Display admin notices.
78
- *
79
- * @since 1.0.0
80
- *
81
- * @return void
82
- */
83
- public function admin_notices() {
84
-
85
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
- return;
87
- }
88
-
89
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
- if ( $flow_id ) { ?>
91
- <div class="wcf-notice-back-edit-flow">
92
- <p>
93
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
- <i class="dashicons dashicons-arrow-left-alt"></i>
95
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
- </a>
97
- </p>
98
- </div>
99
- <?php
100
- }
101
- }
102
-
103
- /**
104
- * Initialize admin actions.
105
- *
106
- * @since 1.0.0
107
- *
108
- * @return void
109
- */
110
- public function admin_init_actions() {
111
- add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
- add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
- add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
- }
115
-
116
- /**
117
- * Delete term data and steps data after deleting flow.
118
- *
119
- * @since 1.0.0
120
- * @param int $pid post id.
121
- *
122
- * @return void
123
- */
124
- public function step_post_sync( $pid ) {
125
-
126
- global $post_type;
127
-
128
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
-
130
- $steps = get_post_meta( $pid, 'wcf-steps', true );
131
-
132
- if ( $steps && is_array( $steps ) ) {
133
- foreach ( $steps as $i => $step ) {
134
- wp_delete_post( $step['id'], true );
135
- }
136
- }
137
-
138
- $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
-
140
- if ( is_array( $term_data ) ) {
141
- wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
- }
143
- }
144
- }
145
-
146
- /**
147
- * Trash steps data after trashing flow.
148
- *
149
- * @since 1.0.0
150
- * @param int $pid post id.
151
- *
152
- * @return void
153
- */
154
- public function step_post_trash_sync( $pid ) {
155
-
156
- global $post_type;
157
-
158
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
-
160
- $steps = get_post_meta( $pid, 'wcf-steps', true );
161
-
162
- if ( $steps && is_array( $steps ) ) {
163
- foreach ( $steps as $i => $step ) {
164
- wp_trash_post( $step['id'] );
165
- }
166
- }
167
- }
168
- }
169
-
170
- /**
171
- * Untrash steps data after restoring flow.
172
- *
173
- * @since 1.0.0
174
- * @param int $pid post id.
175
- *
176
- * @return void
177
- */
178
- public function step_post_untrash_sync( $pid ) {
179
-
180
- global $post_type;
181
-
182
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
-
184
- $steps = get_post_meta( $pid, 'wcf-steps', true );
185
-
186
- if ( $steps && is_array( $steps ) ) {
187
- foreach ( $steps as $i => $step ) {
188
- wp_untrash_post( $step['id'] );
189
- }
190
- }
191
- }
192
- }
193
-
194
- /**
195
- * Create step for given flow.
196
- *
197
- * @param int $flow_id flow ID.
198
- * @param int $step_type step type.
199
- * @param int $step_title step title.
200
- * @since 1.0.0
201
- *
202
- * @return int
203
- */
204
- public function create_step( $flow_id, $step_type, $step_title ) {
205
-
206
- $new_step_id = wp_insert_post(
207
- array(
208
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
- 'post_title' => $step_title,
210
- 'post_status' => 'publish',
211
- )
212
- );
213
-
214
- if ( $new_step_id ) {
215
-
216
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
-
218
- if ( ! is_array( $flow_steps ) ) {
219
- $flow_steps = array();
220
- }
221
-
222
- $flow_steps[] = array(
223
- 'id' => $new_step_id,
224
- 'title' => $step_title,
225
- 'type' => $step_type,
226
- );
227
-
228
- // insert post meta.
229
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
-
232
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
- }
235
-
236
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
-
238
- return $new_step_id;
239
- }
240
-
241
- /**
242
- * Delete step for flow
243
- *
244
- * @since 1.0.0
245
- *
246
- * @return void
247
- */
248
- public function cartflows_delete_flow_step() {
249
-
250
- if ( ! current_user_can( 'manage_options' ) ) {
251
- return;
252
- }
253
-
254
- check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
-
256
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
- $flow_id = intval( $_POST['post_id'] );
258
- $step_id = intval( $_POST['step_id'] );
259
- }
260
- $result = array(
261
- 'status' => false,
262
- /* translators: %s flow id */
263
- 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
- );
265
-
266
- if ( ! $flow_id || ! $step_id ) {
267
- wp_send_json( $result );
268
- }
269
-
270
- wp_delete_post( $step_id, true );
271
-
272
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
-
274
- if ( ! is_array( $flow_steps ) ) {
275
- wp_send_json( $result );
276
- }
277
-
278
- foreach ( $flow_steps as $index => $data ) {
279
-
280
- if ( intval( $data['id'] ) === $step_id ) {
281
- unset( $flow_steps[ $index ] );
282
- break;
283
- }
284
- }
285
-
286
- /* Set index order properly */
287
- $flow_steps = array_merge( $flow_steps );
288
-
289
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
-
291
- $result = array(
292
- 'status' => true,
293
- /* translators: %s flow id */
294
- 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
- );
296
-
297
- wp_send_json( $result );
298
- }
299
-
300
- /**
301
- * Reorder step flow
302
- *
303
- * @since 1.0.0
304
- *
305
- * @return void
306
- */
307
- public function cartflows_reorder_flow_steps() {
308
-
309
- if ( ! current_user_can( 'manage_options' ) ) {
310
- return;
311
- }
312
-
313
- check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
-
315
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
- $flow_id = intval( $_POST['post_id'] );
317
- $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
- }
319
- $result = array(
320
- 'status' => false,
321
- /* translators: %s flow id */
322
- 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
- );
324
-
325
- if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
- wp_send_json( $result );
327
- }
328
-
329
- $new_flow_steps = array();
330
-
331
- foreach ( $step_ids as $index => $step_id ) {
332
-
333
- $new_flow_steps[] = array(
334
- 'id' => intval( $step_id ),
335
- 'title' => get_the_title( $step_id ),
336
- 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
- );
338
- }
339
-
340
- update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
-
342
- $result = array(
343
- 'status' => true,
344
- /* translators: %s flow id */
345
- 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
- );
347
-
348
- wp_send_json( $result );
349
- }
350
-
351
-
352
- /**
353
- * Load admin scripts
354
- *
355
- * @since 1.0.0
356
- *
357
- * @return void
358
- */
359
- public function admin_scripts() {
360
-
361
- global $pagenow;
362
- global $post;
363
-
364
- $screen = get_current_screen();
365
-
366
- if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
-
368
- wp_enqueue_script(
369
- 'wcf-flow-meta',
370
- CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
- array( 'jquery', 'jquery-ui-sortable' ),
372
- CARTFLOWS_VER,
373
- true
374
- );
375
-
376
- wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
- wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
-
379
- $localize = array(
380
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
- );
382
-
383
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
- }
385
- }
386
-
387
- /**
388
- * Initialize meta box
389
- *
390
- * @since 1.0.0
391
- *
392
- * @return void
393
- */
394
- public function init_metabox() {
395
-
396
- /**
397
- * Fires after the title field.
398
- *
399
- * @param WP_Post $post Post object.
400
- */
401
- add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
- add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
- }
405
-
406
- /**
407
- * Is first time import?
408
- *
409
- * @param integer $post_id post ID.
410
- * @return bool
411
- */
412
- public function is_flow_imported( $post_id = 0 ) {
413
-
414
- if ( 0 === $post_id ) {
415
- $post_id = get_the_ID();
416
- }
417
-
418
- $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
- $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
-
421
- if ( empty( $steps ) && 'import' === $choice ) {
422
- return true;
423
- }
424
-
425
- return false;
426
- }
427
-
428
- /**
429
- * Setup meta box.
430
- *
431
- * @return void
432
- */
433
- public function setup_meta_box() {
434
- if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
- return;
436
- }
437
-
438
- /**
439
- * Adding Add new step button to the top*/
440
- echo $this->add_add_new_step_button();
441
-
442
- $this->markup_meta_box();
443
-
444
- $this->add_upgrade_to_pro_metabox();
445
- }
446
-
447
-
448
- /**
449
- * Add metabox when cartflows pro is not enabled.
450
- */
451
- public function add_upgrade_to_pro_metabox() {
452
-
453
- if ( ! _is_cartflows_pro() ) {
454
- add_meta_box(
455
- 'wcf-upgrade-pro',
456
- __( 'Analytics', 'cartflows' ),
457
- array( $this, 'upgrade_to_pro' ),
458
- CARTFLOWS_FLOW_POST_TYPE,
459
- 'side',
460
- 'high'
461
- );
462
- }
463
-
464
- }
465
-
466
- /**
467
- * Show Upgrade To Pro markup.
468
- */
469
- public function upgrade_to_pro() {
470
-
471
- echo '<div>';
472
- /* translators: %s: link */
473
- echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
- echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
- echo '</div>';
476
-
477
- }
478
-
479
- /**
480
- * Settings meta box.
481
- *
482
- * @return void
483
- */
484
- public function settings_meta_box() {
485
-
486
- if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
-
488
- /* No need of sandbox will delete it later */
489
- add_meta_box(
490
- 'wcf-sandbox-settings', // Id.
491
- __( 'Flow Settings', 'cartflows' ), // Title.
492
- array( $this, 'sandbox_meta_box' ), // Callback.
493
- CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
- 'side', // Context.
495
- 'high' // Priority.
496
- );
497
-
498
- do_action( 'cartflows_add_flow_metabox' );
499
- }
500
- }
501
-
502
- /**
503
- * Metabox Markup
504
- *
505
- * @return void
506
- */
507
- public function markup_meta_box() {
508
- global $post;
509
-
510
- wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
-
512
- // Get defaults.
513
- $meta = self::get_current_post_meta( $post->ID );
514
-
515
- /**
516
- * Get options
517
- */
518
- $updated_data = array(
519
- 'steps' => $meta['wcf-steps']['default'],
520
- );
521
-
522
- do_action( 'wcf_flow_settings_markup_before', $meta );
523
- $this->page_header_tab( $updated_data );
524
- do_action( 'wcf_flow_settings_markup_after', $meta );
525
- }
526
-
527
- /**
528
- * Metabox Markup
529
- *
530
- * @param object $post Post object.
531
- * @return void
532
- */
533
- public function sandbox_meta_box( $post ) {
534
-
535
- // Get defaults.
536
- $meta = self::get_current_post_meta( $post->ID );
537
-
538
- /**
539
- * Get options
540
- */
541
- foreach ( $meta as $key => $value ) {
542
- $updated_data[ $key ] = $meta[ $key ]['default'];
543
- }
544
-
545
- do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
- $this->sandbox_markup( $updated_data );
547
- do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
- }
549
-
550
- /**
551
- * Page Header Tabs
552
- *
553
- * @param array $options Post meta.
554
- * @return void
555
- */
556
- public function page_header_tab( $options ) {
557
-
558
- include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
- }
560
-
561
- /**
562
- * Sandbox Markup
563
- *
564
- * @param array $options Post meta.
565
- * @return void
566
- */
567
- public function sandbox_markup( $options ) {
568
- ?>
569
- <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
- <div class="wcf-flow-sandbox-table-container">
571
- <?php
572
- echo wcf()->meta->get_checkbox_field(
573
- array(
574
- 'name' => 'wcf-testing',
575
- 'value' => $options['wcf-testing'],
576
- 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
- )
578
- );
579
-
580
- echo wcf()->meta->get_description_field(
581
- array(
582
- 'name' => 'wcf-testing-note',
583
- 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
- )
585
- );
586
-
587
- ?>
588
- </div>
589
- </div>
590
- <?php
591
- }
592
-
593
- /**
594
- * Keep the menu open when editing the flows.
595
- * Highlights the wanted admin (sub-) menu items for the CPT.
596
- *
597
- * @since 1.0.0
598
- */
599
- public function menu_highlight() {
600
- global $parent_file, $submenu_file, $post_type;
601
- if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
- $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
- $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
- endif;
605
- }
606
-
607
- /**
608
- * Get metabox options
609
- *
610
- * @param int $post_id post id.
611
- * @return array
612
- */
613
- public static function get_meta_option( $post_id ) {
614
-
615
- if ( null === self::$meta_option ) {
616
- /**
617
- * Set metabox options
618
- */
619
- self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
- }
621
-
622
- return self::$meta_option;
623
- }
624
-
625
- /**
626
- * Get metabox options
627
- *
628
- * @param int $post_id post ID.
629
- * @return array
630
- */
631
- public static function get_current_post_meta( $post_id ) {
632
-
633
- $stored = get_post_meta( $post_id );
634
-
635
- $default_meta = self::get_meta_option( $post_id );
636
-
637
- // Set stored and override defaults.
638
- foreach ( $stored as $key => $value ) {
639
- if ( array_key_exists( $key, $default_meta ) ) {
640
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
- } else {
642
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
- }
644
- }
645
-
646
- return self::get_meta_option( $post_id );
647
- }
648
-
649
- /**
650
- * Metabox Save
651
- *
652
- * @param number $post_id Post ID.
653
- * @return void
654
- */
655
- public function save_meta_box( $post_id ) {
656
-
657
- // Checks save status.
658
- $is_autosave = wp_is_post_autosave( $post_id );
659
- $is_revision = wp_is_post_revision( $post_id );
660
-
661
- $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
-
663
- // Exits script depending on save status.
664
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
- return;
666
- }
667
-
668
- wcf()->options->save_flow_fields( $post_id );
669
- }
670
-
671
- /**
672
- * Localize variables in admin
673
- *
674
- * @param array $vars variables.
675
- */
676
- public function localize_vars( $vars ) {
677
-
678
- $ajax_actions = array(
679
- 'wcf_setup_default_steps',
680
- 'wcf_add_flow_step',
681
- 'wcf_delete_flow_step',
682
- 'wcf_reorder_flow_steps',
683
- );
684
-
685
- foreach ( $ajax_actions as $action ) {
686
-
687
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
- }
689
-
690
- return $vars;
691
- }
692
-
693
- /**
694
- * Add New Step Button
695
- *
696
- * @return string
697
- */
698
- public function add_add_new_step_button() {
699
- $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
- $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
- $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
- $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
- $add_new_btn_markup .= '</button>';
704
- $add_new_btn_markup .= '</div>';
705
-
706
- return $add_new_btn_markup;
707
- }
708
-
709
- /**
710
- * Back to flow button gutenberg template
711
- *
712
- * @return void
713
- */
714
- public function gutenberg_module_templates() {
715
-
716
- // Exit if block editor is not enabled.
717
- if ( ! $this->is_gutenberg_editor_active ) {
718
- return;
719
- }
720
-
721
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
- return;
723
- }
724
-
725
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
-
727
- if ( $flow_id ) {
728
- ?>
729
- <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
- <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
- <i class="dashicons dashicons-arrow-left-alt"></i>
733
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
- </a>
735
- </div>
736
- </script>
737
- <?php
738
- }
739
- }
740
-
741
- /**
742
- * Set status true for gutenberg.
743
- *
744
- * @return void
745
- */
746
- public function set_block_editor_status() {
747
-
748
- if ( ! current_user_can( 'manage_options' ) ) {
749
- return;
750
- }
751
-
752
- // Set gutenberg status here.
753
- $this->is_gutenberg_editor_active = true;
754
- }
755
- }
756
-
757
- /**
758
- * Kicking this off by calling 'get_instance()' method
759
- */
760
- Cartflows_Flow_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Flow_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option;
27
+
28
+ /**
29
+ * For Gutenberg
30
+ *
31
+ * @var $is_gutenberg_editor_active
32
+ */
33
+ private $is_gutenberg_editor_active = false;
34
+
35
+ /**
36
+ * Initiator
37
+ */
38
+ public static function get_instance() {
39
+ if ( ! isset( self::$instance ) ) {
40
+ self::$instance = new self();
41
+ }
42
+
43
+ return self::$instance;
44
+ }
45
+
46
+ /**
47
+ * Constructor
48
+ */
49
+ public function __construct() {
50
+
51
+ add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
+
53
+ add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
+
55
+ /* Init Metabox */
56
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
+
59
+ /* Add Scripts */
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
+
62
+ add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
+ add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
+
65
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
+
67
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
+
69
+ /* To check the status of gutenberg */
70
+ add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
+
72
+ /* Add back to edit flow button for gutenberg */
73
+ add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
+ }
75
+
76
+ /**
77
+ * Display admin notices.
78
+ *
79
+ * @since 1.0.0
80
+ *
81
+ * @return void
82
+ */
83
+ public function admin_notices() {
84
+
85
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
+ return;
87
+ }
88
+
89
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
+ if ( $flow_id ) { ?>
91
+ <div class="wcf-notice-back-edit-flow">
92
+ <p>
93
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
+ <i class="dashicons dashicons-arrow-left-alt"></i>
95
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
+ </a>
97
+ </p>
98
+ </div>
99
+ <?php
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Initialize admin actions.
105
+ *
106
+ * @since 1.0.0
107
+ *
108
+ * @return void
109
+ */
110
+ public function admin_init_actions() {
111
+ add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
+ add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
+ add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
+ }
115
+
116
+ /**
117
+ * Delete term data and steps data after deleting flow.
118
+ *
119
+ * @since 1.0.0
120
+ * @param int $pid post id.
121
+ *
122
+ * @return void
123
+ */
124
+ public function step_post_sync( $pid ) {
125
+
126
+ global $post_type;
127
+
128
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
+
130
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
131
+
132
+ if ( $steps && is_array( $steps ) ) {
133
+ foreach ( $steps as $i => $step ) {
134
+ wp_delete_post( $step['id'], true );
135
+ }
136
+ }
137
+
138
+ $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
+
140
+ if ( is_array( $term_data ) ) {
141
+ wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
+ }
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Trash steps data after trashing flow.
148
+ *
149
+ * @since 1.0.0
150
+ * @param int $pid post id.
151
+ *
152
+ * @return void
153
+ */
154
+ public function step_post_trash_sync( $pid ) {
155
+
156
+ global $post_type;
157
+
158
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
+
160
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
161
+
162
+ if ( $steps && is_array( $steps ) ) {
163
+ foreach ( $steps as $i => $step ) {
164
+ wp_trash_post( $step['id'] );
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Untrash steps data after restoring flow.
172
+ *
173
+ * @since 1.0.0
174
+ * @param int $pid post id.
175
+ *
176
+ * @return void
177
+ */
178
+ public function step_post_untrash_sync( $pid ) {
179
+
180
+ global $post_type;
181
+
182
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
+
184
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
185
+
186
+ if ( $steps && is_array( $steps ) ) {
187
+ foreach ( $steps as $i => $step ) {
188
+ wp_untrash_post( $step['id'] );
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Create step for given flow.
196
+ *
197
+ * @param int $flow_id flow ID.
198
+ * @param int $step_type step type.
199
+ * @param int $step_title step title.
200
+ * @since 1.0.0
201
+ *
202
+ * @return int
203
+ */
204
+ public function create_step( $flow_id, $step_type, $step_title ) {
205
+
206
+ $new_step_id = wp_insert_post(
207
+ array(
208
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
+ 'post_title' => $step_title,
210
+ 'post_status' => 'publish',
211
+ )
212
+ );
213
+
214
+ if ( $new_step_id ) {
215
+
216
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
+
218
+ if ( ! is_array( $flow_steps ) ) {
219
+ $flow_steps = array();
220
+ }
221
+
222
+ $flow_steps[] = array(
223
+ 'id' => $new_step_id,
224
+ 'title' => $step_title,
225
+ 'type' => $step_type,
226
+ );
227
+
228
+ // insert post meta.
229
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
+
232
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
+ }
235
+
236
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
+
238
+ return $new_step_id;
239
+ }
240
+
241
+ /**
242
+ * Delete step for flow
243
+ *
244
+ * @since 1.0.0
245
+ *
246
+ * @return void
247
+ */
248
+ public function cartflows_delete_flow_step() {
249
+
250
+ if ( ! current_user_can( 'manage_options' ) ) {
251
+ return;
252
+ }
253
+
254
+ check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
+
256
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
+ $flow_id = intval( $_POST['post_id'] );
258
+ $step_id = intval( $_POST['step_id'] );
259
+ }
260
+ $result = array(
261
+ 'status' => false,
262
+ /* translators: %s flow id */
263
+ 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
+ );
265
+
266
+ if ( ! $flow_id || ! $step_id ) {
267
+ wp_send_json( $result );
268
+ }
269
+
270
+ wp_delete_post( $step_id, true );
271
+
272
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
+
274
+ if ( ! is_array( $flow_steps ) ) {
275
+ wp_send_json( $result );
276
+ }
277
+
278
+ foreach ( $flow_steps as $index => $data ) {
279
+
280
+ if ( intval( $data['id'] ) === $step_id ) {
281
+ unset( $flow_steps[ $index ] );
282
+ break;
283
+ }
284
+ }
285
+
286
+ /* Set index order properly */
287
+ $flow_steps = array_merge( $flow_steps );
288
+
289
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
+
291
+ $result = array(
292
+ 'status' => true,
293
+ /* translators: %s flow id */
294
+ 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
+ );
296
+
297
+ wp_send_json( $result );
298
+ }
299
+
300
+ /**
301
+ * Reorder step flow
302
+ *
303
+ * @since 1.0.0
304
+ *
305
+ * @return void
306
+ */
307
+ public function cartflows_reorder_flow_steps() {
308
+
309
+ if ( ! current_user_can( 'manage_options' ) ) {
310
+ return;
311
+ }
312
+
313
+ check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
+
315
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
+ $flow_id = intval( $_POST['post_id'] );
317
+ $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
+ }
319
+ $result = array(
320
+ 'status' => false,
321
+ /* translators: %s flow id */
322
+ 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
+ );
324
+
325
+ if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
+ wp_send_json( $result );
327
+ }
328
+
329
+ $new_flow_steps = array();
330
+
331
+ foreach ( $step_ids as $index => $step_id ) {
332
+
333
+ $new_flow_steps[] = array(
334
+ 'id' => intval( $step_id ),
335
+ 'title' => get_the_title( $step_id ),
336
+ 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
+ );
338
+ }
339
+
340
+ update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
+
342
+ $result = array(
343
+ 'status' => true,
344
+ /* translators: %s flow id */
345
+ 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
+ );
347
+
348
+ wp_send_json( $result );
349
+ }
350
+
351
+
352
+ /**
353
+ * Load admin scripts
354
+ *
355
+ * @since 1.0.0
356
+ *
357
+ * @return void
358
+ */
359
+ public function admin_scripts() {
360
+
361
+ global $pagenow;
362
+ global $post;
363
+
364
+ $screen = get_current_screen();
365
+
366
+ if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
+
368
+ wp_enqueue_script(
369
+ 'wcf-flow-meta',
370
+ CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
+ array( 'jquery', 'jquery-ui-sortable' ),
372
+ CARTFLOWS_VER,
373
+ true
374
+ );
375
+
376
+ wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
+ wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
+
379
+ $localize = array(
380
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
+ );
382
+
383
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Initialize meta box
389
+ *
390
+ * @since 1.0.0
391
+ *
392
+ * @return void
393
+ */
394
+ public function init_metabox() {
395
+
396
+ /**
397
+ * Fires after the title field.
398
+ *
399
+ * @param WP_Post $post Post object.
400
+ */
401
+ add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
+ add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
+ }
405
+
406
+ /**
407
+ * Is first time import?
408
+ *
409
+ * @param integer $post_id post ID.
410
+ * @return bool
411
+ */
412
+ public function is_flow_imported( $post_id = 0 ) {
413
+
414
+ if ( 0 === $post_id ) {
415
+ $post_id = get_the_ID();
416
+ }
417
+
418
+ $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
+ $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
+
421
+ if ( empty( $steps ) && 'import' === $choice ) {
422
+ return true;
423
+ }
424
+
425
+ return false;
426
+ }
427
+
428
+ /**
429
+ * Setup meta box.
430
+ *
431
+ * @return void
432
+ */
433
+ public function setup_meta_box() {
434
+ if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
+ return;
436
+ }
437
+
438
+ /**
439
+ * Adding Add new step button to the top*/
440
+ echo $this->add_add_new_step_button();
441
+
442
+ $this->markup_meta_box();
443
+
444
+ $this->add_upgrade_to_pro_metabox();
445
+ }
446
+
447
+
448
+ /**
449
+ * Add metabox when cartflows pro is not enabled.
450
+ */
451
+ public function add_upgrade_to_pro_metabox() {
452
+
453
+ if ( ! _is_cartflows_pro() ) {
454
+ add_meta_box(
455
+ 'wcf-upgrade-pro',
456
+ __( 'Analytics', 'cartflows' ),
457
+ array( $this, 'upgrade_to_pro' ),
458
+ CARTFLOWS_FLOW_POST_TYPE,
459
+ 'side',
460
+ 'high'
461
+ );
462
+ }
463
+
464
+ }
465
+
466
+ /**
467
+ * Show Upgrade To Pro markup.
468
+ */
469
+ public function upgrade_to_pro() {
470
+
471
+ echo '<div>';
472
+ /* translators: %s: link */
473
+ echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
+ echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
+ echo '</div>';
476
+
477
+ }
478
+
479
+ /**
480
+ * Settings meta box.
481
+ *
482
+ * @return void
483
+ */
484
+ public function settings_meta_box() {
485
+
486
+ if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
+
488
+ /* No need of sandbox will delete it later */
489
+ add_meta_box(
490
+ 'wcf-sandbox-settings', // Id.
491
+ __( 'Flow Settings', 'cartflows' ), // Title.
492
+ array( $this, 'sandbox_meta_box' ), // Callback.
493
+ CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
+ 'side', // Context.
495
+ 'high' // Priority.
496
+ );
497
+
498
+ do_action( 'cartflows_add_flow_metabox' );
499
+ }
500
+ }
501
+
502
+ /**
503
+ * Metabox Markup
504
+ *
505
+ * @return void
506
+ */
507
+ public function markup_meta_box() {
508
+ global $post;
509
+
510
+ wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
+
512
+ // Get defaults.
513
+ $meta = self::get_current_post_meta( $post->ID );
514
+
515
+ /**
516
+ * Get options
517
+ */
518
+ $updated_data = array(
519
+ 'steps' => $meta['wcf-steps']['default'],
520
+ );
521
+
522
+ do_action( 'wcf_flow_settings_markup_before', $meta );
523
+ $this->page_header_tab( $updated_data );
524
+ do_action( 'wcf_flow_settings_markup_after', $meta );
525
+ }
526
+
527
+ /**
528
+ * Metabox Markup
529
+ *
530
+ * @param object $post Post object.
531
+ * @return void
532
+ */
533
+ public function sandbox_meta_box( $post ) {
534
+
535
+ // Get defaults.
536
+ $meta = self::get_current_post_meta( $post->ID );
537
+
538
+ /**
539
+ * Get options
540
+ */
541
+ foreach ( $meta as $key => $value ) {
542
+ $updated_data[ $key ] = $meta[ $key ]['default'];
543
+ }
544
+
545
+ do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
+ $this->sandbox_markup( $updated_data );
547
+ do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
+ }
549
+
550
+ /**
551
+ * Page Header Tabs
552
+ *
553
+ * @param array $options Post meta.
554
+ * @return void
555
+ */
556
+ public function page_header_tab( $options ) {
557
+
558
+ include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
+ }
560
+
561
+ /**
562
+ * Sandbox Markup
563
+ *
564
+ * @param array $options Post meta.
565
+ * @return void
566
+ */
567
+ public function sandbox_markup( $options ) {
568
+ ?>
569
+ <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
+ <div class="wcf-flow-sandbox-table-container">
571
+ <?php
572
+ echo wcf()->meta->get_checkbox_field(
573
+ array(
574
+ 'name' => 'wcf-testing',
575
+ 'value' => $options['wcf-testing'],
576
+ 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
+ )
578
+ );
579
+
580
+ echo wcf()->meta->get_description_field(
581
+ array(
582
+ 'name' => 'wcf-testing-note',
583
+ 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
+ )
585
+ );
586
+
587
+ ?>
588
+ </div>
589
+ </div>
590
+ <?php
591
+ }
592
+
593
+ /**
594
+ * Keep the menu open when editing the flows.
595
+ * Highlights the wanted admin (sub-) menu items for the CPT.
596
+ *
597
+ * @since 1.0.0
598
+ */
599
+ public function menu_highlight() {
600
+ global $parent_file, $submenu_file, $post_type;
601
+ if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
+ $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
+ $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
+ endif;
605
+ }
606
+
607
+ /**
608
+ * Get metabox options
609
+ *
610
+ * @param int $post_id post id.
611
+ * @return array
612
+ */
613
+ public static function get_meta_option( $post_id ) {
614
+
615
+ if ( null === self::$meta_option ) {
616
+ /**
617
+ * Set metabox options
618
+ */
619
+ self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
+ }
621
+
622
+ return self::$meta_option;
623
+ }
624
+
625
+ /**
626
+ * Get metabox options
627
+ *
628
+ * @param int $post_id post ID.
629
+ * @return array
630
+ */
631
+ public static function get_current_post_meta( $post_id ) {
632
+
633
+ $stored = get_post_meta( $post_id );
634
+
635
+ $default_meta = self::get_meta_option( $post_id );
636
+
637
+ // Set stored and override defaults.
638
+ foreach ( $stored as $key => $value ) {
639
+ if ( array_key_exists( $key, $default_meta ) ) {
640
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
+ } else {
642
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
+ }
644
+ }
645
+
646
+ return self::get_meta_option( $post_id );
647
+ }
648
+
649
+ /**
650
+ * Metabox Save
651
+ *
652
+ * @param number $post_id Post ID.
653
+ * @return void
654
+ */
655
+ public function save_meta_box( $post_id ) {
656
+
657
+ // Checks save status.
658
+ $is_autosave = wp_is_post_autosave( $post_id );
659
+ $is_revision = wp_is_post_revision( $post_id );
660
+
661
+ $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
+
663
+ // Exits script depending on save status.
664
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
+ return;
666
+ }
667
+
668
+ wcf()->options->save_flow_fields( $post_id );
669
+ }
670
+
671
+ /**
672
+ * Localize variables in admin
673
+ *
674
+ * @param array $vars variables.
675
+ */
676
+ public function localize_vars( $vars ) {
677
+
678
+ $ajax_actions = array(
679
+ 'wcf_setup_default_steps',
680
+ 'wcf_add_flow_step',
681
+ 'wcf_delete_flow_step',
682
+ 'wcf_reorder_flow_steps',
683
+ );
684
+
685
+ foreach ( $ajax_actions as $action ) {
686
+
687
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
+ }
689
+
690
+ return $vars;
691
+ }
692
+
693
+ /**
694
+ * Add New Step Button
695
+ *
696
+ * @return string
697
+ */
698
+ public function add_add_new_step_button() {
699
+ $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
+ $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
+ $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
+ $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
+ $add_new_btn_markup .= '</button>';
704
+ $add_new_btn_markup .= '</div>';
705
+
706
+ return $add_new_btn_markup;
707
+ }
708
+
709
+ /**
710
+ * Back to flow button gutenberg template
711
+ *
712
+ * @return void
713
+ */
714
+ public function gutenberg_module_templates() {
715
+
716
+ // Exit if block editor is not enabled.
717
+ if ( ! $this->is_gutenberg_editor_active ) {
718
+ return;
719
+ }
720
+
721
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
+ return;
723
+ }
724
+
725
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
+
727
+ if ( $flow_id ) {
728
+ ?>
729
+ <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
+ <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
+ <i class="dashicons dashicons-arrow-left-alt"></i>
733
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
+ </a>
735
+ </div>
736
+ </script>
737
+ <?php
738
+ }
739
+ }
740
+
741
+ /**
742
+ * Set status true for gutenberg.
743
+ *
744
+ * @return void
745
+ */
746
+ public function set_block_editor_status() {
747
+
748
+ if ( ! current_user_can( 'manage_options' ) ) {
749
+ return;
750
+ }
751
+
752
+ // Set gutenberg status here.
753
+ $this->is_gutenberg_editor_active = true;
754
+ }
755
+ }
756
+
757
+ /**
758
+ * Kicking this off by calling 'get_instance()' method
759
+ */
760
+ Cartflows_Flow_Meta::get_instance();
modules/flow/classes/class-cartflows-flow-post-type.php CHANGED
@@ -1,383 +1,383 @@
1
- <?php
2
- /**
3
- * Flow post type
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Post_Type {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var 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( 'init', array( $this, 'flow_post_type' ) );
39
- add_action( 'admin_menu', array( $this, 'register_as_submenu' ), 100 );
40
- add_action( 'do_meta_boxes', array( $this, 'wcf_change_metabox_position' ) );
41
-
42
- add_filter( 'post_updated_messages', array( $this, 'custom_post_type_post_update_messages' ) );
43
-
44
- add_filter( 'display_post_states', array( $this, 'add_cartflows_post_state' ), 15, 1 );
45
-
46
- add_filter( 'hidden_meta_boxes', array( $this, 'display_flow_slug_meta_box' ), 10, 2 );
47
-
48
- /* View Post URL */
49
- add_filter( 'post_row_actions', array( $this, 'post_row_actions' ), 10, 2 );
50
- add_filter( 'preview_post_link', array( $this, 'preview_post_link' ), 10, 2 );
51
- add_action( 'template_redirect', array( $this, 'redirect_to_step' ), 10 );
52
- }
53
-
54
- /**
55
- * Add CartFlows post status.
56
- *
57
- * @param array $post_states post data.
58
- * @return array
59
- */
60
- public function add_cartflows_post_state( $post_states ) {
61
-
62
- global $post;
63
-
64
- if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
65
-
66
- $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
67
- $flow_title = get_the_title( $flow_id );
68
-
69
- $post_states['cartflows_step'] = '( ' . __( 'Flow: ', 'cartflows' ) . $flow_id . ' | ' . __( 'Name: ', 'cartflows' ) . $flow_title . ')';
70
-
71
- }
72
-
73
- return $post_states;
74
- }
75
-
76
- /**
77
- * Display slugdiv.
78
- *
79
- * @param array $hidden metaboxes.
80
- * @param obj $screen screen.
81
- * @return array
82
- */
83
- public function display_flow_slug_meta_box( $hidden, $screen ) {
84
- $post_type = $screen->id;
85
- if ( ! empty( $post_type ) && CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
86
- $pos = array_search( 'slugdiv', $hidden, true );
87
- unset( $hidden[ $pos ] );
88
- }
89
-
90
- return $hidden;
91
- }
92
-
93
- /**
94
- * Create custom post type
95
- */
96
- public function flow_post_type() {
97
-
98
- $labels = array(
99
- 'name' => esc_html_x( 'Flows', 'flow general name', 'cartflows' ),
100
- 'singular_name' => esc_html_x( 'Flow', 'flow singular name', 'cartflows' ),
101
- 'search_items' => esc_html__( 'Search Flows', 'cartflows' ),
102
- 'all_items' => esc_html__( 'All Flows', 'cartflows' ),
103
- 'edit_item' => esc_html__( 'Edit Flow', 'cartflows' ),
104
- 'view_item' => esc_html__( 'View Flow', 'cartflows' ),
105
- 'add_new' => esc_html__( 'Add New', 'cartflows' ),
106
- 'update_item' => esc_html__( 'Update Flow', 'cartflows' ),
107
- 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
108
- 'new_item_name' => esc_html__( 'New Flow Name', 'cartflows' ),
109
- );
110
-
111
- $args = array(
112
- 'labels' => $labels,
113
- 'show_in_menu' => false,
114
- 'public' => false, // it's not public, not own permalink.
115
- 'publicly_queryable' => true, // you should be able to query it.
116
- 'show_ui' => true,
117
- 'query_var' => true,
118
- 'can_export' => true,
119
- 'show_in_admin_bar' => true,
120
- 'exclude_from_search' => true,
121
- 'has_archive' => false, // it shouldn't have archive page.
122
- 'rewrite' => false, // it shouldn't have rewrite rules.
123
- 'supports' => array( 'title', 'thumbnail', 'slug' ),
124
- 'capability_type' => 'post',
125
- );
126
-
127
- if ( ! _is_cartflows_pro() ) {
128
-
129
- $flow_posts = get_posts(
130
- array(
131
- 'posts_per_page' => 4,
132
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
133
- 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
134
- )
135
- );
136
-
137
- if ( is_array( $flow_posts ) ) {
138
-
139
- $flow_count = count( $flow_posts );
140
-
141
- if ( $flow_count > 3 || 3 === $flow_count ) {
142
-
143
- $args['capabilities'] = array(
144
- 'create_posts' => 'do_not_allow',
145
- );
146
- $args['map_meta_cap'] = true;
147
-
148
- // Add new notice button.
149
- add_action( 'admin_print_footer_scripts', array( $this, 'add_new_notice_button' ) );
150
-
151
- // Add the notice popup HTML to admin footer.
152
- add_action( 'admin_footer', array( $this, 'upgrade_to_pro_notice_popup' ) );
153
- }
154
- }
155
- }
156
-
157
- register_post_type( CARTFLOWS_FLOW_POST_TYPE, $args );
158
- }
159
-
160
- /**
161
- * Show custom add new button.
162
- */
163
- public function add_new_notice_button() {
164
-
165
- $screen = get_current_screen();
166
-
167
- if ( is_object( $screen ) && CARTFLOWS_FLOW_POST_TYPE === $screen->post_type && 'edit-cartflows_flow' === $screen->id ) {
168
- ?>
169
- <script>
170
- jQuery('.wrap h1.wp-heading-inline').after('<a type="button" class="wcf-custom-add-new-button button">Add New</a>');
171
- </script>
172
- <?php
173
- }
174
- }
175
-
176
- /**
177
- * Upgrade to pro notice popup.
178
- *
179
- * @since 1.3.4
180
- *
181
- * @return void
182
- */
183
- public function upgrade_to_pro_notice_popup() {
184
-
185
- ?>
186
- <div id="cartflows-upgrade-notice-overlay" style="display:none;"></div>
187
- <div id="cartflows-upgrade-notice-popup" style="display:none;">
188
- <div class="inner">
189
- <div class="heading">
190
- <span><?php esc_html_e( 'Upgrade to CartFlows Pro', 'cartflows' ); ?></span>
191
- <span class="cartflows-close-popup-button tb-close-icon"></span>
192
- </div>
193
- <div class="contents">
194
- <div class="wcf-notice">
195
- <p>Upgrade to CartFlows Pro for adding more flows and other features. <a href ="https://cartflows.com/" target="_blank"> Click here</a> to upgrade.</p>
196
- </div>
197
- </div>
198
- </div>
199
- </div>
200
- <?php
201
- }
202
-
203
- /**
204
- * Change metabox position.
205
- */
206
- public function wcf_change_metabox_position() {
207
-
208
- remove_meta_box( 'slugdiv', CARTFLOWS_FLOW_POST_TYPE, 'normal' );
209
- add_meta_box( 'slugdiv', __( 'Slug', 'cartflows' ), 'post_slug_meta_box', CARTFLOWS_FLOW_POST_TYPE, 'side', 'high' );
210
- }
211
-
212
- /**
213
- * Add post raw actions
214
- *
215
- * @param array $actions actions.
216
- * @param array $post post data.
217
- * @return array
218
- */
219
- public function post_row_actions( $actions, $post ) {
220
-
221
- $first_step = $this->get_first_step_url( $post );
222
-
223
- if ( $first_step && isset( $actions['view'] ) ) {
224
-
225
- $actions['view'] = '<a href="' . $first_step . '">' . __( 'View', 'cartflows' ) . '</a>';
226
- }
227
-
228
- return $actions;
229
- }
230
-
231
- /**
232
- * Returns previous post link
233
- *
234
- * @param string $prev_link previous link.
235
- * @param array $post post data.
236
- * @return string
237
- */
238
- public function preview_post_link( $prev_link, $post ) {
239
-
240
- if ( $this->is_flow_post_type( $post ) ) {
241
-
242
- $first_step = $this->get_first_step_url( $post );
243
-
244
- if ( $first_step ) {
245
-
246
- return $first_step;
247
- }
248
-
249
- return '';
250
- }
251
-
252
- return $prev_link;
253
- }
254
-
255
- /**
256
- * Check if post type is flow
257
- *
258
- * @param array $post post data.
259
- * @return bool
260
- */
261
- public function is_flow_post_type( $post ) {
262
-
263
- if ( isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
264
-
265
- return true;
266
- }
267
-
268
- return false;
269
- }
270
-
271
- /**
272
- * Redirect to first step
273
- *
274
- * @return void
275
- */
276
- public function redirect_to_step() {
277
-
278
- global $post;
279
-
280
- $first_step = $this->get_first_step_url( $post );
281
-
282
- if ( $first_step ) {
283
-
284
- wp_safe_redirect( $first_step );
285
- die;
286
- }
287
- }
288
-
289
- /**
290
- * Return first step URL
291
- *
292
- * @param array $post post data.
293
- * @return bool
294
- */
295
- public function get_first_step_url( $post ) {
296
-
297
- if ( $this->is_flow_post_type( $post ) ) {
298
-
299
- $flow_id = $post->ID;
300
- $title = $post->post_title;
301
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
302
-
303
- if ( is_array( $steps ) && ! empty( $steps ) && isset( $steps[0]['id'] ) ) {
304
-
305
- return get_permalink( $steps[0]['id'] );
306
- }
307
- }
308
-
309
- return false;
310
- }
311
-
312
- /**
313
- * Register the admin menu for Custom Layouts
314
- *
315
- * @since 1.0.0
316
- * Moved the menu under Appearance -> Custom Layouts
317
- public function register_admin_menu() {
318
- add_submenu_page(
319
- CARTFLOWS_SLUG,
320
- __( 'Flows', 'wcf' ),
321
- __( 'Flows', 'wcf' ),
322
- 'edit_pages',
323
- 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE
324
- );
325
- }
326
- */
327
- public function register_as_submenu() {
328
-
329
- global $submenu;
330
-
331
- $submenu[ CARTFLOWS_SLUG ][0] = array( //phpcs:ignore
332
- __( 'Flows', 'cartflows' ),
333
- 'edit_pages',
334
- 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE,
335
- );
336
- }
337
-
338
- /**
339
- * Add Update messages for any custom post type
340
- *
341
- * @param array $messages Array of default messages.
342
- */
343
- public function custom_post_type_post_update_messages( $messages ) {
344
-
345
- $custom_post_type = get_post_type( get_the_ID() );
346
-
347
- if ( CARTFLOWS_FLOW_POST_TYPE == $custom_post_type ) {
348
-
349
- $obj = get_post_type_object( $custom_post_type );
350
- $singular_name = $obj->labels->singular_name;
351
- $messages[ $custom_post_type ] = array(
352
- 0 => '', // Unused. Messages start at index 1.
353
- /* translators: %s: singular custom post type name */
354
- 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
355
- /* translators: %s: singular custom post type name */
356
- 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
357
- /* translators: %s: singular custom post type name */
358
- 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
359
- /* translators: %s: singular custom post type name */
360
- 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
361
- /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
362
- 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
363
- /* translators: %s: singular custom post type name */
364
- 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
365
- /* translators: %s: singular custom post type name */
366
- 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
367
- /* translators: %s: singular custom post type name */
368
- 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
369
- /* translators: %s: singular custom post type name */
370
- 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
371
- /* translators: %s: singular custom post type name */
372
- 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
373
- );
374
- }
375
-
376
- return $messages;
377
- }
378
- }
379
-
380
- /**
381
- * Kicking this off by calling 'get_instance()' method
382
- */
383
- Cartflows_Flow_Post_Type::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow post type
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Post_Type {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var 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( 'init', array( $this, 'flow_post_type' ) );
39
+ add_action( 'admin_menu', array( $this, 'register_as_submenu' ), 100 );
40
+ add_action( 'do_meta_boxes', array( $this, 'wcf_change_metabox_position' ) );
41
+
42
+ add_filter( 'post_updated_messages', array( $this, 'custom_post_type_post_update_messages' ) );
43
+
44
+ add_filter( 'display_post_states', array( $this, 'add_cartflows_post_state' ), 15, 1 );
45
+
46
+ add_filter( 'hidden_meta_boxes', array( $this, 'display_flow_slug_meta_box' ), 10, 2 );
47
+
48
+ /* View Post URL */
49
+ add_filter( 'post_row_actions', array( $this, 'post_row_actions' ), 10, 2 );
50
+ add_filter( 'preview_post_link', array( $this, 'preview_post_link' ), 10, 2 );
51
+ add_action( 'template_redirect', array( $this, 'redirect_to_step' ), 10 );
52
+ }
53
+
54
+ /**
55
+ * Add CartFlows post status.
56
+ *
57
+ * @param array $post_states post data.
58
+ * @return array
59
+ */
60
+ public function add_cartflows_post_state( $post_states ) {
61
+
62
+ global $post;
63
+
64
+ if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
65
+
66
+ $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
67
+ $flow_title = get_the_title( $flow_id );
68
+
69
+ $post_states['cartflows_step'] = '( ' . __( 'Flow: ', 'cartflows' ) . $flow_id . ' | ' . __( 'Name: ', 'cartflows' ) . $flow_title . ')';
70
+
71
+ }
72
+
73
+ return $post_states;
74
+ }
75
+
76
+ /**
77
+ * Display slugdiv.
78
+ *
79
+ * @param array $hidden metaboxes.
80
+ * @param obj $screen screen.
81
+ * @return array
82
+ */
83
+ public function display_flow_slug_meta_box( $hidden, $screen ) {
84
+ $post_type = $screen->id;
85
+ if ( ! empty( $post_type ) && CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
86
+ $pos = array_search( 'slugdiv', $hidden, true );
87
+ unset( $hidden[ $pos ] );
88
+ }
89
+
90
+ return $hidden;
91
+ }
92
+
93
+ /**
94
+ * Create custom post type
95
+ */
96
+ public function flow_post_type() {
97
+
98
+ $labels = array(
99
+ 'name' => esc_html_x( 'Flows', 'flow general name', 'cartflows' ),
100
+ 'singular_name' => esc_html_x( 'Flow', 'flow singular name', 'cartflows' ),
101
+ 'search_items' => esc_html__( 'Search Flows', 'cartflows' ),
102
+ 'all_items' => esc_html__( 'All Flows', 'cartflows' ),
103
+ 'edit_item' => esc_html__( 'Edit Flow', 'cartflows' ),
104
+ 'view_item' => esc_html__( 'View Flow', 'cartflows' ),
105
+ 'add_new' => esc_html__( 'Add New', 'cartflows' ),
106
+ 'update_item' => esc_html__( 'Update Flow', 'cartflows' ),
107
+ 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
108
+ 'new_item_name' => esc_html__( 'New Flow Name', 'cartflows' ),
109
+ );
110
+
111
+ $args = array(
112
+ 'labels' => $labels,
113
+ 'show_in_menu' => false,
114
+ 'public' => false, // it's not public, not own permalink.
115
+ 'publicly_queryable' => true, // you should be able to query it.
116
+ 'show_ui' => true,
117
+ 'query_var' => true,
118
+ 'can_export' => true,
119
+ 'show_in_admin_bar' => true,
120
+ 'exclude_from_search' => true,
121
+ 'has_archive' => false, // it shouldn't have archive page.
122
+ 'rewrite' => false, // it shouldn't have rewrite rules.
123
+ 'supports' => array( 'title', 'thumbnail', 'slug' ),
124
+ 'capability_type' => 'post',
125
+ );
126
+
127
+ if ( ! _is_cartflows_pro() ) {
128
+
129
+ $flow_posts = get_posts(
130
+ array(
131
+ 'posts_per_page' => 4,
132
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
133
+ 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
134
+ )
135
+ );
136
+
137
+ if ( is_array( $flow_posts ) ) {
138
+
139
+ $flow_count = count( $flow_posts );
140
+
141
+ if ( $flow_count > 3 || 3 === $flow_count ) {
142
+
143
+ $args['capabilities'] = array(
144
+ 'create_posts' => 'do_not_allow',
145
+ );
146
+ $args['map_meta_cap'] = true;
147
+
148
+ // Add new notice button.
149
+ add_action( 'admin_print_footer_scripts', array( $this, 'add_new_notice_button' ) );
150
+
151
+ // Add the notice popup HTML to admin footer.
152
+ add_action( 'admin_footer', array( $this, 'upgrade_to_pro_notice_popup' ) );
153
+ }
154
+ }
155
+ }
156
+
157
+ register_post_type( CARTFLOWS_FLOW_POST_TYPE, $args );
158
+ }
159
+
160
+ /**
161
+ * Show custom add new button.
162
+ */
163
+ public function add_new_notice_button() {
164
+
165
+ $screen = get_current_screen();
166
+
167
+ if ( is_object( $screen ) && CARTFLOWS_FLOW_POST_TYPE === $screen->post_type && 'edit-cartflows_flow' === $screen->id ) {
168
+ ?>
169
+ <script>
170
+ jQuery('.wrap h1.wp-heading-inline').after('<a type="button" class="wcf-custom-add-new-button button">Add New</a>');
171
+ </script>
172
+ <?php
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Upgrade to pro notice popup.
178
+ *
179
+ * @since 1.3.4
180
+ *
181
+ * @return void
182
+ */
183
+ public function upgrade_to_pro_notice_popup() {
184
+
185
+ ?>
186
+ <div id="cartflows-upgrade-notice-overlay" style="display:none;"></div>
187
+ <div id="cartflows-upgrade-notice-popup" style="display:none;">
188
+ <div class="inner">
189
+ <div class="heading">
190
+ <span><?php esc_html_e( 'Upgrade to CartFlows Pro', 'cartflows' ); ?></span>
191
+ <span class="cartflows-close-popup-button tb-close-icon"></span>
192
+ </div>
193
+ <div class="contents">
194
+ <div class="wcf-notice">
195
+ <p>Upgrade to CartFlows Pro for adding more flows and other features. <a href ="https://cartflows.com/" target="_blank"> Click here</a> to upgrade.</p>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ <?php
201
+ }
202
+
203
+ /**
204
+ * Change metabox position.
205
+ */
206
+ public function wcf_change_metabox_position() {
207
+
208
+ remove_meta_box( 'slugdiv', CARTFLOWS_FLOW_POST_TYPE, 'normal' );
209
+ add_meta_box( 'slugdiv', __( 'Slug', 'cartflows' ), 'post_slug_meta_box', CARTFLOWS_FLOW_POST_TYPE, 'side', 'high' );
210
+ }
211
+
212
+ /**
213
+ * Add post raw actions
214
+ *
215
+ * @param array $actions actions.
216
+ * @param array $post post data.
217
+ * @return array
218
+ */
219
+ public function post_row_actions( $actions, $post ) {
220
+
221
+ $first_step = $this->get_first_step_url( $post );
222
+
223
+ if ( $first_step && isset( $actions['view'] ) ) {
224
+
225
+ $actions['view'] = '<a href="' . $first_step . '">' . __( 'View', 'cartflows' ) . '</a>';
226
+ }
227
+
228
+ return $actions;
229
+ }
230
+
231
+ /**
232
+ * Returns previous post link
233
+ *
234
+ * @param string $prev_link previous link.
235
+ * @param array $post post data.
236
+ * @return string
237
+ */
238
+ public function preview_post_link( $prev_link, $post ) {
239
+
240
+ if ( $this->is_flow_post_type( $post ) ) {
241
+
242
+ $first_step = $this->get_first_step_url( $post );
243
+
244
+ if ( $first_step ) {
245
+
246
+ return $first_step;
247
+ }
248
+
249
+ return '';
250
+ }
251
+
252
+ return $prev_link;
253
+ }
254
+
255
+ /**
256
+ * Check if post type is flow
257
+ *
258
+ * @param array $post post data.
259
+ * @return bool
260
+ */
261
+ public function is_flow_post_type( $post ) {
262
+
263
+ if ( isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
264
+
265
+ return true;
266
+ }
267
+
268
+ return false;
269
+ }
270
+
271
+ /**
272
+ * Redirect to first step
273
+ *
274
+ * @return void
275
+ */
276
+ public function redirect_to_step() {
277
+
278
+ global $post;
279
+
280
+ $first_step = $this->get_first_step_url( $post );
281
+
282
+ if ( $first_step ) {
283
+
284
+ wp_safe_redirect( $first_step );
285
+ die;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Return first step URL
291
+ *
292
+ * @param array $post post data.
293
+ * @return bool
294
+ */
295
+ public function get_first_step_url( $post ) {
296
+
297
+ if ( $this->is_flow_post_type( $post ) ) {
298
+
299
+ $flow_id = $post->ID;
300
+ $title = $post->post_title;
301
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
302
+
303
+ if ( is_array( $steps ) && ! empty( $steps ) && isset( $steps[0]['id'] ) ) {
304
+
305
+ return get_permalink( $steps[0]['id'] );
306
+ }
307
+ }
308
+
309
+ return false;
310
+ }
311
+
312
+ /**
313
+ * Register the admin menu for Custom Layouts
314
+ *
315
+ * @since 1.0.0
316
+ * Moved the menu under Appearance -> Custom Layouts
317
+ public function register_admin_menu() {
318
+ add_submenu_page(
319
+ CARTFLOWS_SLUG,
320
+ __( 'Flows', 'wcf' ),
321
+ __( 'Flows', 'wcf' ),
322
+ 'edit_pages',
323
+ 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE
324
+ );
325
+ }
326
+ */
327
+ public function register_as_submenu() {
328
+
329
+ global $submenu;
330
+
331
+ $submenu[ CARTFLOWS_SLUG ][0] = array( //phpcs:ignore
332
+ __( 'Flows', 'cartflows' ),
333
+ 'edit_pages',
334
+ 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE,
335
+ );
336
+ }
337
+
338
+ /**
339
+ * Add Update messages for any custom post type
340
+ *
341
+ * @param array $messages Array of default messages.
342
+ */
343
+ public function custom_post_type_post_update_messages( $messages ) {
344
+
345
+ $custom_post_type = get_post_type( get_the_ID() );
346
+
347
+ if ( CARTFLOWS_FLOW_POST_TYPE == $custom_post_type ) {
348
+
349
+ $obj = get_post_type_object( $custom_post_type );
350
+ $singular_name = $obj->labels->singular_name;
351
+ $messages[ $custom_post_type ] = array(
352
+ 0 => '', // Unused. Messages start at index 1.
353
+ /* translators: %s: singular custom post type name */
354
+ 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
355
+ /* translators: %s: singular custom post type name */
356
+ 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
357
+ /* translators: %s: singular custom post type name */
358
+ 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
359
+ /* translators: %s: singular custom post type name */
360
+ 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
361
+ /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
362
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore
363
+ /* translators: %s: singular custom post type name */
364
+ 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
365
+ /* translators: %s: singular custom post type name */
366
+ 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
367
+ /* translators: %s: singular custom post type name */
368
+ 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
369
+ /* translators: %s: singular custom post type name */
370
+ 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
371
+ /* translators: %s: singular custom post type name */
372
+ 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
373
+ );
374
+ }
375
+
376
+ return $messages;
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Kicking this off by calling 'get_instance()' method
382
+ */
383
+ Cartflows_Flow_Post_Type::get_instance();
modules/flow/view/meta-flow-steps.php CHANGED
@@ -1,210 +1,210 @@
1
- <?php
2
- /**
3
- * View Flow steps
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
-
10
- $steps = array(
11
- 'landing' => __( 'Landing', 'cartflows' ),
12
- 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
- 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
- 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
- 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
- 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
- );
18
-
19
- ?>
20
- <div class="wcf-flow-steps-meta-box">
21
- <div class="wcf-flow-settings">
22
- <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
- <div class="wcf-flow-steps-wrap">
24
- <div class="wcf-flow-steps-container">
25
- <?php if ( is_array( $options['steps'] ) ) { ?>
26
- <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
- <?php
28
- $term_slug = '';
29
- $term_name = '';
30
- $step_wrap_class = '';
31
- $has_product_assigned = true;
32
- $is_global_checkout = '';
33
- $common = '';
34
- $data_step_id = intval( $data['id'] );
35
-
36
- if ( isset( $data['type'] ) ) {
37
- $term_slug = $data['type'];
38
- $term_name = $steps[ $data['type'] ];
39
- }
40
-
41
- if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
- $step_wrap_class .= ' invalid-step';
43
- }
44
-
45
- if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
-
47
- $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
-
49
- if ( $highlight_step_id === $data_step_id ) {
50
- $step_wrap_class .= ' wcf-new-step-highlight';
51
- }
52
- }
53
-
54
- if ( 'checkout' === $term_slug ) {
55
-
56
- $common = Cartflows_Helper::get_common_settings();
57
-
58
- $is_global_checkout = (int) $common['global_checkout'];
59
-
60
- if ( $data['id'] === $is_global_checkout ) {
61
- $step_wrap_class .= ' wcf-global-checkout';
62
- }
63
- }
64
-
65
- if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
-
67
- $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
-
69
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
- $step_wrap_class .= ' wcf-no-product-step';
71
- }
72
- }
73
-
74
- ?>
75
- <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
- <div class="wcf-step">
77
- <div class="wcf-step-left-content">
78
- <span class="dashicons dashicons-menu"></span>
79
- <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
- <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
-
82
- <?php
83
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
- ?>
85
- <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
- <?php
87
- } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
- ?>
89
- <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
- <?php
91
- } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
- ?>
93
- <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
- <?php
95
- }
96
- ?>
97
-
98
- <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
- <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
- </div>
101
- <div class="wcf-steps-action-buttons">
102
- <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
- <span class="dashicons dashicons-visibility"></span>
104
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
- </a>
106
- <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
- <span class="dashicons dashicons-edit"></span>
108
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
- </a>
110
- <?php
111
- if ( _is_cartflows_pro() ) {
112
- ?>
113
- <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
- <span class="dashicons dashicons-admin-page"></span>
115
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
- </a>
117
- <?php } ?>
118
- <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
- <span class="dashicons dashicons-trash"></span>
120
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
- </a>
122
- </div>
123
- </div>
124
- </div><!-- .wcf-step-wrap -->
125
- <?php } ?>
126
- <?php } ?>
127
- </div><!-- .wcf-flow-steps-container -->
128
- </div> <!-- .wcf-flow-steps-wrap -->
129
- <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
- <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
- <div class='wcf-add-new-step-btn-wrap'>
132
- <button class='wcf-trigger-popup button button-primary'>
133
- <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
- </button>
135
- </div>
136
- </div><!-- .wcf-flow-buttons-wrap -->
137
- </div><!-- .wcf-flow-settings -->
138
-
139
- <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
- <div class="wcf-templates-popup-content">
141
- <div class="spinner"></div>
142
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
-
144
- <div id="wcf-remote-step-actions" class="wcf-template-header">
145
- <div class="wcf-template-logo-wrap">
146
- <span class="wcf-cartflows-logo-img">
147
- <span class="cartflows-logo-icon"></span>
148
- </span>
149
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
- </div>
151
- <div class="wcf-tab-wrapper">
152
- <?php if ( 'other' !== $default_page_builder ) { ?>
153
- <div id="wcf-get-started-steps">
154
- <ul class="filter-links ">
155
- <li>
156
- <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>
157
- </li>
158
- <li>
159
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
- </li>
161
- </ul>
162
- </div>
163
- <?php } ?>
164
- </div>
165
- <div class="wcf-popup-close-wrap">
166
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
- </div>
168
- </div>
169
-
170
- <!--<div class="wcf-search-form">
171
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
- </div>-->
174
-
175
- <div id="wcf-remote-content">
176
- <?php if ( 'other' !== $default_page_builder ) { ?>
177
- <div id="wcf-ready-templates">
178
- <div id="wcf-remote-filters">
179
- <div id="wcf-page-builders"></div>
180
- <div id="wcf-categories"></div>
181
- </div>
182
- <div class="wcf-page-builder-notice"></div>
183
- <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
- </div>
186
- <?php } ?>
187
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
- <div class="inner">
189
- <div id="wcf-scratch-steps-categories">
190
- <select class="step-type-filter-links filter-links">
191
- <option value="" class="current"> Select Step Type </option>
192
-
193
- <?php foreach ( $steps as $key => $value ) { ?>
194
- <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
- <?php } ?>
196
- </select>
197
- </div>
198
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
- <?php if ( ! _is_cartflows_pro() ) { ?>
200
- <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
- <?php } ?>
202
- <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>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
- </div><!-- .wcf-templates-popup-overlay -->
209
- </div>
210
- <?php
1
+ <?php
2
+ /**
3
+ * View Flow steps
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
+
10
+ $steps = array(
11
+ 'landing' => __( 'Landing', 'cartflows' ),
12
+ 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
+ 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
+ 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
+ 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
+ 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
+ );
18
+
19
+ ?>
20
+ <div class="wcf-flow-steps-meta-box">
21
+ <div class="wcf-flow-settings">
22
+ <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
+ <div class="wcf-flow-steps-wrap">
24
+ <div class="wcf-flow-steps-container">
25
+ <?php if ( is_array( $options['steps'] ) ) { ?>
26
+ <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
+ <?php
28
+ $term_slug = '';
29
+ $term_name = '';
30
+ $step_wrap_class = '';
31
+ $has_product_assigned = true;
32
+ $is_global_checkout = '';
33
+ $common = '';
34
+ $data_step_id = intval( $data['id'] );
35
+
36
+ if ( isset( $data['type'] ) ) {
37
+ $term_slug = $data['type'];
38
+ $term_name = $steps[ $data['type'] ];
39
+ }
40
+
41
+ if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
+ $step_wrap_class .= ' invalid-step';
43
+ }
44
+
45
+ if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
+
47
+ $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
+
49
+ if ( $highlight_step_id === $data_step_id ) {
50
+ $step_wrap_class .= ' wcf-new-step-highlight';
51
+ }
52
+ }
53
+
54
+ if ( 'checkout' === $term_slug ) {
55
+
56
+ $common = Cartflows_Helper::get_common_settings();
57
+
58
+ $is_global_checkout = (int) $common['global_checkout'];
59
+
60
+ if ( $data['id'] === $is_global_checkout ) {
61
+ $step_wrap_class .= ' wcf-global-checkout';
62
+ }
63
+ }
64
+
65
+ if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
+
67
+ $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
+
69
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
+ $step_wrap_class .= ' wcf-no-product-step';
71
+ }
72
+ }
73
+
74
+ ?>
75
+ <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
+ <div class="wcf-step">
77
+ <div class="wcf-step-left-content">
78
+ <span class="dashicons dashicons-menu"></span>
79
+ <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
+ <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
+
82
+ <?php
83
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
+ ?>
85
+ <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
+ <?php
87
+ } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
+ ?>
89
+ <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
+ <?php
91
+ } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
+ ?>
93
+ <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
+ <?php
95
+ }
96
+ ?>
97
+
98
+ <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
+ <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
+ </div>
101
+ <div class="wcf-steps-action-buttons">
102
+ <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
+ <span class="dashicons dashicons-visibility"></span>
104
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
+ </a>
106
+ <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
+ <span class="dashicons dashicons-edit"></span>
108
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
+ </a>
110
+ <?php
111
+ if ( _is_cartflows_pro() ) {
112
+ ?>
113
+ <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
+ <span class="dashicons dashicons-admin-page"></span>
115
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
+ </a>
117
+ <?php } ?>
118
+ <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
+ <span class="dashicons dashicons-trash"></span>
120
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
+ </a>
122
+ </div>
123
+ </div>
124
+ </div><!-- .wcf-step-wrap -->
125
+ <?php } ?>
126
+ <?php } ?>
127
+ </div><!-- .wcf-flow-steps-container -->
128
+ </div> <!-- .wcf-flow-steps-wrap -->
129
+ <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
+ <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
+ <div class='wcf-add-new-step-btn-wrap'>
132
+ <button class='wcf-trigger-popup button button-primary'>
133
+ <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
+ </button>
135
+ </div>
136
+ </div><!-- .wcf-flow-buttons-wrap -->
137
+ </div><!-- .wcf-flow-settings -->
138
+
139
+ <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
+ <div class="wcf-templates-popup-content">
141
+ <div class="spinner"></div>
142
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
+
144
+ <div id="wcf-remote-step-actions" class="wcf-template-header">
145
+ <div class="wcf-template-logo-wrap">
146
+ <span class="wcf-cartflows-logo-img">
147
+ <span class="cartflows-logo-icon"></span>
148
+ </span>
149
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
+ </div>
151
+ <div class="wcf-tab-wrapper">
152
+ <?php if ( 'other' !== $default_page_builder ) { ?>
153
+ <div id="wcf-get-started-steps">
154
+ <ul class="filter-links ">
155
+ <li>
156
+ <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>
157
+ </li>
158
+ <li>
159
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
+ </li>
161
+ </ul>
162
+ </div>
163
+ <?php } ?>
164
+ </div>
165
+ <div class="wcf-popup-close-wrap">
166
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
+ </div>
168
+ </div>
169
+
170
+ <!--<div class="wcf-search-form">
171
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
+ </div>-->
174
+
175
+ <div id="wcf-remote-content">
176
+ <?php if ( 'other' !== $default_page_builder ) { ?>
177
+ <div id="wcf-ready-templates">
178
+ <div id="wcf-remote-filters">
179
+ <div id="wcf-page-builders"></div>
180
+ <div id="wcf-categories"></div>
181
+ </div>
182
+ <div class="wcf-page-builder-notice"></div>
183
+ <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
+ </div>
186
+ <?php } ?>
187
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
+ <div class="inner">
189
+ <div id="wcf-scratch-steps-categories">
190
+ <select class="step-type-filter-links filter-links">
191
+ <option value="" class="current"> Select Step Type </option>
192
+
193
+ <?php foreach ( $steps as $key => $value ) { ?>
194
+ <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
+ <?php } ?>
196
+ </select>
197
+ </div>
198
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
+ <?php if ( ! _is_cartflows_pro() ) { ?>
200
+ <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
+ <?php } ?>
202
+ <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>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ </div><!-- .wcf-templates-popup-overlay -->
209
+ </div>
210
+ <?php
modules/optin/classes/class-cartflows-optin-meta.php CHANGED
@@ -1,675 +1,675 @@
1
- <?php
2
- /**
3
- * Checkout post meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Optin_Meta extends Cartflows_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option = null;
27
-
28
- /**
29
- * Initiator
30
- */
31
- public static function get_instance() {
32
- if ( ! isset( self::$instance ) ) {
33
- self::$instance = new self();
34
- }
35
-
36
- return self::$instance;
37
- }
38
-
39
- /**
40
- * Constructor
41
- */
42
- public function __construct() {
43
-
44
- /* Init Metabox */
45
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
46
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
47
- }
48
- /**
49
- * Init Metabox
50
- */
51
- public function init_metabox() {
52
-
53
- add_action( 'add_meta_boxes', array( $this, 'setup_meta_box' ) );
54
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
55
- }
56
-
57
- /**
58
- * Setup Metabox
59
- */
60
- public function setup_meta_box() {
61
-
62
- if ( _is_wcf_optin_type() ) {
63
- add_meta_box(
64
- 'wcf-optin-settings', // Id.
65
- __( 'Optin Settings', 'cartflows' ), // Title.
66
- array( $this, 'markup_meta_box' ), // Callback.
67
- wcf()->utils->get_step_post_type(), // Post_type.
68
- 'normal', // Context.
69
- 'high' // Priority.
70
- );
71
- }
72
- }
73
-
74
- /**
75
- * Metabox Markup
76
- *
77
- * @param object $post Post object.
78
- * @return void
79
- */
80
- public function markup_meta_box( $post ) {
81
-
82
- wp_nonce_field( 'save-nonce-optin-step-meta', 'nonce-optin-step-meta' );
83
-
84
- $stored = get_post_meta( $post->ID );
85
-
86
- $optin_meta = self::get_meta_option( $post->ID );
87
-
88
- // Set stored and override defaults.
89
- foreach ( $stored as $key => $value ) {
90
- if ( array_key_exists( $key, $optin_meta ) ) {
91
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
92
- } else {
93
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
94
- }
95
- }
96
-
97
- // Get defaults.
98
- $meta = self::get_meta_option( $post->ID );
99
- $optin_meta = array();
100
-
101
- foreach ( $meta as $key => $value ) {
102
- $optin_meta[ $key ] = $meta[ $key ]['default'];
103
- }
104
-
105
- do_action( 'wcf_optin_settings_markup_before' );
106
- $this->tabs_markup( $optin_meta, $post->ID );
107
- do_action( 'wcf_optin_settings_markup_after' );
108
- }
109
-
110
- /**
111
- * Page Header Tabs
112
- *
113
- * @param array $options options.
114
- * @param int $post_id post ID.
115
- */
116
- public function tabs_markup( $options, $post_id ) {
117
-
118
- $active_tab = get_post_meta( $post_id, 'wcf-active-tab', true );
119
-
120
- if ( empty( $active_tab ) ) {
121
- $active_tab = 'wcf-optin-shortcodes';
122
- }
123
-
124
- $tab_array = array(
125
- array(
126
- 'title' => __( 'Shortcodes', 'cartflows' ),
127
- 'id' => 'wcf-optin-shortcodes',
128
- 'class' => 'wcf-optin-shortcodes' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
129
- 'icon' => 'dashicons-editor-code',
130
- ),
131
- array(
132
- 'title' => __( 'Select Product', 'cartflows' ),
133
- 'id' => 'wcf-optin-general',
134
- 'class' => 'wcf-optin-general' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
135
- 'icon' => 'dashicons-info',
136
- ),
137
- array(
138
- 'title' => __( 'Design', 'cartflows' ),
139
- 'id' => 'wcf-optin-style',
140
- 'class' => 'wcf-optin-style' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
141
- 'icon' => 'dashicons-admin-customizer',
142
- ),
143
- array(
144
- 'title' => __( 'Form Fields', 'cartflows' ),
145
- 'id' => 'wcf-optin-custom-fields',
146
- 'class' => 'wcf-optin-custom-fields' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
147
- 'icon' => 'dashicons-welcome-widgets-menus',
148
- ),
149
- array(
150
- 'title' => __( 'Settings', 'cartflows' ),
151
- 'id' => 'wcf-optin-custom-settings',
152
- 'class' => 'wcf-optin-custom-settings' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
153
- 'icon' => 'dashicons-admin-generic',
154
- ),
155
- array(
156
- 'title' => __( 'Custom Script', 'cartflows' ),
157
- 'id' => 'wcf-optin-custom-script-header',
158
- 'class' => 'wcf-optin-custom-script-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
159
- 'icon' => 'dashicons-format-aside',
160
- ),
161
- );
162
-
163
- $tabs = $tab_array;
164
-
165
- ?>
166
- <div class="wcf-optin-table wcf-metabox-wrap widefat">
167
- <div class="wcf-table-container">
168
- <div class="wcf-column-left">
169
- <div class="wcf-tab-wrapper">
170
-
171
- <?php foreach ( $tabs as $key => $tab ) { ?>
172
- <div class="<?php echo esc_attr( $tab['class'] ); ?>" data-tab="<?php echo esc_attr( $tab['id'] ); ?>">
173
- <span class="dashicons <?php echo esc_attr( $tab['icon'] ); ?>"></span>
174
- <span class="wcf-tab-title"><?php echo esc_html( $tab['title'] ); ?></span>
175
- </div>
176
- <?php } ?>
177
-
178
- <input type="hidden" id="wcf-active-tab" name="wcf-active-tab" value="<?php echo esc_attr( $active_tab ); ?>" />
179
- </div>
180
- </div>
181
- <div class="wcf-column-right">
182
- <?php $this->tab_shortcodes( $options, $post_id ); ?>
183
- <?php $this->tab_general( $options, $post_id ); ?>
184
- <?php $this->tab_style( $options, $post_id ); ?>
185
- <?php $this->tab_custom_fields( $options, $post_id ); ?>
186
- <?php $this->tab_custom_settings( $options, $post_id ); ?>
187
- <?php $this->tab_custom_script( $options, $post_id ); ?>
188
- <?php $this->right_column_footer( $options, $post_id ); ?>
189
- </div>
190
- </div>
191
- </div>
192
-
193
- <?php
194
- }
195
-
196
- /**
197
- * Shortcodes tab
198
- *
199
- * @param array $options options.
200
- * @param int $post_id post ID.
201
- */
202
- public function tab_shortcodes( $options, $post_id ) {
203
- ?>
204
- <div class="wcf-optin-shortcodes wcf-tab-content widefat">
205
-
206
- <?php
207
-
208
- echo wcf()->meta->get_shortcode_field(
209
- array(
210
- 'label' => 'Optin Page',
211
- 'name' => 'wcf-optin-shortcode',
212
- 'content' => '[cartflows_optin]',
213
- 'help' => esc_html__( 'Add this shortcode to your optin page', 'cartflows' ),
214
- )
215
- );
216
- ?>
217
- </div>
218
- <?php
219
- }
220
-
221
-
222
- /**
223
- * General tab
224
- *
225
- * @param array $options options.
226
- * @param int $post_id post ID.
227
- */
228
- public function tab_general( $options, $post_id ) {
229
- ?>
230
- <div class="wcf-optin-general wcf-tab-content widefat">
231
-
232
- <?php
233
-
234
- echo wcf()->meta->get_product_selection_field(
235
- array(
236
- 'name' => 'wcf-optin-product',
237
- 'value' => $options['wcf-optin-product'],
238
- 'label' => __( 'Select Free Product', 'cartflows' ),
239
- 'help' => __( 'Select Free and Virtual product only.', 'cartflows' ),
240
- 'multiple' => false,
241
- 'allow_clear' => true,
242
- 'allowed_product_types' => array( 'simple' ),
243
- 'excluded_product_types' => array(),
244
- 'include_product_types' => array(),
245
- )
246
- );
247
-
248
- ?>
249
- </div>
250
- <?php
251
- }
252
-
253
- /**
254
- * Tab custom fields
255
- *
256
- * @param array $options options.
257
- * @param int $post_id post ID.
258
- */
259
- public function tab_custom_fields( $options, $post_id ) {
260
- ?>
261
- <div class="wcf-optin-custom-fields wcf-tab-content widefat">
262
- <?php
263
- /* Custom Checkout Fields Section */
264
-
265
- if ( ! _is_cartflows_pro() ) {
266
- echo wcf()->meta->get_description_field(
267
- array(
268
- 'name' => 'wcf-upgrade-to-pro',
269
- /* translators: %s: link */
270
- 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
271
- )
272
- );
273
- }
274
- ?>
275
- <?php do_action( 'cartflows_optin_custom_fields_tab_content', $options, $post_id ); ?>
276
- </div>
277
- <?php
278
- }
279
-
280
- /**
281
- * Tab custom settings
282
- *
283
- * @param array $options options.
284
- * @param int $post_id post ID.
285
- */
286
- public function tab_custom_settings( $options, $post_id ) {
287
- ?>
288
- <div class="wcf-optin-custom-settings wcf-tab-content widefat">
289
- <div class="wcf-custom-settings-fields">
290
- <?php
291
- echo wcf()->meta->get_checkbox_field(
292
- array(
293
- 'label' => __( 'Pass Fields as URL Parameters', 'cartflows' ),
294
- 'name' => 'wcf-optin-pass-fields',
295
- 'value' => $options['wcf-optin-pass-fields'],
296
- 'after' => __( 'Enable', 'cartflows' ),
297
- 'help' => __( 'You can pass specific fields from the form to next step as URL query parameters.', 'cartflows' ),
298
- 'toggle' => array(
299
- 'fields' => array(
300
- 'yes' => array( 'wcf-optin-pass-specific-fields' ),
301
- ),
302
- ),
303
- )
304
- );
305
-
306
- echo wcf()->meta->get_text_field(
307
- array(
308
- 'label' => __( 'Enter form field', 'cartflows' ),
309
- 'name' => 'wcf-optin-pass-specific-fields',
310
- 'value' => $options['wcf-optin-pass-specific-fields'],
311
- 'help' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
312
- 'attr' => array(
313
- 'placeholder' => __( 'Fields to pass, separated by commas', 'cartflows' ),
314
- ),
315
- )
316
- );
317
-
318
- echo wcf()->meta->get_description_field(
319
- array(
320
- 'name' => 'wcf-optin-pass-fields-doc',
321
- 'content' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
322
- /* translators: %s: link */
323
- 'content' => sprintf( esc_html__( 'You can pass field value as a URL parameter to the next step. %1$sClick here%2$s for more information.', 'cartflows' ), '<a href="https://cartflows.com/docs/pass-variable-as-query-parameters-to-url/" target="_blank">', '</a>' ),
324
- )
325
- );
326
-
327
- ?>
328
- </div>
329
- </div>
330
- <?php
331
- }
332
-
333
- /**
334
- * Tab style
335
- *
336
- * @param array $options options.
337
- * @param int $post_id post ID.
338
- */
339
- public function tab_style( $options, $post_id ) {
340
- ?>
341
-
342
- <div class="wcf-optin-style wcf-tab-content widefat">
343
- <?php
344
- echo wcf()->meta->get_color_picker_field(
345
- array(
346
- 'label' => __( 'Primary Color', 'cartflows' ),
347
- 'name' => 'wcf-primary-color',
348
- 'value' => $options['wcf-primary-color'],
349
- )
350
- );
351
-
352
- echo wcf()->meta->get_font_family_field(
353
- array(
354
- 'for' => 'wcf-base',
355
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
356
- 'name' => 'wcf-base-font-family',
357
- 'value' => $options['wcf-base-font-family'],
358
- )
359
- );
360
- ?>
361
- <div class="wcf-cs-fields">
362
- <div class="wcf-cs-fields-options">
363
- <?php
364
- echo wcf()->meta->get_section(
365
- array(
366
- 'label' => __( 'Input Fields', 'cartflows' ),
367
- )
368
- );
369
-
370
- $fields_skin_pro_option = array();
371
- if ( ! _is_cartflows_pro() ) {
372
- $fields_skin_pro_option = array(
373
- 'floating-labels' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
374
- );
375
- }
376
-
377
- echo wcf()->meta->get_select_field(
378
- array(
379
- 'label' => __( 'Style', 'cartflows' ),
380
- 'name' => 'wcf-input-fields-skins',
381
- 'value' => $options['wcf-input-fields-skins'],
382
- 'options' => array(
383
- 'default' => esc_html__( 'Default', 'cartflows' ),
384
- 'floating-labels' => esc_html__( 'Floating Labels', 'cartflows' ),
385
- ),
386
- 'pro-options' => $fields_skin_pro_option,
387
-
388
- )
389
- );
390
-
391
- echo wcf()->meta->get_font_family_field(
392
- array(
393
- 'for' => 'wcf-input',
394
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
395
- 'name' => 'wcf-input-font-family',
396
- 'value' => $options['wcf-input-font-family'],
397
- )
398
- );
399
-
400
- echo wcf()->meta->get_font_weight_field(
401
- array(
402
- 'for' => 'wcf-input',
403
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
404
- 'name' => 'wcf-input-font-weight',
405
- 'value' => $options['wcf-input-font-weight'],
406
- )
407
- );
408
-
409
- echo wcf()->meta->get_select_field(
410
- array(
411
- 'label' => __( 'Size', 'cartflows' ),
412
- 'name' => 'wcf-input-field-size',
413
- 'value' => $options['wcf-input-field-size'],
414
- 'options' => array(
415
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
416
- '38px' => esc_html__( 'Small', 'cartflows' ),
417
- '44px' => esc_html__( 'Medium', 'cartflows' ),
418
- '58px' => esc_html__( 'Large', 'cartflows' ),
419
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
420
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
421
- ),
422
- )
423
- );
424
-
425
- echo wcf()->meta->get_number_field(
426
- array(
427
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
428
- 'name' => 'wcf-field-tb-padding',
429
- 'value' => $options['wcf-field-tb-padding'],
430
- )
431
- );
432
-
433
- echo wcf()->meta->get_number_field(
434
- array(
435
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
436
- 'name' => 'wcf-field-lr-padding',
437
- 'value' => $options['wcf-field-lr-padding'],
438
- )
439
- );
440
-
441
- echo wcf()->meta->get_color_picker_field(
442
- array(
443
- 'label' => __( 'Label Color', 'cartflows' ),
444
- 'name' => 'wcf-field-label-color',
445
- 'value' => $options['wcf-field-label-color'],
446
- )
447
- );
448
-
449
- echo wcf()->meta->get_color_picker_field(
450
- array(
451
- 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
452
- 'name' => 'wcf-field-color',
453
- 'value' => $options['wcf-field-color'],
454
- )
455
- );
456
-
457
- echo wcf()->meta->get_color_picker_field(
458
- array(
459
- 'label' => __( 'Background Color', 'cartflows' ),
460
- 'name' => 'wcf-field-bg-color',
461
- 'value' => $options['wcf-field-bg-color'],
462
- )
463
- );
464
-
465
- echo wcf()->meta->get_color_picker_field(
466
- array(
467
- 'label' => __( 'Border Color', 'cartflows' ),
468
- 'name' => 'wcf-field-border-color',
469
- 'value' => $options['wcf-field-border-color'],
470
- )
471
- );
472
-
473
- ?>
474
- </div>
475
- <div class="wcf-cs-button-options">
476
- <?php
477
-
478
- echo wcf()->meta->get_section(
479
- array(
480
- 'label' => __( 'Submit Button', 'cartflows' ),
481
- )
482
- );
483
-
484
- echo wcf()->meta->get_text_field(
485
- array(
486
- 'label' => __( 'Button Text', 'cartflows' ),
487
- 'name' => 'wcf-submit-button-text',
488
- 'value' => $options['wcf-submit-button-text'],
489
- 'attr' => array(
490
- 'placeholder' => __( 'Submit', 'cartflows' ),
491
- ),
492
- )
493
- );
494
-
495
- echo wcf()->meta->get_number_field(
496
- array(
497
- 'label' => __( 'Font Size', 'cartflows' ),
498
- 'name' => 'wcf-submit-font-size',
499
- 'value' => $options['wcf-submit-font-size'],
500
- )
501
- );
502
-
503
- echo wcf()->meta->get_font_family_field(
504
- array(
505
- 'for' => 'wcf-button',
506
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
507
- 'name' => 'wcf-button-font-family',
508
- 'value' => $options['wcf-button-font-family'],
509
- )
510
- );
511
-
512
- echo wcf()->meta->get_font_weight_field(
513
- array(
514
- 'for' => 'wcf-button',
515
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
516
- 'name' => 'wcf-button-font-weight',
517
- 'value' => $options['wcf-button-font-weight'],
518
- )
519
- );
520
-
521
- echo wcf()->meta->get_select_field(
522
- array(
523
- 'label' => __( 'Size', 'cartflows' ),
524
- 'name' => 'wcf-submit-button-size',
525
- 'value' => $options['wcf-submit-button-size'],
526
- 'options' => array(
527
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
528
- '38px' => esc_html__( 'Small', 'cartflows' ),
529
- '44px' => esc_html__( 'Medium', 'cartflows' ),
530
- '58px' => esc_html__( 'Large', 'cartflows' ),
531
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
532
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
533
- ),
534
- )
535
- );
536
-
537
- echo wcf()->meta->get_number_field(
538
- array(
539
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
540
- 'name' => 'wcf-submit-tb-padding',
541
- 'value' => $options['wcf-submit-tb-padding'],
542
- )
543
- );
544
-
545
- echo wcf()->meta->get_number_field(
546
- array(
547
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
548
- 'name' => 'wcf-submit-lr-padding',
549
- 'value' => $options['wcf-submit-lr-padding'],
550
- )
551
- );
552
-
553
- echo wcf()->meta->get_select_field(
554
- array(
555
- 'label' => __( 'Position', 'cartflows' ),
556
- 'name' => 'wcf-submit-button-position',
557
- 'value' => $options['wcf-submit-button-position'],
558
- 'options' => array(
559
- 'left' => esc_html__( 'Left', 'cartflows' ),
560
- 'center' => esc_html__( 'Center', 'cartflows' ),
561
- 'right' => esc_html__( 'Right', 'cartflows' ),
562
- ),
563
- )
564
- );
565
-
566
- echo wcf()->meta->get_color_picker_field(
567
- array(
568
- 'label' => __( 'Text Color', 'cartflows' ),
569
- 'name' => 'wcf-submit-color',
570
- 'value' => $options['wcf-submit-color'],
571
- )
572
- );
573
-
574
- echo wcf()->meta->get_color_picker_field(
575
- array(
576
- 'label' => __( 'Text Hover Color', 'cartflows' ),
577
- 'name' => 'wcf-submit-hover-color',
578
- 'value' => $options['wcf-submit-hover-color'],
579
- )
580
- );
581
-
582
- echo wcf()->meta->get_color_picker_field(
583
- array(
584
- 'label' => __( 'Background Color', 'cartflows' ),
585
- 'name' => 'wcf-submit-bg-color',
586
- 'value' => $options['wcf-submit-bg-color'],
587
- )
588
- );
589
-
590
- echo wcf()->meta->get_color_picker_field(
591
- array(
592
- 'label' => __( 'Background Hover Color', 'cartflows' ),
593
- 'name' => 'wcf-submit-bg-hover-color',
594
- 'value' => $options['wcf-submit-bg-hover-color'],
595
- )
596
- );
597
-
598
- echo wcf()->meta->get_color_picker_field(
599
- array(
600
- 'label' => __( 'Border Color', 'cartflows' ),
601
- 'name' => 'wcf-submit-border-color',
602
- 'value' => $options['wcf-submit-border-color'],
603
- )
604
- );
605
-
606
- echo wcf()->meta->get_color_picker_field(
607
- array(
608
- 'label' => __( 'Border Hover Color', 'cartflows' ),
609
- 'name' => 'wcf-submit-border-hover-color',
610
- 'value' => $options['wcf-submit-border-hover-color'],
611
- )
612
- );
613
-
614
- ?>
615
- </div>
616
- </div>
617
- <?php
618
- echo wcf()->meta->get_hidden_field(
619
- array(
620
- 'name' => 'wcf-field-google-font-url',
621
- 'value' => $options['wcf-field-google-font-url'],
622
- )
623
- );
624
- ?>
625
- </div>
626
- <?php
627
- }
628
-
629
- /**
630
- * Get metabox options
631
- *
632
- * @param int $post_id post ID.
633
- */
634
- public static function get_meta_option( $post_id ) {
635
-
636
- if ( null === self::$meta_option ) {
637
-
638
- /**
639
- * Set metabox options
640
- *
641
- * @see http://php.net/manual/en/filter.filters.sanitize.php
642
- */
643
- self::$meta_option = wcf()->options->get_optin_fields( $post_id );
644
- }
645
-
646
- return self::$meta_option;
647
- }
648
-
649
- /**
650
- * Metabox Save
651
- *
652
- * @param number $post_id Post ID.
653
- * @return void
654
- */
655
- public function save_meta_box( $post_id ) {
656
-
657
- // Checks save status.
658
- $is_autosave = wp_is_post_autosave( $post_id );
659
- $is_revision = wp_is_post_revision( $post_id );
660
-
661
- $is_valid_nonce = ( isset( $_POST['nonce-optin-step-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-optin-step-meta'] ) ), 'save-nonce-optin-step-meta' ) ) ? true : false;
662
-
663
- // Exits script depending on save status.
664
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
- return;
666
- }
667
-
668
- wcf()->options->save_optin_fields( $post_id );
669
- }
670
- }
671
-
672
- /**
673
- * Kicking this off by calling 'get_instance()' method
674
- */
675
- Cartflows_Optin_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Checkout post meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Optin_Meta extends Cartflows_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option = null;
27
+
28
+ /**
29
+ * Initiator
30
+ */
31
+ public static function get_instance() {
32
+ if ( ! isset( self::$instance ) ) {
33
+ self::$instance = new self();
34
+ }
35
+
36
+ return self::$instance;
37
+ }
38
+
39
+ /**
40
+ * Constructor
41
+ */
42
+ public function __construct() {
43
+
44
+ /* Init Metabox */
45
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
46
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
47
+ }
48
+ /**
49
+ * Init Metabox
50
+ */
51
+ public function init_metabox() {
52
+
53
+ add_action( 'add_meta_boxes', array( $this, 'setup_meta_box' ) );
54
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
55
+ }
56
+
57
+ /**
58
+ * Setup Metabox
59
+ */
60
+ public function setup_meta_box() {
61
+
62
+ if ( _is_wcf_optin_type() ) {
63
+ add_meta_box(
64
+ 'wcf-optin-settings', // Id.
65
+ __( 'Optin Settings', 'cartflows' ), // Title.
66
+ array( $this, 'markup_meta_box' ), // Callback.
67
+ wcf()->utils->get_step_post_type(), // Post_type.
68
+ 'normal', // Context.
69
+ 'high' // Priority.
70
+ );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Metabox Markup
76
+ *
77
+ * @param object $post Post object.
78
+ * @return void
79
+ */
80
+ public function markup_meta_box( $post ) {
81
+
82
+ wp_nonce_field( 'save-nonce-optin-step-meta', 'nonce-optin-step-meta' );
83
+
84
+ $stored = get_post_meta( $post->ID );
85
+
86
+ $optin_meta = self::get_meta_option( $post->ID );
87
+
88
+ // Set stored and override defaults.
89
+ foreach ( $stored as $key => $value ) {
90
+ if ( array_key_exists( $key, $optin_meta ) ) {
91
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
92
+ } else {
93
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
94
+ }
95
+ }
96
+
97
+ // Get defaults.
98
+ $meta = self::get_meta_option( $post->ID );
99
+ $optin_meta = array();
100
+
101
+ foreach ( $meta as $key => $value ) {
102
+ $optin_meta[ $key ] = $meta[ $key ]['default'];
103
+ }
104
+
105
+ do_action( 'wcf_optin_settings_markup_before' );
106
+ $this->tabs_markup( $optin_meta, $post->ID );
107
+ do_action( 'wcf_optin_settings_markup_after' );
108
+ }
109
+
110
+ /**
111
+ * Page Header Tabs
112
+ *
113
+ * @param array $options options.
114
+ * @param int $post_id post ID.
115
+ */
116
+ public function tabs_markup( $options, $post_id ) {
117
+
118
+ $active_tab = get_post_meta( $post_id, 'wcf-active-tab', true );
119
+
120
+ if ( empty( $active_tab ) ) {
121
+ $active_tab = 'wcf-optin-shortcodes';
122
+ }
123
+
124
+ $tab_array = array(
125
+ array(
126
+ 'title' => __( 'Shortcodes', 'cartflows' ),
127
+ 'id' => 'wcf-optin-shortcodes',
128
+ 'class' => 'wcf-optin-shortcodes' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
129
+ 'icon' => 'dashicons-editor-code',
130
+ ),
131
+ array(
132
+ 'title' => __( 'Select Product', 'cartflows' ),
133
+ 'id' => 'wcf-optin-general',
134
+ 'class' => 'wcf-optin-general' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
135
+ 'icon' => 'dashicons-info',
136
+ ),
137
+ array(
138
+ 'title' => __( 'Design', 'cartflows' ),
139
+ 'id' => 'wcf-optin-style',
140
+ 'class' => 'wcf-optin-style' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
141
+ 'icon' => 'dashicons-admin-customizer',
142
+ ),
143
+ array(
144
+ 'title' => __( 'Form Fields', 'cartflows' ),
145
+ 'id' => 'wcf-optin-custom-fields',
146
+ 'class' => 'wcf-optin-custom-fields' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
147
+ 'icon' => 'dashicons-welcome-widgets-menus',
148
+ ),
149
+ array(
150
+ 'title' => __( 'Settings', 'cartflows' ),
151
+ 'id' => 'wcf-optin-custom-settings',
152
+ 'class' => 'wcf-optin-custom-settings' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
153
+ 'icon' => 'dashicons-admin-generic',
154
+ ),
155
+ array(
156
+ 'title' => __( 'Custom Script', 'cartflows' ),
157
+ 'id' => 'wcf-optin-custom-script-header',
158
+ 'class' => 'wcf-optin-custom-script-header' === $active_tab ? 'wcf-tab wp-ui-text-highlight active' : 'wcf-tab',
159
+ 'icon' => 'dashicons-format-aside',
160
+ ),
161
+ );
162
+
163
+ $tabs = $tab_array;
164
+
165
+ ?>
166
+ <div class="wcf-optin-table wcf-metabox-wrap widefat">
167
+ <div class="wcf-table-container">
168
+ <div class="wcf-column-left">
169
+ <div class="wcf-tab-wrapper">
170
+
171
+ <?php foreach ( $tabs as $key => $tab ) { ?>
172
+ <div class="<?php echo esc_attr( $tab['class'] ); ?>" data-tab="<?php echo esc_attr( $tab['id'] ); ?>">
173
+ <span class="dashicons <?php echo esc_attr( $tab['icon'] ); ?>"></span>
174
+ <span class="wcf-tab-title"><?php echo esc_html( $tab['title'] ); ?></span>
175
+ </div>
176
+ <?php } ?>
177
+
178
+ <input type="hidden" id="wcf-active-tab" name="wcf-active-tab" value="<?php echo esc_attr( $active_tab ); ?>" />
179
+ </div>
180
+ </div>
181
+ <div class="wcf-column-right">
182
+ <?php $this->tab_shortcodes( $options, $post_id ); ?>
183
+ <?php $this->tab_general( $options, $post_id ); ?>
184
+ <?php $this->tab_style( $options, $post_id ); ?>
185
+ <?php $this->tab_custom_fields( $options, $post_id ); ?>
186
+ <?php $this->tab_custom_settings( $options, $post_id ); ?>
187
+ <?php $this->tab_custom_script( $options, $post_id ); ?>
188
+ <?php $this->right_column_footer( $options, $post_id ); ?>
189
+ </div>
190
+ </div>
191
+ </div>
192
+
193
+ <?php
194
+ }
195
+
196
+ /**
197
+ * Shortcodes tab
198
+ *
199
+ * @param array $options options.
200
+ * @param int $post_id post ID.
201
+ */
202
+ public function tab_shortcodes( $options, $post_id ) {
203
+ ?>
204
+ <div class="wcf-optin-shortcodes wcf-tab-content widefat">
205
+
206
+ <?php
207
+
208
+ echo wcf()->meta->get_shortcode_field(
209
+ array(
210
+ 'label' => 'Optin Page',
211
+ 'name' => 'wcf-optin-shortcode',
212
+ 'content' => '[cartflows_optin]',
213
+ 'help' => esc_html__( 'Add this shortcode to your optin page', 'cartflows' ),
214
+ )
215
+ );
216
+ ?>
217
+ </div>
218
+ <?php
219
+ }
220
+
221
+
222
+ /**
223
+ * General tab
224
+ *
225
+ * @param array $options options.
226
+ * @param int $post_id post ID.
227
+ */
228
+ public function tab_general( $options, $post_id ) {
229
+ ?>
230
+ <div class="wcf-optin-general wcf-tab-content widefat">
231
+
232
+ <?php
233
+
234
+ echo wcf()->meta->get_product_selection_field(
235
+ array(
236
+ 'name' => 'wcf-optin-product',
237
+ 'value' => $options['wcf-optin-product'],
238
+ 'label' => __( 'Select Free Product', 'cartflows' ),
239
+ 'help' => __( 'Select Free and Virtual product only.', 'cartflows' ),
240
+ 'multiple' => false,
241
+ 'allow_clear' => true,
242
+ 'allowed_product_types' => array( 'simple' ),
243
+ 'excluded_product_types' => array(),
244
+ 'include_product_types' => array(),
245
+ )
246
+ );
247
+
248
+ ?>
249
+ </div>
250
+ <?php
251
+ }
252
+
253
+ /**
254
+ * Tab custom fields
255
+ *
256
+ * @param array $options options.
257
+ * @param int $post_id post ID.
258
+ */
259
+ public function tab_custom_fields( $options, $post_id ) {
260
+ ?>
261
+ <div class="wcf-optin-custom-fields wcf-tab-content widefat">
262
+ <?php
263
+ /* Custom Checkout Fields Section */
264
+
265
+ if ( ! _is_cartflows_pro() ) {
266
+ echo wcf()->meta->get_description_field(
267
+ array(
268
+ 'name' => 'wcf-upgrade-to-pro',
269
+ /* translators: %s: link */
270
+ 'content' => '<i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature.', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i>',
271
+ )
272
+ );
273
+ }
274
+ ?>
275
+ <?php do_action( 'cartflows_optin_custom_fields_tab_content', $options, $post_id ); ?>
276
+ </div>
277
+ <?php
278
+ }
279
+
280
+ /**
281
+ * Tab custom settings
282
+ *
283
+ * @param array $options options.
284
+ * @param int $post_id post ID.
285
+ */
286
+ public function tab_custom_settings( $options, $post_id ) {
287
+ ?>
288
+ <div class="wcf-optin-custom-settings wcf-tab-content widefat">
289
+ <div class="wcf-custom-settings-fields">
290
+ <?php
291
+ echo wcf()->meta->get_checkbox_field(
292
+ array(
293
+ 'label' => __( 'Pass Fields as URL Parameters', 'cartflows' ),
294
+ 'name' => 'wcf-optin-pass-fields',
295
+ 'value' => $options['wcf-optin-pass-fields'],
296
+ 'after' => __( 'Enable', 'cartflows' ),
297
+ 'help' => __( 'You can pass specific fields from the form to next step as URL query parameters.', 'cartflows' ),
298
+ 'toggle' => array(
299
+ 'fields' => array(
300
+ 'yes' => array( 'wcf-optin-pass-specific-fields' ),
301
+ ),
302
+ ),
303
+ )
304
+ );
305
+
306
+ echo wcf()->meta->get_text_field(
307
+ array(
308
+ 'label' => __( 'Enter form field', 'cartflows' ),
309
+ 'name' => 'wcf-optin-pass-specific-fields',
310
+ 'value' => $options['wcf-optin-pass-specific-fields'],
311
+ 'help' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
312
+ 'attr' => array(
313
+ 'placeholder' => __( 'Fields to pass, separated by commas', 'cartflows' ),
314
+ ),
315
+ )
316
+ );
317
+
318
+ echo wcf()->meta->get_description_field(
319
+ array(
320
+ 'name' => 'wcf-optin-pass-fields-doc',
321
+ 'content' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
322
+ /* translators: %s: link */
323
+ 'content' => sprintf( esc_html__( 'You can pass field value as a URL parameter to the next step. %1$sClick here%2$s for more information.', 'cartflows' ), '<a href="https://cartflows.com/docs/pass-variable-as-query-parameters-to-url/" target="_blank">', '</a>' ),
324
+ )
325
+ );
326
+
327
+ ?>
328
+ </div>
329
+ </div>
330
+ <?php
331
+ }
332
+
333
+ /**
334
+ * Tab style
335
+ *
336
+ * @param array $options options.
337
+ * @param int $post_id post ID.
338
+ */
339
+ public function tab_style( $options, $post_id ) {
340
+ ?>
341
+
342
+ <div class="wcf-optin-style wcf-tab-content widefat">
343
+ <?php
344
+ echo wcf()->meta->get_color_picker_field(
345
+ array(
346
+ 'label' => __( 'Primary Color', 'cartflows' ),
347
+ 'name' => 'wcf-primary-color',
348
+ 'value' => $options['wcf-primary-color'],
349
+ )
350
+ );
351
+
352
+ echo wcf()->meta->get_font_family_field(
353
+ array(
354
+ 'for' => 'wcf-base',
355
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
356
+ 'name' => 'wcf-base-font-family',
357
+ 'value' => $options['wcf-base-font-family'],
358
+ )
359
+ );
360
+ ?>
361
+ <div class="wcf-cs-fields">
362
+ <div class="wcf-cs-fields-options">
363
+ <?php
364
+ echo wcf()->meta->get_section(
365
+ array(
366
+ 'label' => __( 'Input Fields', 'cartflows' ),
367
+ )
368
+ );
369
+
370
+ $fields_skin_pro_option = array();
371
+ if ( ! _is_cartflows_pro() ) {
372
+ $fields_skin_pro_option = array(
373
+ 'floating-labels' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
374
+ );
375
+ }
376
+
377
+ echo wcf()->meta->get_select_field(
378
+ array(
379
+ 'label' => __( 'Style', 'cartflows' ),
380
+ 'name' => 'wcf-input-fields-skins',
381
+ 'value' => $options['wcf-input-fields-skins'],
382
+ 'options' => array(
383
+ 'default' => esc_html__( 'Default', 'cartflows' ),
384
+ 'floating-labels' => esc_html__( 'Floating Labels', 'cartflows' ),
385
+ ),
386
+ 'pro-options' => $fields_skin_pro_option,
387
+
388
+ )
389
+ );
390
+
391
+ echo wcf()->meta->get_font_family_field(
392
+ array(
393
+ 'for' => 'wcf-input',
394
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
395
+ 'name' => 'wcf-input-font-family',
396
+ 'value' => $options['wcf-input-font-family'],
397
+ )
398
+ );
399
+
400
+ echo wcf()->meta->get_font_weight_field(
401
+ array(
402
+ 'for' => 'wcf-input',
403
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
404
+ 'name' => 'wcf-input-font-weight',
405
+ 'value' => $options['wcf-input-font-weight'],
406
+ )
407
+ );
408
+
409
+ echo wcf()->meta->get_select_field(
410
+ array(
411
+ 'label' => __( 'Size', 'cartflows' ),
412
+ 'name' => 'wcf-input-field-size',
413
+ 'value' => $options['wcf-input-field-size'],
414
+ 'options' => array(
415
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
416
+ '38px' => esc_html__( 'Small', 'cartflows' ),
417
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
418
+ '58px' => esc_html__( 'Large', 'cartflows' ),
419
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
420
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
421
+ ),
422
+ )
423
+ );
424
+
425
+ echo wcf()->meta->get_number_field(
426
+ array(
427
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
428
+ 'name' => 'wcf-field-tb-padding',
429
+ 'value' => $options['wcf-field-tb-padding'],
430
+ )
431
+ );
432
+
433
+ echo wcf()->meta->get_number_field(
434
+ array(
435
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
436
+ 'name' => 'wcf-field-lr-padding',
437
+ 'value' => $options['wcf-field-lr-padding'],
438
+ )
439
+ );
440
+
441
+ echo wcf()->meta->get_color_picker_field(
442
+ array(
443
+ 'label' => __( 'Label Color', 'cartflows' ),
444
+ 'name' => 'wcf-field-label-color',
445
+ 'value' => $options['wcf-field-label-color'],
446
+ )
447
+ );
448
+
449
+ echo wcf()->meta->get_color_picker_field(
450
+ array(
451
+ 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
452
+ 'name' => 'wcf-field-color',
453
+ 'value' => $options['wcf-field-color'],
454
+ )
455
+ );
456
+
457
+ echo wcf()->meta->get_color_picker_field(
458
+ array(
459
+ 'label' => __( 'Background Color', 'cartflows' ),
460
+ 'name' => 'wcf-field-bg-color',
461
+ 'value' => $options['wcf-field-bg-color'],
462
+ )
463
+ );
464
+
465
+ echo wcf()->meta->get_color_picker_field(
466
+ array(
467
+ 'label' => __( 'Border Color', 'cartflows' ),
468
+ 'name' => 'wcf-field-border-color',
469
+ 'value' => $options['wcf-field-border-color'],
470
+ )
471
+ );
472
+
473
+ ?>
474
+ </div>
475
+ <div class="wcf-cs-button-options">
476
+ <?php
477
+
478
+ echo wcf()->meta->get_section(
479
+ array(
480
+ 'label' => __( 'Submit Button', 'cartflows' ),
481
+ )
482
+ );
483
+
484
+ echo wcf()->meta->get_text_field(
485
+ array(
486
+ 'label' => __( 'Button Text', 'cartflows' ),
487
+ 'name' => 'wcf-submit-button-text',
488
+ 'value' => $options['wcf-submit-button-text'],
489
+ 'attr' => array(
490
+ 'placeholder' => __( 'Submit', 'cartflows' ),
491
+ ),
492
+ )
493
+ );
494
+
495
+ echo wcf()->meta->get_number_field(
496
+ array(
497
+ 'label' => __( 'Font Size', 'cartflows' ),
498
+ 'name' => 'wcf-submit-font-size',
499
+ 'value' => $options['wcf-submit-font-size'],
500
+ )
501
+ );
502
+
503
+ echo wcf()->meta->get_font_family_field(
504
+ array(
505
+ 'for' => 'wcf-button',
506
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
507
+ 'name' => 'wcf-button-font-family',
508
+ 'value' => $options['wcf-button-font-family'],
509
+ )
510
+ );
511
+
512
+ echo wcf()->meta->get_font_weight_field(
513
+ array(
514
+ 'for' => 'wcf-button',
515
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
516
+ 'name' => 'wcf-button-font-weight',
517
+ 'value' => $options['wcf-button-font-weight'],
518
+ )
519
+ );
520
+
521
+ echo wcf()->meta->get_select_field(
522
+ array(
523
+ 'label' => __( 'Size', 'cartflows' ),
524
+ 'name' => 'wcf-submit-button-size',
525
+ 'value' => $options['wcf-submit-button-size'],
526
+ 'options' => array(
527
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
528
+ '38px' => esc_html__( 'Small', 'cartflows' ),
529
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
530
+ '58px' => esc_html__( 'Large', 'cartflows' ),
531
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
532
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
533
+ ),
534
+ )
535
+ );
536
+
537
+ echo wcf()->meta->get_number_field(
538
+ array(
539
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
540
+ 'name' => 'wcf-submit-tb-padding',
541
+ 'value' => $options['wcf-submit-tb-padding'],
542
+ )
543
+ );
544
+
545
+ echo wcf()->meta->get_number_field(
546
+ array(
547
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
548
+ 'name' => 'wcf-submit-lr-padding',
549
+ 'value' => $options['wcf-submit-lr-padding'],
550
+ )
551
+ );
552
+
553
+ echo wcf()->meta->get_select_field(
554
+ array(
555
+ 'label' => __( 'Position', 'cartflows' ),
556
+ 'name' => 'wcf-submit-button-position',
557
+ 'value' => $options['wcf-submit-button-position'],
558
+ 'options' => array(
559
+ 'left' => esc_html__( 'Left', 'cartflows' ),
560
+ 'center' => esc_html__( 'Center', 'cartflows' ),
561
+ 'right' => esc_html__( 'Right', 'cartflows' ),
562
+ ),
563
+ )
564
+ );
565
+
566
+ echo wcf()->meta->get_color_picker_field(
567
+ array(
568
+ 'label' => __( 'Text Color', 'cartflows' ),
569
+ 'name' => 'wcf-submit-color',
570
+ 'value' => $options['wcf-submit-color'],
571
+ )
572
+ );
573
+
574
+ echo wcf()->meta->get_color_picker_field(
575
+ array(
576
+ 'label' => __( 'Text Hover Color', 'cartflows' ),
577
+ 'name' => 'wcf-submit-hover-color',
578
+ 'value' => $options['wcf-submit-hover-color'],
579
+ )
580
+ );
581
+
582
+ echo wcf()->meta->get_color_picker_field(
583
+ array(
584
+ 'label' => __( 'Background Color', 'cartflows' ),
585
+ 'name' => 'wcf-submit-bg-color',
586
+ 'value' => $options['wcf-submit-bg-color'],
587
+ )
588
+ );
589
+
590
+ echo wcf()->meta->get_color_picker_field(
591
+ array(
592
+ 'label' => __( 'Background Hover Color', 'cartflows' ),
593
+ 'name' => 'wcf-submit-bg-hover-color',
594
+ 'value' => $options['wcf-submit-bg-hover-color'],
595
+ )
596
+ );
597
+
598
+ echo wcf()->meta->get_color_picker_field(
599
+ array(
600
+ 'label' => __( 'Border Color', 'cartflows' ),
601
+ 'name' => 'wcf-submit-border-color',
602
+ 'value' => $options['wcf-submit-border-color'],
603
+ )
604
+ );
605
+
606
+ echo wcf()->meta->get_color_picker_field(
607
+ array(
608
+ 'label' => __( 'Border Hover Color', 'cartflows' ),
609
+ 'name' => 'wcf-submit-border-hover-color',
610
+ 'value' => $options['wcf-submit-border-hover-color'],
611
+ )
612
+ );
613
+
614
+ ?>
615
+ </div>
616
+ </div>
617
+ <?php
618
+ echo wcf()->meta->get_hidden_field(
619
+ array(
620
+ 'name' => 'wcf-field-google-font-url',
621
+ 'value' => $options['wcf-field-google-font-url'],
622
+ )
623
+ );
624
+ ?>
625
+ </div>
626
+ <?php
627
+ }
628
+
629
+ /**
630
+ * Get metabox options
631
+ *
632
+ * @param int $post_id post ID.
633
+ */
634
+ public static function get_meta_option( $post_id ) {
635
+
636
+ if ( null === self::$meta_option ) {
637
+
638
+ /**
639
+ * Set metabox options
640
+ *
641
+ * @see http://php.net/manual/en/filter.filters.sanitize.php
642
+ */
643
+ self::$meta_option = wcf()->options->get_optin_fields( $post_id );
644
+ }
645
+
646
+ return self::$meta_option;
647
+ }
648
+
649
+ /**
650
+ * Metabox Save
651
+ *
652
+ * @param number $post_id Post ID.
653
+ * @return void
654
+ */
655
+ public function save_meta_box( $post_id ) {
656
+
657
+ // Checks save status.
658
+ $is_autosave = wp_is_post_autosave( $post_id );
659
+ $is_revision = wp_is_post_revision( $post_id );
660
+
661
+ $is_valid_nonce = ( isset( $_POST['nonce-optin-step-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-optin-step-meta'] ) ), 'save-nonce-optin-step-meta' ) ) ? true : false;
662
+
663
+ // Exits script depending on save status.
664
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
+ return;
666
+ }
667
+
668
+ wcf()->options->save_optin_fields( $post_id );
669
+ }
670
+ }
671
+
672
+ /**
673
+ * Kicking this off by calling 'get_instance()' method
674
+ */
675
+ Cartflows_Optin_Meta::get_instance();
modules/thankyou/includes/thankyou-dynamic-css.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
- /**
3
- * Dynamic Thank you css.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $output = "
9
-
10
- .wcf-thankyou-wrap{
11
- color: {$text_color};
12
- font-family: {$text_font_family};
13
- max-width:{$container_width}px;
14
- font-size: {$text_font_size}px;
15
- }
16
-
17
- .woocommerce-order h2.woocommerce-column__title,
18
- .woocommerce-order h2.woocommerce-order-details__title,
19
- .woocommerce-order .woocommerce-thankyou-order-received,
20
- .woocommerce-order-details h2,
21
- .woocommerce-order h2.wc-bacs-bank-details-heading,
22
- .woocommerce-order h2.woocommerce-order-downloads__title {
23
- color: {$heading_text_color};
24
- font-family: {$heading_font_family};
25
- font-weight: {$heading_font_weight};
26
- }
27
-
28
- .woocommerce-order ul.order_details,
29
- .woocommerce-order .woocommerce-order-details,
30
- .woocommerce-order .woocommerce-customer-details,
31
- .woocommerce-order .woocommerce-bacs-bank-details,
32
- .woocommerce-order .woocommerce-order-downloads{
33
- background-color: {$section_bg_color}
34
- }
35
- img.emoji, img.wp-smiley {}
36
- ";
37
-
38
- if ( 'no' == $show_order_review ) {
39
- $output .= '
40
- .woocommerce-order ul.order_details{
41
- display: none;
42
- }
43
- ';
44
- }
45
-
46
- if ( 'no' == $show_order_details ) {
47
- $output .= '
48
- .woocommerce-order .woocommerce-order-details{
49
- display: none;
50
- }
51
- ';
52
- }
53
-
54
- if ( 'no' == $show_billing_details ) {
55
- $output .= '
56
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
- display: none;
58
- }
59
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
- float:left;
61
- }
62
- ';
63
- }
64
-
65
- if ( 'no' == $show_shipping_details ) {
66
- $output .= '
67
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
68
- display: none;
69
- }
70
- ';
71
- }
72
-
73
- if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
74
- $output .= '
75
- .woocommerce-order .woocommerce-customer-details{
76
- display: none;
77
- }
78
- ';
79
- }
1
+ <?php
2
+ /**
3
+ * Dynamic Thank you css.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $output = "
9
+
10
+ .wcf-thankyou-wrap{
11
+ color: {$text_color};
12
+ font-family: {$text_font_family};
13
+ max-width:{$container_width}px;
14
+ font-size: {$text_font_size}px;
15
+ }
16
+
17
+ .woocommerce-order h2.woocommerce-column__title,
18
+ .woocommerce-order h2.woocommerce-order-details__title,
19
+ .woocommerce-order .woocommerce-thankyou-order-received,
20
+ .woocommerce-order-details h2,
21
+ .woocommerce-order h2.wc-bacs-bank-details-heading,
22
+ .woocommerce-order h2.woocommerce-order-downloads__title {
23
+ color: {$heading_text_color};
24
+ font-family: {$heading_font_family};
25
+ font-weight: {$heading_font_weight};
26
+ }
27
+
28
+ .woocommerce-order ul.order_details,
29
+ .woocommerce-order .woocommerce-order-details,
30
+ .woocommerce-order .woocommerce-customer-details,
31
+ .woocommerce-order .woocommerce-bacs-bank-details,
32
+ .woocommerce-order .woocommerce-order-downloads{
33
+ background-color: {$section_bg_color}
34
+ }
35
+ img.emoji, img.wp-smiley {}
36
+ ";
37
+
38
+ if ( 'no' == $show_order_review ) {
39
+ $output .= '
40
+ .woocommerce-order ul.order_details{
41
+ display: none;
42
+ }
43
+ ';
44
+ }
45
+
46
+ if ( 'no' == $show_order_details ) {
47
+ $output .= '
48
+ .woocommerce-order .woocommerce-order-details{
49
+ display: none;
50
+ }
51
+ ';
52
+ }
53
+
54
+ if ( 'no' == $show_billing_details ) {
55
+ $output .= '
56
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
+ display: none;
58
+ }
59
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
+ float:left;
61
+ }
62
+ ';
63
+ }
64
+
65
+ if ( 'no' == $show_shipping_details ) {
66
+ $output .= '
67
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
68
+ display: none;
69
+ }
70
+ ';
71
+ }
72
+
73
+ if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
74
+ $output .= '
75
+ .woocommerce-order .woocommerce-customer-details{
76
+ display: none;
77
+ }
78
+ ';
79
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ 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.4.2
7
- Stable tag: 1.5.13
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,9 @@ Glad you asked! Most normal users have less than 3 funnels on a single website,
127
 
128
  == Changelog ==
129
 
 
 
 
130
  = Version 1.5.13 - Tuesday, 21st July 2020 =
131
  * Improvement: Improved the product search query of meta options.
132
  * Improvement: Added compatibility for a future release of CartFlows Pro.
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4.2
7
+ Stable tag: 1.5.14
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.14 - Thursday, 30th July 2020 =
131
+ * Fix: Not able to search & select the course type of product.
132
+
133
  = Version 1.5.13 - Tuesday, 21st July 2020 =
134
  * Improvement: Improved the product search query of meta options.
135
  * Improvement: Added compatibility for a future release of CartFlows Pro.