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

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

Code changes from version 1.5.10 to 1.5.11

Files changed (39) hide show
  1. admin/assets/css/global-admin-rtl.css +5 -0
  2. admin/assets/css/global-admin.css +5 -0
  3. admin/assets/js/setup-wizard.js +0 -4
  4. admin/bsf-analytics/assets/css/minified/style-rtl.min.css +1 -0
  5. admin/bsf-analytics/assets/css/minified/style.min.css +1 -0
  6. admin/bsf-analytics/assets/css/unminified/style-rtl.css +21 -0
  7. admin/bsf-analytics/assets/css/unminified/style.css +21 -0
  8. admin/bsf-analytics/bin/block-commits-with-merge-conflict.sh +19 -0
  9. admin/bsf-analytics/class-bsf-analytics-stats.php +256 -0
  10. admin/bsf-analytics/class-bsf-analytics.php +528 -0
  11. admin/meta-assets/js/admin-edit.js +43 -1
  12. cartflows.php +1 -1
  13. changelog.txt +7 -0
  14. classes/batch-process/class-cartflows-batch-process.php +295 -295
  15. classes/batch-process/class-cartflows-importer-elementor.php +86 -86
  16. classes/batch-process/class-cartflows-importer-gutenberg-batch.php +63 -63
  17. classes/batch-process/class-cartflows-importer-gutenberg.php +90 -90
  18. classes/class-cartflows-admin-fields.php +271 -271
  19. classes/class-cartflows-admin.php +657 -657
  20. classes/class-cartflows-api.php +382 -382
  21. classes/class-cartflows-cloning.php +465 -465
  22. classes/class-cartflows-default-meta.php +871 -867
  23. classes/class-cartflows-helper.php +10 -4
  24. classes/class-cartflows-importer.php +1739 -1739
  25. classes/class-cartflows-loader.php +8 -1
  26. classes/class-cartflows-meta-fields.php +79 -2
  27. classes/class-cartflows-wizard.php +14 -6
  28. classes/lib/notices/class-astra-notices.php +365 -0
  29. classes/lib/notices/notices.js +95 -0
  30. includes/admin/cartflows-admin.php +35 -35
  31. includes/admin/cartflows-general.php +1 -1
  32. includes/meta-fields/generate-product-repeater.php +99 -99
  33. languages/cartflows.pot +191 -143
  34. modules/checkout/classes/class-cartflows-checkout-markup.php +1288 -1260
  35. modules/flow/classes/class-cartflows-flow-post-type.php +383 -383
  36. modules/flow/classes/class-cartflows-permalink.php +158 -158
  37. modules/flow/classes/class-cartflows-step-post-type.php +500 -496
  38. modules/optin/classes/class-cartflows-optin-meta.php +673 -672
  39. readme.txt +6 -1
admin/assets/css/global-admin-rtl.css CHANGED
@@ -684,6 +684,11 @@ input[type="text"].error:focus{
684
  display: block;
685
  }
686
 
 
 
 
 
 
687
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="text"],
688
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="number"],
689
  .wcf-table-container .wcf-column-right .wcf-field-row select,
684
  display: block;
685
  }
686
 
687
+ .wc-wp-version-gte-53 .wcf-checkout-table .select2-container--default .select2-selection--single .select2-selection__arrow{
688
+ width:20px;
689
+ height: 100%;
690
+ }
691
+
692
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="text"],
693
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="number"],
694
  .wcf-table-container .wcf-column-right .wcf-field-row select,
admin/assets/css/global-admin.css CHANGED
@@ -684,6 +684,11 @@ input[type="text"].error:focus{
684
  display: block;
685
  }
686
 
 
 
 
 
 
687
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="text"],
688
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="number"],
689
  .wcf-table-container .wcf-column-right .wcf-field-row select,
684
  display: block;
685
  }
686
 
687
+ .wc-wp-version-gte-53 .wcf-checkout-table .select2-container--default .select2-selection--single .select2-selection__arrow{
688
+ width:20px;
689
+ height: 100%;
690
+ }
691
+
692
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="text"],
693
  .wcf-table-container .wcf-column-right .wcf-field-row input[type="number"],
694
  .wcf-table-container .wcf-column-right .wcf-field-row select,
admin/assets/js/setup-wizard.js CHANGED
@@ -94,10 +94,6 @@
94
  console.log( plugin_slug );
95
 
96
  if ( 'woocommerce' === plugin_slug ) {
97
- return;
98
- }
99
-
100
- if( 'woo-cart-abandonment-recovery' === plugin_slug ) {
101
  CartFlowsWizard._activateWc();
102
  return;
103
  }
94
  console.log( plugin_slug );
95
 
96
  if ( 'woocommerce' === plugin_slug ) {
 
 
 
 
97
  CartFlowsWizard._activateWc();
98
  return;
99
  }
admin/bsf-analytics/assets/css/minified/style-rtl.min.css ADDED
@@ -0,0 +1 @@
 
1
+ #bsf-optin-notice{padding:1px 12px;border-right-color:#007cba}#bsf-optin-notice .notice-container{padding-top:10px;padding-bottom:12px}#bsf-optin-notice .notice-content{margin:0}#bsf-optin-notice .notice-heading{padding:0 0 12px 20px}#bsf-optin-notice .button-primary{margin-left:5px}
admin/bsf-analytics/assets/css/minified/style.min.css ADDED
@@ -0,0 +1 @@
 
1
+ #bsf-optin-notice{padding:1px 12px;border-left-color:#007cba}#bsf-optin-notice .notice-container{padding-top:10px;padding-bottom:12px}#bsf-optin-notice .notice-content{margin:0}#bsf-optin-notice .notice-heading{padding:0 20px 12px 0}#bsf-optin-notice .button-primary{margin-right:5px}
admin/bsf-analytics/assets/css/unminified/style-rtl.css ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #bsf-optin-notice {
2
+ padding: 1px 12px;
3
+ border-right-color: #007cba;
4
+ }
5
+
6
+ #bsf-optin-notice .notice-container {
7
+ padding-top: 10px;
8
+ padding-bottom: 12px;
9
+ }
10
+
11
+ #bsf-optin-notice .notice-content {
12
+ margin: 0;
13
+ }
14
+
15
+ #bsf-optin-notice .notice-heading {
16
+ padding: 0 0 12px 20px;
17
+ }
18
+
19
+ #bsf-optin-notice .button-primary {
20
+ margin-left: 5px;
21
+ }
admin/bsf-analytics/assets/css/unminified/style.css ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #bsf-optin-notice {
2
+ padding: 1px 12px;
3
+ border-left-color: #007cba;
4
+ }
5
+
6
+ #bsf-optin-notice .notice-container {
7
+ padding-top: 10px;
8
+ padding-bottom: 12px;
9
+ }
10
+
11
+ #bsf-optin-notice .notice-content {
12
+ margin: 0;
13
+ }
14
+
15
+ #bsf-optin-notice .notice-heading {
16
+ padding: 0 20px 12px 0;
17
+ }
18
+
19
+ #bsf-optin-notice .button-primary {
20
+ margin-right: 5px;
21
+ }
admin/bsf-analytics/bin/block-commits-with-merge-conflict.sh ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ ## pre-commit script to prevent merge markers from being committed.
4
+
5
+ changed=$(git diff --cached --name-only)
6
+
7
+ if [[ -z "$changed" ]]
8
+ then
9
+ exit 0
10
+ fi
11
+
12
+ echo $changed | xargs egrep '[><]{7}' -H -I --line-number
13
+
14
+ ## If the egrep command has any hits - echo a warning and exit with non-zero status.
15
+ if [ $? == 0 ]
16
+ then
17
+ echo "\n\nWARNING: You have merge markers in the above files, lines. Fix them before committing.\n\n"
18
+ exit 1
19
+ fi
admin/bsf-analytics/class-bsf-analytics-stats.php ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BSF analytics stat class file.
4
+ *
5
+ * @package bsf-analytics
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ if ( ! class_exists( 'BSF_Analytics_Stats' ) ) {
13
+ /**
14
+ * BSF analytics stat class.
15
+ */
16
+ class BSF_Analytics_Stats {
17
+
18
+ /**
19
+ * Active plugins.
20
+ *
21
+ * Holds the sites active plugins list.
22
+ *
23
+ * @var array
24
+ */
25
+ private $plugins;
26
+
27
+ /**
28
+ * Instance of BSF_Analytics_Stats.
29
+ *
30
+ * Holds only the first object of class.
31
+ *
32
+ * @var object
33
+ */
34
+ private static $instance = null;
35
+
36
+ /**
37
+ * Create only once instance of a class.
38
+ *
39
+ * @return object
40
+ * @since 1.0.0
41
+ */
42
+ public static function instance() {
43
+ if ( null === self::$instance ) {
44
+ self::$instance = new self();
45
+ }
46
+
47
+ return self::$instance;
48
+ }
49
+
50
+ /**
51
+ * Get stats.
52
+ *
53
+ * @return array stats data.
54
+ * @since 1.0.0
55
+ */
56
+ public function get_stats() {
57
+ return apply_filters( 'bsf_core_stats', $this->get_default_stats() );
58
+ }
59
+
60
+ /**
61
+ * Retrieve stats for site.
62
+ *
63
+ * @return array stats data.
64
+ * @since 1.0.0
65
+ */
66
+ private function get_default_stats() {
67
+ return array(
68
+ 'graupi_version' => defined( 'BSF_UPDATER_VERSION' ) ? BSF_UPDATER_VERSION : false,
69
+ 'domain_name' => get_site_url(),
70
+ 'php_os' => PHP_OS,
71
+ 'server_software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? filter_var( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ), FILTER_SANITIZE_STRING ) : '',
72
+ 'mysql_version' => $this->get_mysql_version(),
73
+ 'php_version' => $this->get_php_version(),
74
+ 'php_max_input_vars' => ini_get( 'max_input_vars' ), // phpcs:ignore:PHPCompatibility.IniDirectives.NewIniDirectives.max_input_varsFound
75
+ 'php_post_max_size' => ini_get( 'post_max_size' ),
76
+ 'php_max_execution_time' => ini_get( 'max_execution_time' ),
77
+ 'php_memory_limit' => ini_get( 'memory_limit' ),
78
+ 'zip_installed' => extension_loaded( 'zip' ),
79
+ 'imagick_availabile' => extension_loaded( 'imagick' ),
80
+ 'xmlreader_exists' => class_exists( 'XMLReader' ),
81
+ 'gd_available' => extension_loaded( 'gd' ),
82
+ 'curl_version' => $this->get_curl_version(),
83
+ 'curl_ssl_version' => $this->get_curl_ssl_version(),
84
+ 'is_writable' => $this->is_content_writable(),
85
+
86
+ 'wp_version' => get_bloginfo( 'version' ),
87
+ 'user_count' => $this->get_user_count(),
88
+ 'site_language' => get_locale(),
89
+ 'timezone' => wp_timezone_string(),
90
+ 'is_ssl' => is_ssl(),
91
+ 'is_multisite' => is_multisite(),
92
+ 'network_url' => network_site_url(),
93
+ 'external_object_cache' => (bool) wp_using_ext_object_cache(),
94
+ 'wp_debug' => WP_DEBUG,
95
+ 'wp_debug_display' => WP_DEBUG_DISPLAY,
96
+ 'script_debug' => SCRIPT_DEBUG,
97
+
98
+ 'active_plugins' => $this->get_active_plugins(),
99
+
100
+ 'active_theme' => get_template(),
101
+ 'active_stylesheet' => get_stylesheet(),
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Get installed PHP version.
107
+ *
108
+ * @return float PHP version.
109
+ * @since 1.0.0
110
+ */
111
+ private function get_php_version() {
112
+ if ( defined( 'PHP_MAJOR_VERSION' ) && defined( 'PHP_MINOR_VERSION' ) && defined( 'PHP_RELEASE_VERSION' ) ) { // phpcs:ignore
113
+ return PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
114
+ }
115
+
116
+ return phpversion();
117
+ }
118
+
119
+ /**
120
+ * User count on site.
121
+ *
122
+ * @return int User count.
123
+ * @since 1.0.0
124
+ */
125
+ private function get_user_count() {
126
+ if ( is_multisite() ) {
127
+ $user_count = get_user_count();
128
+ } else {
129
+ $count = count_users();
130
+ $user_count = $count['total_users'];
131
+ }
132
+
133
+ return $user_count;
134
+ }
135
+
136
+ /**
137
+ * Get active plugin's data.
138
+ *
139
+ * @return array active plugin's list.
140
+ * @since 1.0.0
141
+ */
142
+ private function get_active_plugins() {
143
+ if ( ! $this->plugins ) {
144
+ // Ensure get_plugin_data function is loaded.
145
+ if ( ! function_exists( 'get_plugin_data' ) ) {
146
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
147
+ }
148
+
149
+ $plugins = wp_get_active_and_valid_plugins();
150
+ $plugins = array_map( 'get_plugin_data', $plugins );
151
+ $this->plugins = array_map( array( $this, 'format_plugin' ), $plugins );
152
+ }
153
+
154
+ return $this->plugins;
155
+ }
156
+
157
+ /**
158
+ * Format plugin data.
159
+ *
160
+ * @param string $plugin plugin.
161
+ * @return array formatted plugin data.
162
+ * @since 1.0.0
163
+ */
164
+ public function format_plugin( $plugin ) {
165
+ return array(
166
+ 'name' => html_entity_decode( $plugin['Name'], ENT_COMPAT, 'UTF-8' ),
167
+ 'url' => $plugin['PluginURI'],
168
+ 'version' => $plugin['Version'],
169
+ 'slug' => $plugin['TextDomain'],
170
+ 'author_name' => html_entity_decode( wp_strip_all_tags( $plugin['Author'] ), ENT_COMPAT, 'UTF-8' ),
171
+ 'author_url' => $plugin['AuthorURI'],
172
+ );
173
+ }
174
+
175
+ /**
176
+ * Curl SSL version.
177
+ *
178
+ * @return float SSL version.
179
+ * @since 1.0.0
180
+ */
181
+ private function get_curl_ssl_version() {
182
+ $curl = array();
183
+ if ( function_exists( 'curl_version' ) ) {
184
+ $curl = curl_version(); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_version
185
+ }
186
+
187
+ return isset( $curl['ssl_version'] ) ? $curl['ssl_version'] : false;
188
+ }
189
+
190
+ /**
191
+ * Get cURL version.
192
+ *
193
+ * @return float cURL version.
194
+ * @since 1.0.0
195
+ */
196
+ private function get_curl_version() {
197
+ if ( function_exists( 'curl_version' ) ) {
198
+ $curl = curl_version(); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_version
199
+ }
200
+
201
+ return isset( $curl['version'] ) ? $curl['version'] : false;
202
+ }
203
+
204
+ /**
205
+ * Get MySQL version.
206
+ *
207
+ * @return float MySQL version.
208
+ * @since 1.0.0
209
+ */
210
+ private function get_mysql_version() {
211
+ global $wpdb;
212
+ return $wpdb->db_version();
213
+ }
214
+
215
+ /**
216
+ * Check if content directory is writable.
217
+ *
218
+ * @return bool
219
+ * @since 1.0.0
220
+ */
221
+ private function is_content_writable() {
222
+ $upload_dir = wp_upload_dir();
223
+ return wp_is_writable( $upload_dir['basedir'] );
224
+ }
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Polyfill for sites using WP version less than 5.3
230
+ */
231
+ if ( ! function_exists( 'wp_timezone_string' ) ) {
232
+ /**
233
+ * Get timezone string.
234
+ *
235
+ * @return string timezone string.
236
+ * @since 1.0.0
237
+ */
238
+ function wp_timezone_string() {
239
+ $timezone_string = get_option( 'timezone_string' );
240
+
241
+ if ( $timezone_string ) {
242
+ return $timezone_string;
243
+ }
244
+
245
+ $offset = (float) get_option( 'gmt_offset' );
246
+ $hours = (int) $offset;
247
+ $minutes = ( $offset - $hours );
248
+
249
+ $sign = ( $offset < 0 ) ? '-' : '+';
250
+ $abs_hour = abs( $hours );
251
+ $abs_mins = abs( $minutes * 60 );
252
+ $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
253
+
254
+ return $tz_offset;
255
+ }
256
+ }
admin/bsf-analytics/class-bsf-analytics.php ADDED
@@ -0,0 +1,528 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 Usage tracking document URL
25
+ */
26
+ private $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
27
+
28
+ /**
29
+ * Setup actions, load files.
30
+ *
31
+ * @since 1.0.0
32
+ */
33
+ public function __construct() {
34
+
35
+ define( 'BSF_ANALYTICS_FILE', __FILE__ );
36
+ define( 'BSF_ANALYTICS_VERSION', '1.0.2' );
37
+ define( 'BSF_ANALYTICS_PATH', dirname( __FILE__ ) );
38
+ define( 'BSF_ANALYTICS_URI', $this->bsf_analytics_url() );
39
+
40
+ add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
41
+ add_action( 'cron_schedules', array( $this, 'every_two_days_schedule' ) );
42
+ add_action( 'admin_notices', array( $this, 'option_notice' ) );
43
+ add_action( 'astra_notice_before_markup_bsf-optin-notice', array( $this, 'enqueue_assets' ) );
44
+
45
+ add_action( 'init', array( $this, 'schedule_unschedule_event' ) );
46
+
47
+ if ( ! has_action( 'bsf_analytics_send', array( $this, 'send' ) ) ) {
48
+ add_action( 'bsf_analytics_send', array( $this, 'send' ) );
49
+ }
50
+
51
+ add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
52
+
53
+ add_action( 'update_option_bsf_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
54
+ add_action( 'add_option_bsf_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
55
+
56
+ $this->includes();
57
+ }
58
+
59
+ /**
60
+ * BSF Analytics URL
61
+ *
62
+ * @return String URL of bsf-analytics directory.
63
+ * @since 1.0.0
64
+ */
65
+ public function bsf_analytics_url() {
66
+
67
+ $path = wp_normalize_path( BSF_ANALYTICS_PATH );
68
+ $theme_dir = wp_normalize_path( get_template_directory() );
69
+
70
+ if ( strpos( $path, $theme_dir ) !== false ) {
71
+ return rtrim( get_template_directory_uri() . '/admin/bsf-analytics/', '/' );
72
+ } else {
73
+ return rtrim( plugin_dir_url( BSF_ANALYTICS_FILE ), '/' );
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Get API URL for sending analytics.
79
+ *
80
+ * @return string API URL.
81
+ * @since 1.0.0
82
+ */
83
+ private function get_api_url() {
84
+ return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
85
+ }
86
+
87
+ /**
88
+ * Enqueue Scripts.
89
+ *
90
+ * @since 1.0.0
91
+ * @return void
92
+ */
93
+ public function enqueue_assets() {
94
+
95
+ /**
96
+ * Load unminified if SCRIPT_DEBUG is true.
97
+ *
98
+ * Directory and Extensions.
99
+ */
100
+ $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
101
+ $file_rtl = ( is_rtl() ) ? '-rtl' : '';
102
+ $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
103
+
104
+ $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
105
+
106
+ wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, BSF_ANALYTICS_VERSION, 'all' );
107
+ }
108
+
109
+ /**
110
+ * Send analytics API call.
111
+ *
112
+ * @since 1.0.0
113
+ */
114
+ public function send() {
115
+ wp_remote_post(
116
+ $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
117
+ array(
118
+ 'body' => BSF_Analytics_Stats::instance()->get_stats(),
119
+ 'timeout' => 5,
120
+ 'blocking' => false,
121
+ )
122
+ );
123
+ }
124
+
125
+ /**
126
+ * Check if usage tracking is enabled.
127
+ *
128
+ * @return bool
129
+ * @since 1.0.0
130
+ */
131
+ public function is_tracking_enabled() {
132
+ $is_enabled = get_site_option( 'bsf_analytics_optin' ) === 'yes' ? true : false;
133
+ $is_enabled = $this->is_white_label_enabled() ? false : $is_enabled;
134
+
135
+ return apply_filters( 'bsf_tracking_enabled', $is_enabled );
136
+ }
137
+
138
+ /**
139
+ * Check if WHITE label is enabled for BSF products.
140
+ *
141
+ * @return bool
142
+ * @since 1.0.0
143
+ */
144
+ public function is_white_label_enabled() {
145
+
146
+ $options = apply_filters( 'bsf_white_label_options', array() );
147
+ $is_enabled = false;
148
+
149
+ if ( is_array( $options ) ) {
150
+ foreach ( $options as $option ) {
151
+ if ( true === $option ) {
152
+ $is_enabled = true;
153
+ break;
154
+ }
155
+ }
156
+ }
157
+
158
+ return $is_enabled;
159
+ }
160
+
161
+ /**
162
+ * Display admin notice for usage tracking.
163
+ *
164
+ * @since 1.0.0
165
+ */
166
+ public function option_notice() {
167
+
168
+ if ( ! current_user_can( 'manage_options' ) ) {
169
+ return;
170
+ }
171
+
172
+ // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
173
+ if ( false !== get_site_option( 'bsf_analytics_optin', false ) || $this->is_white_label_enabled() ) {
174
+ return;
175
+ }
176
+
177
+ // Show tracker consent notice after 24 hours from installed time.
178
+ if ( strtotime( '+24 hours', $this->get_analytics_install_time() ) > time() ) {
179
+ return;
180
+ }
181
+
182
+ /* translators: %s product name */
183
+ $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'cartflows' );
184
+
185
+ if ( is_multisite() ) {
186
+ $notice_string .= __( 'This will be applicable for all sites from the network.', 'cartflows' );
187
+ }
188
+
189
+ $language_dir = is_rtl() ? 'rtl' : 'ltr';
190
+
191
+ Astra_Notices::add_notice(
192
+ array(
193
+ 'id' => 'bsf-optin-notice',
194
+ 'type' => '',
195
+ 'message' => sprintf(
196
+ '<div class="notice-content">
197
+ <div class="notice-heading">
198
+ %1$s
199
+ </div>
200
+ <div class="astra-notices-container">
201
+ <a href="%2$s" class="astra-notices button-primary">
202
+ %3$s
203
+ </a>
204
+ <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
205
+ %6$s
206
+ </a>
207
+ </div>
208
+ </div>',
209
+ /* translators: %s usage doc link */
210
+ sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $this->get_product_name() ), $language_dir, esc_url( $this->usage_doc_link ), __( ' Know More.', 'cartflows' ) ),
211
+ add_query_arg(
212
+ array(
213
+ 'bsf_analytics_optin' => 'yes',
214
+ 'bsf_analytics_nonce' => wp_create_nonce( 'bsf_analytics_optin' ),
215
+ )
216
+ ),
217
+ __( 'Yes! Allow it', 'cartflows' ),
218
+ add_query_arg(
219
+ array(
220
+ 'bsf_analytics_optin' => 'no',
221
+ 'bsf_analytics_nonce' => wp_create_nonce( 'bsf_analytics_optin' ),
222
+ )
223
+ ),
224
+ MONTH_IN_SECONDS,
225
+ __( 'No Thanks', 'cartflows' )
226
+ ),
227
+ 'show_if' => true,
228
+ 'repeat-notice-after' => false,
229
+ 'priority' => 18,
230
+ 'display-with-other-notices' => true,
231
+ )
232
+ );
233
+ }
234
+
235
+ /**
236
+ * Process usage tracking opt out.
237
+ *
238
+ * @since 1.0.0
239
+ */
240
+ public function handle_optin_optout() {
241
+ if ( ! isset( $_GET['bsf_analytics_nonce'] ) ) {
242
+ return;
243
+ }
244
+
245
+ if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['bsf_analytics_nonce'] ) ), 'bsf_analytics_optin' ) ) {
246
+ return;
247
+ }
248
+
249
+ $optin_status = isset( $_GET['bsf_analytics_optin'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_optin'] ) ) : '';
250
+
251
+ if ( 'yes' === $optin_status ) {
252
+ $this->optin();
253
+ } elseif ( 'no' === $optin_status ) {
254
+ $this->optout();
255
+ }
256
+
257
+ wp_safe_redirect(
258
+ remove_query_arg(
259
+ array(
260
+ 'bsf_analytics_optin',
261
+ 'bsf_analytics_nonce',
262
+ )
263
+ )
264
+ );
265
+ }
266
+
267
+ /**
268
+ * Opt in to usage tracking.
269
+ *
270
+ * @since 1.0.0
271
+ */
272
+ private function optin() {
273
+ update_site_option( 'bsf_analytics_optin', 'yes' );
274
+ }
275
+
276
+ /**
277
+ * Opt out to usage tracking.
278
+ *
279
+ * @since 1.0.0
280
+ */
281
+ private function optout() {
282
+ update_site_option( 'bsf_analytics_optin', 'no' );
283
+ }
284
+
285
+ /**
286
+ * Add two days event schedule variables.
287
+ *
288
+ * @param array $schedules scheduled array data.
289
+ * @since 1.0.0
290
+ */
291
+ public function every_two_days_schedule( $schedules ) {
292
+ $schedules['every_two_days'] = array(
293
+ 'interval' => 2 * DAY_IN_SECONDS,
294
+ 'display' => __( 'Every two days', 'cartflows' ),
295
+ );
296
+
297
+ return $schedules;
298
+ }
299
+
300
+ /**
301
+ * Schedule usage tracking event.
302
+ *
303
+ * @since 1.0.0
304
+ */
305
+ private function schedule_event() {
306
+ if ( ! wp_next_scheduled( 'bsf_analytics_send' ) && $this->is_tracking_enabled() ) {
307
+ wp_schedule_event( time(), 'every_two_days', 'bsf_analytics_send' );
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Unschedule usage tracking event.
313
+ *
314
+ * @since 1.0.0
315
+ */
316
+ private function unschedule_event() {
317
+ wp_clear_scheduled_hook( 'bsf_analytics_send' );
318
+ }
319
+
320
+ /**
321
+ * Load analytics stat class.
322
+ *
323
+ * @since 1.0.0
324
+ */
325
+ private function includes() {
326
+ require_once __DIR__ . '/class-bsf-analytics-stats.php';
327
+ }
328
+
329
+ /**
330
+ * Register usage tracking option in General settings page.
331
+ *
332
+ * @since 1.0.0
333
+ */
334
+ public function register_usage_tracking_setting() {
335
+
336
+ if ( ! apply_filters( 'bsf_tracking_enabled', true ) || $this->is_white_label_enabled() ) {
337
+ return;
338
+ }
339
+
340
+ register_setting(
341
+ 'general', // Options group.
342
+ 'bsf_analytics_optin', // Option name/database.
343
+ array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
344
+ );
345
+
346
+ add_settings_field(
347
+ 'bsf-analytics-optin', // Field ID.
348
+ __( 'Usage Tracking', 'cartflows' ), // Field title.
349
+ array( $this, 'render_settings_field_html' ), // Field callback function.
350
+ 'general' // Settings page slug.
351
+ );
352
+ }
353
+
354
+ /**
355
+ * Sanitize Callback Function
356
+ *
357
+ * @param bool $input Option value.
358
+ * @since 1.0.0
359
+ */
360
+ public function sanitize_option( $input ) {
361
+
362
+ if ( ! $input || 'no' === $input ) {
363
+ return 'no';
364
+ }
365
+
366
+ return 'yes';
367
+ }
368
+
369
+ /**
370
+ * Print settings field HTML.
371
+ *
372
+ * @since 1.0.0
373
+ */
374
+ public function render_settings_field_html() {
375
+ ?>
376
+ <fieldset>
377
+ <label for="bsf-analytics-optin">
378
+ <input id="bsf-analytics-optin" type="checkbox" value="1" name="bsf_analytics_optin" <?php checked( get_site_option( 'bsf_analytics_optin', 'no' ), 'yes' ); ?>>
379
+ <?php
380
+ esc_html_e( 'Allow Brainstorm Force products to track non-sensitive usage tracking data.', 'cartflows' );
381
+
382
+ if ( is_multisite() ) {
383
+ esc_html_e( ' This will be applicable for all sites from the network.', 'cartflows' );
384
+ }
385
+ ?>
386
+ </label>
387
+ <?php
388
+ echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $this->usage_doc_link ), __( 'Learn More.', 'cartflows' ) ) );
389
+ ?>
390
+ </fieldset>
391
+ <?php
392
+ }
393
+
394
+ /**
395
+ * Get current product name.
396
+ *
397
+ * @return string $plugin_data['Name] Name of plugin.
398
+ * @since 1.0.0
399
+ */
400
+ private function get_product_name() {
401
+
402
+ $base = wp_normalize_path( dirname( __FILE__ ) );
403
+ $theme_dir = wp_normalize_path( get_template_directory() );
404
+
405
+ if ( false !== strpos( $base, $theme_dir ) ) {
406
+ $theme = wp_get_theme( get_template() );
407
+ return $theme->get( 'Name' );
408
+ }
409
+
410
+ $base = plugin_basename( __FILE__ );
411
+
412
+ $exploded_path = explode( '/', $base, 2 );
413
+ $plugin_slug = $exploded_path[0];
414
+
415
+ return $this->get_plugin_name( $plugin_slug );
416
+ }
417
+
418
+ /**
419
+ * Get plugin name by plugin slug.
420
+ *
421
+ * @param string $plugin_slug Plugin slug.
422
+ * @return string $plugin_info['Name'] Plugin name.
423
+ */
424
+ private function get_plugin_name( $plugin_slug ) {
425
+
426
+ $plugins = get_option( 'active_plugins' );
427
+
428
+ if ( ! function_exists( 'get_plugin_data' ) ) {
429
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
430
+ }
431
+
432
+ foreach ( $plugins as $plugin_file ) {
433
+
434
+ $plugin_folder = explode( '/', $plugin_file );
435
+ $plugin_folder = $plugin_folder[0];
436
+ if ( $plugin_folder === $plugin_slug ) {
437
+ $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
438
+ $plugin_data = get_plugin_data( $plugin_path );
439
+ return $plugin_data['Name'];
440
+ }
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Set analytics installed time in option.
446
+ *
447
+ * @return string $time analytics installed time.
448
+ * @since 1.0.0
449
+ */
450
+ private function get_analytics_install_time() {
451
+
452
+ $time = get_site_option( 'bsf_analytics_installed_time' );
453
+
454
+ if ( ! $time ) {
455
+ $time = time();
456
+ update_site_option( 'bsf_analytics_installed_time', time() );
457
+ }
458
+
459
+ return $time;
460
+ }
461
+
462
+ /**
463
+ * Schedule/unschedule cron event on updation of option.
464
+ *
465
+ * @param string $old_value old value of option.
466
+ * @param string $value value of option.
467
+ * @param string $option Option name.
468
+ * @since 1.0.0
469
+ */
470
+ public function update_analytics_option_callback( $old_value, $value, $option ) {
471
+ $this->add_option_to_network( $value );
472
+ }
473
+
474
+ /**
475
+ * Analytics option add callback.
476
+ *
477
+ * @param string $option Option name.
478
+ * @param string $value value of option.
479
+ * @since 1.0.0
480
+ */
481
+ public function add_analytics_option_callback( $option, $value ) {
482
+ $this->add_option_to_network( $value );
483
+ }
484
+
485
+ /**
486
+ * Schedule or unschedule event based on analytics option value.
487
+ *
488
+ * @since 1.0.0
489
+ */
490
+ public function schedule_unschedule_event() {
491
+
492
+ if ( true === $this->is_white_label_enabled() ) {
493
+ $this->unschedule_event();
494
+ return;
495
+ }
496
+
497
+ $analytics_option = get_site_option( 'bsf_analytics_optin' );
498
+
499
+ if ( 'no' === $analytics_option ) {
500
+ $this->unschedule_event();
501
+ } elseif ( 'yes' === $analytics_option ) {
502
+ $this->schedule_event();
503
+ }
504
+ }
505
+
506
+ /**
507
+ * Save analytics option to network.
508
+ *
509
+ * @param string $value value of option.
510
+ * @since 1.0.0
511
+ */
512
+ public function add_option_to_network( $value ) {
513
+
514
+ // If action coming from general settings page.
515
+ if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
516
+
517
+ if ( get_site_option( 'bsf_analytics_optin' ) ) {
518
+ update_site_option( 'bsf_analytics_optin', $value );
519
+ } else {
520
+ add_site_option( 'bsf_analytics_optin', $value );
521
+ }
522
+ }
523
+ }
524
+ }
525
+
526
+ new BSF_Analytics();
527
+
528
+ }
admin/meta-assets/js/admin-edit.js CHANGED
@@ -177,7 +177,7 @@
177
  return wc_enhanced_select_params.i18n_no_matches;
178
  },
179
  errorLoading: function() {
180
- return wc_enhanced_select_params.i18n_ajax_error;
181
  },
182
  inputTooShort: function( args ) {
183
  var remainingChars = args.minimum - args.input.length;
@@ -274,6 +274,48 @@
274
  $( this ).select2( select2_args ).addClass( 'enhanced' );
275
  });
276
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  var wcf_pages_search_init = function() {
278
 
279
 
177
  return wc_enhanced_select_params.i18n_no_matches;
178
  },
179
  errorLoading: function() {
180
+ return wc_enhanced_select_params.i18n_searching;
181
  },
182
  inputTooShort: function( args ) {
183
  var remainingChars = args.minimum - args.input.length;
274
  $( this ).select2( select2_args ).addClass( 'enhanced' );
275
  });
276
  };
277
+
278
+ var wcf_cartflows_woo_product_search_init = function() {
279
+
280
+ $( 'select.wcf-product-search' ).filter( ':not(.enhanced)' ).each( function() {
281
+ var select2_args = {
282
+ allowClear: $( this ).data( 'allow_clear' ) ? true : false,
283
+ placeholder: $( this ).data( 'placeholder' ),
284
+ minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3',
285
+ escapeMarkup: function( m ) {
286
+ return m;
287
+ },
288
+ ajax: {
289
+ url: wc_enhanced_select_params.ajax_url,
290
+ dataType: 'json',
291
+ quietMillis: 250,
292
+ data: function( params, page ) {
293
+ return {
294
+ term: params.term,
295
+ action: $( this ).data( 'action' ) || 'wcf_json_search_products_and_variations',
296
+ excluded : $( this ).data( 'excluded_product_types' ) || '',
297
+ security: cartflows_admin.wcf_json_search_products_and_variations_nonce
298
+ };
299
+ },
300
+ processResults: function( data, page ) {
301
+ var terms = [];
302
+ if ( data ) {
303
+ $.each( data, function( id, text ) {
304
+ terms.push( { id: id, text: text } );
305
+ });
306
+ }
307
+ return { results: terms };
308
+ },
309
+ cache: true
310
+ }
311
+ };
312
+
313
+ select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
314
+
315
+ $( this ).select2( select2_args ).addClass( 'enhanced' );
316
+ });
317
+ };
318
+
319
  var wcf_pages_search_init = function() {
320
 
321
 
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.10
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.11
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,7 +1,14 @@
 
 
 
 
 
 
1
  Version 1.5.10 - Wednesday, 3rd June 2020
2
  - New: Gutenberg templates added.
3
  - New: Import/Export content support added.
4
  - Fix: Step slug was not editable in some permalink cases.
 
5
 
6
  Version 1.5.9 - Thursday, 14th May 2020
7
  - New: Added quantity and discount options for the product.
1
+ Version 1.5.11 - Tuesday, 16th June 2020
2
+ - New: Users can now share [non-personal usage data] to help us test and develop better products. ( https://store.brainstormforce.com/usage-tracking/?utm_source=wp_repo&utm_medium=changelog&utm_campaign=usage_tracking )
3
+ - Fix: CartFlows setup wizard.
4
+ - Fix: Showing notice 'Remove selected product from checkout' even there is no product selected in Global checkout.
5
+ - Fix: Redirected to the cart when the order canceled by a user for PayPal checkout gateway.
6
+
7
  Version 1.5.10 - Wednesday, 3rd June 2020
8
  - New: Gutenberg templates added.
9
  - New: Import/Export content support added.
10
  - Fix: Step slug was not editable in some permalink cases.
11
+ - Improvement: Trashed flows will not be consider for flow restriction.
12
 
13
  Version 1.5.9 - Thursday, 14th May 2020
14
  - New: Added quantity and discount options for the product.
classes/batch-process/class-cartflows-batch-process.php CHANGED
@@ -1,295 +1,295 @@
1
- <?php
2
- /**
3
- * Batch Processing
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
-
11
- /**
12
- * CartFlows_Batch_Process
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Batch_Process {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @var object Class object.
23
- * @access private
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Elementor Batch Instance
29
- *
30
- * @since 1.1.1 Updated instance name with elementor specific.
31
- *
32
- * @since 1.0.0
33
- * @var object Class object.
34
- * @access public
35
- */
36
- public static $batch_instance_elementor;
37
-
38
- /**
39
- * Beaver Builder Batch Instance
40
- *
41
- * @since 1.1.1
42
- * @var object Class object.
43
- * @access public
44
- */
45
- public static $batch_instance_bb;
46
-
47
- /**
48
- * Divi Batch Instance
49
- *
50
- * @since 1.1.1
51
- * @var object Class object.
52
- * @access public
53
- */
54
- public static $batch_instance_divi;
55
-
56
- /**
57
- * Gutenberg Batch Instance
58
- *
59
- * @since 1.5.9
60
- * @var object Class object.
61
- * @access public
62
- */
63
- public static $batch_instance_gb;
64
-
65
- /**
66
- * Initiator
67
- *
68
- * @since 1.0.0
69
- * @return object initialized object of class.
70
- */
71
- public static function get_instance() {
72
- if ( ! isset( self::$instance ) ) {
73
- self::$instance = new self();
74
- }
75
- return self::$instance;
76
- }
77
-
78
- /**
79
- * Constructor
80
- *
81
- * @since 1.0.0
82
- */
83
- public function __construct() {
84
-
85
- // Not BB or Elementor then avoid importer.
86
- // if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
87
- // return;
88
- // }
89
- // Core Helpers - Image.
90
- require_once ABSPATH . 'wp-admin/includes/image.php';
91
-
92
- // Core Helpers - Batch Processing.
93
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
94
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
95
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
96
-
97
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
98
-
99
- // Elementor.
100
- if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
101
- // Add "elementor" in import [queue].
102
- // @todo Remove required `allow_url_fopen` support.
103
- if ( ini_get( 'allow_url_fopen' ) ) {
104
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
105
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
106
- self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
107
- }
108
- }
109
-
110
- // Beaver Builder.
111
- if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
112
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
113
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
114
- self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
115
- }
116
-
117
- // Divi.
118
- if ( ( 'divi' === $default_page_builder ) && ( class_exists( 'ET_Builder_Plugin' ) || Cartflows_Compatibility::get_instance()->is_divi_enabled() ) ) {
119
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi.php';
120
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi-batch.php';
121
- self::$batch_instance_divi = new Cartflows_Importer_Divi_Batch();
122
- }
123
-
124
- // Gutenberg.
125
- if ( ( 'gutenberg' === $default_page_builder ) ) {
126
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg.php';
127
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg-batch.php';
128
- self::$batch_instance_gb = new Cartflows_Importer_Gutenberg_Batch();
129
- }
130
-
131
- // Start image importing after site import complete.
132
- add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
133
- add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
134
- add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
135
- add_filter( 'wp_prepare_attachment_for_js', array( $this, 'add_svg_image_support' ), 10, 3 );
136
- }
137
-
138
- /**
139
- * Added .svg files as supported format in the uploader.
140
- *
141
- * @since 1.1.4
142
- *
143
- * @param array $mimes Already supported mime types.
144
- */
145
- public function custom_upload_mimes( $mimes ) {
146
-
147
- // Allow SVG files.
148
- $mimes['svg'] = 'image/svg+xml';
149
- $mimes['svgz'] = 'image/svg+xml';
150
-
151
- // Allow XML files.
152
- $mimes['xml'] = 'text/xml';
153
-
154
- return $mimes;
155
- }
156
-
157
- /**
158
- * Add SVG image support
159
- *
160
- * @since 1.1.4
161
- *
162
- * @param array $response Attachment response.
163
- * @param object $attachment Attachment object.
164
- * @param array $meta Attachment meta data.
165
- */
166
- public function add_svg_image_support( $response, $attachment, $meta ) {
167
- if ( ! function_exists( 'simplexml_load_file' ) ) {
168
- return $response;
169
- }
170
-
171
- if ( ! empty( $response['sizes'] ) ) {
172
- return $response;
173
- }
174
-
175
- if ( 'image/svg+xml' !== $response['mime'] ) {
176
- return $response;
177
- }
178
-
179
- $svg_path = get_attached_file( $attachment->ID );
180
-
181
- $dimensions = self::get_svg_dimensions( $svg_path );
182
-
183
- $response['sizes'] = array(
184
- 'full' => array(
185
- 'url' => $response['url'],
186
- 'width' => $dimensions->width,
187
- 'height' => $dimensions->height,
188
- 'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait',
189
- ),
190
- );
191
-
192
- return $response;
193
- }
194
-
195
- /**
196
- * Get SVG Dimensions
197
- *
198
- * @since 1.1.4.
199
- *
200
- * @param string $svg SVG file path.
201
- * @return array Return SVG file height & width for valid SVG file.
202
- */
203
- public static function get_svg_dimensions( $svg ) {
204
-
205
- $svg = simplexml_load_file( $svg );
206
-
207
- if ( false === $svg ) {
208
- $width = '0';
209
- $height = '0';
210
- } else {
211
- $attributes = $svg->attributes();
212
- $width = (string) $attributes->width;
213
- $height = (string) $attributes->height;
214
- }
215
-
216
- return (object) array(
217
- 'width' => $width,
218
- 'height' => $height,
219
- );
220
- }
221
-
222
- /**
223
- * Batch Process Complete.
224
- *
225
- * @return void
226
- */
227
- public function complete_batch_import() {
228
- wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
229
- }
230
-
231
- /**
232
- * Start Image Import
233
- *
234
- * @param integer $post_id Post Id.
235
- *
236
- * @return void
237
- */
238
- public function start_batch_process( $post_id = '' ) {
239
-
240
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
241
-
242
- wcf()->logger->import_log( '(✓) BATCH Started!' );
243
- wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
244
-
245
- // Add "elementor" in import [queue].
246
- if ( 'beaver-builder' === $default_page_builder && self::$batch_instance_bb ) {
247
-
248
- // Add to queue.
249
- self::$batch_instance_bb->push_to_queue( $post_id );
250
-
251
- // Dispatch Queue.
252
- self::$batch_instance_bb->save()->dispatch();
253
-
254
- wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
255
-
256
- } elseif ( 'elementor' === $default_page_builder && self::$batch_instance_elementor ) {
257
-
258
- // Add to queue.
259
- self::$batch_instance_elementor->push_to_queue( $post_id );
260
-
261
- // Dispatch Queue.
262
- self::$batch_instance_elementor->save()->dispatch();
263
-
264
- wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
265
- } elseif ( 'divi' === $default_page_builder && self::$batch_instance_divi ) {
266
-
267
- // Add to queue.
268
- self::$batch_instance_divi->push_to_queue( $post_id );
269
-
270
- // Dispatch Queue.
271
- self::$batch_instance_divi->save()->dispatch();
272
-
273
- wcf()->logger->import_log( '(✓) Dispatch "Divi" Request..' );
274
- } elseif ( 'gutenberg' === $default_page_builder && self::$batch_instance_gb ) {
275
-
276
- // Add to queue.
277
- self::$batch_instance_gb->push_to_queue( $post_id );
278
-
279
- // Dispatch Queue.
280
- self::$batch_instance_gb->save()->dispatch();
281
-
282
- wcf()->logger->import_log( '(✓) Dispatch "Gutenberg" Request..' );
283
- } else {
284
- wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
285
- }
286
- }
287
-
288
- }
289
-
290
- /**
291
- * Kicking this off by calling 'get_instance()' method
292
- */
293
- CartFlows_Batch_Process::get_instance();
294
-
295
- endif;
1
+ <?php
2
+ /**
3
+ * Batch Processing
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
+
11
+ /**
12
+ * CartFlows_Batch_Process
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Batch_Process {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @var object Class object.
23
+ * @access private
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Elementor Batch Instance
29
+ *
30
+ * @since 1.1.1 Updated instance name with elementor specific.
31
+ *
32
+ * @since 1.0.0
33
+ * @var object Class object.
34
+ * @access public
35
+ */
36
+ public static $batch_instance_elementor;
37
+
38
+ /**
39
+ * Beaver Builder Batch Instance
40
+ *
41
+ * @since 1.1.1
42
+ * @var object Class object.
43
+ * @access public
44
+ */
45
+ public static $batch_instance_bb;
46
+
47
+ /**
48
+ * Divi Batch Instance
49
+ *
50
+ * @since 1.1.1
51
+ * @var object Class object.
52
+ * @access public
53
+ */
54
+ public static $batch_instance_divi;
55
+
56
+ /**
57
+ * Gutenberg Batch Instance
58
+ *
59
+ * @since 1.5.9
60
+ * @var object Class object.
61
+ * @access public
62
+ */
63
+ public static $batch_instance_gb;
64
+
65
+ /**
66
+ * Initiator
67
+ *
68
+ * @since 1.0.0
69
+ * @return object initialized object of class.
70
+ */
71
+ public static function get_instance() {
72
+ if ( ! isset( self::$instance ) ) {
73
+ self::$instance = new self();
74
+ }
75
+ return self::$instance;
76
+ }
77
+
78
+ /**
79
+ * Constructor
80
+ *
81
+ * @since 1.0.0
82
+ */
83
+ public function __construct() {
84
+
85
+ // Not BB or Elementor then avoid importer.
86
+ // if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
87
+ // return;
88
+ // }
89
+ // Core Helpers - Image.
90
+ require_once ABSPATH . 'wp-admin/includes/image.php';
91
+
92
+ // Core Helpers - Batch Processing.
93
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
94
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
95
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
96
+
97
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
98
+
99
+ // Elementor.
100
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
101
+ // Add "elementor" in import [queue].
102
+ // @todo Remove required `allow_url_fopen` support.
103
+ if ( ini_get( 'allow_url_fopen' ) ) {
104
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
105
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
106
+ self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
107
+ }
108
+ }
109
+
110
+ // Beaver Builder.
111
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
112
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
113
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
114
+ self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
115
+ }
116
+
117
+ // Divi.
118
+ if ( ( 'divi' === $default_page_builder ) && ( class_exists( 'ET_Builder_Plugin' ) || Cartflows_Compatibility::get_instance()->is_divi_enabled() ) ) {
119
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi.php';
120
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-divi-batch.php';
121
+ self::$batch_instance_divi = new Cartflows_Importer_Divi_Batch();
122
+ }
123
+
124
+ // Gutenberg.
125
+ if ( ( 'gutenberg' === $default_page_builder ) ) {
126
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg.php';
127
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-gutenberg-batch.php';
128
+ self::$batch_instance_gb = new Cartflows_Importer_Gutenberg_Batch();
129
+ }
130
+
131
+ // Start image importing after site import complete.
132
+ add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
133
+ add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
134
+ add_filter( 'upload_mimes', array( $this, 'custom_upload_mimes' ) );
135
+ add_filter( 'wp_prepare_attachment_for_js', array( $this, 'add_svg_image_support' ), 10, 3 );
136
+ }
137
+
138
+ /**
139
+ * Added .svg files as supported format in the uploader.
140
+ *
141
+ * @since 1.1.4
142
+ *
143
+ * @param array $mimes Already supported mime types.
144
+ */
145
+ public function custom_upload_mimes( $mimes ) {
146
+
147
+ // Allow SVG files.
148
+ $mimes['svg'] = 'image/svg+xml';
149
+ $mimes['svgz'] = 'image/svg+xml';
150
+
151
+ // Allow XML files.
152
+ $mimes['xml'] = 'text/xml';
153
+
154
+ return $mimes;
155
+ }
156
+
157
+ /**
158
+ * Add SVG image support
159
+ *
160
+ * @since 1.1.4
161
+ *
162
+ * @param array $response Attachment response.
163
+ * @param object $attachment Attachment object.
164
+ * @param array $meta Attachment meta data.
165
+ */
166
+ public function add_svg_image_support( $response, $attachment, $meta ) {
167
+ if ( ! function_exists( 'simplexml_load_file' ) ) {
168
+ return $response;
169
+ }
170
+
171
+ if ( ! empty( $response['sizes'] ) ) {
172
+ return $response;
173
+ }
174
+
175
+ if ( 'image/svg+xml' !== $response['mime'] ) {
176
+ return $response;
177
+ }
178
+
179
+ $svg_path = get_attached_file( $attachment->ID );
180
+
181
+ $dimensions = self::get_svg_dimensions( $svg_path );
182
+
183
+ $response['sizes'] = array(
184
+ 'full' => array(
185
+ 'url' => $response['url'],
186
+ 'width' => $dimensions->width,
187
+ 'height' => $dimensions->height,
188
+ 'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait',
189
+ ),
190
+ );
191
+
192
+ return $response;
193
+ }
194
+
195
+ /**
196
+ * Get SVG Dimensions
197
+ *
198
+ * @since 1.1.4.
199
+ *
200
+ * @param string $svg SVG file path.
201
+ * @return array Return SVG file height & width for valid SVG file.
202
+ */
203
+ public static function get_svg_dimensions( $svg ) {
204
+
205
+ $svg = simplexml_load_file( $svg );
206
+
207
+ if ( false === $svg ) {
208
+ $width = '0';
209
+ $height = '0';
210
+ } else {
211
+ $attributes = $svg->attributes();
212
+ $width = (string) $attributes->width;
213
+ $height = (string) $attributes->height;
214
+ }
215
+
216
+ return (object) array(
217
+ 'width' => $width,
218
+ 'height' => $height,
219
+ );
220
+ }
221
+
222
+ /**
223
+ * Batch Process Complete.
224
+ *
225
+ * @return void
226
+ */
227
+ public function complete_batch_import() {
228
+ wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
229
+ }
230
+
231
+ /**
232
+ * Start Image Import
233
+ *
234
+ * @param integer $post_id Post Id.
235
+ *
236
+ * @return void
237
+ */
238
+ public function start_batch_process( $post_id = '' ) {
239
+
240
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
241
+
242
+ wcf()->logger->import_log( '(✓) BATCH Started!' );
243
+ wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
244
+
245
+ // Add "elementor" in import [queue].
246
+ if ( 'beaver-builder' === $default_page_builder && self::$batch_instance_bb ) {
247
+
248
+ // Add to queue.
249
+ self::$batch_instance_bb->push_to_queue( $post_id );
250
+
251
+ // Dispatch Queue.
252
+ self::$batch_instance_bb->save()->dispatch();
253
+
254
+ wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
255
+
256
+ } elseif ( 'elementor' === $default_page_builder && self::$batch_instance_elementor ) {
257
+
258
+ // Add to queue.
259
+ self::$batch_instance_elementor->push_to_queue( $post_id );
260
+
261
+ // Dispatch Queue.
262
+ self::$batch_instance_elementor->save()->dispatch();
263
+
264
+ wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
265
+ } elseif ( 'divi' === $default_page_builder && self::$batch_instance_divi ) {
266
+
267
+ // Add to queue.
268
+ self::$batch_instance_divi->push_to_queue( $post_id );
269
+
270
+ // Dispatch Queue.
271
+ self::$batch_instance_divi->save()->dispatch();
272
+
273
+ wcf()->logger->import_log( '(✓) Dispatch "Divi" Request..' );
274
+ } elseif ( 'gutenberg' === $default_page_builder && self::$batch_instance_gb ) {
275
+
276
+ // Add to queue.
277
+ self::$batch_instance_gb->push_to_queue( $post_id );
278
+
279
+ // Dispatch Queue.
280
+ self::$batch_instance_gb->save()->dispatch();
281
+
282
+ wcf()->logger->import_log( '(✓) Dispatch "Gutenberg" Request..' );
283
+ } else {
284
+ wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
285
+ }
286
+ }
287
+
288
+ }
289
+
290
+ /**
291
+ * Kicking this off by calling 'get_instance()' method
292
+ */
293
+ CartFlows_Batch_Process::get_instance();
294
+
295
+ endif;
classes/batch-process/class-cartflows-importer-elementor.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
- /**
3
- * Elementor Importer
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- namespace Elementor\TemplateLibrary;
9
-
10
- use Elementor\Core\Base\Document;
11
- use Elementor\DB;
12
- use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
- use Elementor\Core\Settings\Manager as SettingsManager;
14
- use Elementor\Core\Settings\Page\Model;
15
- use Elementor\Editor;
16
- use Elementor\Plugin;
17
- use Elementor\Settings;
18
- use Elementor\Utils;
19
-
20
- if ( ! defined( 'ABSPATH' ) ) {
21
- exit; // Exit if accessed directly.
22
- }
23
-
24
- /**
25
- * Elementor template library local source.
26
- *
27
- * Elementor template library local source handler class is responsible for
28
- * handling local Elementor templates saved by the user locally on his site.
29
- *
30
- * @since 1.0.0
31
- */
32
- class CartFlows_Importer_Elementor extends Source_Local {
33
-
34
- /**
35
- * Import single template
36
- *
37
- * @param int $post_id post ID.
38
- */
39
- public function import_single_template( $post_id ) {
40
-
41
- $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
-
43
- if ( empty( $rest_content ) ) {
44
- $data = __( 'Invalid content.', 'cartflows' );
45
- wcf()->logger->import_log( '(✕) ' . $data );
46
- }
47
-
48
- if ( is_array( $rest_content ) ) {
49
- $content = $rest_content;
50
- } else {
51
- $rest_content = add_magic_quotes( $rest_content );
52
- $content = json_decode( $rest_content, true );
53
- }
54
-
55
- if ( ! is_array( $content ) ) {
56
- $data = __( 'Invalid content. Expected an array.', 'cartflows' );
57
- wcf()->logger->import_log( '(✕) ' . $data );
58
- wcf()->logger->import_log( $content );
59
- } else {
60
-
61
- wcf()->logger->import_log( '(✓) Processing Request..' );
62
-
63
- // Import the data.
64
- $content = $this->process_export_import_content( $content, 'on_import' );
65
-
66
- // Update content.
67
- update_metadata( 'post', $post_id, '_elementor_data', $content );
68
-
69
- $this->clear_cache();
70
-
71
- wcf()->logger->import_log( '(✓) Process Complete' );
72
- }
73
- }
74
-
75
- /**
76
- * Clear Cache.
77
- *
78
- * @since 1.0.0
79
- */
80
- public function clear_cache() {
81
- // Clear 'Elementor' file cache.
82
- if ( class_exists( '\Elementor\Plugin' ) ) {
83
- \Elementor\Plugin::$instance->files_manager->clear_cache();
84
- }
85
- }
86
- }
1
+ <?php
2
+ /**
3
+ * Elementor Importer
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ namespace Elementor\TemplateLibrary;
9
+
10
+ use Elementor\Core\Base\Document;
11
+ use Elementor\DB;
12
+ use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
+ use Elementor\Core\Settings\Manager as SettingsManager;
14
+ use Elementor\Core\Settings\Page\Model;
15
+ use Elementor\Editor;
16
+ use Elementor\Plugin;
17
+ use Elementor\Settings;
18
+ use Elementor\Utils;
19
+
20
+ if ( ! defined( 'ABSPATH' ) ) {
21
+ exit; // Exit if accessed directly.
22
+ }
23
+
24
+ /**
25
+ * Elementor template library local source.
26
+ *
27
+ * Elementor template library local source handler class is responsible for
28
+ * handling local Elementor templates saved by the user locally on his site.
29
+ *
30
+ * @since 1.0.0
31
+ */
32
+ class CartFlows_Importer_Elementor extends Source_Local {
33
+
34
+ /**
35
+ * Import single template
36
+ *
37
+ * @param int $post_id post ID.
38
+ */
39
+ public function import_single_template( $post_id ) {
40
+
41
+ $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
+
43
+ if ( empty( $rest_content ) ) {
44
+ $data = __( 'Invalid content.', 'cartflows' );
45
+ wcf()->logger->import_log( '(✕) ' . $data );
46
+ }
47
+
48
+ if ( is_array( $rest_content ) ) {
49
+ $content = $rest_content;
50
+ } else {
51
+ $rest_content = add_magic_quotes( $rest_content );
52
+ $content = json_decode( $rest_content, true );
53
+ }
54
+
55
+ if ( ! is_array( $content ) ) {
56
+ $data = __( 'Invalid content. Expected an array.', 'cartflows' );
57
+ wcf()->logger->import_log( '(✕) ' . $data );
58
+ wcf()->logger->import_log( $content );
59
+ } else {
60
+
61
+ wcf()->logger->import_log( '(✓) Processing Request..' );
62
+
63
+ // Import the data.
64
+ $content = $this->process_export_import_content( $content, 'on_import' );
65
+
66
+ // Update content.
67
+ update_metadata( 'post', $post_id, '_elementor_data', $content );
68
+
69
+ $this->clear_cache();
70
+
71
+ wcf()->logger->import_log( '(✓) Process Complete' );
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Clear Cache.
77
+ *
78
+ * @since 1.0.0
79
+ */
80
+ public function clear_cache() {
81
+ // Clear 'Elementor' file cache.
82
+ if ( class_exists( '\Elementor\Plugin' ) ) {
83
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
84
+ }
85
+ }
86
+ }
classes/batch-process/class-cartflows-importer-gutenberg-batch.php CHANGED
@@ -1,63 +1,63 @@
1
- <?php
2
- /**
3
- * Gutenberg Batch Process
4
- *
5
- * @package CartFlows
6
- * @since x.x.x
7
- */
8
-
9
- if ( ! class_exists( 'Cartflows_Importer_Gutenberg_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
-
11
- /**
12
- * Image Background Process
13
- *
14
- * @since x.x.x
15
- */
16
- class Cartflows_Importer_Gutenberg_Batch extends WP_Background_Process {
17
-
18
- /**
19
- * Image Process
20
- *
21
- * @var string
22
- */
23
- protected $action = 'cartflows_gutenberg_image_process';
24
-
25
- /**
26
- * Task
27
- *
28
- * Override this method to perform any actions required on each
29
- * queue item. Return the modified item for further processing
30
- * in the next pass through. Or, return false to remove the
31
- * item from the queue.
32
- *
33
- * @since x.x.x
34
- *
35
- * @param integer $post_id Post Id.
36
- * @return mixed
37
- */
38
- protected function task( $post_id ) {
39
-
40
- CartFlows_Importer_Gutenberg::get_instance()->import_single_post( $post_id );
41
-
42
- return false;
43
- }
44
-
45
- /**
46
- * Complete
47
- *
48
- * Override if applicable, but ensure that the below actions are
49
- * performed, or, call parent::complete().
50
- *
51
- * @since x.x.x
52
- */
53
- protected function complete() {
54
-
55
- parent::complete();
56
-
57
- do_action( 'cartflows_import_complete' );
58
-
59
- }
60
-
61
- }
62
-
63
- endif;
1
+ <?php
2
+ /**
3
+ * Gutenberg Batch Process
4
+ *
5
+ * @package CartFlows
6
+ * @since x.x.x
7
+ */
8
+
9
+ if ( ! class_exists( 'Cartflows_Importer_Gutenberg_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
+
11
+ /**
12
+ * Image Background Process
13
+ *
14
+ * @since x.x.x
15
+ */
16
+ class Cartflows_Importer_Gutenberg_Batch extends WP_Background_Process {
17
+
18
+ /**
19
+ * Image Process
20
+ *
21
+ * @var string
22
+ */
23
+ protected $action = 'cartflows_gutenberg_image_process';
24
+
25
+ /**
26
+ * Task
27
+ *
28
+ * Override this method to perform any actions required on each
29
+ * queue item. Return the modified item for further processing
30
+ * in the next pass through. Or, return false to remove the
31
+ * item from the queue.
32
+ *
33
+ * @since x.x.x
34
+ *
35
+ * @param integer $post_id Post Id.
36
+ * @return mixed
37
+ */
38
+ protected function task( $post_id ) {
39
+
40
+ CartFlows_Importer_Gutenberg::get_instance()->import_single_post( $post_id );
41
+
42
+ return false;
43
+ }
44
+
45
+ /**
46
+ * Complete
47
+ *
48
+ * Override if applicable, but ensure that the below actions are
49
+ * performed, or, call parent::complete().
50
+ *
51
+ * @since x.x.x
52
+ */
53
+ protected function complete() {
54
+
55
+ parent::complete();
56
+
57
+ do_action( 'cartflows_import_complete' );
58
+
59
+ }
60
+
61
+ }
62
+
63
+ endif;
classes/batch-process/class-cartflows-importer-gutenberg.php CHANGED
@@ -1,90 +1,90 @@
1
- <?php
2
- /**
3
- * Gutenberg Importer
4
- *
5
- * @package CartFlows
6
- * @since x.x.x
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer_Gutenberg' ) ) :
10
-
11
- /**
12
- * CartFlows Import Gutenberg
13
- *
14
- * @since x.x.x
15
- */
16
- class CartFlows_Importer_Gutenberg {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since x.x.x
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since x.x.x
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
-
35
- if ( ! isset( self::$instance ) ) {
36
- self::$instance = new self();
37
- }
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since x.x.x
45
- */
46
- public function __construct() {}
47
-
48
- /**
49
- * Update post meta.
50
- *
51
- * @param integer $post_id Post ID.
52
- * @return void
53
- */
54
- public function import_single_post( $post_id = 0 ) {
55
-
56
- // Download and replace images.
57
- $content = get_post_field( 'post_content', $post_id );
58
-
59
- if ( empty( $content ) ) {
60
- wcf()->logger->import_log( '(✕) Not have "Gutenberg" Data. Post content is empty!' );
61
- } else {
62
-
63
- wcf()->logger->import_log( '(✓) Processing Request..' );
64
-
65
- // Update hotlink images.
66
- $content = CartFlows_Importer::get_instance()->get_content( $content );
67
-
68
- // Fix for gutenberg invalid html due & -> &amp -> \u0026amp.
69
- $content = str_replace( '&amp;', "\u0026amp;", $content );
70
-
71
- // Update post content.
72
- wp_update_post(
73
- array(
74
- 'ID' => $post_id,
75
- 'post_content' => $content,
76
- )
77
- );
78
-
79
- wcf()->logger->import_log( '(✓) Process Complete' );
80
- }
81
- }
82
-
83
- }
84
-
85
- /**
86
- * Initialize class object with 'get_instance()' method
87
- */
88
- CartFlows_Importer_Gutenberg::get_instance();
89
-
90
- endif;
1
+ <?php
2
+ /**
3
+ * Gutenberg Importer
4
+ *
5
+ * @package CartFlows
6
+ * @since x.x.x
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer_Gutenberg' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import Gutenberg
13
+ *
14
+ * @since x.x.x
15
+ */
16
+ class CartFlows_Importer_Gutenberg {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since x.x.x
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since x.x.x
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+
35
+ if ( ! isset( self::$instance ) ) {
36
+ self::$instance = new self();
37
+ }
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since x.x.x
45
+ */
46
+ public function __construct() {}
47
+
48
+ /**
49
+ * Update post meta.
50
+ *
51
+ * @param integer $post_id Post ID.
52
+ * @return void
53
+ */
54
+ public function import_single_post( $post_id = 0 ) {
55
+
56
+ // Download and replace images.
57
+ $content = get_post_field( 'post_content', $post_id );
58
+
59
+ if ( empty( $content ) ) {
60
+ wcf()->logger->import_log( '(✕) Not have "Gutenberg" Data. Post content is empty!' );
61
+ } else {
62
+
63
+ wcf()->logger->import_log( '(✓) Processing Request..' );
64
+
65
+ // Update hotlink images.
66
+ $content = CartFlows_Importer::get_instance()->get_content( $content );
67
+
68
+ // Fix for gutenberg invalid html due & -> &amp -> \u0026amp.
69
+ $content = str_replace( '&amp;', "\u0026amp;", $content );
70
+
71
+ // Update post content.
72
+ wp_update_post(
73
+ array(
74
+ 'ID' => $post_id,
75
+ 'post_content' => $content,
76
+ )
77
+ );
78
+
79
+ wcf()->logger->import_log( '(✓) Process Complete' );
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ /**
86
+ * Initialize class object with 'get_instance()' method
87
+ */
88
+ CartFlows_Importer_Gutenberg::get_instance();
89
+
90
+ endif;
classes/class-cartflows-admin-fields.php CHANGED
@@ -1,271 +1,271 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Admin Fields.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- /**
9
- * Class Cartflows_Admin_Fields.
10
- */
11
- class Cartflows_Admin_Fields {
12
-
13
- /**
14
- * Title Field
15
- *
16
- * @param array $args Args.
17
- * @return string
18
- */
19
- public static function title_field( $args ) {
20
-
21
- $title = $args['title'];
22
- $description = isset( $args['description'] ) ? $args['description'] : '';
23
-
24
- $output = '<h4 class="form-field wcf-title-field">';
25
- $output .= '<span>' . $title . '</span>';
26
- $output .= '</h4>';
27
-
28
- if ( ! empty( $description ) ) {
29
- $output .= '<div class="form-field-desc">';
30
- $output .= '<p>' . $description . '</p>';
31
- $output .= '</div>';
32
- }
33
-
34
- return $output;
35
- }
36
-
37
- /**
38
- * Text Field
39
- *
40
- * @param array $args Args.
41
- * @return string
42
- */
43
- public static function text_field( $args ) {
44
-
45
- $id = $args['id'];
46
- $name = $args['name'];
47
- $title = $args['title'];
48
- $value = $args['value'];
49
- $description = isset( $args['description'] ) ? $args['description'] : '';
50
- $placeholder = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
51
-
52
- $output = '<div class="form-field" id="form-field-' . $id . '">';
53
- $output .= '<label for="' . $id . '">' . $title . '</label>';
54
- $output .= '<input placeholder="' . $placeholder . '" type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_attr( $value ) . '">';
55
- $output .= '</div>';
56
-
57
- if ( ! empty( $description ) ) {
58
- $output .= '<div class="form-field-desc">';
59
- $output .= '<p>';
60
- $output .= $description;
61
- $output .= '</p>';
62
- $output .= '</div>';
63
- }
64
-
65
- return $output;
66
- }
67
-
68
- /**
69
- * URL Field
70
- *
71
- * @param array $args Args.
72
- * @return string
73
- */
74
- public static function url_field( $args ) {
75
-
76
- $id = $args['id'];
77
- $name = $args['name'];
78
- $title = $args['title'];
79
- $value = $args['value'];
80
-
81
- $output = '<div class="form-field">';
82
- $output .= '<label for="' . $id . '">' . $title . '</label>';
83
- $output .= '<input type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_url( $value ) . '">';
84
- $output .= '</div>';
85
-
86
- return $output;
87
- }
88
-
89
- /**
90
- * Checkbox Field
91
- *
92
- * @param array $args Args.
93
- * @return string
94
- */
95
- public static function checkobox_field( $args ) {
96
-
97
- $id = $args['id'];
98
- $name = $args['name'];
99
- $title = $args['title'];
100
- $value = $args['value'];
101
-
102
- $output = '<div class="form-field" id="form-field-' . $id . '">';
103
- $output .= '<label for="' . $id . '">';
104
- $output .= '<input type="hidden" id="wcf_hid_' . $id . '" name="' . $name . '" value="disable">';
105
- $output .= '<input type="checkbox" id="wcf_' . $id . '" name="' . $name . '" value="enable" ' . checked( $value, 'enable', false ) . '>';
106
- $output .= $title;
107
- $output .= '</label>';
108
- $output .= '</div>';
109
-
110
- return $output;
111
- }
112
-
113
- /**
114
- * Radio Field
115
- *
116
- * @param array $args Args.
117
- * @return string
118
- */
119
- public static function radio_field( $args ) {
120
-
121
- $name = $args['name'];
122
- $id = $args['id'];
123
- $options = $args['options'];
124
- $value = $args['value'];
125
-
126
- $output = '';
127
-
128
- if ( isset( $args['title'] ) ) {
129
- $output .= '<h4 class="form-field-label">';
130
- $output .= '<span>' . $args['title'] . '</span>';
131
- $output .= '</h4>';
132
- }
133
-
134
- foreach ( $options as $type => $data ) {
135
-
136
- $output .= '<div class="form-field">';
137
- $output .= '<label for="' . $id . '">';
138
- $output .= '<input type="radio" class="wcf_permalink_structure" name="' . $name . '" value="' . $type . '" ' . checked( $value, $type, false ) . '>' . $data['label'] . '</label>';
139
- $output .= '<div class="form-field-desc">';
140
- $output .= '<p>';
141
-
142
- $output .= $data['description'];
143
-
144
- $output .= '</p>';
145
- $output .= '</div>';
146
- $output .= '</div>';
147
- }
148
-
149
- return $output;
150
- }
151
-
152
- /**
153
- * Select Field
154
- *
155
- * @since 1.1.4
156
- *
157
- * @param array $args Args.
158
- * @return string
159
- */
160
- public static function select_field( $args ) {
161
-
162
- $id = $args['id'];
163
- $name = $args['name'];
164
- $title = $args['title'];
165
- $description = $args['description'];
166
- $value = $args['value'];
167
- $options = $args['options'];
168
-
169
- $output = '<div class="form-field" id="form-field-' . $id . '">';
170
-
171
- $output .= '<div class="form-field-label">';
172
- $output .= $title;
173
- $output .= '</div>';
174
-
175
- $output .= '<div class="form-field-data">';
176
- $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
177
- foreach ( $options as $option_value => $option_title ) {
178
- $output .= '<option value="' . $option_value . '" ' . selected( $value, $option_value, false ) . '>' . $option_title . '</option>';
179
- }
180
- $output .= '</select>';
181
- $output .= '</div>';
182
-
183
- $output .= '<div class="form-field-desc">';
184
- $output .= '<p>';
185
- $output .= $description;
186
- $output .= '</p>';
187
- $output .= '</div>';
188
- $output .= '</div>';
189
-
190
- return $output;
191
- }
192
-
193
- /**
194
- * Checkout Selection Field
195
- *
196
- * @param array $args Args.
197
- * @return string
198
- */
199
- public static function flow_checkout_selection_field( $args ) {
200
-
201
- $id = $args['id'];
202
- $name = $args['name'];
203
- $title = $args['title'];
204
- $value = $args['value'];
205
-
206
- $checkout_steps = get_posts(
207
- array(
208
- 'posts_per_page' => -1,
209
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
210
- 'post_status' => 'publish',
211
- 'orderby' => 'ID',
212
- 'order' => 'ASC',
213
- 'tax_query' => array( //phpcs:ignore
214
- array(
215
- 'taxonomy' => CARTFLOWS_TAXONOMY_STEP_TYPE,
216
- 'field' => 'slug',
217
- 'terms' => 'checkout',
218
- ),
219
- ),
220
- )
221
- );
222
-
223
- $output = '<div class="form-field" id="form-field-' . $id . '">';
224
-
225
- $output .= '<div class="form-field-label">';
226
- $output .= '<label for="' . $id . '">';
227
- $output .= $title;
228
- $output .= '</label>';
229
- $output .= '</div>';
230
-
231
- $output .= '<div class="form-field-data">';
232
- $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
233
-
234
- if ( ! empty( $checkout_steps ) ) {
235
- $output .= '<option value="">' . __( 'Select', 'cartflows' ) . '</option>';
236
- } else {
237
-
238
- $output .= '<option value="">' . __( 'No Checkout Steps', 'cartflows' ) . '</option>';
239
- }
240
-
241
- foreach ( $checkout_steps as $index => $step_data ) {
242
-
243
- $output .= '<option value="' . $step_data->ID . '" ' . selected( $value, $step_data->ID, false ) . '>' . $step_data->post_title . ' (#' . $step_data->ID . ') </option>';
244
- }
245
-
246
- $output .= '</select>';
247
- $output .= '</div>';
248
-
249
- if ( '' !== $value ) {
250
- $output .= '<div class="form-field-actions">';
251
- $output .= '<a href="' . get_edit_post_link( $value ) . '" target="_blank" class="" title="Edit">';
252
- $output .= '<span class="dashicons dashicons-edit"></span>';
253
- $output .= '<span class="">Edit</span>';
254
- $output .= '</a>';
255
- $output .= '<a href="' . get_permalink( $value ) . '" target="_blank" class="" title="View">';
256
- $output .= '<span class="dashicons dashicons-visibility"></span>';
257
- $output .= '<span class="">View</span>';
258
- $output .= '</a>';
259
- $output .= '</div>';
260
- }
261
-
262
- $output .= '<div class="form-field-desc">';
263
- /* translators: %s: link */
264
- $output .= '<p>' . sprintf( __( 'Be sure not to add any product in above selected Global Checkout step. Please read information about how to set up Global Checkout %1$shere%2$s.', 'cartflows' ), '<a href="https://cartflows.com/docs/global-checkout/" target="_blank">', '</a>' ) . '</p>';
265
- $output .= '</div>';
266
-
267
- $output .= '</div>';
268
-
269
- return $output;
270
- }
271
- }
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Admin Fields.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Admin_Fields.
10
+ */
11
+ class Cartflows_Admin_Fields {
12
+
13
+ /**
14
+ * Title Field
15
+ *
16
+ * @param array $args Args.
17
+ * @return string
18
+ */
19
+ public static function title_field( $args ) {
20
+
21
+ $title = $args['title'];
22
+ $description = isset( $args['description'] ) ? $args['description'] : '';
23
+
24
+ $output = '<h4 class="form-field wcf-title-field">';
25
+ $output .= '<span>' . $title . '</span>';
26
+ $output .= '</h4>';
27
+
28
+ if ( ! empty( $description ) ) {
29
+ $output .= '<div class="form-field-desc">';
30
+ $output .= '<p>' . $description . '</p>';
31
+ $output .= '</div>';
32
+ }
33
+
34
+ return $output;
35
+ }
36
+
37
+ /**
38
+ * Text Field
39
+ *
40
+ * @param array $args Args.
41
+ * @return string
42
+ */
43
+ public static function text_field( $args ) {
44
+
45
+ $id = $args['id'];
46
+ $name = $args['name'];
47
+ $title = $args['title'];
48
+ $value = $args['value'];
49
+ $description = isset( $args['description'] ) ? $args['description'] : '';
50
+ $placeholder = isset( $args['placeholder'] ) ? $args['placeholder'] : '';
51
+
52
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
53
+ $output .= '<label for="' . $id . '">' . $title . '</label>';
54
+ $output .= '<input placeholder="' . $placeholder . '" type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_attr( $value ) . '">';
55
+ $output .= '</div>';
56
+
57
+ if ( ! empty( $description ) ) {
58
+ $output .= '<div class="form-field-desc">';
59
+ $output .= '<p>';
60
+ $output .= $description;
61
+ $output .= '</p>';
62
+ $output .= '</div>';
63
+ }
64
+
65
+ return $output;
66
+ }
67
+
68
+ /**
69
+ * URL Field
70
+ *
71
+ * @param array $args Args.
72
+ * @return string
73
+ */
74
+ public static function url_field( $args ) {
75
+
76
+ $id = $args['id'];
77
+ $name = $args['name'];
78
+ $title = $args['title'];
79
+ $value = $args['value'];
80
+
81
+ $output = '<div class="form-field">';
82
+ $output .= '<label for="' . $id . '">' . $title . '</label>';
83
+ $output .= '<input type="text" name="' . $name . '" id="' . $id . '" class="placeholder placeholder-active" value="' . esc_url( $value ) . '">';
84
+ $output .= '</div>';
85
+
86
+ return $output;
87
+ }
88
+
89
+ /**
90
+ * Checkbox Field
91
+ *
92
+ * @param array $args Args.
93
+ * @return string
94
+ */
95
+ public static function checkobox_field( $args ) {
96
+
97
+ $id = $args['id'];
98
+ $name = $args['name'];
99
+ $title = $args['title'];
100
+ $value = $args['value'];
101
+
102
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
103
+ $output .= '<label for="' . $id . '">';
104
+ $output .= '<input type="hidden" id="wcf_hid_' . $id . '" name="' . $name . '" value="disable">';
105
+ $output .= '<input type="checkbox" id="wcf_' . $id . '" name="' . $name . '" value="enable" ' . checked( $value, 'enable', false ) . '>';
106
+ $output .= $title;
107
+ $output .= '</label>';
108
+ $output .= '</div>';
109
+
110
+ return $output;
111
+ }
112
+
113
+ /**
114
+ * Radio Field
115
+ *
116
+ * @param array $args Args.
117
+ * @return string
118
+ */
119
+ public static function radio_field( $args ) {
120
+
121
+ $name = $args['name'];
122
+ $id = $args['id'];
123
+ $options = $args['options'];
124
+ $value = $args['value'];
125
+
126
+ $output = '';
127
+
128
+ if ( isset( $args['title'] ) ) {
129
+ $output .= '<h4 class="form-field-label">';
130
+ $output .= '<span>' . $args['title'] . '</span>';
131
+ $output .= '</h4>';
132
+ }
133
+
134
+ foreach ( $options as $type => $data ) {
135
+
136
+ $output .= '<div class="form-field">';
137
+ $output .= '<label for="' . $id . '">';
138
+ $output .= '<input type="radio" class="wcf_permalink_structure" name="' . $name . '" value="' . $type . '" ' . checked( $value, $type, false ) . '>' . $data['label'] . '</label>';
139
+ $output .= '<div class="form-field-desc">';
140
+ $output .= '<p>';
141
+
142
+ $output .= $data['description'];
143
+
144
+ $output .= '</p>';
145
+ $output .= '</div>';
146
+ $output .= '</div>';
147
+ }
148
+
149
+ return $output;
150
+ }
151
+
152
+ /**
153
+ * Select Field
154
+ *
155
+ * @since 1.1.4
156
+ *
157
+ * @param array $args Args.
158
+ * @return string
159
+ */
160
+ public static function select_field( $args ) {
161
+
162
+ $id = $args['id'];
163
+ $name = $args['name'];
164
+ $title = $args['title'];
165
+ $description = $args['description'];
166
+ $value = $args['value'];
167
+ $options = $args['options'];
168
+
169
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
170
+
171
+ $output .= '<div class="form-field-label">';
172
+ $output .= $title;
173
+ $output .= '</div>';
174
+
175
+ $output .= '<div class="form-field-data">';
176
+ $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
177
+ foreach ( $options as $option_value => $option_title ) {
178
+ $output .= '<option value="' . $option_value . '" ' . selected( $value, $option_value, false ) . '>' . $option_title . '</option>';
179
+ }
180
+ $output .= '</select>';
181
+ $output .= '</div>';
182
+
183
+ $output .= '<div class="form-field-desc">';
184
+ $output .= '<p>';
185
+ $output .= $description;
186
+ $output .= '</p>';
187
+ $output .= '</div>';
188
+ $output .= '</div>';
189
+
190
+ return $output;
191
+ }
192
+
193
+ /**
194
+ * Checkout Selection Field
195
+ *
196
+ * @param array $args Args.
197
+ * @return string
198
+ */
199
+ public static function flow_checkout_selection_field( $args ) {
200
+
201
+ $id = $args['id'];
202
+ $name = $args['name'];
203
+ $title = $args['title'];
204
+ $value = $args['value'];
205
+
206
+ $checkout_steps = get_posts(
207
+ array(
208
+ 'posts_per_page' => -1,
209
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
210
+ 'post_status' => 'publish',
211
+ 'orderby' => 'ID',
212
+ 'order' => 'ASC',
213
+ 'tax_query' => array( //phpcs:ignore
214
+ array(
215
+ 'taxonomy' => CARTFLOWS_TAXONOMY_STEP_TYPE,
216
+ 'field' => 'slug',
217
+ 'terms' => 'checkout',
218
+ ),
219
+ ),
220
+ )
221
+ );
222
+
223
+ $output = '<div class="form-field" id="form-field-' . $id . '">';
224
+
225
+ $output .= '<div class="form-field-label">';
226
+ $output .= '<label for="' . $id . '">';
227
+ $output .= $title;
228
+ $output .= '</label>';
229
+ $output .= '</div>';
230
+
231
+ $output .= '<div class="form-field-data">';
232
+ $output .= '<select id="wcf_' . $id . '" name="' . $name . '">';
233
+
234
+ if ( ! empty( $checkout_steps ) ) {
235
+ $output .= '<option value="">' . __( 'Select', 'cartflows' ) . '</option>';
236
+ } else {
237
+
238
+ $output .= '<option value="">' . __( 'No Checkout Steps', 'cartflows' ) . '</option>';
239
+ }
240
+
241
+ foreach ( $checkout_steps as $index => $step_data ) {
242
+
243
+ $output .= '<option value="' . $step_data->ID . '" ' . selected( $value, $step_data->ID, false ) . '>' . $step_data->post_title . ' (#' . $step_data->ID . ') </option>';
244
+ }
245
+
246
+ $output .= '</select>';
247
+ $output .= '</div>';
248
+
249
+ if ( '' !== $value ) {
250
+ $output .= '<div class="form-field-actions">';
251
+ $output .= '<a href="' . get_edit_post_link( $value ) . '" target="_blank" class="" title="Edit">';
252
+ $output .= '<span class="dashicons dashicons-edit"></span>';
253
+ $output .= '<span class="">Edit</span>';
254
+ $output .= '</a>';
255
+ $output .= '<a href="' . get_permalink( $value ) . '" target="_blank" class="" title="View">';
256
+ $output .= '<span class="dashicons dashicons-visibility"></span>';
257
+ $output .= '<span class="">View</span>';
258
+ $output .= '</a>';
259
+ $output .= '</div>';
260
+ }
261
+
262
+ $output .= '<div class="form-field-desc">';
263
+ /* translators: %s: link */
264
+ $output .= '<p>' . sprintf( __( 'Be sure not to add any product in above selected Global Checkout step. Please read information about how to set up Global Checkout %1$shere%2$s.', 'cartflows' ), '<a href="https://cartflows.com/docs/global-checkout/" target="_blank">', '</a>' ) . '</p>';
265
+ $output .= '</div>';
266
+
267
+ $output .= '</div>';
268
+
269
+ return $output;
270
+ }
271
+ }
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-api.php CHANGED
@@ -1,382 +1,382 @@
1
- <?php
2
- /**
3
- * CartFlows API
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_API' ) ) :
10
-
11
- /**
12
- * CartFlows API
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_API {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @access private
22
- * @var object Class object.
23
- * @since 1.0.0
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- *
43
- * @since 1.0.0
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get site URL.
50
- *
51
- * @since 1.0.0
52
- *
53
- * @return string Site URL.
54
- */
55
- public static function get_site_url() {
56
- return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
- }
58
-
59
- /**
60
- * Get Client Site Templates Rest API URL.
61
- *
62
- * @since 1.0.0
63
- *
64
- * @return string API site URL.
65
- */
66
- public static function get_step_endpoint_url() {
67
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
- }
69
-
70
- /**
71
- * Get Client Site Category Rest API URL.
72
- *
73
- * @since 1.0.0
74
- *
75
- * @return string API site URL.
76
- */
77
- public static function get_category_endpoint_url() {
78
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
- }
80
-
81
- /**
82
- * Get API request URL.
83
- *
84
- * @since 1.0.0
85
- *
86
- * @param string $api_base base of api request.
87
- * @return string API site URL.
88
- */
89
- public static function get_request_api_url( $api_base = '' ) {
90
- return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
- }
92
-
93
- /**
94
- * License Args.
95
- *
96
- * @return array License arguments.
97
- */
98
- public static function get_licence_args() {
99
- return apply_filters( 'cartflows_licence_args', array() );
100
- }
101
-
102
- /**
103
- * Get single demo.
104
- *
105
- * @since 1.0.0
106
- *
107
- * @param string $site_id Template ID of the site.
108
- * @return array Template data.
109
- */
110
- public static function get_template( $site_id ) {
111
- // @codingStandardsIgnoreStart
112
- $request_params = array(
113
- 'licence_args' => self::get_licence_args(),
114
- '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta,content',
115
- );
116
- // @codingStandardsIgnoreEnd
117
-
118
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
-
120
- $api_args = array(
121
- 'timeout' => 15,
122
- );
123
-
124
- $response = self::remote_get( $url, $api_args );
125
-
126
- if ( $response['success'] ) {
127
- $template = $response['data'];
128
- return array(
129
- 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
- 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
- 'data' => $template,
132
- 'original_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
- 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
134
- 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
135
- 'success' => $response['success'],
136
- );
137
- }
138
-
139
- return array(
140
- 'title' => '',
141
- 'post_meta' => array(),
142
- 'message' => $response['message'],
143
- 'data' => $response['data'],
144
- 'divi_content' => '',
145
- 'success' => $response['success'],
146
- );
147
- }
148
-
149
- /**
150
- * Get Cloud Templates
151
- *
152
- * @since 1.0.0
153
- *
154
- * @param array $args For selecting the demos (Search terms, pagination etc).
155
- * @return array CartFlows list.
156
- */
157
- public static function get_templates( $args = array() ) {
158
-
159
- $request_params = wp_parse_args(
160
- $args,
161
- array(
162
- 'page' => '1',
163
- 'per_page' => '100',
164
- )
165
- );
166
-
167
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
168
-
169
- $api_args = array(
170
- 'timeout' => 15,
171
- );
172
-
173
- $response = self::remote_get( $url, $api_args );
174
-
175
- if ( $response['success'] ) {
176
- $templates_data = $response['data'];
177
- $templates = array();
178
- foreach ( $templates_data as $key => $template ) {
179
-
180
- if ( ! isset( $template->id ) ) {
181
- continue;
182
- }
183
-
184
- $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
185
- $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
186
- $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
187
- $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
188
- $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
189
- $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
190
- $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
191
- $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
192
- $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
193
- }
194
-
195
- return array(
196
- 'templates' => $templates,
197
- 'templates_count' => $response['count'],
198
- 'data' => $response,
199
- );
200
- }
201
-
202
- return array(
203
- 'templates' => array(),
204
- 'templates_count' => 0,
205
- 'data' => $response,
206
- );
207
-
208
- }
209
-
210
- /**
211
- * Get categories.
212
- *
213
- * @since 1.0.0
214
- * @param array $args Arguments.
215
- * @return array Category data.
216
- */
217
- public static function get_categories( $args = array() ) {
218
-
219
- $request_params = apply_filters(
220
- 'cartflows_categories_api_params',
221
- wp_parse_args(
222
- $args,
223
- array(
224
- 'page' => '1',
225
- 'per_page' => '100',
226
- )
227
- )
228
- );
229
-
230
- $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
231
-
232
- $api_args = apply_filters(
233
- 'cartflows_api_args',
234
- array(
235
- 'timeout' => 15,
236
- )
237
- );
238
-
239
- $response = self::remote_get( $url, $api_args );
240
-
241
- if ( $response['success'] ) {
242
- $categories_data = $response['data'];
243
- $categories = array();
244
-
245
- foreach ( $categories_data as $key => $category ) {
246
- if ( isset( $category->count ) && ! empty( $category->count ) ) {
247
- $categories[] = array(
248
- 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
249
- 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
250
- 'description' => isset( $category->description ) ? $category->description : '',
251
- 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
252
- 'name' => isset( $category->name ) ? $category->name : '',
253
- 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
254
- 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
255
- 'parent' => isset( $category->parent ) ? $category->parent : '',
256
- );
257
- }
258
- }
259
-
260
- return array(
261
- 'categories' => $categories,
262
- 'categories_count' => $response['count'],
263
- 'data' => $response,
264
- );
265
- }
266
-
267
- return array(
268
- 'categories' => array(),
269
- 'categories_count' => 0,
270
- 'data' => $response,
271
- );
272
- }
273
-
274
- /**
275
- * Remote GET API Request
276
- *
277
- * @since 1.0.0
278
- *
279
- * @param string $url Target server API URL.
280
- * @param array $args Array of arguments for the API request.
281
- * @return mixed Return the API request result.
282
- */
283
- public static function remote_get( $url = '', $args = array() ) {
284
- $request = wp_remote_get( $url, $args );
285
- return self::request( $request );
286
- }
287
-
288
- /**
289
- * Remote POST API Request
290
- *
291
- * @since 1.0.0
292
- *
293
- * @param string $url Target server API URL.
294
- * @param array $args Array of arguments for the API request.
295
- * @return mixed Return the API request result.
296
- */
297
- public static function remote_post( $url = '', $args = array() ) {
298
- $request = wp_remote_post( $url, $args );
299
-
300
- return self::request( $request );
301
- }
302
-
303
- /**
304
- * Site API Request
305
- *
306
- * @since 1.0.0
307
- *
308
- * @param boolean $api_base Target server API URL.
309
- * @param array $args Array of arguments for the API request.
310
- * @return mixed Return the API request result.
311
- */
312
- public static function site_request( $api_base = '', $args = array() ) {
313
-
314
- $api_url = self::get_request_api_url( $api_base );
315
-
316
- return self::remote_post( $api_url, $args );
317
- }
318
-
319
- /**
320
- * API Request
321
- *
322
- * Handle the API request and return the result.
323
- *
324
- * @since 1.0.0
325
- *
326
- * @param array $request Array of arguments for the API request.
327
- * @return mixed Return the API request result.
328
- */
329
- public static function request( $request ) {
330
-
331
- // Is WP Error?
332
- if ( is_wp_error( $request ) ) {
333
- return array(
334
- 'success' => false,
335
- 'message' => $request->get_error_message(),
336
- 'data' => $request,
337
- 'count' => 0,
338
- );
339
- }
340
-
341
- // Invalid response code.
342
- if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
343
- return array(
344
- 'success' => false,
345
- 'message' => $request['response'],
346
- 'data' => $request,
347
- 'count' => 0,
348
- );
349
- }
350
-
351
- // Get body data.
352
- $body = wp_remote_retrieve_body( $request );
353
-
354
- // Is WP Error?
355
- if ( is_wp_error( $body ) ) {
356
- return array(
357
- 'success' => false,
358
- 'message' => $body->get_error_message(),
359
- 'data' => $request,
360
- 'count' => 0,
361
- );
362
- }
363
-
364
- // Decode body content.
365
- $body_decoded = json_decode( $body );
366
-
367
- return array(
368
- 'success' => true,
369
- 'message' => __( 'Request successfully processed!', 'cartflows' ),
370
- 'data' => (array) $body_decoded,
371
- 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
372
- );
373
- }
374
-
375
- }
376
-
377
- /**
378
- * Initialize class object with 'get_instance()' method
379
- */
380
- CartFlows_API::get_instance();
381
-
382
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows API
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_API' ) ) :
10
+
11
+ /**
12
+ * CartFlows API
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_API {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @access private
22
+ * @var object Class object.
23
+ * @since 1.0.0
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ *
43
+ * @since 1.0.0
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get site URL.
50
+ *
51
+ * @since 1.0.0
52
+ *
53
+ * @return string Site URL.
54
+ */
55
+ public static function get_site_url() {
56
+ return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
+ }
58
+
59
+ /**
60
+ * Get Client Site Templates Rest API URL.
61
+ *
62
+ * @since 1.0.0
63
+ *
64
+ * @return string API site URL.
65
+ */
66
+ public static function get_step_endpoint_url() {
67
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
+ }
69
+
70
+ /**
71
+ * Get Client Site Category Rest API URL.
72
+ *
73
+ * @since 1.0.0
74
+ *
75
+ * @return string API site URL.
76
+ */
77
+ public static function get_category_endpoint_url() {
78
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
+ }
80
+
81
+ /**
82
+ * Get API request URL.
83
+ *
84
+ * @since 1.0.0
85
+ *
86
+ * @param string $api_base base of api request.
87
+ * @return string API site URL.
88
+ */
89
+ public static function get_request_api_url( $api_base = '' ) {
90
+ return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
+ }
92
+
93
+ /**
94
+ * License Args.
95
+ *
96
+ * @return array License arguments.
97
+ */
98
+ public static function get_licence_args() {
99
+ return apply_filters( 'cartflows_licence_args', array() );
100
+ }
101
+
102
+ /**
103
+ * Get single demo.
104
+ *
105
+ * @since 1.0.0
106
+ *
107
+ * @param string $site_id Template ID of the site.
108
+ * @return array Template data.
109
+ */
110
+ public static function get_template( $site_id ) {
111
+ // @codingStandardsIgnoreStart
112
+ $request_params = array(
113
+ 'licence_args' => self::get_licence_args(),
114
+ '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta,content',
115
+ );
116
+ // @codingStandardsIgnoreEnd
117
+
118
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
+
120
+ $api_args = array(
121
+ 'timeout' => 15,
122
+ );
123
+
124
+ $response = self::remote_get( $url, $api_args );
125
+
126
+ if ( $response['success'] ) {
127
+ $template = $response['data'];
128
+ return array(
129
+ 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
+ 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
+ 'data' => $template,
132
+ 'original_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
+ 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
134
+ 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
135
+ 'success' => $response['success'],
136
+ );
137
+ }
138
+
139
+ return array(
140
+ 'title' => '',
141
+ 'post_meta' => array(),
142
+ 'message' => $response['message'],
143
+ 'data' => $response['data'],
144
+ 'divi_content' => '',
145
+ 'success' => $response['success'],
146
+ );
147
+ }
148
+
149
+ /**
150
+ * Get Cloud Templates
151
+ *
152
+ * @since 1.0.0
153
+ *
154
+ * @param array $args For selecting the demos (Search terms, pagination etc).
155
+ * @return array CartFlows list.
156
+ */
157
+ public static function get_templates( $args = array() ) {
158
+
159
+ $request_params = wp_parse_args(
160
+ $args,
161
+ array(
162
+ 'page' => '1',
163
+ 'per_page' => '100',
164
+ )
165
+ );
166
+
167
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
168
+
169
+ $api_args = array(
170
+ 'timeout' => 15,
171
+ );
172
+
173
+ $response = self::remote_get( $url, $api_args );
174
+
175
+ if ( $response['success'] ) {
176
+ $templates_data = $response['data'];
177
+ $templates = array();
178
+ foreach ( $templates_data as $key => $template ) {
179
+
180
+ if ( ! isset( $template->id ) ) {
181
+ continue;
182
+ }
183
+
184
+ $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
185
+ $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
186
+ $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
187
+ $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
188
+ $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
189
+ $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
190
+ $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
191
+ $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
192
+ $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
193
+ }
194
+
195
+ return array(
196
+ 'templates' => $templates,
197
+ 'templates_count' => $response['count'],
198
+ 'data' => $response,
199
+ );
200
+ }
201
+
202
+ return array(
203
+ 'templates' => array(),
204
+ 'templates_count' => 0,
205
+ 'data' => $response,
206
+ );
207
+
208
+ }
209
+
210
+ /**
211
+ * Get categories.
212
+ *
213
+ * @since 1.0.0
214
+ * @param array $args Arguments.
215
+ * @return array Category data.
216
+ */
217
+ public static function get_categories( $args = array() ) {
218
+
219
+ $request_params = apply_filters(
220
+ 'cartflows_categories_api_params',
221
+ wp_parse_args(
222
+ $args,
223
+ array(
224
+ 'page' => '1',
225
+ 'per_page' => '100',
226
+ )
227
+ )
228
+ );
229
+
230
+ $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
231
+
232
+ $api_args = apply_filters(
233
+ 'cartflows_api_args',
234
+ array(
235
+ 'timeout' => 15,
236
+ )
237
+ );
238
+
239
+ $response = self::remote_get( $url, $api_args );
240
+
241
+ if ( $response['success'] ) {
242
+ $categories_data = $response['data'];
243
+ $categories = array();
244
+
245
+ foreach ( $categories_data as $key => $category ) {
246
+ if ( isset( $category->count ) && ! empty( $category->count ) ) {
247
+ $categories[] = array(
248
+ 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
249
+ 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
250
+ 'description' => isset( $category->description ) ? $category->description : '',
251
+ 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
252
+ 'name' => isset( $category->name ) ? $category->name : '',
253
+ 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
254
+ 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
255
+ 'parent' => isset( $category->parent ) ? $category->parent : '',
256
+ );
257
+ }
258
+ }
259
+
260
+ return array(
261
+ 'categories' => $categories,
262
+ 'categories_count' => $response['count'],
263
+ 'data' => $response,
264
+ );
265
+ }
266
+
267
+ return array(
268
+ 'categories' => array(),
269
+ 'categories_count' => 0,
270
+ 'data' => $response,
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Remote GET API Request
276
+ *
277
+ * @since 1.0.0
278
+ *
279
+ * @param string $url Target server API URL.
280
+ * @param array $args Array of arguments for the API request.
281
+ * @return mixed Return the API request result.
282
+ */
283
+ public static function remote_get( $url = '', $args = array() ) {
284
+ $request = wp_remote_get( $url, $args );
285
+ return self::request( $request );
286
+ }
287
+
288
+ /**
289
+ * Remote POST API Request
290
+ *
291
+ * @since 1.0.0
292
+ *
293
+ * @param string $url Target server API URL.
294
+ * @param array $args Array of arguments for the API request.
295
+ * @return mixed Return the API request result.
296
+ */
297
+ public static function remote_post( $url = '', $args = array() ) {
298
+ $request = wp_remote_post( $url, $args );
299
+
300
+ return self::request( $request );
301
+ }
302
+
303
+ /**
304
+ * Site API Request
305
+ *
306
+ * @since 1.0.0
307
+ *
308
+ * @param boolean $api_base Target server API URL.
309
+ * @param array $args Array of arguments for the API request.
310
+ * @return mixed Return the API request result.
311
+ */
312
+ public static function site_request( $api_base = '', $args = array() ) {
313
+
314
+ $api_url = self::get_request_api_url( $api_base );
315
+
316
+ return self::remote_post( $api_url, $args );
317
+ }
318
+
319
+ /**
320
+ * API Request
321
+ *
322
+ * Handle the API request and return the result.
323
+ *
324
+ * @since 1.0.0
325
+ *
326
+ * @param array $request Array of arguments for the API request.
327
+ * @return mixed Return the API request result.
328
+ */
329
+ public static function request( $request ) {
330
+
331
+ // Is WP Error?
332
+ if ( is_wp_error( $request ) ) {
333
+ return array(
334
+ 'success' => false,
335
+ 'message' => $request->get_error_message(),
336
+ 'data' => $request,
337
+ 'count' => 0,
338
+ );
339
+ }
340
+
341
+ // Invalid response code.
342
+ if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
343
+ return array(
344
+ 'success' => false,
345
+ 'message' => $request['response'],
346
+ 'data' => $request,
347
+ 'count' => 0,
348
+ );
349
+ }
350
+
351
+ // Get body data.
352
+ $body = wp_remote_retrieve_body( $request );
353
+
354
+ // Is WP Error?
355
+ if ( is_wp_error( $body ) ) {
356
+ return array(
357
+ 'success' => false,
358
+ 'message' => $body->get_error_message(),
359
+ 'data' => $request,
360
+ 'count' => 0,
361
+ );
362
+ }
363
+
364
+ // Decode body content.
365
+ $body_decoded = json_decode( $body );
366
+
367
+ return array(
368
+ 'success' => true,
369
+ 'message' => __( 'Request successfully processed!', 'cartflows' ),
370
+ 'data' => (array) $body_decoded,
371
+ 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
372
+ );
373
+ }
374
+
375
+ }
376
+
377
+ /**
378
+ * Initialize class object with 'get_instance()' method
379
+ */
380
+ CartFlows_API::get_instance();
381
+
382
+ endif;
classes/class-cartflows-cloning.php CHANGED
@@ -1,465 +1,465 @@
1
- <?php
2
- /**
3
- * Cloning.
4
- *
5
- * @package cartflows-pro
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Cloning {
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_filter( 'post_row_actions', array( $this, 'clone_link' ), 99, 2 );
39
- add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
- add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
41
- }
42
-
43
- /**
44
- * Clone flow with steps and its meta.
45
- */
46
- public function clone_flow() {
47
-
48
- global $wpdb;
49
-
50
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_flow' === $_REQUEST['action'] ) ) ) {
51
- wp_die( 'No post to duplicate has been supplied!' );
52
- }
53
-
54
- /*
55
- * Nonce verification
56
- */
57
- if ( ! isset( $_GET['flow_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_clone_nonce'] ) ), basename( __FILE__ ) ) ) {
58
- return;
59
- }
60
-
61
- /**
62
- * Get the original post id
63
- */
64
- $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
65
-
66
- /**
67
- * And all the original post data then
68
- */
69
- $post = get_post( $post_id );
70
-
71
- /**
72
- * Assign current user to be the new post author
73
- */
74
- $current_user = wp_get_current_user();
75
- $new_post_author = $current_user->ID;
76
-
77
- /**
78
- * If post data exists, create the post duplicate
79
- */
80
- if ( isset( $post ) && null !== $post ) {
81
-
82
- /**
83
- * New post data array
84
- */
85
-
86
- $args = array(
87
- 'comment_status' => $post->comment_status,
88
- 'ping_status' => $post->ping_status,
89
- 'post_author' => $new_post_author,
90
- 'post_content' => $post->post_content,
91
- 'post_excerpt' => $post->post_excerpt,
92
- 'post_name' => $post->post_name,
93
- 'post_parent' => $post->post_parent,
94
- 'post_password' => $post->post_password,
95
- 'post_status' => $post->post_status,
96
- 'post_title' => $post->post_title . ' Clone',
97
- 'post_type' => $post->post_type,
98
- 'to_ping' => $post->to_ping,
99
- 'menu_order' => $post->menu_order,
100
- );
101
-
102
- /**
103
- * Insert the post
104
- */
105
- $new_flow_id = wp_insert_post( $args );
106
-
107
- /**
108
- * Get all current post terms ad set them to the new post
109
- */
110
- // returns array of taxonomy names for post type, ex array("category", "post_tag");.
111
- $taxonomies = get_object_taxonomies( $post->post_type );
112
-
113
- foreach ( $taxonomies as $taxonomy ) {
114
-
115
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
116
-
117
- wp_set_object_terms( $new_flow_id, $post_terms, $taxonomy, false );
118
- }
119
-
120
- /**
121
- * Duplicate all post meta just in two SQL queries
122
- */
123
- // @codingStandardsIgnoreStart
124
- $post_meta_infos = $wpdb->get_results(
125
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
126
- );
127
- // @codingStandardsIgnoreEnd
128
-
129
- if ( ! empty( $post_meta_infos ) ) {
130
-
131
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
132
-
133
- $sql_query_sel = array();
134
-
135
- foreach ( $post_meta_infos as $meta_info ) {
136
-
137
- $meta_key = $meta_info->meta_key;
138
-
139
- if ( '_wp_old_slug' === $meta_key ) {
140
- continue;
141
- }
142
-
143
- $meta_value = addslashes( $meta_info->meta_value );
144
-
145
- $sql_query_sel[] = "($new_flow_id, '$meta_key', '$meta_value')";
146
- }
147
-
148
- $sql_query .= implode( ',', $sql_query_sel );
149
-
150
- // @codingStandardsIgnoreStart
151
- $wpdb->query( $sql_query );
152
- // @codingStandardsIgnoreEnd
153
- }
154
-
155
- /* Steps Cloning */
156
- $flow_steps = get_post_meta( $post_id, 'wcf-steps', true );
157
- $new_flow_steps = array();
158
-
159
- /* Set Steps Empty */
160
- update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
161
-
162
- if ( is_array( $flow_steps ) && ! empty( $flow_steps ) ) {
163
-
164
- foreach ( $flow_steps as $index => $step_data ) {
165
-
166
- $step_id = $step_data['id'];
167
- $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
168
-
169
- $step_object = get_post( $step_id );
170
-
171
- /**
172
- * New step post data array
173
- */
174
- $step_args = array(
175
- 'comment_status' => $step_object->comment_status,
176
- 'ping_status' => $step_object->ping_status,
177
- 'post_author' => $new_post_author,
178
- 'post_content' => $step_object->post_content,
179
- 'post_excerpt' => $step_object->post_excerpt,
180
- 'post_name' => $step_object->post_name,
181
- 'post_parent' => $step_object->post_parent,
182
- 'post_password' => $step_object->post_password,
183
- 'post_status' => $step_object->post_status,
184
- 'post_title' => $step_object->post_title,
185
- 'post_type' => $step_object->post_type,
186
- 'to_ping' => $step_object->to_ping,
187
- 'menu_order' => $step_object->menu_order,
188
- );
189
-
190
- /**
191
- * Insert the post
192
- */
193
- $new_step_id = wp_insert_post( $step_args );
194
-
195
- /**
196
- * Duplicate all step meta
197
- */
198
- // @codingStandardsIgnoreStart
199
- $post_meta_infos = $wpdb->get_results(
200
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$step_id"
201
- );
202
- // @codingStandardsIgnoreEnd
203
-
204
- if ( ! empty( $post_meta_infos ) ) {
205
-
206
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
207
-
208
- $sql_query_sel = array();
209
-
210
- foreach ( $post_meta_infos as $meta_info ) {
211
-
212
- $meta_key = $meta_info->meta_key;
213
-
214
- if ( '_wp_old_slug' === $meta_key ) {
215
- continue;
216
- }
217
-
218
- $meta_value = addslashes( $meta_info->meta_value );
219
-
220
- $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
221
- }
222
-
223
- $sql_query .= implode( ',', $sql_query_sel );
224
-
225
- // @codingStandardsIgnoreStart
226
- $wpdb->query( $sql_query );
227
- // @codingStandardsIgnoreEnd
228
- }
229
-
230
- // insert post meta.
231
- update_post_meta( $new_step_id, 'wcf-flow-id', $new_flow_id );
232
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
233
-
234
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
235
- wp_set_object_terms( $new_step_id, 'flow-' . $new_flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
236
-
237
- /* Add New Flow Steps */
238
- $new_flow_steps[] = array(
239
- 'id' => $new_step_id,
240
- 'title' => $step_object->post_title,
241
- 'type' => $step_type,
242
- );
243
- }
244
- }
245
-
246
- /* Update New Flow Step Post Meta */
247
- update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
248
-
249
- /* Clear Page Builder Cache */
250
- $this->clear_cache();
251
-
252
- /**
253
- * Redirect to the new flow edit screen
254
- */
255
- wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_flow_id ) );
256
- exit;
257
- } else {
258
- wp_die( 'Post creation failed, could not find original post: ' . $post_id );
259
- }
260
- }
261
-
262
- /**
263
- * Clone step with its meta.
264
- */
265
- public function clone_step() {
266
-
267
- global $wpdb;
268
-
269
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_step' === $_REQUEST['action'] ) ) ) {
270
- wp_die( 'No post to duplicate has been supplied!' );
271
- }
272
-
273
- /*
274
- * Nonce verification
275
- */
276
- if ( ! isset( $_GET['step_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['step_clone_nonce'] ) ), 'step_clone' ) ) {
277
- return;
278
- }
279
-
280
- /**
281
- * Get the original post id
282
- */
283
- $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
284
-
285
- /**
286
- * And all the original post data then
287
- */
288
- $post = get_post( $post_id );
289
-
290
- /**
291
- * Assign current user to be the new post author
292
- */
293
- $current_user = wp_get_current_user();
294
- $new_post_author = $current_user->ID;
295
-
296
- /**
297
- * If post data exists, create the post duplicate
298
- */
299
- if ( isset( $post ) && null !== $post ) {
300
-
301
- /**
302
- * New post data array
303
- */
304
- $args = array(
305
- 'comment_status' => $post->comment_status,
306
- 'ping_status' => $post->ping_status,
307
- 'post_author' => $new_post_author,
308
- 'post_content' => $post->post_content,
309
- 'post_excerpt' => $post->post_excerpt,
310
- 'post_name' => $post->post_name,
311
- 'post_parent' => $post->post_parent,
312
- 'post_password' => $post->post_password,
313
- 'post_status' => $post->post_status,
314
- 'post_title' => $post->post_title . ' Clone',
315
- 'post_type' => $post->post_type,
316
- 'to_ping' => $post->to_ping,
317
- 'menu_order' => $post->menu_order,
318
- );
319
-
320
- /**
321
- * Insert the post
322
- */
323
- $new_step_id = wp_insert_post( $args );
324
-
325
- /**
326
- * Get all current post terms ad set them to the new post
327
- */
328
- // returns array of taxonomy names for post type, ex array("category", "post_tag");.
329
- $taxonomies = get_object_taxonomies( $post->post_type );
330
-
331
- foreach ( $taxonomies as $taxonomy ) {
332
-
333
- $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
334
-
335
- wp_set_object_terms( $new_step_id, $post_terms, $taxonomy, false );
336
- }
337
-
338
- /**
339
- * Duplicate all post meta just in two SQL queries
340
- */
341
- // @codingStandardsIgnoreStart
342
- $post_meta_infos = $wpdb->get_results(
343
- "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
344
- );
345
- // @codingStandardsIgnoreEnd
346
-
347
- if ( ! empty( $post_meta_infos ) ) {
348
-
349
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
350
-
351
- $sql_query_sel = array();
352
-
353
- foreach ( $post_meta_infos as $meta_info ) {
354
-
355
- $meta_key = $meta_info->meta_key;
356
-
357
- if ( '_wp_old_slug' === $meta_key ) {
358
- continue;
359
- }
360
-
361
- $meta_value = addslashes( $meta_info->meta_value );
362
-
363
- $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
364
- }
365
-
366
- $sql_query .= implode( ',', $sql_query_sel );
367
-
368
- // @codingStandardsIgnoreStart
369
- $wpdb->query( $sql_query );
370
- // @codingStandardsIgnoreEnd
371
- }
372
-
373
- $flow_id = get_post_meta( $post_id, 'wcf-flow-id', true );
374
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
375
- $step_type = get_post_meta( $post_id, 'wcf-step-type', true );
376
-
377
- if ( ! is_array( $flow_steps ) ) {
378
- $flow_steps = array();
379
- }
380
-
381
- $flow_steps[] = array(
382
- 'id' => $new_step_id,
383
- 'title' => $post->post_title,
384
- 'type' => $step_type,
385
- );
386
-
387
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
388
-
389
- /* Clear Page Builder Cache */
390
- $this->clear_cache();
391
-
392
- /**
393
- * Redirect to the new flow edit screen
394
- */
395
- $redirect_url = add_query_arg( 'highlight-step-id', $new_step_id, get_edit_post_link( $flow_id, 'default' ) );
396
-
397
- wp_safe_redirect( $redirect_url );
398
- exit;
399
- } else {
400
- wp_die( 'Post creation failed, could not find original post: ' . $post_id );
401
- }
402
- }
403
-
404
- /**
405
- * Add the clone link to action list for flows row actions
406
- *
407
- * @param array $actions Actions array.
408
- * @param object $post Post object.
409
- *
410
- * @return array
411
- */
412
- public function clone_link( $actions, $post ) {
413
-
414
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
415
-
416
- if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
417
- unset( $actions['duplicate'] );
418
- }
419
- if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
420
- unset( $actions['edit_as_new_draft'] );
421
- }
422
-
423
- $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
424
-
425
- if ( ! _is_cartflows_pro() ) {
426
-
427
- $flow_posts = get_posts(
428
- array(
429
- 'posts_per_page' => 4,
430
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
431
- 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
432
- )
433
- );
434
-
435
- if ( is_array( $flow_posts ) ) {
436
-
437
- $flow_count = count( $flow_posts );
438
-
439
- if ( $flow_count > 3 || 3 === $flow_count ) {
440
- unset( $actions['clone'] );
441
- }
442
- }
443
- }
444
- }
445
-
446
- return $actions;
447
- }
448
-
449
- /**
450
- * Clear Page Builder Cache
451
- */
452
- public function clear_cache() {
453
-
454
- // Clear 'Elementor' file cache.
455
- if ( class_exists( '\Elementor\Plugin' ) ) {
456
- Elementor\Plugin::$instance->files_manager->clear_cache();
457
- }
458
- }
459
-
460
- }
461
-
462
- /**
463
- * Kicking this off by calling 'get_instance()' method
464
- */
465
- Cartflows_Cloning::get_instance();
1
+ <?php
2
+ /**
3
+ * Cloning.
4
+ *
5
+ * @package cartflows-pro
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Cloning {
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_filter( 'post_row_actions', array( $this, 'clone_link' ), 99, 2 );
39
+ add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
+ add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
41
+ }
42
+
43
+ /**
44
+ * Clone flow with steps and its meta.
45
+ */
46
+ public function clone_flow() {
47
+
48
+ global $wpdb;
49
+
50
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_flow' === $_REQUEST['action'] ) ) ) {
51
+ wp_die( 'No post to duplicate has been supplied!' );
52
+ }
53
+
54
+ /*
55
+ * Nonce verification
56
+ */
57
+ if ( ! isset( $_GET['flow_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_clone_nonce'] ) ), basename( __FILE__ ) ) ) {
58
+ return;
59
+ }
60
+
61
+ /**
62
+ * Get the original post id
63
+ */
64
+ $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
65
+
66
+ /**
67
+ * And all the original post data then
68
+ */
69
+ $post = get_post( $post_id );
70
+
71
+ /**
72
+ * Assign current user to be the new post author
73
+ */
74
+ $current_user = wp_get_current_user();
75
+ $new_post_author = $current_user->ID;
76
+
77
+ /**
78
+ * If post data exists, create the post duplicate
79
+ */
80
+ if ( isset( $post ) && null !== $post ) {
81
+
82
+ /**
83
+ * New post data array
84
+ */
85
+
86
+ $args = array(
87
+ 'comment_status' => $post->comment_status,
88
+ 'ping_status' => $post->ping_status,
89
+ 'post_author' => $new_post_author,
90
+ 'post_content' => $post->post_content,
91
+ 'post_excerpt' => $post->post_excerpt,
92
+ 'post_name' => $post->post_name,
93
+ 'post_parent' => $post->post_parent,
94
+ 'post_password' => $post->post_password,
95
+ 'post_status' => $post->post_status,
96
+ 'post_title' => $post->post_title . ' Clone',
97
+ 'post_type' => $post->post_type,
98
+ 'to_ping' => $post->to_ping,
99
+ 'menu_order' => $post->menu_order,
100
+ );
101
+
102
+ /**
103
+ * Insert the post
104
+ */
105
+ $new_flow_id = wp_insert_post( $args );
106
+
107
+ /**
108
+ * Get all current post terms ad set them to the new post
109
+ */
110
+ // returns array of taxonomy names for post type, ex array("category", "post_tag");.
111
+ $taxonomies = get_object_taxonomies( $post->post_type );
112
+
113
+ foreach ( $taxonomies as $taxonomy ) {
114
+
115
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
116
+
117
+ wp_set_object_terms( $new_flow_id, $post_terms, $taxonomy, false );
118
+ }
119
+
120
+ /**
121
+ * Duplicate all post meta just in two SQL queries
122
+ */
123
+ // @codingStandardsIgnoreStart
124
+ $post_meta_infos = $wpdb->get_results(
125
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
126
+ );
127
+ // @codingStandardsIgnoreEnd
128
+
129
+ if ( ! empty( $post_meta_infos ) ) {
130
+
131
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
132
+
133
+ $sql_query_sel = array();
134
+
135
+ foreach ( $post_meta_infos as $meta_info ) {
136
+
137
+ $meta_key = $meta_info->meta_key;
138
+
139
+ if ( '_wp_old_slug' === $meta_key ) {
140
+ continue;
141
+ }
142
+
143
+ $meta_value = addslashes( $meta_info->meta_value );
144
+
145
+ $sql_query_sel[] = "($new_flow_id, '$meta_key', '$meta_value')";
146
+ }
147
+
148
+ $sql_query .= implode( ',', $sql_query_sel );
149
+
150
+ // @codingStandardsIgnoreStart
151
+ $wpdb->query( $sql_query );
152
+ // @codingStandardsIgnoreEnd
153
+ }
154
+
155
+ /* Steps Cloning */
156
+ $flow_steps = get_post_meta( $post_id, 'wcf-steps', true );
157
+ $new_flow_steps = array();
158
+
159
+ /* Set Steps Empty */
160
+ update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
161
+
162
+ if ( is_array( $flow_steps ) && ! empty( $flow_steps ) ) {
163
+
164
+ foreach ( $flow_steps as $index => $step_data ) {
165
+
166
+ $step_id = $step_data['id'];
167
+ $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
168
+
169
+ $step_object = get_post( $step_id );
170
+
171
+ /**
172
+ * New step post data array
173
+ */
174
+ $step_args = array(
175
+ 'comment_status' => $step_object->comment_status,
176
+ 'ping_status' => $step_object->ping_status,
177
+ 'post_author' => $new_post_author,
178
+ 'post_content' => $step_object->post_content,
179
+ 'post_excerpt' => $step_object->post_excerpt,
180
+ 'post_name' => $step_object->post_name,
181
+ 'post_parent' => $step_object->post_parent,
182
+ 'post_password' => $step_object->post_password,
183
+ 'post_status' => $step_object->post_status,
184
+ 'post_title' => $step_object->post_title,
185
+ 'post_type' => $step_object->post_type,
186
+ 'to_ping' => $step_object->to_ping,
187
+ 'menu_order' => $step_object->menu_order,
188
+ );
189
+
190
+ /**
191
+ * Insert the post
192
+ */
193
+ $new_step_id = wp_insert_post( $step_args );
194
+
195
+ /**
196
+ * Duplicate all step meta
197
+ */
198
+ // @codingStandardsIgnoreStart
199
+ $post_meta_infos = $wpdb->get_results(
200
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$step_id"
201
+ );
202
+ // @codingStandardsIgnoreEnd
203
+
204
+ if ( ! empty( $post_meta_infos ) ) {
205
+
206
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
207
+
208
+ $sql_query_sel = array();
209
+
210
+ foreach ( $post_meta_infos as $meta_info ) {
211
+
212
+ $meta_key = $meta_info->meta_key;
213
+
214
+ if ( '_wp_old_slug' === $meta_key ) {
215
+ continue;
216
+ }
217
+
218
+ $meta_value = addslashes( $meta_info->meta_value );
219
+
220
+ $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
221
+ }
222
+
223
+ $sql_query .= implode( ',', $sql_query_sel );
224
+
225
+ // @codingStandardsIgnoreStart
226
+ $wpdb->query( $sql_query );
227
+ // @codingStandardsIgnoreEnd
228
+ }
229
+
230
+ // insert post meta.
231
+ update_post_meta( $new_step_id, 'wcf-flow-id', $new_flow_id );
232
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
233
+
234
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
235
+ wp_set_object_terms( $new_step_id, 'flow-' . $new_flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
236
+
237
+ /* Add New Flow Steps */
238
+ $new_flow_steps[] = array(
239
+ 'id' => $new_step_id,
240
+ 'title' => $step_object->post_title,
241
+ 'type' => $step_type,
242
+ );
243
+ }
244
+ }
245
+
246
+ /* Update New Flow Step Post Meta */
247
+ update_post_meta( $new_flow_id, 'wcf-steps', $new_flow_steps );
248
+
249
+ /* Clear Page Builder Cache */
250
+ $this->clear_cache();
251
+
252
+ /**
253
+ * Redirect to the new flow edit screen
254
+ */
255
+ wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_flow_id ) );
256
+ exit;
257
+ } else {
258
+ wp_die( 'Post creation failed, could not find original post: ' . $post_id );
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Clone step with its meta.
264
+ */
265
+ public function clone_step() {
266
+
267
+ global $wpdb;
268
+
269
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_clone_step' === $_REQUEST['action'] ) ) ) {
270
+ wp_die( 'No post to duplicate has been supplied!' );
271
+ }
272
+
273
+ /*
274
+ * Nonce verification
275
+ */
276
+ if ( ! isset( $_GET['step_clone_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['step_clone_nonce'] ) ), 'step_clone' ) ) {
277
+ return;
278
+ }
279
+
280
+ /**
281
+ * Get the original post id
282
+ */
283
+ $post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
284
+
285
+ /**
286
+ * And all the original post data then
287
+ */
288
+ $post = get_post( $post_id );
289
+
290
+ /**
291
+ * Assign current user to be the new post author
292
+ */
293
+ $current_user = wp_get_current_user();
294
+ $new_post_author = $current_user->ID;
295
+
296
+ /**
297
+ * If post data exists, create the post duplicate
298
+ */
299
+ if ( isset( $post ) && null !== $post ) {
300
+
301
+ /**
302
+ * New post data array
303
+ */
304
+ $args = array(
305
+ 'comment_status' => $post->comment_status,
306
+ 'ping_status' => $post->ping_status,
307
+ 'post_author' => $new_post_author,
308
+ 'post_content' => $post->post_content,
309
+ 'post_excerpt' => $post->post_excerpt,
310
+ 'post_name' => $post->post_name,
311
+ 'post_parent' => $post->post_parent,
312
+ 'post_password' => $post->post_password,
313
+ 'post_status' => $post->post_status,
314
+ 'post_title' => $post->post_title . ' Clone',
315
+ 'post_type' => $post->post_type,
316
+ 'to_ping' => $post->to_ping,
317
+ 'menu_order' => $post->menu_order,
318
+ );
319
+
320
+ /**
321
+ * Insert the post
322
+ */
323
+ $new_step_id = wp_insert_post( $args );
324
+
325
+ /**
326
+ * Get all current post terms ad set them to the new post
327
+ */
328
+ // returns array of taxonomy names for post type, ex array("category", "post_tag");.
329
+ $taxonomies = get_object_taxonomies( $post->post_type );
330
+
331
+ foreach ( $taxonomies as $taxonomy ) {
332
+
333
+ $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
334
+
335
+ wp_set_object_terms( $new_step_id, $post_terms, $taxonomy, false );
336
+ }
337
+
338
+ /**
339
+ * Duplicate all post meta just in two SQL queries
340
+ */
341
+ // @codingStandardsIgnoreStart
342
+ $post_meta_infos = $wpdb->get_results(
343
+ "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id"
344
+ );
345
+ // @codingStandardsIgnoreEnd
346
+
347
+ if ( ! empty( $post_meta_infos ) ) {
348
+
349
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES ";
350
+
351
+ $sql_query_sel = array();
352
+
353
+ foreach ( $post_meta_infos as $meta_info ) {
354
+
355
+ $meta_key = $meta_info->meta_key;
356
+
357
+ if ( '_wp_old_slug' === $meta_key ) {
358
+ continue;
359
+ }
360
+
361
+ $meta_value = addslashes( $meta_info->meta_value );
362
+
363
+ $sql_query_sel[] = "($new_step_id, '$meta_key', '$meta_value')";
364
+ }
365
+
366
+ $sql_query .= implode( ',', $sql_query_sel );
367
+
368
+ // @codingStandardsIgnoreStart
369
+ $wpdb->query( $sql_query );
370
+ // @codingStandardsIgnoreEnd
371
+ }
372
+
373
+ $flow_id = get_post_meta( $post_id, 'wcf-flow-id', true );
374
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
375
+ $step_type = get_post_meta( $post_id, 'wcf-step-type', true );
376
+
377
+ if ( ! is_array( $flow_steps ) ) {
378
+ $flow_steps = array();
379
+ }
380
+
381
+ $flow_steps[] = array(
382
+ 'id' => $new_step_id,
383
+ 'title' => $post->post_title,
384
+ 'type' => $step_type,
385
+ );
386
+
387
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
388
+
389
+ /* Clear Page Builder Cache */
390
+ $this->clear_cache();
391
+
392
+ /**
393
+ * Redirect to the new flow edit screen
394
+ */
395
+ $redirect_url = add_query_arg( 'highlight-step-id', $new_step_id, get_edit_post_link( $flow_id, 'default' ) );
396
+
397
+ wp_safe_redirect( $redirect_url );
398
+ exit;
399
+ } else {
400
+ wp_die( 'Post creation failed, could not find original post: ' . $post_id );
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Add the clone link to action list for flows row actions
406
+ *
407
+ * @param array $actions Actions array.
408
+ * @param object $post Post object.
409
+ *
410
+ * @return array
411
+ */
412
+ public function clone_link( $actions, $post ) {
413
+
414
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
415
+
416
+ if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
417
+ unset( $actions['duplicate'] );
418
+ }
419
+ if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
420
+ unset( $actions['edit_as_new_draft'] );
421
+ }
422
+
423
+ $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
424
+
425
+ if ( ! _is_cartflows_pro() ) {
426
+
427
+ $flow_posts = get_posts(
428
+ array(
429
+ 'posts_per_page' => 4,
430
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
431
+ 'post_status' => array( 'publish', 'pending', 'draft', 'future', 'private' ),
432
+ )
433
+ );
434
+
435
+ if ( is_array( $flow_posts ) ) {
436
+
437
+ $flow_count = count( $flow_posts );
438
+
439
+ if ( $flow_count > 3 || 3 === $flow_count ) {
440
+ unset( $actions['clone'] );
441
+ }
442
+ }
443
+ }
444
+ }
445
+
446
+ return $actions;
447
+ }
448
+
449
+ /**
450
+ * Clear Page Builder Cache
451
+ */
452
+ public function clear_cache() {
453
+
454
+ // Clear 'Elementor' file cache.
455
+ if ( class_exists( '\Elementor\Plugin' ) ) {
456
+ Elementor\Plugin::$instance->files_manager->clear_cache();
457
+ }
458
+ }
459
+
460
+ }
461
+
462
+ /**
463
+ * Kicking this off by calling 'get_instance()' method
464
+ */
465
+ Cartflows_Cloning::get_instance();
classes/class-cartflows-default-meta.php CHANGED
@@ -1,867 +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
- foreach ( $p_data as $i_key => $i_value ) {
379
- if ( is_array( $i_value ) ) {
380
- foreach ( $i_value as $q_key => $q_value ) {
381
- $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
382
-
383
- $q++;
384
- }
385
- } else {
386
- $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
387
- }
388
- }
389
-
390
- $i++;
391
- }
392
- }
393
- break;
394
-
395
- case 'FILTER_CARTFLOWS_IMAGES':
396
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
397
-
398
- if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
399
-
400
- if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
401
-
402
- $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
403
- $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
404
-
405
- $image_data = array(
406
- 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
407
- 'url' => array(
408
- 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
409
- 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
410
- 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
411
- ),
412
- );
413
-
414
- $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
415
- update_post_meta( $post_id, $key . '-obj', $new_meta_value );
416
- }
417
- }
418
-
419
- break;
420
-
421
- default:
422
- if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
423
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
424
- } else {
425
- $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
426
- }
427
-
428
- break;
429
- }
430
-
431
- if ( false !== $meta_value ) {
432
- update_post_meta( $post_id, $key, $meta_value );
433
- } else {
434
- delete_post_meta( $post_id, $key );
435
- }
436
- }
437
- }
438
-
439
- /**
440
- * Get checkout meta.
441
- *
442
- * @param int $post_id post id.
443
- * @param string $key options key.
444
- * @param mix $default options default value.
445
- * @return string
446
- */
447
- public function get_flow_meta_value( $post_id, $key, $default = false ) {
448
-
449
- $value = $this->get_save_meta( $post_id, $key );
450
-
451
- if ( ! $value ) {
452
- if ( $default ) {
453
- $value = $default;
454
- } else {
455
- $fields = $this->get_flow_fields( $post_id );
456
-
457
- if ( isset( $fields[ $key ]['default'] ) ) {
458
- $value = $fields[ $key ]['default'];
459
- }
460
- }
461
- }
462
-
463
- return $value;
464
- }
465
-
466
- /**
467
- * Get checkout meta.
468
- *
469
- * @param int $post_id post id.
470
- * @param string $key options key.
471
- * @param mix $default options default value.
472
- * @return string
473
- */
474
- public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
475
-
476
- $value = $this->get_save_meta( $post_id, $key );
477
-
478
- if ( ! $value ) {
479
- if ( false !== $default ) {
480
- $value = $default;
481
- } else {
482
- $fields = $this->get_checkout_fields( $post_id );
483
-
484
- if ( isset( $fields[ $key ]['default'] ) ) {
485
- $value = $fields[ $key ]['default'];
486
- }
487
- }
488
- }
489
-
490
- return $value;
491
- }
492
-
493
- /**
494
- * Get post meta.
495
- *
496
- * @param int $post_id post id.
497
- * @param string $key options key.
498
- * @return string
499
- */
500
- public function get_save_meta( $post_id, $key ) {
501
-
502
- $value = get_post_meta( $post_id, $key, true );
503
-
504
- return $value;
505
- }
506
-
507
- /**
508
- * Thank You Default fields.
509
- *
510
- * @param int $post_id post id.
511
- * @return array
512
- */
513
- public function get_thankyou_fields( $post_id ) {
514
-
515
- if ( null === self::$thankyou_fields ) {
516
- self::$thankyou_fields = array(
517
- 'wcf-field-google-font-url' => array(
518
- 'default' => '',
519
- 'sanitize' => 'FILTER_DEFAULT',
520
- ),
521
- 'wcf-active-tab' => array(
522
- 'default' => '',
523
- 'sanitize' => 'FILTER_DEFAULT',
524
- ),
525
- 'wcf-tq-text-color' => array(
526
- 'default' => '',
527
- 'sanitize' => 'FILTER_DEFAULT',
528
- ),
529
- 'wcf-tq-font-family' => array(
530
- 'default' => '',
531
- 'sanitize' => 'FILTER_DEFAULT',
532
- ),
533
- 'wcf-tq-font-size' => array(
534
- 'default' => '',
535
- 'sanitize' => 'FILTER_DEFAULT',
536
- ),
537
- 'wcf-tq-heading-color' => array(
538
- 'default' => '',
539
- 'sanitize' => 'FILTER_DEFAULT',
540
- ),
541
- 'wcf-tq-heading-font-family' => array(
542
- 'default' => '',
543
- 'sanitize' => 'FILTER_DEFAULT',
544
- ),
545
- 'wcf-tq-heading-font-wt' => array(
546
- 'default' => '',
547
- 'sanitize' => 'FILTER_DEFAULT',
548
- ),
549
- 'wcf-tq-container-width' => array(
550
- 'default' => '',
551
- 'sanitize' => 'FILTER_DEFAULT',
552
- ),
553
- 'wcf-tq-section-bg-color' => array(
554
- 'default' => '',
555
- 'sanitize' => 'FILTER_DEFAULT',
556
- ),
557
- 'wcf-tq-advance-options-fields' => array(
558
- 'default' => '',
559
- 'sanitize' => 'FILTER_DEFAULT',
560
- ),
561
- 'wcf-show-overview-section' => array(
562
- 'default' => 'yes',
563
- 'sanitize' => 'FILTER_DEFAULT',
564
- ),
565
- 'wcf-show-details-section' => array(
566
- 'default' => 'yes',
567
- 'sanitize' => 'FILTER_DEFAULT',
568
- ),
569
- 'wcf-show-billing-section' => array(
570
- 'default' => 'yes',
571
- 'sanitize' => 'FILTER_DEFAULT',
572
- ),
573
- 'wcf-show-shipping-section' => array(
574
- 'default' => 'yes',
575
- 'sanitize' => 'FILTER_DEFAULT',
576
- ),
577
- 'wcf-show-tq-redirect-section' => array(
578
- 'default' => '',
579
- 'sanitize' => 'FILTER_DEFAULT',
580
- ),
581
- 'wcf-tq-redirect-link' => array(
582
- 'default' => '',
583
- 'sanitize' => 'FILTER_SANITIZE_URL',
584
- ),
585
- 'wcf-tq-text' => array(
586
- 'default' => '',
587
- 'sanitize' => 'FILTER_DEFAULT',
588
- ),
589
- 'wcf-custom-script' => array(
590
- 'default' => '',
591
- 'sanitize' => 'FILTER_DEFAULT',
592
- ),
593
- );
594
- }
595
-
596
- return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
597
- }
598
-
599
- /**
600
- * Get Thank you section meta.
601
- *
602
- * @param int $post_id post id.
603
- * @param string $key options key.
604
- * @param mix $default options default value.
605
- * @return string
606
- */
607
- public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
608
-
609
- $value = $this->get_save_meta( $post_id, $key );
610
-
611
- if ( ! $value ) {
612
- if ( $default ) {
613
- $value = $default;
614
- } else {
615
- $fields = $this->get_thankyou_fields( $post_id );
616
-
617
- if ( isset( $fields[ $key ]['default'] ) ) {
618
- $value = $fields[ $key ]['default'];
619
- }
620
- }
621
- }
622
-
623
- return $value;
624
- }
625
-
626
- /**
627
- * Get Landing section meta.
628
- *
629
- * @param int $post_id post id.
630
- * @param string $key options key.
631
- * @param mix $default options default value.
632
- * @return string
633
- */
634
- public function get_landing_meta_value( $post_id, $key, $default = false ) {
635
-
636
- $value = $this->get_save_meta( $post_id, $key );
637
- if ( ! $value ) {
638
- if ( $default ) {
639
- $value = $default;
640
- } else {
641
- $fields = $this->get_landing_fields( $post_id );
642
-
643
- if ( isset( $fields[ $key ]['default'] ) ) {
644
- $value = $fields[ $key ]['default'];
645
- }
646
- }
647
- }
648
-
649
- return $value;
650
- }
651
-
652
- /**
653
- * Landing Default fields.
654
- *
655
- * @param int $post_id post id.
656
- * @return array
657
- */
658
- public function get_landing_fields( $post_id ) {
659
-
660
- if ( null === self::$landing_fields ) {
661
- self::$landing_fields = array(
662
- 'wcf-custom-script' => array(
663
- 'default' => '',
664
- 'sanitize' => 'FILTER_DEFAULT',
665
- ),
666
- );
667
- }
668
- return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
669
- }
670
-
671
- /**
672
- * Optin Default fields.
673
- *
674
- * @param int $post_id post id.
675
- * @return array
676
- */
677
- public function get_optin_fields( $post_id ) {
678
-
679
- if ( null === self::$optin_fields ) {
680
- self::$optin_fields = array(
681
-
682
- 'wcf-optin-product' => array(
683
- 'default' => array(),
684
- 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
685
- ),
686
-
687
- /* Style */
688
- 'wcf-field-google-font-url' => array(
689
- 'default' => '',
690
- 'sanitize' => 'FILTER_DEFAULT',
691
- ),
692
- 'wcf-primary-color' => array(
693
- 'default' => '',
694
- 'sanitize' => 'FILTER_DEFAULT',
695
- ),
696
- 'wcf-base-font-family' => array(
697
- 'default' => '',
698
- 'sanitize' => 'FILTER_DEFAULT',
699
- ),
700
- 'wcf-input-fields-skins' => array(
701
- 'default' => '',
702
- 'sanitize' => 'FILTER_DEFAULT',
703
- ),
704
- 'wcf-input-font-family' => array(
705
- 'default' => '',
706
- 'sanitize' => 'FILTER_DEFAULT',
707
- ),
708
- 'wcf-input-font-weight' => array(
709
- 'default' => '',
710
- 'sanitize' => 'FILTER_DEFAULT',
711
- ),
712
- 'wcf-input-field-size' => array(
713
- 'default' => '33px',
714
- 'sanitize' => 'FILTER_DEFAULT',
715
- ),
716
- 'wcf-field-tb-padding' => array(
717
- 'default' => '',
718
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
719
- ),
720
- 'wcf-field-lr-padding' => array(
721
- 'default' => '',
722
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
- ),
724
- 'wcf-field-color' => array(
725
- 'default' => '',
726
- 'sanitize' => 'FILTER_DEFAULT',
727
- ),
728
- 'wcf-field-bg-color' => array(
729
- 'default' => '',
730
- 'sanitize' => 'FILTER_DEFAULT',
731
- ),
732
- 'wcf-field-border-color' => array(
733
- 'default' => '',
734
- 'sanitize' => 'FILTER_DEFAULT',
735
- ),
736
- 'wcf-field-label-color' => array(
737
- 'default' => '',
738
- 'sanitize' => 'FILTER_DEFAULT',
739
- ),
740
- 'wcf-submit-button-text' => array(
741
- 'default' => __( 'Submit', 'cartflows' ),
742
- 'sanitize' => 'FILTER_DEFAULT',
743
- ),
744
- 'wcf-submit-font-size' => array(
745
- 'default' => '',
746
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
747
- ),
748
- 'wcf-button-font-family' => array(
749
- 'default' => '',
750
- 'sanitize' => 'FILTER_DEFAULT',
751
- ),
752
- 'wcf-button-font-weight' => array(
753
- 'default' => '',
754
- 'sanitize' => 'FILTER_DEFAULT',
755
- ),
756
- 'wcf-submit-button-size' => array(
757
- 'default' => '33px',
758
- 'sanitize' => 'FILTER_DEFAULT',
759
- ),
760
- 'wcf-submit-tb-padding' => array(
761
- 'default' => '',
762
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
763
- ),
764
- 'wcf-submit-lr-padding' => array(
765
- 'default' => '',
766
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
- ),
768
- 'wcf-submit-button-position' => array(
769
- 'default' => 'center',
770
- 'sanitize' => 'FILTER_DEFAULT',
771
- ),
772
- 'wcf-submit-color' => array(
773
- 'default' => '',
774
- 'sanitize' => 'FILTER_DEFAULT',
775
- ),
776
- 'wcf-submit-hover-color' => array(
777
- 'default' => '',
778
- 'sanitize' => 'FILTER_DEFAULT',
779
- ),
780
- 'wcf-submit-bg-color' => array(
781
- 'default' => '',
782
- 'sanitize' => 'FILTER_DEFAULT',
783
- ),
784
- 'wcf-submit-bg-hover-color' => array(
785
- 'default' => '',
786
- 'sanitize' => 'FILTER_DEFAULT',
787
- ),
788
- 'wcf-submit-border-color' => array(
789
- 'default' => '',
790
- 'sanitize' => 'FILTER_DEFAULT',
791
- ),
792
- 'wcf-submit-border-hover-color' => array(
793
- 'default' => '',
794
- 'sanitize' => 'FILTER_DEFAULT',
795
- ),
796
-
797
- /* Settings */
798
- 'wcf-optin-pass-fields' => array(
799
- 'default' => '',
800
- 'sanitize' => 'FILTER_DEFAULT',
801
- ),
802
- 'wcf-optin-pass-specific-fields' => array(
803
- 'default' => 'first_name',
804
- 'sanitize' => 'FILTER_DEFAULT',
805
- ),
806
-
807
- /* Script */
808
- 'wcf-custom-script' => array(
809
- 'default' => '',
810
- 'sanitize' => 'FILTER_DEFAULT',
811
- ),
812
-
813
- /* Hidden */
814
- 'wcf-active-tab' => array(
815
- 'default' => '',
816
- 'sanitize' => 'FILTER_DEFAULT',
817
- ),
818
- );
819
- }
820
- return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
821
- }
822
-
823
- /**
824
- * Save Optin Meta fields.
825
- *
826
- * @param int $post_id post id.
827
- * @return void
828
- */
829
- public function save_optin_fields( $post_id ) {
830
-
831
- $post_meta = $this->get_optin_fields( $post_id );
832
-
833
- $this->save_meta_fields( $post_id, $post_meta );
834
- }
835
-
836
- /**
837
- * Get optin meta.
838
- *
839
- * @param int $post_id post id.
840
- * @param string $key options key.
841
- * @param mix $default options default value.
842
- * @return string
843
- */
844
- public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
845
-
846
- $value = $this->get_save_meta( $post_id, $key );
847
-
848
- if ( ! $value ) {
849
- if ( false !== $default ) {
850
- $value = $default;
851
- } else {
852
- $fields = $this->get_optin_fields( $post_id );
853
-
854
- if ( isset( $fields[ $key ]['default'] ) ) {
855
- $value = $fields[ $key ]['default'];
856
- }
857
- }
858
- }
859
-
860
- return $value;
861
- }
862
- }
863
-
864
- /**
865
- * Kicking this off by calling 'get_instance()' method
866
- */
867
- 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-helper.php CHANGED
@@ -581,16 +581,22 @@ class Cartflows_Helper {
581
 
582
  $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
583
 
 
 
584
  if ( 'checkout' == $step_type ) {
585
  $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
 
 
 
 
586
  } else {
587
  $product = get_post_meta( $step_id, 'wcf-offer-product', true );
 
 
 
588
  }
589
 
590
- if ( ! empty( $product ) ) {
591
- return true;
592
- }
593
- return false;
594
 
595
  }
596
 
581
 
582
  $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
583
 
584
+ $has_product_assigned = false;
585
+
586
  if ( 'checkout' == $step_type ) {
587
  $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
588
+
589
+ if ( ! empty( $product ) && isset( $product[0]['product'] ) ) {
590
+ $has_product_assigned = true;
591
+ }
592
  } else {
593
  $product = get_post_meta( $step_id, 'wcf-offer-product', true );
594
+ if ( ! empty( $product ) ) {
595
+ $has_product_assigned = true;
596
+ }
597
  }
598
 
599
+ return $has_product_assigned;
 
 
 
600
 
601
  }
602
 
classes/class-cartflows-importer.php CHANGED
@@ -1,1739 +1,1739 @@
1
- <?php
2
- /**
3
- * CartFlows Admin
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
-
11
- /**
12
- * CartFlows Import
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Importer {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
-
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.0.0
45
- */
46
- public function __construct() {
47
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
-
49
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
-
55
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
-
58
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
-
60
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
-
62
- add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
- add_action( 'admin_init', array( $this, 'export_json' ) );
64
- add_action( 'admin_init', array( $this, 'import_json' ) );
65
- add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
- add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
- }
68
-
69
- /**
70
- * Add the export link to action list for flows row actions
71
- *
72
- * @since 1.1.4
73
- *
74
- * @param array $actions Actions array.
75
- * @param object $post Post object.
76
- *
77
- * @return array
78
- */
79
- public function export_link( $actions, $post ) {
80
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
- $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
- }
83
- return $actions;
84
- }
85
-
86
- /**
87
- * Add menus
88
- *
89
- * @since 1.1.4
90
- */
91
- public function add_to_menus() {
92
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
- }
95
-
96
- /**
97
- * Export flow with steps and its meta
98
- *
99
- * @since 1.1.4
100
- */
101
- public function export_flow() {
102
-
103
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
- wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
- }
106
-
107
- if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
- return;
109
- }
110
-
111
- // Get the original post id.
112
- $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
-
114
- $flows = array();
115
- $flows[] = $this->get_flow_export_data( $flow_id );
116
- $flows = apply_filters( 'cartflows_export_data', $flows );
117
-
118
- nocache_headers();
119
- header( 'Content-Type: application/json; charset=utf-8' );
120
- header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
- header( 'Expires: 0' );
122
-
123
- echo wp_json_encode( $flows );
124
- exit;
125
- }
126
-
127
- /**
128
- * Export flow markup
129
- *
130
- * @since 1.1.4
131
- */
132
- public function exporter_markup() {
133
- include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
- }
135
-
136
- /**
137
- * Import flow markup
138
- *
139
- * @since 1.1.4
140
- */
141
- public function importer_markup() {
142
- include_once CARTFLOWS_DIR . 'includes/importer.php';
143
- }
144
-
145
- /**
146
- * Export flow
147
- *
148
- * @since 1.1.4
149
- */
150
- public function export_json() {
151
- if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
- return;
153
- }
154
-
155
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
- return;
157
- }
158
-
159
- if ( ! current_user_can( 'manage_options' ) ) {
160
- return;
161
- }
162
-
163
- $flows = $this->get_all_flow_export_data();
164
- $flows = apply_filters( 'cartflows_export_data', $flows );
165
-
166
- nocache_headers();
167
- header( 'Content-Type: application/json; charset=utf-8' );
168
- header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
- header( 'Expires: 0' );
170
-
171
- echo wp_json_encode( $flows );
172
- exit;
173
- }
174
-
175
- /**
176
- * Get flow export data
177
- *
178
- * @since 1.1.4
179
- *
180
- * @param integer $flow_id Flow ID.
181
- * @return array
182
- */
183
- public function get_flow_export_data( $flow_id ) {
184
-
185
- $export_all = apply_filters( 'cartflows_export_all', true );
186
-
187
- $valid_step_meta_keys = array(
188
- '_wp_page_template',
189
- '_thumbnail_id',
190
- 'classic-editor-remember',
191
- );
192
-
193
- $new_steps = array();
194
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
- if ( $steps ) {
196
- foreach ( $steps as $key => $step ) {
197
-
198
- // Add step post meta.
199
- $new_all_meta = array();
200
- $all_meta = get_post_meta( $step['id'] );
201
-
202
- // Add single step.
203
- $step_data_arr = array(
204
- 'title' => get_the_title( $step['id'] ),
205
- 'type' => $step['type'],
206
- 'meta' => $all_meta,
207
- 'post_content' => '',
208
- );
209
-
210
- if ( $export_all ) {
211
-
212
- $step_post_obj = get_post( $step['id'] );
213
-
214
- $step_data_arr['post_content'] = $step_post_obj->post_content;
215
- }
216
-
217
- $new_steps[] = $step_data_arr;
218
- }
219
- }
220
-
221
- // Add single flow.
222
- return array(
223
- 'title' => get_the_title( $flow_id ),
224
- 'steps' => $new_steps,
225
- );
226
- }
227
-
228
- /**
229
- * Get all flow export data
230
- *
231
- * @since 1.1.4
232
- */
233
- public function get_all_flow_export_data() {
234
-
235
- $query_args = array(
236
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
-
238
- // Query performance optimization.
239
- 'fields' => 'ids',
240
- 'no_found_rows' => true,
241
- 'posts_per_page' => -1,
242
- );
243
-
244
- $query = new WP_Query( $query_args );
245
- $flows = array();
246
- if ( $query->posts ) {
247
- foreach ( $query->posts as $key => $post_id ) {
248
- $flows[] = $this->get_flow_export_data( $post_id );
249
- }
250
- }
251
-
252
- return $flows;
253
- }
254
-
255
- /**
256
- * Import our exported file
257
- *
258
- * @since 1.1.4
259
- */
260
- public function import_json() {
261
- if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
- return;
263
- }
264
-
265
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
- return;
267
- }
268
-
269
- if ( ! current_user_can( 'manage_options' ) ) {
270
- return;
271
- }
272
-
273
- $filename = $_FILES['file']['name']; //phpcs:ignore
274
- $file_info = explode( '.', $filename );
275
- $extension = end( $file_info );
276
-
277
- if ( 'json' != $extension ) {
278
- wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
- }
280
-
281
- $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
-
283
- if ( empty( $file ) ) {
284
- wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
- }
286
-
287
- // Retrieve the settings from the file and convert the JSON object to an array.
288
- $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
-
290
- $this->import_from_json_data( $flows );
291
-
292
- add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
- }
294
-
295
- /**
296
- * Import flow from the JSON data
297
- *
298
- * @since x.x.x
299
- * @param array $flows JSON array.
300
- * @return void
301
- */
302
- public function import_from_json_data( $flows ) {
303
- if ( $flows ) {
304
-
305
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
-
307
- foreach ( $flows as $key => $flow ) {
308
-
309
- $flow_title = $flow['title'];
310
- if ( post_exists( $flow['title'] ) ) {
311
- $flow_title = $flow['title'] . ' Copy';
312
- }
313
-
314
- // Create post object.
315
- $new_flow_args = apply_filters(
316
- 'cartflows_flow_importer_args',
317
- array(
318
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
- 'post_title' => $flow_title,
320
- 'post_status' => 'publish',
321
- )
322
- );
323
-
324
- // Insert the post into the database.
325
- $flow_id = wp_insert_post( $new_flow_args );
326
-
327
- /**
328
- * Fire after flow import
329
- *
330
- * @since x.x.x
331
- * @param int $flow_id Flow ID.
332
- * @param array $new_flow_args Flow post args.
333
- * @param array $flows Flow JSON data.
334
- */
335
- do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
-
337
- if ( $flow['steps'] ) {
338
- foreach ( $flow['steps'] as $key => $step ) {
339
-
340
- $new_all_meta = array();
341
- if ( is_array( $step['meta'] ) ) {
342
- foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
- $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
- }
345
- }
346
- $new_step_args = apply_filters(
347
- 'cartflows_step_importer_args',
348
- array(
349
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
- 'post_title' => $step['title'],
351
- 'post_status' => 'publish',
352
- 'meta_input' => $new_all_meta,
353
- 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
- )
355
- );
356
-
357
- $new_step_id = wp_insert_post( $new_step_args );
358
-
359
- /**
360
- * Fire after step import
361
- *
362
- * @since x.x.x
363
- * @param int $new_step_id step ID.
364
- * @param int $flow_id flow ID.
365
- * @param array $new_step_args Step post args.
366
- * @param array $flow_steps Flow steps.
367
- * @param array $flows All flows JSON data.
368
- */
369
- do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
-
371
- // Insert post meta.
372
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
-
374
- $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
- $current_term = term_exists( $step['type'], $step_taxonomy );
376
-
377
- // // Set type object.
378
- $data = get_term( $current_term['term_id'], $step_taxonomy );
379
- $step_slug = $data->slug;
380
- wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
-
382
- // Set type.
383
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
-
385
- // Set flow.
386
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
-
388
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
-
390
- if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
-
392
- // Download and replace images.
393
- $content = $this->get_content( $step['post_content'] );
394
-
395
- // Update post content.
396
- wp_update_post(
397
- array(
398
- 'ID' => $new_step_id,
399
- 'post_content' => $content,
400
- )
401
- );
402
- }
403
-
404
- // Elementor Data.
405
- if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
- // Add "elementor" in import [queue].
407
- // @todo Remove required `allow_url_fopen` support.
408
- if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
- $obj->import_single_template( $new_step_id );
411
- }
412
- }
413
-
414
- // Beaver Builder.
415
- if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
- if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
- CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
- }
419
- }
420
- }
421
- }
422
- }
423
- }
424
- }
425
-
426
- /**
427
- * Download and Replace hotlink images
428
- *
429
- * @since x.x.x
430
- *
431
- * @param string $content Mixed post content.
432
- * @return array Hotlink image array.
433
- */
434
- public function get_content( $content = '' ) {
435
-
436
- $content = stripslashes( $content );
437
-
438
- // Extract all links.
439
- $all_links = wp_extract_urls( $content );
440
-
441
- // Not have any link.
442
- if ( empty( $all_links ) ) {
443
- return $content;
444
- }
445
-
446
- $link_mapping = array();
447
- $image_links = array();
448
- $other_links = array();
449
-
450
- // Extract normal and image links.
451
- foreach ( $all_links as $key => $link ) {
452
- if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
-
454
- // Get all image links.
455
- // Avoid *-150x, *-300x and *-1024x images.
456
- if (
457
- false === strpos( $link, '-150x' ) &&
458
- false === strpos( $link, '-300x' ) &&
459
- false === strpos( $link, '-1024x' )
460
- ) {
461
- $image_links[] = $link;
462
- }
463
- } else {
464
-
465
- // Collect other links.
466
- $other_links[] = $link;
467
- }
468
- }
469
-
470
- // Step 1: Download images.
471
- if ( ! empty( $image_links ) ) {
472
- foreach ( $image_links as $key => $image_url ) {
473
- // Download remote image.
474
- $image = array(
475
- 'url' => $image_url,
476
- 'id' => 0,
477
- );
478
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
-
480
- // Old and New image mapping links.
481
- $link_mapping[ $image_url ] = $downloaded_image['url'];
482
- }
483
- }
484
-
485
- // Step 3: Replace mapping links.
486
- foreach ( $link_mapping as $old_url => $new_url ) {
487
- $content = str_replace( $old_url, $new_url, $content );
488
-
489
- // Replace the slashed URLs if any exist.
490
- $old_url = str_replace( '/', '/\\', $old_url );
491
- $new_url = str_replace( '/', '/\\', $new_url );
492
- $content = str_replace( $old_url, $new_url, $content );
493
- }
494
-
495
- return $content;
496
- }
497
-
498
- /**
499
- * Imported notice
500
- *
501
- * @since 1.1.4
502
- */
503
- public function imported_successfully() {
504
- ?>
505
- <div class="notice notice-success">
506
- <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
- </div>
508
- <?php
509
- }
510
-
511
- /**
512
- * Clear Cache.
513
- *
514
- * @since 1.0.0
515
- */
516
- public function clear_cache() {
517
- // Clear 'Elementor' file cache.
518
- if ( class_exists( '\Elementor\Plugin' ) ) {
519
- \Elementor\Plugin::$instance->files_manager->clear_cache();
520
- }
521
- }
522
-
523
- /**
524
- * JS Templates
525
- *
526
- * @since 1.0.0
527
- *
528
- * @return void
529
- */
530
- public function js_templates() {
531
-
532
- // Loading Templates.
533
- ?>
534
- <script type="text/template" id="tmpl-cartflows-step-loading">
535
- <div class="template-message-block cartflows-step-loading">
536
- <h2>
537
- <span class="spinner"></span>
538
- <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
- </h2>
540
- <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
- </div>
542
- </script>
543
-
544
- <?php
545
- // Search Templates.
546
- ?>
547
- <script type="text/template" id="tmpl-cartflows-searching-templates">
548
- <div class="template-message-block cartflows-searching-templates">
549
- <h2>
550
- <span class="spinner"></span>
551
- <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
- </h2>
553
- <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
- </div>
555
- </script>
556
-
557
- <?php
558
- // CartFlows Importing Template.
559
- ?>
560
- <script type="text/template" id="tmpl-cartflows-step-importing">
561
- <div class="template-message-block cartflows-step-importing">
562
- <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
- </div>
564
- </script>
565
-
566
- <?php
567
- // CartFlows Imported.
568
- ?>
569
- <script type="text/template" id="tmpl-cartflows-step-imported">
570
- <div class="template-message-block cartflows-step-imported">
571
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
- </script>
574
-
575
- <?php
576
- // No templates.
577
- ?>
578
- <script type="text/template" id="tmpl-cartflows-no-steps">
579
- <div class="cartflows-no-steps">
580
- <div class="template-message-block">
581
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
- <p class="description"></p>
583
- </div>
584
- </div>
585
- </script>
586
-
587
- <?php
588
- // No templates.
589
- ?>
590
- <script type="text/template" id="tmpl-cartflows-no-flows">
591
- <div class="cartflows-no-flows">
592
- <div class="template-message-block">
593
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
- <p class="description"></p>
595
- </div>
596
- </div>
597
- </script>
598
-
599
- <?php
600
- // Error handling.
601
- ?>
602
- <script type="text/template" id="tmpl-templator-error">
603
- <div class="notice notice-error"><p>{{ data }}</p></div>
604
- </script>
605
-
606
- <?php
607
- // Redirect to Elementor.
608
- ?>
609
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
- <div class="template-message-block templator-redirect-to-elementor">
611
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
- </script>
614
-
615
- <?php
616
- /**
617
- * Responsive Buttons
618
- */
619
- ?>
620
- <script type="text/template" id="tmpl-cartflows-responsive-view">
621
- <span class="responsive-view">
622
- <span class="actions">
623
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
- </span>
627
- </span>
628
- </script>
629
-
630
- <?php
631
- // Templates data.
632
- ?>
633
- <script type="text/template" id="tmpl-cartflows-flows-list">
634
-
635
- <# console.log( data.items.length ) #>
636
- <# console.log( data.items ) #>
637
- <# if ( data.items.length ) { #>
638
- <# for ( key in data.items ) { #>
639
- <#
640
- var flow_steps = [];
641
- if( data.items[ key ].flow_steps ) {
642
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
- return value['id'];
644
- });
645
- }
646
- #>
647
- <div class="inner">
648
- <div class="template">
649
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
650
- <div class="template-screenshot">
651
- <# if( data.items[ key ].featured_image_url ) { #>
652
- <img src="{{ data.items[ key ].featured_image_url }}" />
653
- <# } else { #>
654
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
- <# } #>
656
- </div>
657
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
- <# } #>
660
- <# if( data.items[ key ].woo_required ) { #>
661
- <div class="notice notice-info" style="width: auto;">
662
- <p class="wcf-learn-how">
663
- Install/Activate WooCommerce to use this template.
664
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
- <i class="dashicons dashicons-external"></i>
667
- </a>
668
- </p>
669
- </div>
670
- <# } else { #>
671
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
672
- <# } #>
673
-
674
- </span>
675
- <div class="template-id-container">
676
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
- <div class="template-actions">
678
-
679
- <#
680
- if( data.items[ key ].page_builder.slug ) {
681
- required_plugin_group = data.items[ key ].page_builder.slug;
682
- } else {
683
- required_plugin_group = '';
684
- }
685
-
686
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
687
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
- } else {
689
- import_btn_title = 'Import';
690
- } #>
691
-
692
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
- <# if( ! data.items[ key ].woo_required ) { #>
694
- <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
695
- <# } else { #>
696
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
- <# } #>
698
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
- <# } else { #>
701
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
- <# } #>
703
- </div>
704
- </div>
705
- </div>
706
- </div>
707
- <# } #>
708
- <# } #>
709
- </script>
710
-
711
- <?php
712
- // Empty Step.
713
- ?>
714
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
- <div class="inner">
716
- <div class="template">
717
- <span class="thumbnail site-preview cartflows-flow-preview">
718
- <div class="template-screenshot">
719
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
- </div>
721
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
- </span>
723
- <div class="template-id-container">
724
- <h3 class="template-name"> Blank </h3>
725
- <div class="template-actions">
726
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
- </div>
728
- </div>
729
- </div>
730
- </div>
731
- </script>
732
-
733
- <?php
734
- // Templates data.
735
- ?>
736
- <script type="text/template" id="tmpl-cartflows-steps-list">
737
- <# if ( data.items.length ) { #>
738
- <# for ( key in data.items ) { #>
739
- <#
740
- var flow_steps = [];
741
- if( data.items[ key ].flow_steps ) {
742
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
- return value['id'];
744
- });
745
- }
746
- #>
747
- <div class="inner">
748
- <div class="template">
749
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
750
- <div class="template-screenshot">
751
- <# if( data.items[ key ].featured_image_url ) { #>
752
- <img src="{{ data.items[ key ].featured_image_url }}" />
753
- <# } else { #>
754
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
- <# } #>
756
- </div>
757
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
-
759
- <# if( data.items[ key ].woo_required ) { #>
760
- <div class="notice notice-info" style="width: auto;">
761
- <p class="wcf-learn-how">
762
- Install/Activate WooCommerce to use this template.
763
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
- <i class="dashicons dashicons-external"></i>
766
- </a>
767
- </p>
768
- </div>
769
- <# } else { #>
770
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
771
- <# } #>
772
-
773
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
- <# } #>
776
- </span>
777
- <div class="template-id-container">
778
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
- <div class="template-actions">
780
-
781
- <#
782
-
783
- var step_slug = data.items[ key ].step_type.slug || '';
784
- var step_title = data.items[ key ].step_type.name || '';
785
- var import_btn_title = 'Import';
786
-
787
- var required_plugin_group = '';
788
- if( data.items[ key ].page_builder ) {
789
- required_plugin_group = data.items[ key ].page_builder.slug;
790
-
791
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
792
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
- }
794
- }
795
- #>
796
-
797
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
-
799
- <# if( ! data.items[ key ].woo_required ) { #>
800
- <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
801
- <# } else { #>
802
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
- <# } #>
804
-
805
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
- <# } else { #>
808
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
- <# } #>
810
- </div>
811
- </div>
812
- </div>
813
- </div>
814
- <# } #>
815
- <# } #>
816
- </script>
817
-
818
- <?php
819
- /**
820
- * TMPL - Website Unreachable
821
- */
822
- ?>
823
- <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
- <div class="postbox cartflows-website-unreachable">
825
- <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
- <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
- <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
- </div>
829
- </script>
830
-
831
- <?php
832
- /**
833
- * TMPL - Filters
834
- */
835
- ?>
836
- <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
- <?php
838
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
- $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
- $title = $page_builder['title'];
841
-
842
- $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
- $theme_status = '';
844
- if ( 'divi' === $default_page_builder ) {
845
-
846
- $theme_status = $page_builder['theme-status'];
847
- $plugin_status = $page_builder['plugin-status'];
848
-
849
- if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
- $plugin_string = 'Please activate ' . esc_html( $title );
851
- } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
- $plugin_string = 'Please install and activate ' . esc_html( $title );
853
- }
854
- }
855
- ?>
856
- <div class="wcf-page-builder-message">
857
- <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
- <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
- <p>We plan to add design templates made with more page builder shortly!</p>
860
- </div>
861
- </script>
862
-
863
- <?php
864
- /**
865
- * TMPL - Filters
866
- */
867
- ?>
868
- <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
- <# if ( data ) { #>
870
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
- <# if ( data.args.show_all ) { #>
872
- <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
- <# } #>
874
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
- <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
- <# } #>
877
- <# var step_slug_data = []; #>
878
- <# for ( key in data.items ) { #>
879
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
880
-
881
- <# step_slug_data.push( data.items[ key ].slug ); #>
882
-
883
- <# } #>
884
- <# if( step_slug_data.indexOf("optin") === -1){ #>
885
- <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
- <# } #>
887
- </select>
888
- <# } #>
889
- </script>
890
-
891
- <script type="text/template" id="tmpl-cartflows-term-filters">
892
-
893
- <# if ( data ) { #>
894
-
895
- <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
-
898
- <# if ( data.args.show_all ) { #>
899
- <li>
900
- <a href="#" data-group="all"> All </a>
901
- </li>
902
- <# } #>
903
-
904
- <# for ( key in data.items ) { #>
905
- <li>
906
- <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
907
- </li>
908
- <# } #>
909
-
910
- </ul>
911
-
912
- <?php
913
-
914
- /**
915
- <# } else { #>
916
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
-
918
- <# if ( data.args.show_all ) { #>
919
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
- <# } #>
921
-
922
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
- <# } #>
925
-
926
- <# for ( key in data.items ) { #>
927
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
928
- <# } #>
929
-
930
- </select>
931
- */
932
- ?>
933
-
934
- <?php /* <# } #> */ ?>
935
-
936
- <# } #>
937
- </script>
938
-
939
- <?php
940
- // Step Type.
941
- ?>
942
- <script type="text/template" id="tmpl-cartflows-step-types">
943
- <ul class="wcf-tab nav-tabs">
944
- <# if( data.items_count ) { #>
945
- <# for( key in data.items ) { #>
946
- <# console.log( data.items[ key ].id ) #>
947
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
- </li>
950
- <# } #>
951
- <# } #>
952
- </ul>
953
- </script>
954
-
955
- <?php
956
- // Add to library button.
957
- ?>
958
- <script type="text/template" id="tmpl-templator-add-to-library">
959
- <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
960
- </script>
961
- <?php
962
- }
963
-
964
- /**
965
- * Enqueue scripts
966
- *
967
- * @since 1.0.0
968
- *
969
- * @hook admin_enqueue_scripts
970
- * @param string $hook Current page hook.
971
- */
972
- public function scripts( $hook = '' ) {
973
-
974
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
- return;
976
- }
977
-
978
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
-
983
- $installed_plugins = get_plugins();
984
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
- $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
-
987
- $localize_vars = array(
988
- '_is_pro_active' => _is_cartflows_pro(),
989
- 'is_wc_installed' => $is_wc_installed,
990
- 'is_wc_activated' => $is_wc_activated,
991
-
992
- // Flow and its rest fields.
993
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
994
- 'flow_fields' => array(
995
- 'id',
996
- 'title',
997
- 'flow_type',
998
- 'page_builder',
999
- 'flow_steps',
1000
- 'licence_status',
1001
- 'featured_image_url',
1002
- 'featured_media', // @required for field `featured_image_url`.
1003
- ),
1004
-
1005
- // Flow type and rest fields.
1006
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1007
- 'flow_type_fields' => array(
1008
- 'id',
1009
- 'name',
1010
- 'slug',
1011
- ),
1012
-
1013
- // Flow page builder and rest fields.
1014
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1015
- 'flow_page_builder_fields' => array(
1016
- 'id',
1017
- 'name',
1018
- 'slug',
1019
- ),
1020
-
1021
- // Step page builder and rest fields.
1022
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1023
- 'step_page_builder_fields' => array(
1024
- 'id',
1025
- 'name',
1026
- 'slug',
1027
- ),
1028
-
1029
- // Step and its rest fields.
1030
- 'step' => CARTFLOWS_STEP_POST_TYPE,
1031
- 'step_fields' => array(
1032
- 'title',
1033
- 'featured_image_url',
1034
- 'featured_media', // @required for field `featured_image_url`.
1035
- 'id',
1036
- 'flow_type',
1037
- 'step_type',
1038
- 'page_builder',
1039
- 'licence_status',
1040
- ),
1041
-
1042
- // Step type and its rest fields.
1043
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1044
- 'step_type_fields' => array(
1045
- 'id',
1046
- 'name',
1047
- 'slug',
1048
- ),
1049
-
1050
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
1051
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
1052
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1053
- 'site_url' => site_url(),
1054
- 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1055
- 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1056
- 'admin_url' => admin_url(),
1057
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1058
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1059
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1060
-
1061
- 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1062
-
1063
- 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1064
- );
1065
-
1066
- $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1067
-
1068
- // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1069
- // wp_die( );
1070
- // Add thickbox.
1071
- add_thickbox();
1072
-
1073
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1074
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1075
- }
1076
-
1077
- /**
1078
- * Import.
1079
- *
1080
- * @since 1.0.0
1081
- *
1082
- * @hook wp_ajax_cartflows_import_flow_step
1083
- * @return void
1084
- */
1085
- public function import_flow() {
1086
-
1087
- if ( ! current_user_can( 'manage_options' ) ) {
1088
- return;
1089
- }
1090
-
1091
- check_ajax_referer( 'cf-import-flow-step', 'security' );
1092
-
1093
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1094
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1095
-
1096
- wcf()->logger->import_log( '------------------------------------' );
1097
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1098
- wcf()->logger->import_log( '------------------------------------' );
1099
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1100
-
1101
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1102
-
1103
- $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1104
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1105
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1106
- $post_content = $response['data']['divi_content'];
1107
- }
1108
- }
1109
-
1110
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1111
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1112
- $post_content = $response['data']['divi_content'];
1113
- }
1114
- }
1115
-
1116
- if ( false === $response['success'] ) {
1117
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1118
- wp_send_json_error( $response );
1119
- }
1120
-
1121
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1122
-
1123
- $new_step_id = wp_insert_post(
1124
- array(
1125
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1126
- 'post_title' => $response['title'],
1127
- 'post_content' => $post_content,
1128
- 'post_status' => 'publish',
1129
- )
1130
- );
1131
-
1132
- if ( is_wp_error( $new_step_id ) ) {
1133
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1134
- wp_send_json_error( $new_step_id );
1135
- }
1136
-
1137
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1138
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1139
- update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1140
- }
1141
- }
1142
-
1143
- /* Imported Step */
1144
- update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1145
-
1146
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1147
- // insert post meta.
1148
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1149
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1150
-
1151
- /**
1152
- * Import & Set type.
1153
- */
1154
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1155
-
1156
- $term_slug = '';
1157
- if ( $term ) {
1158
-
1159
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1160
- $term_exist = term_exists( $term->slug, $taxonomy );
1161
-
1162
- if ( empty( $term_exist ) ) {
1163
- $terms = array(
1164
- array(
1165
- 'name' => $term->name,
1166
- 'slug' => $term->slug,
1167
- ),
1168
- );
1169
-
1170
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1171
- wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1172
- }
1173
-
1174
- $current_term = term_exists( $term->slug, $taxonomy );
1175
-
1176
- // Set type object.
1177
- $data = get_term( $current_term['term_id'], $taxonomy );
1178
- $term_slug = $data->slug;
1179
- $term_name = $data->name;
1180
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1181
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1182
-
1183
- // Set type.
1184
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1185
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1186
- }
1187
-
1188
- // Set flow.
1189
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1190
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1191
-
1192
- /**
1193
- * Update steps for the current flow.
1194
- */
1195
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1196
-
1197
- if ( ! is_array( $flow_steps ) ) {
1198
- $flow_steps = array();
1199
- }
1200
-
1201
- $flow_steps[] = array(
1202
- 'id' => $new_step_id,
1203
- 'title' => $response['title'],
1204
- 'type' => $term_slug,
1205
- );
1206
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1207
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1208
-
1209
- // Import Post Meta.
1210
- self::import_post_meta( $new_step_id, $response );
1211
-
1212
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1213
- wcf()->logger->import_log( '------------------------------------' );
1214
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1215
- wcf()->logger->import_log( '------------------------------------' );
1216
-
1217
- do_action( 'cartflows_import_complete' );
1218
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1219
-
1220
- // Batch Process.
1221
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
1222
-
1223
- /**
1224
- * End
1225
- */
1226
- wp_send_json_success( $new_step_id );
1227
- }
1228
-
1229
- /**
1230
- * Import Step.
1231
- *
1232
- * @since 1.0.0
1233
- * @hook wp_ajax_cartflows_step_import
1234
- *
1235
- * @return void
1236
- */
1237
- public function create_default_flow() {
1238
-
1239
- if ( ! current_user_can( 'manage_options' ) ) {
1240
- return;
1241
- }
1242
-
1243
- check_ajax_referer( 'cf-default-flow', 'security' );
1244
-
1245
- // Create post object.
1246
- $new_flow_post = array(
1247
- 'post_content' => '',
1248
- 'post_status' => 'publish',
1249
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1250
- );
1251
-
1252
- // Insert the post into the database.
1253
- $flow_id = wp_insert_post( $new_flow_post );
1254
-
1255
- if ( is_wp_error( $flow_id ) ) {
1256
- wp_send_json_error( $flow_id->get_error_message() );
1257
- }
1258
-
1259
- $flow_steps = array();
1260
-
1261
- if ( wcf()->is_woo_active ) {
1262
- $steps_data = array(
1263
- 'sales' => array(
1264
- 'title' => __( 'Sales Landing', 'cartflows' ),
1265
- 'type' => 'landing',
1266
- ),
1267
- 'order-form' => array(
1268
- 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1269
- 'type' => 'checkout',
1270
- ),
1271
- 'order-confirmation' => array(
1272
- 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1273
- 'type' => 'thankyou',
1274
- ),
1275
- );
1276
-
1277
- } else {
1278
- $steps_data = array(
1279
- 'landing' => array(
1280
- 'title' => __( 'Landing', 'cartflows' ),
1281
- 'type' => 'landing',
1282
- ),
1283
- 'thankyou' => array(
1284
- 'title' => __( 'Thank You', 'cartflows' ),
1285
- 'type' => 'landing',
1286
- ),
1287
- );
1288
- }
1289
-
1290
- foreach ( $steps_data as $slug => $data ) {
1291
-
1292
- $post_content = '';
1293
- $step_type = trim( $data['type'] );
1294
-
1295
- $step_id = wp_insert_post(
1296
- array(
1297
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1298
- 'post_title' => $data['title'],
1299
- 'post_content' => $post_content,
1300
- 'post_status' => 'publish',
1301
- )
1302
- );
1303
-
1304
- if ( is_wp_error( $step_id ) ) {
1305
- wp_send_json_error( $step_id->get_error_message() );
1306
- }
1307
-
1308
- if ( $step_id ) {
1309
-
1310
- $flow_steps[] = array(
1311
- 'id' => $step_id,
1312
- 'title' => $data['title'],
1313
- 'type' => $step_type,
1314
- );
1315
-
1316
- // insert post meta.
1317
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1318
- update_post_meta( $step_id, 'wcf-step-type', $step_type );
1319
-
1320
- wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1321
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1322
-
1323
- update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1324
- }
1325
- }
1326
-
1327
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1328
-
1329
- wp_send_json_success( $flow_id );
1330
- }
1331
-
1332
- /**
1333
- * Create Flow
1334
- *
1335
- * @return void
1336
- */
1337
- public function create_flow() {
1338
-
1339
- if ( ! current_user_can( 'manage_options' ) ) {
1340
- return;
1341
- }
1342
-
1343
- check_ajax_referer( 'cf-create-flow', 'security' );
1344
-
1345
- // Create post object.
1346
- $new_flow_post = array(
1347
- 'post_content' => '',
1348
- 'post_status' => 'publish',
1349
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1350
- );
1351
-
1352
- // Insert the post into the database.
1353
- $flow_id = wp_insert_post( $new_flow_post );
1354
-
1355
- if ( is_wp_error( $flow_id ) ) {
1356
- wp_send_json_error( $flow_id->get_error_message() );
1357
- }
1358
-
1359
- /* Imported Flow */
1360
- update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1361
-
1362
- wp_send_json_success( $flow_id );
1363
- }
1364
-
1365
- /**
1366
- * Create Step
1367
- *
1368
- * @return void
1369
- */
1370
- public function import_step() {
1371
-
1372
- if ( ! current_user_can( 'manage_options' ) ) {
1373
- return;
1374
- }
1375
-
1376
- check_ajax_referer( 'cf-step-import', 'security' );
1377
-
1378
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1379
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1380
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1381
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1382
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1383
-
1384
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1385
-
1386
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1387
-
1388
- wcf()->logger->import_log( '------------------------------------' );
1389
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
1390
- wcf()->logger->import_log( '------------------------------------' );
1391
-
1392
- if ( empty( $template_id ) || empty( $post_id ) ) {
1393
- /* translators: %s: template ID */
1394
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1395
- wcf()->logger->import_log( $data );
1396
- wp_send_json_error( $data );
1397
- }
1398
-
1399
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1400
-
1401
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1402
-
1403
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1404
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1405
-
1406
- update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1407
-
1408
- wp_update_post(
1409
- array(
1410
- 'ID' => $post_id,
1411
- 'post_content' => $response['data']['divi_content'],
1412
- )
1413
- );
1414
- }
1415
- }
1416
-
1417
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1418
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1419
-
1420
- wp_update_post(
1421
- array(
1422
- 'ID' => $post_id,
1423
- 'post_content' => $response['data']['divi_content'],
1424
- )
1425
- );
1426
- }
1427
- }
1428
-
1429
- /* Imported Step */
1430
- update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1431
-
1432
- // Import Post Meta.
1433
- self::import_post_meta( $post_id, $response );
1434
-
1435
- do_action( 'cartflows_import_complete' );
1436
-
1437
- // Batch Process.
1438
- do_action( 'cartflows_after_template_import', $post_id, $response );
1439
-
1440
- wcf()->logger->import_log( '------------------------------------' );
1441
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1442
- wcf()->logger->import_log( '------------------------------------' );
1443
-
1444
- wp_send_json_success( $post_id );
1445
- }
1446
-
1447
- /**
1448
- * Import Step.
1449
- *
1450
- * @since 1.0.0
1451
- * @hook wp_ajax_cartflows_step_create_blank
1452
- *
1453
- * @return void
1454
- */
1455
- public function step_create_blank() {
1456
-
1457
- if ( ! current_user_can( 'manage_options' ) ) {
1458
- return;
1459
- }
1460
-
1461
- check_ajax_referer( 'cf-step-create-blank', 'security' );
1462
-
1463
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1464
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1465
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1466
-
1467
- if ( empty( $flow_id ) || empty( $step_type ) ) {
1468
- /* translators: %s: flow ID */
1469
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1470
- wcf()->logger->import_log( $data );
1471
- wp_send_json_error( $data );
1472
- }
1473
-
1474
- wcf()->logger->import_log( '------------------------------------' );
1475
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1476
-
1477
- $step_type_title = str_replace( '-', ' ', $step_type );
1478
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1479
-
1480
- $new_step_id = wp_insert_post(
1481
- array(
1482
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1483
- 'post_title' => $step_title,
1484
- 'post_content' => '',
1485
- 'post_status' => 'publish',
1486
- )
1487
- );
1488
-
1489
- // insert post meta.
1490
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1491
-
1492
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1493
- $term_exist = term_exists( $step_type_slug, $taxonomy );
1494
-
1495
- if ( empty( $term_exist ) ) {
1496
- $terms = array(
1497
- array(
1498
- 'name' => $step_type_title,
1499
- 'slug' => $step_type_slug,
1500
- ),
1501
- );
1502
-
1503
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1504
- wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1505
- }
1506
-
1507
- $current_term = term_exists( $step_type_slug, $taxonomy );
1508
-
1509
- // Set type object.
1510
- $data = get_term( $current_term['term_id'], $taxonomy );
1511
- $step_slug = $data->slug;
1512
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1513
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1514
-
1515
- // Set Default page Layout.
1516
- update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1517
-
1518
- // Set type.
1519
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1520
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1521
-
1522
- // Set flow.
1523
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1524
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1525
-
1526
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1527
-
1528
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1529
- wcf()->logger->import_log( '------------------------------------' );
1530
-
1531
- wp_send_json_success( $new_step_id );
1532
- }
1533
-
1534
- /**
1535
- * Import Post Meta
1536
- *
1537
- * @since 1.0.0
1538
- *
1539
- * @param integer $post_id Post ID.
1540
- * @param array $response Post meta.
1541
- * @return void
1542
- */
1543
- public static function import_post_meta( $post_id, $response ) {
1544
-
1545
- $metadata = (array) $response['post_meta'];
1546
-
1547
- foreach ( $metadata as $meta_key => $meta_value ) {
1548
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1549
-
1550
- if ( $meta_value ) {
1551
-
1552
- if ( is_serialized( $meta_value, true ) ) {
1553
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1554
- } elseif ( is_array( $meta_value ) ) {
1555
- $raw_data = json_decode( stripslashes( $meta_value ), true );
1556
- } else {
1557
- $raw_data = $meta_value;
1558
- }
1559
-
1560
- if ( '_elementor_data' === $meta_key ) {
1561
- if ( is_array( $raw_data ) ) {
1562
- $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1563
- } else {
1564
- $raw_data = wp_slash( $raw_data );
1565
- }
1566
- }
1567
- if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1568
- if ( is_array( $raw_data ) ) {
1569
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1570
- } else {
1571
- if ( ! is_object( $raw_data ) ) {
1572
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1573
- }
1574
- }
1575
- }
1576
-
1577
- update_post_meta( $post_id, $meta_key, $raw_data );
1578
- }
1579
- }
1580
- }
1581
-
1582
- /**
1583
- * Import Template for Elementor
1584
- *
1585
- * @since 1.0.0
1586
- *
1587
- * @param integer $post_id Post ID.
1588
- * @param array $response Post meta.
1589
- * @param array $page_build_data Page build data.
1590
- * @return void
1591
- */
1592
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1593
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1594
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1595
- wcf()->logger->import_log( $data );
1596
- wp_send_json_error( $data );
1597
- }
1598
-
1599
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1600
-
1601
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1602
-
1603
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1604
- $obj->import_single_template( $post_id );
1605
-
1606
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1607
- }
1608
-
1609
- /**
1610
- * Supported post types
1611
- *
1612
- * @since 1.0.0
1613
- *
1614
- * @return array Supported post types.
1615
- */
1616
- public static function supported_post_types() {
1617
- return apply_filters(
1618
- 'cartflows_supported_post_types',
1619
- array(
1620
- CARTFLOWS_FLOW_POST_TYPE,
1621
- )
1622
- );
1623
- }
1624
-
1625
- /**
1626
- * Check supported post type
1627
- *
1628
- * @since 1.0.0
1629
- *
1630
- * @param string $post_type Post type.
1631
- * @return boolean Supported post type status.
1632
- */
1633
- public static function is_supported_post( $post_type = '' ) {
1634
-
1635
- if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1636
- return true;
1637
- }
1638
-
1639
- return false;
1640
- }
1641
-
1642
- /**
1643
- * Set steps to the flow
1644
- *
1645
- * @param integer $flow_id Flow ID.
1646
- * @param integer $new_step_id New step ID.
1647
- * @param string $step_title Flow Type.
1648
- * @param string $step_slug Flow Type.
1649
- */
1650
- public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1651
- // Update steps for the current flow.
1652
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1653
-
1654
- if ( ! is_array( $flow_steps ) ) {
1655
- $flow_steps = array();
1656
- }
1657
-
1658
- $flow_steps[] = array(
1659
- 'id' => $new_step_id,
1660
- 'title' => $step_title,
1661
- 'type' => $step_slug,
1662
- );
1663
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1664
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1665
- }
1666
-
1667
- /**
1668
- * Localize variables in admin
1669
- *
1670
- * @param array $vars variables.
1671
- */
1672
- public function localize_vars( $vars ) {
1673
-
1674
- $ajax_actions = array(
1675
- 'cf_step_import',
1676
- 'cf_load_steps',
1677
- 'cf_create_flow',
1678
- 'cf_default_flow',
1679
- 'cf_step_create_blank',
1680
- 'cf_import_flow_step',
1681
- );
1682
-
1683
- foreach ( $ajax_actions as $action ) {
1684
-
1685
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1686
- }
1687
-
1688
- return $vars;
1689
- }
1690
-
1691
- /**
1692
- * Ajax action to activate plugin
1693
- */
1694
- public function activate_plugin() {
1695
-
1696
- if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1697
- wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1698
- }
1699
-
1700
- if ( ! current_user_can( 'activate_plugins' ) ) {
1701
- wp_send_json_error(
1702
- array(
1703
- 'success' => false,
1704
- 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1705
- )
1706
- );
1707
- }
1708
-
1709
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1710
-
1711
- $activate = activate_plugin( $plugin_init, '', false, true );
1712
-
1713
- if ( is_wp_error( $activate ) ) {
1714
- wp_send_json_error(
1715
- array(
1716
- 'success' => false,
1717
- 'message' => $activate->get_error_message(),
1718
- 'init' => $plugin_init,
1719
- )
1720
- );
1721
- }
1722
-
1723
- wp_send_json_success(
1724
- array(
1725
- 'success' => true,
1726
- 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1727
- 'init' => $plugin_init,
1728
- )
1729
- );
1730
- }
1731
-
1732
- }
1733
-
1734
- /**
1735
- * Initialize class object with 'get_instance()' method
1736
- */
1737
- CartFlows_Importer::get_instance();
1738
-
1739
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows Admin
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Importer {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since 1.0.0
45
+ */
46
+ public function __construct() {
47
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
+
49
+ add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
+ add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
+ add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
+ add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
+ add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
+
55
+ add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
+ add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
+
58
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
+
60
+ add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
+
62
+ add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
+ add_action( 'admin_init', array( $this, 'export_json' ) );
64
+ add_action( 'admin_init', array( $this, 'import_json' ) );
65
+ add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
+ add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
+ }
68
+
69
+ /**
70
+ * Add the export link to action list for flows row actions
71
+ *
72
+ * @since 1.1.4
73
+ *
74
+ * @param array $actions Actions array.
75
+ * @param object $post Post object.
76
+ *
77
+ * @return array
78
+ */
79
+ public function export_link( $actions, $post ) {
80
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
+ $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
+ }
83
+ return $actions;
84
+ }
85
+
86
+ /**
87
+ * Add menus
88
+ *
89
+ * @since 1.1.4
90
+ */
91
+ public function add_to_menus() {
92
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
+ }
95
+
96
+ /**
97
+ * Export flow with steps and its meta
98
+ *
99
+ * @since 1.1.4
100
+ */
101
+ public function export_flow() {
102
+
103
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
+ wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
+ }
106
+
107
+ if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
+ return;
109
+ }
110
+
111
+ // Get the original post id.
112
+ $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
+
114
+ $flows = array();
115
+ $flows[] = $this->get_flow_export_data( $flow_id );
116
+ $flows = apply_filters( 'cartflows_export_data', $flows );
117
+
118
+ nocache_headers();
119
+ header( 'Content-Type: application/json; charset=utf-8' );
120
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
+ header( 'Expires: 0' );
122
+
123
+ echo wp_json_encode( $flows );
124
+ exit;
125
+ }
126
+
127
+ /**
128
+ * Export flow markup
129
+ *
130
+ * @since 1.1.4
131
+ */
132
+ public function exporter_markup() {
133
+ include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
+ }
135
+
136
+ /**
137
+ * Import flow markup
138
+ *
139
+ * @since 1.1.4
140
+ */
141
+ public function importer_markup() {
142
+ include_once CARTFLOWS_DIR . 'includes/importer.php';
143
+ }
144
+
145
+ /**
146
+ * Export flow
147
+ *
148
+ * @since 1.1.4
149
+ */
150
+ public function export_json() {
151
+ if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
+ return;
153
+ }
154
+
155
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
+ return;
157
+ }
158
+
159
+ if ( ! current_user_can( 'manage_options' ) ) {
160
+ return;
161
+ }
162
+
163
+ $flows = $this->get_all_flow_export_data();
164
+ $flows = apply_filters( 'cartflows_export_data', $flows );
165
+
166
+ nocache_headers();
167
+ header( 'Content-Type: application/json; charset=utf-8' );
168
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
+ header( 'Expires: 0' );
170
+
171
+ echo wp_json_encode( $flows );
172
+ exit;
173
+ }
174
+
175
+ /**
176
+ * Get flow export data
177
+ *
178
+ * @since 1.1.4
179
+ *
180
+ * @param integer $flow_id Flow ID.
181
+ * @return array
182
+ */
183
+ public function get_flow_export_data( $flow_id ) {
184
+
185
+ $export_all = apply_filters( 'cartflows_export_all', true );
186
+
187
+ $valid_step_meta_keys = array(
188
+ '_wp_page_template',
189
+ '_thumbnail_id',
190
+ 'classic-editor-remember',
191
+ );
192
+
193
+ $new_steps = array();
194
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
+ if ( $steps ) {
196
+ foreach ( $steps as $key => $step ) {
197
+
198
+ // Add step post meta.
199
+ $new_all_meta = array();
200
+ $all_meta = get_post_meta( $step['id'] );
201
+
202
+ // Add single step.
203
+ $step_data_arr = array(
204
+ 'title' => get_the_title( $step['id'] ),
205
+ 'type' => $step['type'],
206
+ 'meta' => $all_meta,
207
+ 'post_content' => '',
208
+ );
209
+
210
+ if ( $export_all ) {
211
+
212
+ $step_post_obj = get_post( $step['id'] );
213
+
214
+ $step_data_arr['post_content'] = $step_post_obj->post_content;
215
+ }
216
+
217
+ $new_steps[] = $step_data_arr;
218
+ }
219
+ }
220
+
221
+ // Add single flow.
222
+ return array(
223
+ 'title' => get_the_title( $flow_id ),
224
+ 'steps' => $new_steps,
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Get all flow export data
230
+ *
231
+ * @since 1.1.4
232
+ */
233
+ public function get_all_flow_export_data() {
234
+
235
+ $query_args = array(
236
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
+
238
+ // Query performance optimization.
239
+ 'fields' => 'ids',
240
+ 'no_found_rows' => true,
241
+ 'posts_per_page' => -1,
242
+ );
243
+
244
+ $query = new WP_Query( $query_args );
245
+ $flows = array();
246
+ if ( $query->posts ) {
247
+ foreach ( $query->posts as $key => $post_id ) {
248
+ $flows[] = $this->get_flow_export_data( $post_id );
249
+ }
250
+ }
251
+
252
+ return $flows;
253
+ }
254
+
255
+ /**
256
+ * Import our exported file
257
+ *
258
+ * @since 1.1.4
259
+ */
260
+ public function import_json() {
261
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
+ return;
263
+ }
264
+
265
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
+ return;
267
+ }
268
+
269
+ if ( ! current_user_can( 'manage_options' ) ) {
270
+ return;
271
+ }
272
+
273
+ $filename = $_FILES['file']['name']; //phpcs:ignore
274
+ $file_info = explode( '.', $filename );
275
+ $extension = end( $file_info );
276
+
277
+ if ( 'json' != $extension ) {
278
+ wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
+ }
280
+
281
+ $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
+
283
+ if ( empty( $file ) ) {
284
+ wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
+ }
286
+
287
+ // Retrieve the settings from the file and convert the JSON object to an array.
288
+ $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
+
290
+ $this->import_from_json_data( $flows );
291
+
292
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
+ }
294
+
295
+ /**
296
+ * Import flow from the JSON data
297
+ *
298
+ * @since x.x.x
299
+ * @param array $flows JSON array.
300
+ * @return void
301
+ */
302
+ public function import_from_json_data( $flows ) {
303
+ if ( $flows ) {
304
+
305
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
+
307
+ foreach ( $flows as $key => $flow ) {
308
+
309
+ $flow_title = $flow['title'];
310
+ if ( post_exists( $flow['title'] ) ) {
311
+ $flow_title = $flow['title'] . ' Copy';
312
+ }
313
+
314
+ // Create post object.
315
+ $new_flow_args = apply_filters(
316
+ 'cartflows_flow_importer_args',
317
+ array(
318
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
+ 'post_title' => $flow_title,
320
+ 'post_status' => 'publish',
321
+ )
322
+ );
323
+
324
+ // Insert the post into the database.
325
+ $flow_id = wp_insert_post( $new_flow_args );
326
+
327
+ /**
328
+ * Fire after flow import
329
+ *
330
+ * @since x.x.x
331
+ * @param int $flow_id Flow ID.
332
+ * @param array $new_flow_args Flow post args.
333
+ * @param array $flows Flow JSON data.
334
+ */
335
+ do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
+
337
+ if ( $flow['steps'] ) {
338
+ foreach ( $flow['steps'] as $key => $step ) {
339
+
340
+ $new_all_meta = array();
341
+ if ( is_array( $step['meta'] ) ) {
342
+ foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
+ }
345
+ }
346
+ $new_step_args = apply_filters(
347
+ 'cartflows_step_importer_args',
348
+ array(
349
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
+ 'post_title' => $step['title'],
351
+ 'post_status' => 'publish',
352
+ 'meta_input' => $new_all_meta,
353
+ 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
+ )
355
+ );
356
+
357
+ $new_step_id = wp_insert_post( $new_step_args );
358
+
359
+ /**
360
+ * Fire after step import
361
+ *
362
+ * @since x.x.x
363
+ * @param int $new_step_id step ID.
364
+ * @param int $flow_id flow ID.
365
+ * @param array $new_step_args Step post args.
366
+ * @param array $flow_steps Flow steps.
367
+ * @param array $flows All flows JSON data.
368
+ */
369
+ do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
+
371
+ // Insert post meta.
372
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
+
374
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
+ $current_term = term_exists( $step['type'], $step_taxonomy );
376
+
377
+ // // Set type object.
378
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
379
+ $step_slug = $data->slug;
380
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
+
382
+ // Set type.
383
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
+
385
+ // Set flow.
386
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
+
388
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
+
390
+ if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
+
392
+ // Download and replace images.
393
+ $content = $this->get_content( $step['post_content'] );
394
+
395
+ // Update post content.
396
+ wp_update_post(
397
+ array(
398
+ 'ID' => $new_step_id,
399
+ 'post_content' => $content,
400
+ )
401
+ );
402
+ }
403
+
404
+ // Elementor Data.
405
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
+ // Add "elementor" in import [queue].
407
+ // @todo Remove required `allow_url_fopen` support.
408
+ if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
+ $obj->import_single_template( $new_step_id );
411
+ }
412
+ }
413
+
414
+ // Beaver Builder.
415
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
+ if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
+ CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Download and Replace hotlink images
428
+ *
429
+ * @since x.x.x
430
+ *
431
+ * @param string $content Mixed post content.
432
+ * @return array Hotlink image array.
433
+ */
434
+ public function get_content( $content = '' ) {
435
+
436
+ $content = stripslashes( $content );
437
+
438
+ // Extract all links.
439
+ $all_links = wp_extract_urls( $content );
440
+
441
+ // Not have any link.
442
+ if ( empty( $all_links ) ) {
443
+ return $content;
444
+ }
445
+
446
+ $link_mapping = array();
447
+ $image_links = array();
448
+ $other_links = array();
449
+
450
+ // Extract normal and image links.
451
+ foreach ( $all_links as $key => $link ) {
452
+ if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
+
454
+ // Get all image links.
455
+ // Avoid *-150x, *-300x and *-1024x images.
456
+ if (
457
+ false === strpos( $link, '-150x' ) &&
458
+ false === strpos( $link, '-300x' ) &&
459
+ false === strpos( $link, '-1024x' )
460
+ ) {
461
+ $image_links[] = $link;
462
+ }
463
+ } else {
464
+
465
+ // Collect other links.
466
+ $other_links[] = $link;
467
+ }
468
+ }
469
+
470
+ // Step 1: Download images.
471
+ if ( ! empty( $image_links ) ) {
472
+ foreach ( $image_links as $key => $image_url ) {
473
+ // Download remote image.
474
+ $image = array(
475
+ 'url' => $image_url,
476
+ 'id' => 0,
477
+ );
478
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
+
480
+ // Old and New image mapping links.
481
+ $link_mapping[ $image_url ] = $downloaded_image['url'];
482
+ }
483
+ }
484
+
485
+ // Step 3: Replace mapping links.
486
+ foreach ( $link_mapping as $old_url => $new_url ) {
487
+ $content = str_replace( $old_url, $new_url, $content );
488
+
489
+ // Replace the slashed URLs if any exist.
490
+ $old_url = str_replace( '/', '/\\', $old_url );
491
+ $new_url = str_replace( '/', '/\\', $new_url );
492
+ $content = str_replace( $old_url, $new_url, $content );
493
+ }
494
+
495
+ return $content;
496
+ }
497
+
498
+ /**
499
+ * Imported notice
500
+ *
501
+ * @since 1.1.4
502
+ */
503
+ public function imported_successfully() {
504
+ ?>
505
+ <div class="notice notice-success">
506
+ <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
+ </div>
508
+ <?php
509
+ }
510
+
511
+ /**
512
+ * Clear Cache.
513
+ *
514
+ * @since 1.0.0
515
+ */
516
+ public function clear_cache() {
517
+ // Clear 'Elementor' file cache.
518
+ if ( class_exists( '\Elementor\Plugin' ) ) {
519
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
520
+ }
521
+ }
522
+
523
+ /**
524
+ * JS Templates
525
+ *
526
+ * @since 1.0.0
527
+ *
528
+ * @return void
529
+ */
530
+ public function js_templates() {
531
+
532
+ // Loading Templates.
533
+ ?>
534
+ <script type="text/template" id="tmpl-cartflows-step-loading">
535
+ <div class="template-message-block cartflows-step-loading">
536
+ <h2>
537
+ <span class="spinner"></span>
538
+ <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
+ </h2>
540
+ <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
+ </div>
542
+ </script>
543
+
544
+ <?php
545
+ // Search Templates.
546
+ ?>
547
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
548
+ <div class="template-message-block cartflows-searching-templates">
549
+ <h2>
550
+ <span class="spinner"></span>
551
+ <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
+ </h2>
553
+ <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
+ </div>
555
+ </script>
556
+
557
+ <?php
558
+ // CartFlows Importing Template.
559
+ ?>
560
+ <script type="text/template" id="tmpl-cartflows-step-importing">
561
+ <div class="template-message-block cartflows-step-importing">
562
+ <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
+ </div>
564
+ </script>
565
+
566
+ <?php
567
+ // CartFlows Imported.
568
+ ?>
569
+ <script type="text/template" id="tmpl-cartflows-step-imported">
570
+ <div class="template-message-block cartflows-step-imported">
571
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
+ </script>
574
+
575
+ <?php
576
+ // No templates.
577
+ ?>
578
+ <script type="text/template" id="tmpl-cartflows-no-steps">
579
+ <div class="cartflows-no-steps">
580
+ <div class="template-message-block">
581
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
+ <p class="description"></p>
583
+ </div>
584
+ </div>
585
+ </script>
586
+
587
+ <?php
588
+ // No templates.
589
+ ?>
590
+ <script type="text/template" id="tmpl-cartflows-no-flows">
591
+ <div class="cartflows-no-flows">
592
+ <div class="template-message-block">
593
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
+ <p class="description"></p>
595
+ </div>
596
+ </div>
597
+ </script>
598
+
599
+ <?php
600
+ // Error handling.
601
+ ?>
602
+ <script type="text/template" id="tmpl-templator-error">
603
+ <div class="notice notice-error"><p>{{ data }}</p></div>
604
+ </script>
605
+
606
+ <?php
607
+ // Redirect to Elementor.
608
+ ?>
609
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
+ <div class="template-message-block templator-redirect-to-elementor">
611
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
+ </script>
614
+
615
+ <?php
616
+ /**
617
+ * Responsive Buttons
618
+ */
619
+ ?>
620
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
621
+ <span class="responsive-view">
622
+ <span class="actions">
623
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
+ </span>
627
+ </span>
628
+ </script>
629
+
630
+ <?php
631
+ // Templates data.
632
+ ?>
633
+ <script type="text/template" id="tmpl-cartflows-flows-list">
634
+
635
+ <# console.log( data.items.length ) #>
636
+ <# console.log( data.items ) #>
637
+ <# if ( data.items.length ) { #>
638
+ <# for ( key in data.items ) { #>
639
+ <#
640
+ var flow_steps = [];
641
+ if( data.items[ key ].flow_steps ) {
642
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
+ return value['id'];
644
+ });
645
+ }
646
+ #>
647
+ <div class="inner">
648
+ <div class="template">
649
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
650
+ <div class="template-screenshot">
651
+ <# if( data.items[ key ].featured_image_url ) { #>
652
+ <img src="{{ data.items[ key ].featured_image_url }}" />
653
+ <# } else { #>
654
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
+ <# } #>
656
+ </div>
657
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
+ <# } #>
660
+ <# if( data.items[ key ].woo_required ) { #>
661
+ <div class="notice notice-info" style="width: auto;">
662
+ <p class="wcf-learn-how">
663
+ Install/Activate WooCommerce to use this template.
664
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
+ <i class="dashicons dashicons-external"></i>
667
+ </a>
668
+ </p>
669
+ </div>
670
+ <# } else { #>
671
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
672
+ <# } #>
673
+
674
+ </span>
675
+ <div class="template-id-container">
676
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
+ <div class="template-actions">
678
+
679
+ <#
680
+ if( data.items[ key ].page_builder.slug ) {
681
+ required_plugin_group = data.items[ key ].page_builder.slug;
682
+ } else {
683
+ required_plugin_group = '';
684
+ }
685
+
686
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
687
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
+ } else {
689
+ import_btn_title = 'Import';
690
+ } #>
691
+
692
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
+ <# if( ! data.items[ key ].woo_required ) { #>
694
+ <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
695
+ <# } else { #>
696
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
+ <# } #>
698
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
+ <# } else { #>
701
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
+ <# } #>
703
+ </div>
704
+ </div>
705
+ </div>
706
+ </div>
707
+ <# } #>
708
+ <# } #>
709
+ </script>
710
+
711
+ <?php
712
+ // Empty Step.
713
+ ?>
714
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
+ <div class="inner">
716
+ <div class="template">
717
+ <span class="thumbnail site-preview cartflows-flow-preview">
718
+ <div class="template-screenshot">
719
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
+ </div>
721
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
+ </span>
723
+ <div class="template-id-container">
724
+ <h3 class="template-name"> Blank </h3>
725
+ <div class="template-actions">
726
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
+ </div>
728
+ </div>
729
+ </div>
730
+ </div>
731
+ </script>
732
+
733
+ <?php
734
+ // Templates data.
735
+ ?>
736
+ <script type="text/template" id="tmpl-cartflows-steps-list">
737
+ <# if ( data.items.length ) { #>
738
+ <# for ( key in data.items ) { #>
739
+ <#
740
+ var flow_steps = [];
741
+ if( data.items[ key ].flow_steps ) {
742
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
+ return value['id'];
744
+ });
745
+ }
746
+ #>
747
+ <div class="inner">
748
+ <div class="template">
749
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
750
+ <div class="template-screenshot">
751
+ <# if( data.items[ key ].featured_image_url ) { #>
752
+ <img src="{{ data.items[ key ].featured_image_url }}" />
753
+ <# } else { #>
754
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
+ <# } #>
756
+ </div>
757
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
+
759
+ <# if( data.items[ key ].woo_required ) { #>
760
+ <div class="notice notice-info" style="width: auto;">
761
+ <p class="wcf-learn-how">
762
+ Install/Activate WooCommerce to use this template.
763
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
+ <i class="dashicons dashicons-external"></i>
766
+ </a>
767
+ </p>
768
+ </div>
769
+ <# } else { #>
770
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
771
+ <# } #>
772
+
773
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
+ <# } #>
776
+ </span>
777
+ <div class="template-id-container">
778
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
+ <div class="template-actions">
780
+
781
+ <#
782
+
783
+ var step_slug = data.items[ key ].step_type.slug || '';
784
+ var step_title = data.items[ key ].step_type.name || '';
785
+ var import_btn_title = 'Import';
786
+
787
+ var required_plugin_group = '';
788
+ if( data.items[ key ].page_builder ) {
789
+ required_plugin_group = data.items[ key ].page_builder.slug;
790
+
791
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
792
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
+ }
794
+ }
795
+ #>
796
+
797
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
+
799
+ <# if( ! data.items[ key ].woo_required ) { #>
800
+ <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
801
+ <# } else { #>
802
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
+ <# } #>
804
+
805
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
+ <# } else { #>
808
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
+ <# } #>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ </div>
814
+ <# } #>
815
+ <# } #>
816
+ </script>
817
+
818
+ <?php
819
+ /**
820
+ * TMPL - Website Unreachable
821
+ */
822
+ ?>
823
+ <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
+ <div class="postbox cartflows-website-unreachable">
825
+ <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
+ <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
+ <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
+ </div>
829
+ </script>
830
+
831
+ <?php
832
+ /**
833
+ * TMPL - Filters
834
+ */
835
+ ?>
836
+ <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
+ <?php
838
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
+ $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
+ $title = $page_builder['title'];
841
+
842
+ $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
+ $theme_status = '';
844
+ if ( 'divi' === $default_page_builder ) {
845
+
846
+ $theme_status = $page_builder['theme-status'];
847
+ $plugin_status = $page_builder['plugin-status'];
848
+
849
+ if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
+ $plugin_string = 'Please activate ' . esc_html( $title );
851
+ } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
+ $plugin_string = 'Please install and activate ' . esc_html( $title );
853
+ }
854
+ }
855
+ ?>
856
+ <div class="wcf-page-builder-message">
857
+ <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
+ <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
+ <p>We plan to add design templates made with more page builder shortly!</p>
860
+ </div>
861
+ </script>
862
+
863
+ <?php
864
+ /**
865
+ * TMPL - Filters
866
+ */
867
+ ?>
868
+ <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
+ <# if ( data ) { #>
870
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
+ <# if ( data.args.show_all ) { #>
872
+ <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
+ <# } #>
874
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
+ <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
+ <# } #>
877
+ <# var step_slug_data = []; #>
878
+ <# for ( key in data.items ) { #>
879
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
880
+
881
+ <# step_slug_data.push( data.items[ key ].slug ); #>
882
+
883
+ <# } #>
884
+ <# if( step_slug_data.indexOf("optin") === -1){ #>
885
+ <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
+ <# } #>
887
+ </select>
888
+ <# } #>
889
+ </script>
890
+
891
+ <script type="text/template" id="tmpl-cartflows-term-filters">
892
+
893
+ <# if ( data ) { #>
894
+
895
+ <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
+
898
+ <# if ( data.args.show_all ) { #>
899
+ <li>
900
+ <a href="#" data-group="all"> All </a>
901
+ </li>
902
+ <# } #>
903
+
904
+ <# for ( key in data.items ) { #>
905
+ <li>
906
+ <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
907
+ </li>
908
+ <# } #>
909
+
910
+ </ul>
911
+
912
+ <?php
913
+
914
+ /**
915
+ <# } else { #>
916
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
+
918
+ <# if ( data.args.show_all ) { #>
919
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
+ <# } #>
921
+
922
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
+ <# } #>
925
+
926
+ <# for ( key in data.items ) { #>
927
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
928
+ <# } #>
929
+
930
+ </select>
931
+ */
932
+ ?>
933
+
934
+ <?php /* <# } #> */ ?>
935
+
936
+ <# } #>
937
+ </script>
938
+
939
+ <?php
940
+ // Step Type.
941
+ ?>
942
+ <script type="text/template" id="tmpl-cartflows-step-types">
943
+ <ul class="wcf-tab nav-tabs">
944
+ <# if( data.items_count ) { #>
945
+ <# for( key in data.items ) { #>
946
+ <# console.log( data.items[ key ].id ) #>
947
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
+ </li>
950
+ <# } #>
951
+ <# } #>
952
+ </ul>
953
+ </script>
954
+
955
+ <?php
956
+ // Add to library button.
957
+ ?>
958
+ <script type="text/template" id="tmpl-templator-add-to-library">
959
+ <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
960
+ </script>
961
+ <?php
962
+ }
963
+
964
+ /**
965
+ * Enqueue scripts
966
+ *
967
+ * @since 1.0.0
968
+ *
969
+ * @hook admin_enqueue_scripts
970
+ * @param string $hook Current page hook.
971
+ */
972
+ public function scripts( $hook = '' ) {
973
+
974
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
+ return;
976
+ }
977
+
978
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
+
983
+ $installed_plugins = get_plugins();
984
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
+ $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
+
987
+ $localize_vars = array(
988
+ '_is_pro_active' => _is_cartflows_pro(),
989
+ 'is_wc_installed' => $is_wc_installed,
990
+ 'is_wc_activated' => $is_wc_activated,
991
+
992
+ // Flow and its rest fields.
993
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
994
+ 'flow_fields' => array(
995
+ 'id',
996
+ 'title',
997
+ 'flow_type',
998
+ 'page_builder',
999
+ 'flow_steps',
1000
+ 'licence_status',
1001
+ 'featured_image_url',
1002
+ 'featured_media', // @required for field `featured_image_url`.
1003
+ ),
1004
+
1005
+ // Flow type and rest fields.
1006
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1007
+ 'flow_type_fields' => array(
1008
+ 'id',
1009
+ 'name',
1010
+ 'slug',
1011
+ ),
1012
+
1013
+ // Flow page builder and rest fields.
1014
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1015
+ 'flow_page_builder_fields' => array(
1016
+ 'id',
1017
+ 'name',
1018
+ 'slug',
1019
+ ),
1020
+
1021
+ // Step page builder and rest fields.
1022
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1023
+ 'step_page_builder_fields' => array(
1024
+ 'id',
1025
+ 'name',
1026
+ 'slug',
1027
+ ),
1028
+
1029
+ // Step and its rest fields.
1030
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1031
+ 'step_fields' => array(
1032
+ 'title',
1033
+ 'featured_image_url',
1034
+ 'featured_media', // @required for field `featured_image_url`.
1035
+ 'id',
1036
+ 'flow_type',
1037
+ 'step_type',
1038
+ 'page_builder',
1039
+ 'licence_status',
1040
+ ),
1041
+
1042
+ // Step type and its rest fields.
1043
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1044
+ 'step_type_fields' => array(
1045
+ 'id',
1046
+ 'name',
1047
+ 'slug',
1048
+ ),
1049
+
1050
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1051
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1052
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1053
+ 'site_url' => site_url(),
1054
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1055
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1056
+ 'admin_url' => admin_url(),
1057
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1058
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1059
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1060
+
1061
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1062
+
1063
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1064
+ );
1065
+
1066
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1067
+
1068
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1069
+ // wp_die( );
1070
+ // Add thickbox.
1071
+ add_thickbox();
1072
+
1073
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1074
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1075
+ }
1076
+
1077
+ /**
1078
+ * Import.
1079
+ *
1080
+ * @since 1.0.0
1081
+ *
1082
+ * @hook wp_ajax_cartflows_import_flow_step
1083
+ * @return void
1084
+ */
1085
+ public function import_flow() {
1086
+
1087
+ if ( ! current_user_can( 'manage_options' ) ) {
1088
+ return;
1089
+ }
1090
+
1091
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1092
+
1093
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1094
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1095
+
1096
+ wcf()->logger->import_log( '------------------------------------' );
1097
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1098
+ wcf()->logger->import_log( '------------------------------------' );
1099
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1100
+
1101
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1102
+
1103
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1104
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1105
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1106
+ $post_content = $response['data']['divi_content'];
1107
+ }
1108
+ }
1109
+
1110
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1111
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1112
+ $post_content = $response['data']['divi_content'];
1113
+ }
1114
+ }
1115
+
1116
+ if ( false === $response['success'] ) {
1117
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1118
+ wp_send_json_error( $response );
1119
+ }
1120
+
1121
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1122
+
1123
+ $new_step_id = wp_insert_post(
1124
+ array(
1125
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1126
+ 'post_title' => $response['title'],
1127
+ 'post_content' => $post_content,
1128
+ 'post_status' => 'publish',
1129
+ )
1130
+ );
1131
+
1132
+ if ( is_wp_error( $new_step_id ) ) {
1133
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1134
+ wp_send_json_error( $new_step_id );
1135
+ }
1136
+
1137
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1138
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1139
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1140
+ }
1141
+ }
1142
+
1143
+ /* Imported Step */
1144
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1145
+
1146
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1147
+ // insert post meta.
1148
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1149
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1150
+
1151
+ /**
1152
+ * Import & Set type.
1153
+ */
1154
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1155
+
1156
+ $term_slug = '';
1157
+ if ( $term ) {
1158
+
1159
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1160
+ $term_exist = term_exists( $term->slug, $taxonomy );
1161
+
1162
+ if ( empty( $term_exist ) ) {
1163
+ $terms = array(
1164
+ array(
1165
+ 'name' => $term->name,
1166
+ 'slug' => $term->slug,
1167
+ ),
1168
+ );
1169
+
1170
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1171
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1172
+ }
1173
+
1174
+ $current_term = term_exists( $term->slug, $taxonomy );
1175
+
1176
+ // Set type object.
1177
+ $data = get_term( $current_term['term_id'], $taxonomy );
1178
+ $term_slug = $data->slug;
1179
+ $term_name = $data->name;
1180
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1181
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1182
+
1183
+ // Set type.
1184
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1185
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1186
+ }
1187
+
1188
+ // Set flow.
1189
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1190
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1191
+
1192
+ /**
1193
+ * Update steps for the current flow.
1194
+ */
1195
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1196
+
1197
+ if ( ! is_array( $flow_steps ) ) {
1198
+ $flow_steps = array();
1199
+ }
1200
+
1201
+ $flow_steps[] = array(
1202
+ 'id' => $new_step_id,
1203
+ 'title' => $response['title'],
1204
+ 'type' => $term_slug,
1205
+ );
1206
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1207
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1208
+
1209
+ // Import Post Meta.
1210
+ self::import_post_meta( $new_step_id, $response );
1211
+
1212
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1213
+ wcf()->logger->import_log( '------------------------------------' );
1214
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1215
+ wcf()->logger->import_log( '------------------------------------' );
1216
+
1217
+ do_action( 'cartflows_import_complete' );
1218
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1219
+
1220
+ // Batch Process.
1221
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1222
+
1223
+ /**
1224
+ * End
1225
+ */
1226
+ wp_send_json_success( $new_step_id );
1227
+ }
1228
+
1229
+ /**
1230
+ * Import Step.
1231
+ *
1232
+ * @since 1.0.0
1233
+ * @hook wp_ajax_cartflows_step_import
1234
+ *
1235
+ * @return void
1236
+ */
1237
+ public function create_default_flow() {
1238
+
1239
+ if ( ! current_user_can( 'manage_options' ) ) {
1240
+ return;
1241
+ }
1242
+
1243
+ check_ajax_referer( 'cf-default-flow', 'security' );
1244
+
1245
+ // Create post object.
1246
+ $new_flow_post = array(
1247
+ 'post_content' => '',
1248
+ 'post_status' => 'publish',
1249
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1250
+ );
1251
+
1252
+ // Insert the post into the database.
1253
+ $flow_id = wp_insert_post( $new_flow_post );
1254
+
1255
+ if ( is_wp_error( $flow_id ) ) {
1256
+ wp_send_json_error( $flow_id->get_error_message() );
1257
+ }
1258
+
1259
+ $flow_steps = array();
1260
+
1261
+ if ( wcf()->is_woo_active ) {
1262
+ $steps_data = array(
1263
+ 'sales' => array(
1264
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1265
+ 'type' => 'landing',
1266
+ ),
1267
+ 'order-form' => array(
1268
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1269
+ 'type' => 'checkout',
1270
+ ),
1271
+ 'order-confirmation' => array(
1272
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1273
+ 'type' => 'thankyou',
1274
+ ),
1275
+ );
1276
+
1277
+ } else {
1278
+ $steps_data = array(
1279
+ 'landing' => array(
1280
+ 'title' => __( 'Landing', 'cartflows' ),
1281
+ 'type' => 'landing',
1282
+ ),
1283
+ 'thankyou' => array(
1284
+ 'title' => __( 'Thank You', 'cartflows' ),
1285
+ 'type' => 'landing',
1286
+ ),
1287
+ );
1288
+ }
1289
+
1290
+ foreach ( $steps_data as $slug => $data ) {
1291
+
1292
+ $post_content = '';
1293
+ $step_type = trim( $data['type'] );
1294
+
1295
+ $step_id = wp_insert_post(
1296
+ array(
1297
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1298
+ 'post_title' => $data['title'],
1299
+ 'post_content' => $post_content,
1300
+ 'post_status' => 'publish',
1301
+ )
1302
+ );
1303
+
1304
+ if ( is_wp_error( $step_id ) ) {
1305
+ wp_send_json_error( $step_id->get_error_message() );
1306
+ }
1307
+
1308
+ if ( $step_id ) {
1309
+
1310
+ $flow_steps[] = array(
1311
+ 'id' => $step_id,
1312
+ 'title' => $data['title'],
1313
+ 'type' => $step_type,
1314
+ );
1315
+
1316
+ // insert post meta.
1317
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1318
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1319
+
1320
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1321
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1322
+
1323
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1324
+ }
1325
+ }
1326
+
1327
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1328
+
1329
+ wp_send_json_success( $flow_id );
1330
+ }
1331
+
1332
+ /**
1333
+ * Create Flow
1334
+ *
1335
+ * @return void
1336
+ */
1337
+ public function create_flow() {
1338
+
1339
+ if ( ! current_user_can( 'manage_options' ) ) {
1340
+ return;
1341
+ }
1342
+
1343
+ check_ajax_referer( 'cf-create-flow', 'security' );
1344
+
1345
+ // Create post object.
1346
+ $new_flow_post = array(
1347
+ 'post_content' => '',
1348
+ 'post_status' => 'publish',
1349
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1350
+ );
1351
+
1352
+ // Insert the post into the database.
1353
+ $flow_id = wp_insert_post( $new_flow_post );
1354
+
1355
+ if ( is_wp_error( $flow_id ) ) {
1356
+ wp_send_json_error( $flow_id->get_error_message() );
1357
+ }
1358
+
1359
+ /* Imported Flow */
1360
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1361
+
1362
+ wp_send_json_success( $flow_id );
1363
+ }
1364
+
1365
+ /**
1366
+ * Create Step
1367
+ *
1368
+ * @return void
1369
+ */
1370
+ public function import_step() {
1371
+
1372
+ if ( ! current_user_can( 'manage_options' ) ) {
1373
+ return;
1374
+ }
1375
+
1376
+ check_ajax_referer( 'cf-step-import', 'security' );
1377
+
1378
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1379
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1380
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1381
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1382
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1383
+
1384
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1385
+
1386
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1387
+
1388
+ wcf()->logger->import_log( '------------------------------------' );
1389
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1390
+ wcf()->logger->import_log( '------------------------------------' );
1391
+
1392
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1393
+ /* translators: %s: template ID */
1394
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1395
+ wcf()->logger->import_log( $data );
1396
+ wp_send_json_error( $data );
1397
+ }
1398
+
1399
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1400
+
1401
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1402
+
1403
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1404
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1405
+
1406
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1407
+
1408
+ wp_update_post(
1409
+ array(
1410
+ 'ID' => $post_id,
1411
+ 'post_content' => $response['data']['divi_content'],
1412
+ )
1413
+ );
1414
+ }
1415
+ }
1416
+
1417
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1418
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1419
+
1420
+ wp_update_post(
1421
+ array(
1422
+ 'ID' => $post_id,
1423
+ 'post_content' => $response['data']['divi_content'],
1424
+ )
1425
+ );
1426
+ }
1427
+ }
1428
+
1429
+ /* Imported Step */
1430
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1431
+
1432
+ // Import Post Meta.
1433
+ self::import_post_meta( $post_id, $response );
1434
+
1435
+ do_action( 'cartflows_import_complete' );
1436
+
1437
+ // Batch Process.
1438
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1439
+
1440
+ wcf()->logger->import_log( '------------------------------------' );
1441
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1442
+ wcf()->logger->import_log( '------------------------------------' );
1443
+
1444
+ wp_send_json_success( $post_id );
1445
+ }
1446
+
1447
+ /**
1448
+ * Import Step.
1449
+ *
1450
+ * @since 1.0.0
1451
+ * @hook wp_ajax_cartflows_step_create_blank
1452
+ *
1453
+ * @return void
1454
+ */
1455
+ public function step_create_blank() {
1456
+
1457
+ if ( ! current_user_can( 'manage_options' ) ) {
1458
+ return;
1459
+ }
1460
+
1461
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1462
+
1463
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1464
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1465
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1466
+
1467
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1468
+ /* translators: %s: flow ID */
1469
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1470
+ wcf()->logger->import_log( $data );
1471
+ wp_send_json_error( $data );
1472
+ }
1473
+
1474
+ wcf()->logger->import_log( '------------------------------------' );
1475
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1476
+
1477
+ $step_type_title = str_replace( '-', ' ', $step_type );
1478
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1479
+
1480
+ $new_step_id = wp_insert_post(
1481
+ array(
1482
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1483
+ 'post_title' => $step_title,
1484
+ 'post_content' => '',
1485
+ 'post_status' => 'publish',
1486
+ )
1487
+ );
1488
+
1489
+ // insert post meta.
1490
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1491
+
1492
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1493
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1494
+
1495
+ if ( empty( $term_exist ) ) {
1496
+ $terms = array(
1497
+ array(
1498
+ 'name' => $step_type_title,
1499
+ 'slug' => $step_type_slug,
1500
+ ),
1501
+ );
1502
+
1503
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1504
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1505
+ }
1506
+
1507
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1508
+
1509
+ // Set type object.
1510
+ $data = get_term( $current_term['term_id'], $taxonomy );
1511
+ $step_slug = $data->slug;
1512
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1513
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1514
+
1515
+ // Set Default page Layout.
1516
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1517
+
1518
+ // Set type.
1519
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1520
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1521
+
1522
+ // Set flow.
1523
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1524
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1525
+
1526
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1527
+
1528
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1529
+ wcf()->logger->import_log( '------------------------------------' );
1530
+
1531
+ wp_send_json_success( $new_step_id );
1532
+ }
1533
+
1534
+ /**
1535
+ * Import Post Meta
1536
+ *
1537
+ * @since 1.0.0
1538
+ *
1539
+ * @param integer $post_id Post ID.
1540
+ * @param array $response Post meta.
1541
+ * @return void
1542
+ */
1543
+ public static function import_post_meta( $post_id, $response ) {
1544
+
1545
+ $metadata = (array) $response['post_meta'];
1546
+
1547
+ foreach ( $metadata as $meta_key => $meta_value ) {
1548
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1549
+
1550
+ if ( $meta_value ) {
1551
+
1552
+ if ( is_serialized( $meta_value, true ) ) {
1553
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1554
+ } elseif ( is_array( $meta_value ) ) {
1555
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1556
+ } else {
1557
+ $raw_data = $meta_value;
1558
+ }
1559
+
1560
+ if ( '_elementor_data' === $meta_key ) {
1561
+ if ( is_array( $raw_data ) ) {
1562
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1563
+ } else {
1564
+ $raw_data = wp_slash( $raw_data );
1565
+ }
1566
+ }
1567
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1568
+ if ( is_array( $raw_data ) ) {
1569
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1570
+ } else {
1571
+ if ( ! is_object( $raw_data ) ) {
1572
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ update_post_meta( $post_id, $meta_key, $raw_data );
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ /**
1583
+ * Import Template for Elementor
1584
+ *
1585
+ * @since 1.0.0
1586
+ *
1587
+ * @param integer $post_id Post ID.
1588
+ * @param array $response Post meta.
1589
+ * @param array $page_build_data Page build data.
1590
+ * @return void
1591
+ */
1592
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1593
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1594
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1595
+ wcf()->logger->import_log( $data );
1596
+ wp_send_json_error( $data );
1597
+ }
1598
+
1599
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1600
+
1601
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1602
+
1603
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1604
+ $obj->import_single_template( $post_id );
1605
+
1606
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1607
+ }
1608
+
1609
+ /**
1610
+ * Supported post types
1611
+ *
1612
+ * @since 1.0.0
1613
+ *
1614
+ * @return array Supported post types.
1615
+ */
1616
+ public static function supported_post_types() {
1617
+ return apply_filters(
1618
+ 'cartflows_supported_post_types',
1619
+ array(
1620
+ CARTFLOWS_FLOW_POST_TYPE,
1621
+ )
1622
+ );
1623
+ }
1624
+
1625
+ /**
1626
+ * Check supported post type
1627
+ *
1628
+ * @since 1.0.0
1629
+ *
1630
+ * @param string $post_type Post type.
1631
+ * @return boolean Supported post type status.
1632
+ */
1633
+ public static function is_supported_post( $post_type = '' ) {
1634
+
1635
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1636
+ return true;
1637
+ }
1638
+
1639
+ return false;
1640
+ }
1641
+
1642
+ /**
1643
+ * Set steps to the flow
1644
+ *
1645
+ * @param integer $flow_id Flow ID.
1646
+ * @param integer $new_step_id New step ID.
1647
+ * @param string $step_title Flow Type.
1648
+ * @param string $step_slug Flow Type.
1649
+ */
1650
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1651
+ // Update steps for the current flow.
1652
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1653
+
1654
+ if ( ! is_array( $flow_steps ) ) {
1655
+ $flow_steps = array();
1656
+ }
1657
+
1658
+ $flow_steps[] = array(
1659
+ 'id' => $new_step_id,
1660
+ 'title' => $step_title,
1661
+ 'type' => $step_slug,
1662
+ );
1663
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1664
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1665
+ }
1666
+
1667
+ /**
1668
+ * Localize variables in admin
1669
+ *
1670
+ * @param array $vars variables.
1671
+ */
1672
+ public function localize_vars( $vars ) {
1673
+
1674
+ $ajax_actions = array(
1675
+ 'cf_step_import',
1676
+ 'cf_load_steps',
1677
+ 'cf_create_flow',
1678
+ 'cf_default_flow',
1679
+ 'cf_step_create_blank',
1680
+ 'cf_import_flow_step',
1681
+ );
1682
+
1683
+ foreach ( $ajax_actions as $action ) {
1684
+
1685
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1686
+ }
1687
+
1688
+ return $vars;
1689
+ }
1690
+
1691
+ /**
1692
+ * Ajax action to activate plugin
1693
+ */
1694
+ public function activate_plugin() {
1695
+
1696
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1697
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1698
+ }
1699
+
1700
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1701
+ wp_send_json_error(
1702
+ array(
1703
+ 'success' => false,
1704
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1705
+ )
1706
+ );
1707
+ }
1708
+
1709
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1710
+
1711
+ $activate = activate_plugin( $plugin_init, '', false, true );
1712
+
1713
+ if ( is_wp_error( $activate ) ) {
1714
+ wp_send_json_error(
1715
+ array(
1716
+ 'success' => false,
1717
+ 'message' => $activate->get_error_message(),
1718
+ 'init' => $plugin_init,
1719
+ )
1720
+ );
1721
+ }
1722
+
1723
+ wp_send_json_success(
1724
+ array(
1725
+ 'success' => true,
1726
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1727
+ 'init' => $plugin_init,
1728
+ )
1729
+ );
1730
+ }
1731
+
1732
+ }
1733
+
1734
+ /**
1735
+ * Initialize class object with 'get_instance()' method
1736
+ */
1737
+ CartFlows_Importer::get_instance();
1738
+
1739
+ endif;
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.10' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
@@ -249,6 +249,13 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
249
 
250
  require_once CARTFLOWS_DIR . 'classes/class-cartflows-tracking.php';
251
 
 
 
 
 
 
 
 
252
  $this->utils = Cartflows_Utils::get_instance();
253
  $this->options = Cartflows_Default_Meta::get_instance();
254
  $this->alldata = Cartflows_Tracking::get_instance();
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.11' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
249
 
250
  require_once CARTFLOWS_DIR . 'classes/class-cartflows-tracking.php';
251
 
252
+ if ( is_admin() ) {
253
+ require_once CARTFLOWS_DIR . 'classes/lib/notices/class-astra-notices.php';
254
+ }
255
+
256
+ /* Load BSF Analytics */
257
+ require_once CARTFLOWS_DIR . 'admin/bsf-analytics/class-bsf-analytics.php';
258
+
259
  $this->utils = Cartflows_Utils::get_instance();
260
  $this->options = Cartflows_Default_Meta::get_instance();
261
  $this->alldata = Cartflows_Tracking::get_instance();
classes/class-cartflows-meta-fields.php CHANGED
@@ -38,6 +38,8 @@ class Cartflows_Meta_Fields {
38
 
39
  add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
40
 
 
 
41
  add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
42
 
43
  add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
@@ -97,6 +99,74 @@ class Cartflows_Meta_Fields {
97
  }
98
  }
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  /**
101
  * Function to search coupons
102
  */
@@ -622,7 +692,12 @@ class Cartflows_Meta_Fields {
622
  */
623
  public function get_product_selection_field( $field_data ) {
624
 
625
- $value = $field_data['value'];
 
 
 
 
 
626
 
627
  $multiple = '';
628
 
@@ -640,7 +715,8 @@ class Cartflows_Meta_Fields {
640
  name="' . $field_data['name'] . '[]"
641
  class="wcf-product-search" ' . $multiple . $allow_clear . '
642
  data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
643
- data-action="woocommerce_json_search_products_and_variations">';
 
644
 
645
  if ( is_array( $value ) && ! empty( $value ) ) {
646
 
@@ -876,6 +952,7 @@ class Cartflows_Meta_Fields {
876
  $ajax_actions = array(
877
  'wcf_json_search_pages',
878
  'wcf_json_search_coupons',
 
879
  );
880
 
881
  foreach ( $ajax_actions as $action ) {
38
 
39
  add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
40
 
41
+ add_action( 'wp_ajax_wcf_json_search_products_and_variations', array( $this, 'json_search_products' ) );
42
+
43
  add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
44
 
45
  add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
99
  }
100
  }
101
 
102
+ /**
103
+ * Function to search products
104
+ */
105
+ public function json_search_products() {
106
+
107
+ check_admin_referer( 'wcf-json-search-products-and-variations', 'security' );
108
+
109
+ global $wpdb;
110
+
111
+ $allowed_products_type = array( 'simple', 'variation', 'variable', 'subscription', 'variable-subscription', 'grouped' );
112
+
113
+ // get search term.
114
+ $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
115
+
116
+ if ( empty( $term ) ) {
117
+ die();
118
+ }
119
+
120
+ // get excluded product types.
121
+ if ( isset( $_GET['excluded'] ) || ! empty( $_GET['excluded'] ) ) {
122
+
123
+ $excluded_types = sanitize_text_field( ( wp_unslash( $_GET['excluded'] ) ) );
124
+
125
+ if ( ! is_array( $excluded_types ) ) {
126
+ $excluded_types = explode( ',', $excluded_types );
127
+ }
128
+
129
+ // Sanitize the excluded types against valid product types.
130
+ foreach ( $excluded_types as $index => $value ) {
131
+ $excluded_types[ $index ] = strtolower( trim( $value ) );
132
+ }
133
+
134
+ $allowed_products_type = array_diff( $allowed_products_type, $excluded_types );
135
+ }
136
+
137
+ $posts = wp_cache_get( 'wcf_search_products', 'wcf_funnel_Cart' );
138
+
139
+ if ( false === $posts ) {
140
+ $posts = $wpdb->get_results( // phpcs:ignore
141
+ $wpdb->prepare(
142
+ "SELECT *
143
+ FROM {$wpdb->prefix}posts
144
+ WHERE post_type = %s
145
+ AND post_title LIKE %s
146
+ AND post_status = %s",
147
+ 'product',
148
+ $wpdb->esc_like( $term ) . '%',
149
+ 'publish'
150
+ )
151
+ );
152
+ wp_cache_set( 'wcf_search_products', $posts, 'wcf_funnel_Cart' );
153
+ }
154
+
155
+ $product_found = array();
156
+
157
+ if ( $posts ) {
158
+ foreach ( $posts as $post ) {
159
+ $product = wc_get_product( $post->ID );
160
+ $type = $product->get_type();
161
+ if ( in_array( $type, $allowed_products_type, true ) ) {
162
+ $product_found[ $post->ID ] = get_the_title( $post->ID ) . ' (#' . $post->ID . ')';
163
+ }
164
+ }
165
+ }
166
+
167
+ wp_send_json( $product_found );
168
+ }
169
+
170
  /**
171
  * Function to search coupons
172
  */
692
  */
693
  public function get_product_selection_field( $field_data ) {
694
 
695
+ $value = $field_data['value'];
696
+ $excluded = '';
697
+
698
+ if ( isset( $field_data['excluded_product_types'] ) && is_array( $field_data['excluded_product_types'] ) ) {
699
+ $excluded = html_entity_decode( implode( ',', $field_data['excluded_product_types'] ), ENT_COMPAT, 'UTF-8' );
700
+ }
701
 
702
  $multiple = '';
703
 
715
  name="' . $field_data['name'] . '[]"
716
  class="wcf-product-search" ' . $multiple . $allow_clear . '
717
  data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
718
+ data-action="woocommerce_json_search_products_and_variations"
719
+ data-excluded_product_types =" ' . $excluded . '">';
720
 
721
  if ( is_array( $value ) && ! empty( $value ) ) {
722
 
952
  $ajax_actions = array(
953
  'wcf_json_search_pages',
954
  'wcf_json_search_coupons',
955
+ 'wcf_json_search_products_and_variations',
956
  );
957
 
958
  foreach ( $ajax_actions as $action ) {
classes/class-cartflows-wizard.php CHANGED
@@ -60,10 +60,6 @@ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
60
  */
61
  public function disable_woo_setup_redirect() {
62
 
63
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
64
- return;
65
- }
66
-
67
  delete_transient( '_wc_activation_redirect' );
68
  }
69
 
@@ -75,11 +71,23 @@ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
75
  */
76
  public function show_setup_wizard() {
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  $status = get_option( 'wcf_setup_complete', false );
79
  $skip_setup = get_option( 'wcf_setup_skipped', false );
80
-
81
  if ( false === $status && ! $skip_setup ) { ?>
82
- <div class="notice notice-info">
83
  <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
84
  <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
85
  <p>
60
  */
61
  public function disable_woo_setup_redirect() {
62
 
 
 
 
 
63
  delete_transient( '_wc_activation_redirect' );
64
  }
65
 
71
  */
72
  public function show_setup_wizard() {
73
 
74
+ $screen = get_current_screen();
75
+ $screen_id = $screen ? $screen->id : '';
76
+ $allowed_screens = array(
77
+ 'cartflows_page_cartflows_settings',
78
+ 'edit-cartflows_flow',
79
+ 'dashboard',
80
+ 'plugins',
81
+ );
82
+
83
+ if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
84
+ return;
85
+ }
86
+
87
  $status = get_option( 'wcf_setup_complete', false );
88
  $skip_setup = get_option( 'wcf_setup_skipped', false );
 
89
  if ( false === $status && ! $skip_setup ) { ?>
90
+ <div class="notice notice-info wcf-notice">
91
  <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
92
  <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
93
  <p>
classes/lib/notices/class-astra-notices.php ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Astra Sites Notices
4
+ *
5
+ * Closing notice on click on `astra-notice-close` class.
6
+ *
7
+ * If notice has the data attribute `data-repeat-notice-after="%2$s"` then notice close for that SPECIFIC TIME.
8
+ * If notice has NO data attribute `data-repeat-notice-after="%2$s"` then notice close for the CURRENT USER FOREVER.
9
+ *
10
+ * > Create custom close notice link in the notice markup. E.g.
11
+ * `<a href="#" data-repeat-notice-after="<?php echo MONTH_IN_SECONDS; ?>" class="astra-notice-close">`
12
+ * It close the notice for 30 days.
13
+ *
14
+ * @package Astra Sites
15
+ * @since 1.4.0
16
+ */
17
+
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit; // Exit if accessed directly.
20
+ }
21
+
22
+ if ( ! class_exists( 'Astra_Notices' ) ) :
23
+
24
+ /**
25
+ * Astra_Notices
26
+ *
27
+ * @since 1.4.0
28
+ */
29
+ class Astra_Notices {
30
+
31
+ /**
32
+ * Notices
33
+ *
34
+ * @access private
35
+ * @var array Notices.
36
+ * @since 1.4.0
37
+ */
38
+ private static $version = '1.1.5';
39
+
40
+ /**
41
+ * Notices
42
+ *
43
+ * @access private
44
+ * @var array Notices.
45
+ * @since 1.4.0
46
+ */
47
+ private static $notices = array();
48
+
49
+ /**
50
+ * Instance
51
+ *
52
+ * @access private
53
+ * @var object Class object.
54
+ * @since 1.4.0
55
+ */
56
+ private static $instance;
57
+
58
+ /**
59
+ * Initiator
60
+ *
61
+ * @since 1.4.0
62
+ * @return object initialized object of class.
63
+ */
64
+ public static function get_instance() {
65
+ if ( ! isset( self::$instance ) ) {
66
+ self::$instance = new self();
67
+ }
68
+ return self::$instance;
69
+ }
70
+
71
+ /**
72
+ * Constructor
73
+ *
74
+ * @since 1.4.0
75
+ */
76
+ public function __construct() {
77
+ add_action( 'admin_notices', array( $this, 'show_notices' ), 30 );
78
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
79
+ add_action( 'wp_ajax_astra-notice-dismiss', array( $this, 'dismiss_notice' ) );
80
+ add_filter( 'wp_kses_allowed_html', array( $this, 'add_data_attributes' ), 10, 2 );
81
+ }
82
+
83
+ /**
84
+ * Filters and Returns a list of allowed tags and attributes for a given context.
85
+ *
86
+ * @param Array $allowedposttags Array of allowed tags.
87
+ * @param String $context Context type (explicit).
88
+ * @since 1.4.0
89
+ * @return Array
90
+ */
91
+ public function add_data_attributes( $allowedposttags, $context ) {
92
+ $allowedposttags['a']['data-repeat-notice-after'] = true;
93
+
94
+ return $allowedposttags;
95
+ }
96
+
97
+ /**
98
+ * Add Notice.
99
+ *
100
+ * @since 1.4.0
101
+ * @param array $args Notice arguments.
102
+ * @return void
103
+ */
104
+ public static function add_notice( $args = array() ) {
105
+ self::$notices[] = $args;
106
+ }
107
+
108
+ /**
109
+ * Dismiss Notice.
110
+ *
111
+ * @since 1.4.0
112
+ * @return void
113
+ */
114
+ public function dismiss_notice() {
115
+
116
+ if ( ! apply_filters( 'astra_notices_user_cap_check', current_user_can( 'manage_options' ) ) ) {
117
+ return;
118
+ }
119
+
120
+ $notice_id = ( isset( $_POST['notice_id'] ) ) ? sanitize_key( $_POST['notice_id'] ) : '';
121
+ $repeat_notice_after = ( isset( $_POST['repeat_notice_after'] ) ) ? absint( $_POST['repeat_notice_after'] ) : '';
122
+ $nonce = ( isset( $_POST['nonce'] ) ) ? sanitize_key( $_POST['nonce'] ) : '';
123
+
124
+ if ( false === wp_verify_nonce( $nonce, 'astra-notices' ) ) {
125
+ wp_send_json_error( esc_html_e( 'WordPress Nonce not validated.', 'cartflows' ) );
126
+ }
127
+
128
+ // Valid inputs?
129
+ if ( ! empty( $notice_id ) ) {
130
+
131
+ if ( ! empty( $repeat_notice_after ) ) {
132
+ set_transient( $notice_id, true, $repeat_notice_after );
133
+ } else {
134
+ update_user_meta( get_current_user_id(), $notice_id, 'notice-dismissed' );
135
+ }
136
+
137
+ wp_send_json_success();
138
+ }
139
+
140
+ wp_send_json_error();
141
+ }
142
+
143
+ /**
144
+ * Enqueue Scripts.
145
+ *
146
+ * @since 1.4.0
147
+ * @return void
148
+ */
149
+ public function enqueue_scripts() {
150
+ wp_register_script( 'astra-notices', self::_get_uri() . 'notices.js', array( 'jquery' ), self::$version, true );
151
+ wp_localize_script(
152
+ 'astra-notices',
153
+ 'astraNotices',
154
+ array(
155
+ '_notice_nonce' => wp_create_nonce( 'astra-notices' ),
156
+ )
157
+ );
158
+ }
159
+
160
+ /**
161
+ * Rating priority sort
162
+ *
163
+ * @since 1.5.2
164
+ * @param array $array1 array one.
165
+ * @param array $array2 array two.
166
+ * @return array
167
+ */
168
+ public function sort_notices( $array1, $array2 ) {
169
+ if ( ! isset( $array1['priority'] ) ) {
170
+ $array1['priority'] = 10;
171
+ }
172
+ if ( ! isset( $array2['priority'] ) ) {
173
+ $array2['priority'] = 10;
174
+ }
175
+
176
+ return $array1['priority'] - $array2['priority'];
177
+ }
178
+
179
+ /**
180
+ * Notice Types
181
+ *
182
+ * @since 1.4.0
183
+ * @return void
184
+ */
185
+ public function show_notices() {
186
+
187
+ $defaults = array(
188
+ 'id' => '', // Optional, Notice ID. If empty it set `astra-notices-id-<$array-index>`.
189
+ 'type' => 'info', // Optional, Notice type. Default `info`. Expected [info, warning, notice, error].
190
+ 'message' => '', // Optional, Message.
191
+ 'show_if' => true, // Optional, Show notice on custom condition. E.g. 'show_if' => if( is_admin() ) ? true, false, .
192
+ 'repeat-notice-after' => '', // Optional, Dismiss-able notice time. It'll auto show after given time.
193
+ 'display-notice-after' => false, // Optional, Dismiss-able notice time. It'll auto show after given time.
194
+ 'class' => '', // Optional, Additional notice wrapper class.
195
+ 'priority' => 10, // Priority of the notice.
196
+ 'display-with-other-notices' => true, // Should the notice be displayed if other notices are being displayed from Astra_Notices.
197
+ 'is_dismissible' => true,
198
+ );
199
+
200
+ // Count for the notices that are rendered.
201
+ $notices_displayed = 0;
202
+
203
+ // sort the array with priority.
204
+ usort( self::$notices, array( $this, 'sort_notices' ) );
205
+
206
+ foreach ( self::$notices as $key => $notice ) {
207
+
208
+ $notice = wp_parse_args( $notice, $defaults );
209
+
210
+ $notice['id'] = self::get_notice_id( $notice, $key );
211
+
212
+ $notice['classes'] = self::get_wrap_classes( $notice );
213
+
214
+ // Notices visible after transient expire.
215
+ if ( isset( $notice['show_if'] ) && true === $notice['show_if'] ) {
216
+
217
+ // don't display the notice if it is not supposed to be displayed with other notices.
218
+ if ( 0 !== $notices_displayed && false === $notice['display-with-other-notices'] ) {
219
+ continue;
220
+ }
221
+
222
+ if ( self::is_expired( $notice ) ) {
223
+
224
+ self::markup( $notice );
225
+ ++$notices_displayed;
226
+ }
227
+ }
228
+ }
229
+
230
+ }
231
+
232
+ /**
233
+ * Markup Notice.
234
+ *
235
+ * @since 1.4.0
236
+ * @param array $notice Notice markup.
237
+ * @return void
238
+ */
239
+ public static function markup( $notice = array() ) {
240
+
241
+ wp_enqueue_script( 'astra-notices' );
242
+
243
+ do_action( 'astra_notice_before_markup' );
244
+
245
+ do_action( "astra_notice_before_markup_{$notice['id']}" );
246
+
247
+ ?>
248
+ <div id="<?php echo esc_attr( $notice['id'] ); ?>" class="<?php echo esc_attr( $notice['classes'] ); ?>" data-repeat-notice-after="<?php echo esc_attr( $notice['repeat-notice-after'] ); ?>">
249
+ <div class="notice-container">
250
+ <?php do_action( "astra_notice_inside_markup_{$notice['id']}" ); ?>
251
+ <?php echo wp_kses_post( $notice['message'] ); ?>
252
+ </div>
253
+ </div>
254
+ <?php
255
+
256
+ do_action( "astra_notice_after_markup_{$notice['id']}" );
257
+
258
+ do_action( 'astra_notice_after_markup' );
259
+
260
+ }
261
+
262
+ /**
263
+ * Notice classes.
264
+ *
265
+ * @since 1.4.0
266
+ *
267
+ * @param array $notice Notice arguments.
268
+ * @return array Notice wrapper classes.
269
+ */
270
+ private static function get_wrap_classes( $notice ) {
271
+ $classes = array( 'astra-notice', 'notice' );
272
+
273
+ if ( $notice['is_dismissible'] ) {
274
+ $classes[] = 'is-dismissible';
275
+ }
276
+
277
+ $classes[] = $notice['class'];
278
+ if ( isset( $notice['type'] ) && '' !== $notice['type'] ) {
279
+ $classes[] = 'notice-' . $notice['type'];
280
+ }
281
+
282
+ return esc_attr( implode( ' ', $classes ) );
283
+ }
284
+
285
+ /**
286
+ * Get Notice ID.
287
+ *
288
+ * @since 1.4.0
289
+ *
290
+ * @param array $notice Notice arguments.
291
+ * @param int $key Notice array index.
292
+ * @return string Notice id.
293
+ */
294
+ private static function get_notice_id( $notice, $key ) {
295
+ if ( isset( $notice['id'] ) && ! empty( $notice['id'] ) ) {
296
+ return $notice['id'];
297
+ }
298
+
299
+ return 'astra-notices-id-' . $key;
300
+ }
301
+
302
+ /**
303
+ * Is notice expired?
304
+ *
305
+ * @since 1.4.0
306
+ *
307
+ * @param array $notice Notice arguments.
308
+ * @return boolean
309
+ */
310
+ private static function is_expired( $notice ) {
311
+ $transient_status = get_transient( $notice['id'] );
312
+
313
+ if ( false === $transient_status ) {
314
+
315
+ if ( isset( $notice['display-notice-after'] ) && false !== $notice['display-notice-after'] ) {
316
+
317
+ if ( 'delayed-notice' !== get_user_meta( get_current_user_id(), $notice['id'], true ) &&
318
+ 'notice-dismissed' !== get_user_meta( get_current_user_id(), $notice['id'], true ) ) {
319
+ set_transient( $notice['id'], 'delayed-notice', $notice['display-notice-after'] );
320
+ update_user_meta( get_current_user_id(), $notice['id'], 'delayed-notice' );
321
+
322
+ return false;
323
+ }
324
+ }
325
+
326
+ // Check the user meta status if current notice is dismissed or delay completed.
327
+ $meta_status = get_user_meta( get_current_user_id(), $notice['id'], true );
328
+
329
+ if ( empty( $meta_status ) || 'delayed-notice' === $meta_status ) {
330
+ return true;
331
+ }
332
+ }
333
+
334
+ return false;
335
+ }
336
+
337
+ /**
338
+ * Get URI
339
+ *
340
+ * @return mixed URL.
341
+ */
342
+ public static function _get_uri() { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
343
+ $path = wp_normalize_path( dirname( __FILE__ ) );
344
+ $theme_dir = wp_normalize_path( get_template_directory() );
345
+ $plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );
346
+
347
+ if ( strpos( $path, $theme_dir ) !== false ) {
348
+ return trailingslashit( get_template_directory_uri() . str_replace( $theme_dir, '', $path ) );
349
+ } elseif ( strpos( $path, $plugin_dir ) !== false ) {
350
+ return plugin_dir_url( __FILE__ );
351
+ } elseif ( strpos( $path, dirname( plugin_basename( __FILE__ ) ) ) !== false ) {
352
+ return plugin_dir_url( __FILE__ );
353
+ }
354
+
355
+ return; // phpcs:ignore Squiz.PHP.NonExecutableCode.ReturnNotRequired
356
+ }
357
+
358
+ }
359
+
360
+ /**
361
+ * Kicking this off by calling 'get_instance()' method
362
+ */
363
+ Astra_Notices::get_instance();
364
+
365
+ endif;
classes/lib/notices/notices.js ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Customizer controls toggles
3
+ *
4
+ * @package Astra
5
+ */
6
+
7
+ ( function( $ ) {
8
+
9
+ /**
10
+ * Helper class for the main Customizer interface.
11
+ *
12
+ * @since 1.0.0
13
+ * @class ASTCustomizer
14
+ */
15
+ AstraNotices = {
16
+
17
+ /**
18
+ * Initializes our custom logic for the Customizer.
19
+ *
20
+ * @since 1.0.0
21
+ * @method init
22
+ */
23
+ init: function()
24
+ {
25
+ this._bind();
26
+ },
27
+
28
+ /**
29
+ * Binds events for the Astra Portfolio.
30
+ *
31
+ * @since 1.0.0
32
+ * @access private
33
+ * @method _bind
34
+ */
35
+ _bind: function()
36
+ {
37
+ $( document ).on('click', '.astra-notice-close', AstraNotices._dismissNoticeNew );
38
+ $( document ).on('click', '.astra-notice .notice-dismiss', AstraNotices._dismissNotice );
39
+ },
40
+
41
+ _dismissNotice: function( event ) {
42
+ event.preventDefault();
43
+
44
+ var repeat_notice_after = $( this ).parents('.astra-notice').data( 'repeat-notice-after' ) || '';
45
+ var notice_id = $( this ).parents('.astra-notice').attr( 'id' ) || '';
46
+
47
+ AstraNotices._ajax( notice_id, repeat_notice_after );
48
+ },
49
+
50
+ _dismissNoticeNew: function( event ) {
51
+ event.preventDefault();
52
+
53
+ var repeat_notice_after = $( this ).attr( 'data-repeat-notice-after' ) || '';
54
+ var notice_id = $( this ).parents('.astra-notice').attr( 'id' ) || '';
55
+
56
+ var $el = $( this ).parents('.astra-notice');
57
+ $el.fadeTo( 100, 0, function() {
58
+ $el.slideUp( 100, function() {
59
+ $el.remove();
60
+ });
61
+ });
62
+
63
+ AstraNotices._ajax( notice_id, repeat_notice_after );
64
+
65
+ var link = $( this ).attr( 'href' ) || '';
66
+ var target = $( this ).attr( 'target' ) || '';
67
+ if( '' !== link && '_blank' === target ) {
68
+ window.open(link , '_blank');
69
+ }
70
+ },
71
+
72
+ _ajax: function( notice_id, repeat_notice_after ) {
73
+
74
+ if( '' === notice_id ) {
75
+ return;
76
+ }
77
+
78
+ $.ajax({
79
+ url: ajaxurl,
80
+ type: 'POST',
81
+ data: {
82
+ action : 'astra-notice-dismiss',
83
+ nonce : astraNotices._notice_nonce,
84
+ notice_id : notice_id,
85
+ repeat_notice_after : parseInt( repeat_notice_after ),
86
+ },
87
+ });
88
+
89
+ }
90
+ };
91
+
92
+ $( function() {
93
+ AstraNotices.init();
94
+ } );
95
+ } )( jQuery );
includes/admin/cartflows-admin.php CHANGED
@@ -1,35 +1,35 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Admin HTML.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- ?>
9
- <div class="wcf-menu-page-wrapper">
10
- <div id="wcf-menu-page">
11
- <div class="wcf-menu-page-header <?php echo esc_attr( implode( ' ', $header_wrapper_class ) ); ?>">
12
- <div class="wcf-container wcf-flex">
13
- <div class="wcf-title">
14
- <span class="screen-reader-text"><?php echo esc_attr( CARTFLOWS_PLUGIN_NAME ); ?></span>
15
- <img class="wcf-logo" src="<?php echo esc_attr( CARTFLOWS_URL ) . 'assets/images/cartflows-logo.svg'; ?>" />
16
- </div>
17
- <div class="wcf-top-links">
18
- <?php
19
- esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
20
- ?>
21
- </div>
22
- </div>
23
- </div>
24
-
25
- <?php
26
- // Settings update message.
27
- if ( isset( $_REQUEST['message'] ) && ( 'saved' === $_REQUEST['message'] ) ) { //phpcs:ignore
28
- ?>
29
- <div id="message" class="notice notice-success is-dismissive wcf-notice"><p> <?php esc_html_e( 'Settings saved successfully.', 'cartflows' ); ?> </p></div>
30
- <?php
31
- }
32
- ?>
33
- <?php do_action( 'cartflows_render_admin_content', $menu_page_slug ); ?>
34
- </div>
35
- </div>
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Admin HTML.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ ?>
9
+ <div class="wcf-menu-page-wrapper">
10
+ <div id="wcf-menu-page">
11
+ <div class="wcf-menu-page-header <?php echo esc_attr( implode( ' ', $header_wrapper_class ) ); ?>">
12
+ <div class="wcf-container wcf-flex">
13
+ <div class="wcf-title">
14
+ <span class="screen-reader-text"><?php echo esc_attr( CARTFLOWS_PLUGIN_NAME ); ?></span>
15
+ <img class="wcf-logo" src="<?php echo esc_attr( CARTFLOWS_URL ) . 'assets/images/cartflows-logo.svg'; ?>" />
16
+ </div>
17
+ <div class="wcf-top-links">
18
+ <?php
19
+ esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
20
+ ?>
21
+ </div>
22
+ </div>
23
+ </div>
24
+
25
+ <?php
26
+ // Settings update message.
27
+ if ( isset( $_REQUEST['message'] ) && ( 'saved' === $_REQUEST['message'] ) ) { //phpcs:ignore
28
+ ?>
29
+ <div id="message" class="notice notice-success is-dismissive wcf-notice"><p> <?php esc_html_e( 'Settings saved successfully.', 'cartflows' ); ?> </p></div>
30
+ <?php
31
+ }
32
+ ?>
33
+ <?php do_action( 'cartflows_render_admin_content', $menu_page_slug ); ?>
34
+ </div>
35
+ </div>
includes/admin/cartflows-general.php CHANGED
@@ -521,5 +521,5 @@ $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOO
521
  /**
522
  * Loads Zapier settings admin view.
523
  */
524
- do_action( 'cartflows_after_general_settings' );
525
  ?>
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-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="woocommerce_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="woocommerce_json_search_products_and_variations"><?php echo $options; ?></select>
31
+ </span>
32
+
33
+ <span class="wcf-repeatable-row-actions">
34
+ <a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">
35
+ <span class="dashicons dashicons-trash"></span>
36
+ <span class="wcf-repeatable-remove-button"><?php echo __( 'Remove', 'cartflows' ); ?></span>
37
+ </a>
38
+ </span>
39
+ </div>
40
+
41
+ <div class="wcf_toggle_advance_fields"><i class="dashicons dashicons-arrow-down"></i></div>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="wcf-repeatable-row-advance-fields <?php echo $hide_advance; ?>">
46
+
47
+ <!-- Qty field. -->
48
+ <div class="wcf-repeatable-row-qty-field wcf-checkout-products-qty-<?php echo $id; ?>">
49
+ <div class="wcf-field-row">
50
+ <div class="wcf-field-row-heading">
51
+ <label><?php echo __( 'Product Quantity', 'cartflows' ); ?></label>
52
+ </div>
53
+
54
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
55
+ <input type="number" class="input-text qty text" step="1" min="1" max="" name="wcf-checkout-products[<?php echo $id; ?>][quantity]" value="<?php echo $selected_data['quantity']; ?>" title="Qty" inputmode="numeric">
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <!-- Qty field end -->
60
+
61
+ <!-- Type field. -->
62
+ <div class="wcf-repeatable-discount-type-field">
63
+ <div class="wcf-field-row">
64
+ <div class="wcf-field-row-heading">
65
+ <label><?php echo __( 'Discount Type', 'cartflows' ); ?></label>
66
+ </div>
67
+
68
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
69
+ <select name="wcf-checkout-products[<?php echo $id; ?>][discount_type]" data-allow_clear="allow_clear" data-placeholder="<?php echo __( 'Select Discount Type', 'cartflows' ); ?>">
70
+ <option value="" <?php selected( $selected_data['discount_type'], '', true ); ?>><?php echo __( 'Original', 'cartflows' ); ?></option>
71
+ <option value="discount_percent" <?php selected( $selected_data['discount_type'], 'discount_percent', true ); ?>><?php echo __( 'Percentage', 'cartflows' ); ?></option>
72
+ <option value="discount_price" <?php selected( $selected_data['discount_type'], 'discount_price', true ); ?>><?php echo __( 'Price', 'cartflows' ); ?></option>
73
+ </select>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <!-- Type field end -->
78
+
79
+ <!-- Discount field -->
80
+ <div class="wcf-repeatable-row-discount-field <?php echo $hide_advance; ?> wcf-checkout-products-discount-<?php echo $id; ?>">
81
+ <div class="wcf-field-row">
82
+ <div class="wcf-field-row-heading">
83
+ <label><?php echo __( 'Discount Value', 'cartflows' ); ?></label>
84
+ <i class="wcf-field-heading-help dashicons dashicons-editor-help"></i>
85
+ <span class="wcf-tooltip-text"><?php echo __( 'Discount value will apply for each quantity of product.', 'cartflows' ); ?></span>
86
+ </div>
87
+ <div class="wcf-field-row-content wcf-field-row-advance-content">
88
+ <input type="text" class="input-text text" name="wcf-checkout-products[<?php echo $id; ?>][discount_value]" value="<?php echo $selected_data['discount_value']; ?>" title="" inputmode="numeric">
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <div class="wcf-repeatable-row-unique-id-field">
94
+ <input name="wcf-checkout-products[<?php echo $id; ?>][unique_id]" type="hidden" class="wcf-checkout-product-unique" value="<?php echo $selected_data['unique_id']; ?>">
95
+ </div>
96
+
97
+ <?php do_action( 'cartflows_repeatable_row_advance_fields', $id ); ?>
98
+ </div>
99
+ </div>
languages/cartflows.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: CartFlows 1.5.10\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2020-06-03 09:23:29+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -24,6 +24,50 @@ msgstr ""
24
  "X-Textdomain-Support: yes\n"
25
  "X-Generator: grunt-wp-i18n 1.0.3\n"
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  #: classes/batch-process/class-cartflows-importer-elementor.php:44
28
  msgid "Invalid content."
29
  msgstr ""
@@ -114,8 +158,8 @@ msgstr ""
114
  msgid "Clone"
115
  msgstr ""
116
 
117
- #: classes/class-cartflows-default-meta.php:741
118
- #: modules/optin/classes/class-cartflows-optin-meta.php:487
119
  msgid "Submit"
120
  msgstr ""
121
 
@@ -332,18 +376,18 @@ msgid ""
332
  "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
333
  msgstr ""
334
 
335
- #: classes/class-cartflows-loader.php:464
336
  #. translators: %s: html tags
337
  msgid ""
338
  "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
339
  "activated."
340
  msgstr ""
341
 
342
- #: classes/class-cartflows-loader.php:474
343
  msgid "Activate WooCommerce"
344
  msgstr ""
345
 
346
- #: classes/class-cartflows-loader.php:482
347
  msgid "Install WooCommerce"
348
  msgstr ""
349
 
@@ -351,48 +395,48 @@ msgstr ""
351
  msgid "Action failed. Please refresh the page and retry."
352
  msgstr ""
353
 
354
- #: classes/class-cartflows-meta-fields.php:82
355
  msgid "Thin 100"
356
  msgstr ""
357
 
358
- #: classes/class-cartflows-meta-fields.php:83
359
  msgid "Extra-Light 200"
360
  msgstr ""
361
 
362
- #: classes/class-cartflows-meta-fields.php:84
363
  msgid "Light 300"
364
  msgstr ""
365
 
366
- #: classes/class-cartflows-meta-fields.php:85
367
  msgid "Normal 400"
368
  msgstr ""
369
 
370
- #: classes/class-cartflows-meta-fields.php:86
371
  msgid "Medium 500"
372
  msgstr ""
373
 
374
- #: classes/class-cartflows-meta-fields.php:87
375
  msgid "Semi-Bold 600"
376
  msgstr ""
377
 
378
- #: classes/class-cartflows-meta-fields.php:88
379
  msgid "Bold 700"
380
  msgstr ""
381
 
382
- #: classes/class-cartflows-meta-fields.php:89
383
  msgid "Extra-Bold 800"
384
  msgstr ""
385
 
386
- #: classes/class-cartflows-meta-fields.php:90
387
  msgid "Ultra-Bold 900"
388
  msgstr ""
389
 
390
- #: classes/class-cartflows-meta-fields.php:642
391
  #: includes/meta-fields/generate-product-repeater.php:30
392
  msgid "Search for a product&hellip;"
393
  msgstr ""
394
 
395
- #: classes/class-cartflows-meta-fields.php:690
396
  msgid "Search for a coupon&hellip;"
397
  msgstr ""
398
 
@@ -424,198 +468,202 @@ msgstr ""
424
  msgid "Flow Details"
425
  msgstr ""
426
 
427
- #: classes/class-cartflows-wizard.php:83
428
  msgid "Thanks for installing and using CartFlows!"
429
  msgstr ""
430
 
431
- #: classes/class-cartflows-wizard.php:84
432
  msgid ""
433
  "It is easy to use the CartFlows. Please use the setup wizard to quick start "
434
  "setup."
435
  msgstr ""
436
 
437
- #: classes/class-cartflows-wizard.php:86
438
  msgid "Start Wizard"
439
  msgstr ""
440
 
441
- #: classes/class-cartflows-wizard.php:87
442
  msgid "Skip Setup"
443
  msgstr ""
444
 
445
- #: classes/class-cartflows-wizard.php:117
446
  #: includes/admin/cartflows-general-bck.php:24
447
  msgid "Welcome"
448
  msgstr ""
449
 
450
- #: classes/class-cartflows-wizard.php:122
451
  msgid "Page Builder"
452
  msgstr ""
453
 
454
- #: classes/class-cartflows-wizard.php:126
455
  msgid "Checkout"
456
  msgstr ""
457
 
458
- #: classes/class-cartflows-wizard.php:130
459
  msgid "Training"
460
  msgstr ""
461
 
462
- #: classes/class-cartflows-wizard.php:134
463
  msgid "Ready!"
464
  msgstr ""
465
 
466
- #: classes/class-cartflows-wizard.php:209
467
  msgid "CartFlows Setup"
468
  msgstr ""
469
 
470
- #: classes/class-cartflows-wizard.php:235
471
  msgid "Exit Setup Wizard"
472
  msgstr ""
473
 
474
- #: classes/class-cartflows-wizard.php:288
475
  msgid "Welcome to CartFlows!"
476
  msgstr ""
477
 
478
- #: classes/class-cartflows-wizard.php:289
479
  msgid ""
480
  "Thank you for choosing CartFlows to get more leads, increase conversions, & "
481
  "maximize profits. This short setup wizard will guide you though configuring "
482
  "CartFlows and creating your first funnel."
483
  msgstr ""
484
 
485
- #: classes/class-cartflows-wizard.php:295
486
  msgid "Lets Go »"
487
  msgstr ""
488
 
489
- #: classes/class-cartflows-wizard.php:322
490
  msgid "Page Builder Setup"
491
  msgstr ""
492
 
493
- #: classes/class-cartflows-wizard.php:323
494
  msgid "Please select a page builder you would like to use with CartFlows."
495
  msgstr ""
496
 
497
- #: classes/class-cartflows-wizard.php:328
498
  msgid "Select Page Builder"
499
  msgstr ""
500
 
501
- #: classes/class-cartflows-wizard.php:335
502
  #: includes/admin/cartflows-general.php:94
503
  msgid "Elementor"
504
  msgstr ""
505
 
506
- #: classes/class-cartflows-wizard.php:345
507
  msgid "Beaver Builder Plugin (Lite Version)"
508
  msgstr ""
509
 
510
- #: classes/class-cartflows-wizard.php:355
511
  #: includes/admin/cartflows-general.php:96
512
  msgid "Divi"
513
  msgstr ""
514
 
515
- #: classes/class-cartflows-wizard.php:365
516
  #: includes/admin/cartflows-general.php:97
517
  msgid "Gutenberg"
518
  msgstr ""
519
 
520
- #: classes/class-cartflows-wizard.php:375
521
  #: includes/admin/cartflows-general.php:98
522
  msgid "Other"
523
  msgstr ""
524
 
525
- #: classes/class-cartflows-wizard.php:397
526
  msgid ""
527
  "While CartFlows Should work with most page builders, we offer templates for "
528
  "the above page builders."
529
  msgstr ""
530
 
531
- #: classes/class-cartflows-wizard.php:400
532
- #: classes/class-cartflows-wizard.php:445
533
- #: classes/class-cartflows-wizard.php:632
534
  msgid "« Previous"
535
  msgstr ""
536
 
537
- #: classes/class-cartflows-wizard.php:403
538
  msgid "Skip this step"
539
  msgstr ""
540
 
541
- #: classes/class-cartflows-wizard.php:404
542
  msgid "Next »"
543
  msgstr ""
544
 
545
- #: classes/class-cartflows-wizard.php:423
546
  msgid "Choose a checkout"
547
  msgstr ""
548
 
549
- #: classes/class-cartflows-wizard.php:426
550
  msgid ""
551
  "While CartFlows is designed to use WooCommerce sell digital and physical "
552
  "products, not all funnels need a checkout system."
553
  msgstr ""
554
 
555
- #: classes/class-cartflows-wizard.php:428
556
  msgid ""
557
  "Would you like to install WooCommerce to sell digital and physical products "
558
  "in your funnels?"
559
  msgstr ""
560
 
561
- #: classes/class-cartflows-wizard.php:435
562
  msgid "The following plugin will be installed and activated for you:"
563
  msgstr ""
564
 
565
- #: classes/class-cartflows-wizard.php:436
566
  msgid "WooCommerce"
567
  msgstr ""
568
 
569
- #: classes/class-cartflows-wizard.php:437
570
  msgid "WooCommerce Cart Abandonment Recovery"
571
  msgstr ""
572
 
573
- #: classes/class-cartflows-wizard.php:448
574
- #: classes/class-cartflows-wizard.php:635
575
  msgid "No thanks"
576
  msgstr ""
577
 
578
- #: classes/class-cartflows-wizard.php:449
579
  msgid "Yes"
580
  msgstr ""
581
 
582
- #: classes/class-cartflows-wizard.php:568
583
  msgid "Congratulations, You Did It!"
584
  msgstr ""
585
 
586
- #: classes/class-cartflows-wizard.php:575
587
  msgid ""
588
  "CartFlows is ready to use on your website. You've successfully completed "
589
  "the setup process and all that is left for you to do is create your first "
590
  "flow."
591
  msgstr ""
592
 
593
- #: classes/class-cartflows-wizard.php:589
594
  msgid "Create a flow"
595
  msgstr ""
596
 
597
- #: classes/class-cartflows-wizard.php:606
598
  msgid "Exclusive CartFlows Training Course Offer"
599
  msgstr ""
600
 
601
- #: classes/class-cartflows-wizard.php:617
602
  msgid ""
603
  "We want you to get off to a great start using CartFlows, so we would like "
604
  "to give access to our exclusive training course."
605
  msgstr ""
606
 
607
- #: classes/class-cartflows-wizard.php:618
608
  msgid "Get access to this couse, for free, by entering your email below."
609
  msgstr ""
610
 
611
- #: classes/class-cartflows-wizard.php:620
612
  msgid "Enter Email address"
613
  msgstr ""
614
 
615
- #: classes/class-cartflows-wizard.php:636
616
  msgid "Allow"
617
  msgstr ""
618
 
 
 
 
 
619
  #: classes/logger/class-cartflows-log-handler-file.php:351
620
  #: classes/logger/class-cartflows-log-handler-file.php:371
621
  msgid "This method should not be called before plugins_loaded."
@@ -713,7 +761,7 @@ msgstr ""
713
 
714
  #: includes/admin/cartflows-general.php:134
715
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
716
- #: modules/optin/classes/class-cartflows-optin-meta.php:380
717
  msgid "Default"
718
  msgstr ""
719
 
@@ -948,7 +996,7 @@ msgstr ""
948
  msgid "Create Product"
949
  msgstr ""
950
 
951
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:256
952
  #: modules/optin/classes/class-cartflows-optin-markup.php:146
953
  #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
954
  msgid ""
@@ -956,60 +1004,60 @@ msgid ""
956
  "it."
957
  msgstr ""
958
 
959
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:257
960
  #: modules/optin/classes/class-cartflows-optin-markup.php:147
961
  #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
962
  msgid "Click Here to Reload"
963
  msgstr ""
964
 
965
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:275
966
  msgid "Checkout ID not found"
967
  msgstr ""
968
 
969
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:338
970
  #: modules/checkout/templates/embed/checkout-template-simple.php:25
971
  #: modules/checkout/templates/wcf-template.php:36
972
  #: modules/optin/templates/optin-template-simple.php:25
973
  msgid "Your cart is currently empty."
974
  msgstr ""
975
 
976
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:404
977
  msgid ""
978
  "No product is selected. Please select products from the checkout meta "
979
  "settings to continue."
980
  msgstr ""
981
 
982
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:493
983
  msgid "Variations Not set"
984
  msgstr ""
985
 
986
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:501
987
  msgid "This product can't be purchased"
988
  msgstr ""
989
 
990
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:946
991
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:989
992
  msgid "Coupon Code"
993
  msgstr ""
994
 
995
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:947
996
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:998
997
  msgid "Apply"
998
  msgstr ""
999
 
1000
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1154
1001
  msgid "Sorry there was a problem removing this coupon."
1002
  msgstr ""
1003
 
1004
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1157
1005
  msgid "Coupon has been removed."
1006
  msgstr ""
1007
 
1008
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1176
1009
  msgid "Sorry there was a problem removing "
1010
  msgstr ""
1011
 
1012
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1179
1013
  msgid " has been removed."
1014
  msgstr ""
1015
 
@@ -1104,7 +1152,7 @@ msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1104
  msgstr ""
1105
 
1106
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1107
- #: modules/optin/classes/class-cartflows-optin-meta.php:267
1108
  #. translators: %s: link
1109
  msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1110
  msgstr ""
@@ -1155,7 +1203,7 @@ msgid "Two Step"
1155
  msgstr ""
1156
 
1157
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1158
- #: modules/optin/classes/class-cartflows-optin-meta.php:343
1159
  msgid "Primary Color"
1160
  msgstr ""
1161
 
@@ -1163,9 +1211,9 @@ msgstr ""
1163
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1164
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1165
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1166
- #: modules/optin/classes/class-cartflows-optin-meta.php:352
1167
- #: modules/optin/classes/class-cartflows-optin-meta.php:391
1168
- #: modules/optin/classes/class-cartflows-optin-meta.php:503
1169
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1170
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1171
  msgid "Font Family"
@@ -1187,116 +1235,116 @@ msgstr ""
1187
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1188
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1189
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1190
- #: modules/optin/classes/class-cartflows-optin-meta.php:400
1191
- #: modules/optin/classes/class-cartflows-optin-meta.php:512
1192
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1193
  msgid "Font Weight"
1194
  msgstr ""
1195
 
1196
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1197
- #: modules/optin/classes/class-cartflows-optin-meta.php:363
1198
  msgid "Input Fields"
1199
  msgstr ""
1200
 
1201
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1202
- #: modules/optin/classes/class-cartflows-optin-meta.php:370
1203
  msgid "Floating Labels (Available in CartFlows Pro)"
1204
  msgstr ""
1205
 
1206
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1207
- #: modules/optin/classes/class-cartflows-optin-meta.php:376
1208
  msgid "Style"
1209
  msgstr ""
1210
 
1211
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1212
- #: modules/optin/classes/class-cartflows-optin-meta.php:381
1213
  msgid "Floating Labels"
1214
  msgstr ""
1215
 
1216
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1217
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1218
- #: modules/optin/classes/class-cartflows-optin-meta.php:408
1219
- #: modules/optin/classes/class-cartflows-optin-meta.php:520
1220
  msgid "Size"
1221
  msgstr ""
1222
 
1223
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1224
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1225
- #: modules/optin/classes/class-cartflows-optin-meta.php:412
1226
- #: modules/optin/classes/class-cartflows-optin-meta.php:524
1227
  msgid "Extra Small"
1228
  msgstr ""
1229
 
1230
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1231
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1232
- #: modules/optin/classes/class-cartflows-optin-meta.php:413
1233
- #: modules/optin/classes/class-cartflows-optin-meta.php:525
1234
  msgid "Small"
1235
  msgstr ""
1236
 
1237
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1238
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1239
- #: modules/optin/classes/class-cartflows-optin-meta.php:414
1240
- #: modules/optin/classes/class-cartflows-optin-meta.php:526
1241
  msgid "Medium"
1242
  msgstr ""
1243
 
1244
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1245
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1246
- #: modules/optin/classes/class-cartflows-optin-meta.php:415
1247
- #: modules/optin/classes/class-cartflows-optin-meta.php:527
1248
  msgid "Large"
1249
  msgstr ""
1250
 
1251
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1252
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1253
- #: modules/optin/classes/class-cartflows-optin-meta.php:416
1254
- #: modules/optin/classes/class-cartflows-optin-meta.php:528
1255
  msgid "Extra Large"
1256
  msgstr ""
1257
 
1258
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1259
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1260
- #: modules/optin/classes/class-cartflows-optin-meta.php:417
1261
- #: modules/optin/classes/class-cartflows-optin-meta.php:529
1262
  msgid "Custom"
1263
  msgstr ""
1264
 
1265
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1266
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1267
- #: modules/optin/classes/class-cartflows-optin-meta.php:424
1268
- #: modules/optin/classes/class-cartflows-optin-meta.php:536
1269
  msgid "Top Bottom Spacing"
1270
  msgstr ""
1271
 
1272
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1273
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1274
- #: modules/optin/classes/class-cartflows-optin-meta.php:432
1275
- #: modules/optin/classes/class-cartflows-optin-meta.php:544
1276
  msgid "Left Right Spacing"
1277
  msgstr ""
1278
 
1279
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1280
- #: modules/optin/classes/class-cartflows-optin-meta.php:448
1281
  msgid "Text / Placeholder Color"
1282
  msgstr ""
1283
 
1284
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1285
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1286
- #: modules/optin/classes/class-cartflows-optin-meta.php:456
1287
- #: modules/optin/classes/class-cartflows-optin-meta.php:581
1288
  msgid "Background Color"
1289
  msgstr ""
1290
 
1291
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1292
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1293
- #: modules/optin/classes/class-cartflows-optin-meta.php:464
1294
- #: modules/optin/classes/class-cartflows-optin-meta.php:597
1295
  msgid "Border Color"
1296
  msgstr ""
1297
 
1298
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1299
- #: modules/optin/classes/class-cartflows-optin-meta.php:440
1300
  msgid "Label Color"
1301
  msgstr ""
1302
 
@@ -1305,22 +1353,22 @@ msgid "Buttons"
1305
  msgstr ""
1306
 
1307
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1308
- #: modules/optin/classes/class-cartflows-optin-meta.php:565
1309
  msgid "Text Color"
1310
  msgstr ""
1311
 
1312
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1313
- #: modules/optin/classes/class-cartflows-optin-meta.php:573
1314
  msgid "Text Hover Color"
1315
  msgstr ""
1316
 
1317
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1318
- #: modules/optin/classes/class-cartflows-optin-meta.php:589
1319
  msgid "Background Hover Color"
1320
  msgstr ""
1321
 
1322
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1323
- #: modules/optin/classes/class-cartflows-optin-meta.php:605
1324
  msgid "Border Hover Color"
1325
  msgstr ""
1326
 
@@ -1449,57 +1497,57 @@ msgstr ""
1449
 
1450
  #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1451
  #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1452
- #: modules/flow/classes/class-cartflows-step-post-type.php:397
1453
- #: modules/flow/classes/class-cartflows-step-post-type.php:403
1454
  #. translators: %s: singular custom post type name
1455
  msgid "%s updated."
1456
  msgstr ""
1457
 
1458
  #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1459
- #: modules/flow/classes/class-cartflows-step-post-type.php:399
1460
  #. translators: %s: singular custom post type name
1461
  msgid "Custom %s updated."
1462
  msgstr ""
1463
 
1464
  #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1465
- #: modules/flow/classes/class-cartflows-step-post-type.php:401
1466
  #. translators: %s: singular custom post type name
1467
  msgid "Custom %s deleted."
1468
  msgstr ""
1469
 
1470
  #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1471
- #: modules/flow/classes/class-cartflows-step-post-type.php:405
1472
  #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1473
  #. the revision
1474
  msgid "%1$s restored to revision from %2$s"
1475
  msgstr ""
1476
 
1477
  #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1478
- #: modules/flow/classes/class-cartflows-step-post-type.php:407
1479
  #. translators: %s: singular custom post type name
1480
  msgid "%s published."
1481
  msgstr ""
1482
 
1483
  #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1484
- #: modules/flow/classes/class-cartflows-step-post-type.php:409
1485
  #. translators: %s: singular custom post type name
1486
  msgid "%s saved."
1487
  msgstr ""
1488
 
1489
  #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1490
- #: modules/flow/classes/class-cartflows-step-post-type.php:411
1491
  #. translators: %s: singular custom post type name
1492
  msgid "%s submitted."
1493
  msgstr ""
1494
 
1495
  #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1496
- #: modules/flow/classes/class-cartflows-step-post-type.php:413
1497
  #. translators: %s: singular custom post type name
1498
  msgid "%s scheduled for."
1499
  msgstr ""
1500
 
1501
  #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1502
- #: modules/flow/classes/class-cartflows-step-post-type.php:415
1503
  #. translators: %s: singular custom post type name
1504
  msgid "%s draft updated."
1505
  msgstr ""
@@ -1646,66 +1694,66 @@ msgstr ""
1646
  msgid "Select Free and Virtual product only."
1647
  msgstr ""
1648
 
1649
- #: modules/optin/classes/class-cartflows-optin-meta.php:290
1650
  msgid "Pass Fields as URL Parameters"
1651
  msgstr ""
1652
 
1653
- #: modules/optin/classes/class-cartflows-optin-meta.php:293
1654
  msgid "Enable"
1655
  msgstr ""
1656
 
1657
- #: modules/optin/classes/class-cartflows-optin-meta.php:294
1658
  msgid ""
1659
  "You can pass specific fields from the form to next step as URL query "
1660
  "parameters."
1661
  msgstr ""
1662
 
1663
- #: modules/optin/classes/class-cartflows-optin-meta.php:305
1664
  msgid "Enter form field"
1665
  msgstr ""
1666
 
1667
- #: modules/optin/classes/class-cartflows-optin-meta.php:308
1668
- #: modules/optin/classes/class-cartflows-optin-meta.php:318
1669
  msgid "Enter comma seprated field name. E.g. first_name, last_name"
1670
  msgstr ""
1671
 
1672
- #: modules/optin/classes/class-cartflows-optin-meta.php:310
1673
  msgid "Fields to pass, separated by commas"
1674
  msgstr ""
1675
 
1676
- #: modules/optin/classes/class-cartflows-optin-meta.php:320
1677
  #. translators: %s: link
1678
  msgid ""
1679
  "You can pass field value as a URL parameter to the next step. %1$sClick "
1680
  "here%2$s for more information."
1681
  msgstr ""
1682
 
1683
- #: modules/optin/classes/class-cartflows-optin-meta.php:477
1684
  msgid "Submit Button"
1685
  msgstr ""
1686
 
1687
- #: modules/optin/classes/class-cartflows-optin-meta.php:483
1688
  msgid "Button Text"
1689
  msgstr ""
1690
 
1691
- #: modules/optin/classes/class-cartflows-optin-meta.php:494
1692
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1693
  msgid "Font Size"
1694
  msgstr ""
1695
 
1696
- #: modules/optin/classes/class-cartflows-optin-meta.php:552
1697
  msgid "Position"
1698
  msgstr ""
1699
 
1700
- #: modules/optin/classes/class-cartflows-optin-meta.php:556
1701
  msgid "Left"
1702
  msgstr ""
1703
 
1704
- #: modules/optin/classes/class-cartflows-optin-meta.php:557
1705
  msgid "Center"
1706
  msgstr ""
1707
 
1708
- #: modules/optin/classes/class-cartflows-optin-meta.php:558
1709
  msgid "Right"
1710
  msgstr ""
1711
 
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: CartFlows 1.5.11\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-06-16 09:42:20+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
24
  "X-Textdomain-Support: yes\n"
25
  "X-Generator: grunt-wp-i18n 1.0.3\n"
26
 
27
+ #: admin/bsf-analytics/class-bsf-analytics.php:183
28
+ #. translators: %s product name
29
+ msgid ""
30
+ "Want to help make <strong>%1s</strong> even more awesome? Allow us to "
31
+ "collect non-sensitive diagnostic data and usage information. "
32
+ msgstr ""
33
+
34
+ #: admin/bsf-analytics/class-bsf-analytics.php:186
35
+ msgid "This will be applicable for all sites from the network."
36
+ msgstr ""
37
+
38
+ #: admin/bsf-analytics/class-bsf-analytics.php:210
39
+ #. translators: %s usage doc link
40
+ msgid " Know More."
41
+ msgstr ""
42
+
43
+ #: admin/bsf-analytics/class-bsf-analytics.php:217
44
+ msgid "Yes! Allow it"
45
+ msgstr ""
46
+
47
+ #: admin/bsf-analytics/class-bsf-analytics.php:225
48
+ msgid "No Thanks"
49
+ msgstr ""
50
+
51
+ #: admin/bsf-analytics/class-bsf-analytics.php:294
52
+ msgid "Every two days"
53
+ msgstr ""
54
+
55
+ #: admin/bsf-analytics/class-bsf-analytics.php:348
56
+ msgid "Usage Tracking"
57
+ msgstr ""
58
+
59
+ #: admin/bsf-analytics/class-bsf-analytics.php:380
60
+ msgid "Allow Brainstorm Force products to track non-sensitive usage tracking data."
61
+ msgstr ""
62
+
63
+ #: admin/bsf-analytics/class-bsf-analytics.php:383
64
+ msgid " This will be applicable for all sites from the network."
65
+ msgstr ""
66
+
67
+ #: admin/bsf-analytics/class-bsf-analytics.php:388
68
+ msgid "Learn More."
69
+ msgstr ""
70
+
71
  #: classes/batch-process/class-cartflows-importer-elementor.php:44
72
  msgid "Invalid content."
73
  msgstr ""
158
  msgid "Clone"
159
  msgstr ""
160
 
161
+ #: classes/class-cartflows-default-meta.php:745
162
+ #: modules/optin/classes/class-cartflows-optin-meta.php:488
163
  msgid "Submit"
164
  msgstr ""
165
 
376
  "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
377
  msgstr ""
378
 
379
+ #: classes/class-cartflows-loader.php:471
380
  #. translators: %s: html tags
381
  msgid ""
382
  "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
383
  "activated."
384
  msgstr ""
385
 
386
+ #: classes/class-cartflows-loader.php:481
387
  msgid "Activate WooCommerce"
388
  msgstr ""
389
 
390
+ #: classes/class-cartflows-loader.php:489
391
  msgid "Install WooCommerce"
392
  msgstr ""
393
 
395
  msgid "Action failed. Please refresh the page and retry."
396
  msgstr ""
397
 
398
+ #: classes/class-cartflows-meta-fields.php:84
399
  msgid "Thin 100"
400
  msgstr ""
401
 
402
+ #: classes/class-cartflows-meta-fields.php:85
403
  msgid "Extra-Light 200"
404
  msgstr ""
405
 
406
+ #: classes/class-cartflows-meta-fields.php:86
407
  msgid "Light 300"
408
  msgstr ""
409
 
410
+ #: classes/class-cartflows-meta-fields.php:87
411
  msgid "Normal 400"
412
  msgstr ""
413
 
414
+ #: classes/class-cartflows-meta-fields.php:88
415
  msgid "Medium 500"
416
  msgstr ""
417
 
418
+ #: classes/class-cartflows-meta-fields.php:89
419
  msgid "Semi-Bold 600"
420
  msgstr ""
421
 
422
+ #: classes/class-cartflows-meta-fields.php:90
423
  msgid "Bold 700"
424
  msgstr ""
425
 
426
+ #: classes/class-cartflows-meta-fields.php:91
427
  msgid "Extra-Bold 800"
428
  msgstr ""
429
 
430
+ #: classes/class-cartflows-meta-fields.php:92
431
  msgid "Ultra-Bold 900"
432
  msgstr ""
433
 
434
+ #: classes/class-cartflows-meta-fields.php:717
435
  #: includes/meta-fields/generate-product-repeater.php:30
436
  msgid "Search for a product&hellip;"
437
  msgstr ""
438
 
439
+ #: classes/class-cartflows-meta-fields.php:766
440
  msgid "Search for a coupon&hellip;"
441
  msgstr ""
442
 
468
  msgid "Flow Details"
469
  msgstr ""
470
 
471
+ #: classes/class-cartflows-wizard.php:91
472
  msgid "Thanks for installing and using CartFlows!"
473
  msgstr ""
474
 
475
+ #: classes/class-cartflows-wizard.php:92
476
  msgid ""
477
  "It is easy to use the CartFlows. Please use the setup wizard to quick start "
478
  "setup."
479
  msgstr ""
480
 
481
+ #: classes/class-cartflows-wizard.php:94
482
  msgid "Start Wizard"
483
  msgstr ""
484
 
485
+ #: classes/class-cartflows-wizard.php:95
486
  msgid "Skip Setup"
487
  msgstr ""
488
 
489
+ #: classes/class-cartflows-wizard.php:125
490
  #: includes/admin/cartflows-general-bck.php:24
491
  msgid "Welcome"
492
  msgstr ""
493
 
494
+ #: classes/class-cartflows-wizard.php:130
495
  msgid "Page Builder"
496
  msgstr ""
497
 
498
+ #: classes/class-cartflows-wizard.php:134
499
  msgid "Checkout"
500
  msgstr ""
501
 
502
+ #: classes/class-cartflows-wizard.php:138
503
  msgid "Training"
504
  msgstr ""
505
 
506
+ #: classes/class-cartflows-wizard.php:142
507
  msgid "Ready!"
508
  msgstr ""
509
 
510
+ #: classes/class-cartflows-wizard.php:217
511
  msgid "CartFlows Setup"
512
  msgstr ""
513
 
514
+ #: classes/class-cartflows-wizard.php:243
515
  msgid "Exit Setup Wizard"
516
  msgstr ""
517
 
518
+ #: classes/class-cartflows-wizard.php:296
519
  msgid "Welcome to CartFlows!"
520
  msgstr ""
521
 
522
+ #: classes/class-cartflows-wizard.php:297
523
  msgid ""
524
  "Thank you for choosing CartFlows to get more leads, increase conversions, & "
525
  "maximize profits. This short setup wizard will guide you though configuring "
526
  "CartFlows and creating your first funnel."
527
  msgstr ""
528
 
529
+ #: classes/class-cartflows-wizard.php:303
530
  msgid "Lets Go »"
531
  msgstr ""
532
 
533
+ #: classes/class-cartflows-wizard.php:330
534
  msgid "Page Builder Setup"
535
  msgstr ""
536
 
537
+ #: classes/class-cartflows-wizard.php:331
538
  msgid "Please select a page builder you would like to use with CartFlows."
539
  msgstr ""
540
 
541
+ #: classes/class-cartflows-wizard.php:336
542
  msgid "Select Page Builder"
543
  msgstr ""
544
 
545
+ #: classes/class-cartflows-wizard.php:343
546
  #: includes/admin/cartflows-general.php:94
547
  msgid "Elementor"
548
  msgstr ""
549
 
550
+ #: classes/class-cartflows-wizard.php:353
551
  msgid "Beaver Builder Plugin (Lite Version)"
552
  msgstr ""
553
 
554
+ #: classes/class-cartflows-wizard.php:363
555
  #: includes/admin/cartflows-general.php:96
556
  msgid "Divi"
557
  msgstr ""
558
 
559
+ #: classes/class-cartflows-wizard.php:373
560
  #: includes/admin/cartflows-general.php:97
561
  msgid "Gutenberg"
562
  msgstr ""
563
 
564
+ #: classes/class-cartflows-wizard.php:383
565
  #: includes/admin/cartflows-general.php:98
566
  msgid "Other"
567
  msgstr ""
568
 
569
+ #: classes/class-cartflows-wizard.php:405
570
  msgid ""
571
  "While CartFlows Should work with most page builders, we offer templates for "
572
  "the above page builders."
573
  msgstr ""
574
 
575
+ #: classes/class-cartflows-wizard.php:408
576
+ #: classes/class-cartflows-wizard.php:453
577
+ #: classes/class-cartflows-wizard.php:640
578
  msgid "« Previous"
579
  msgstr ""
580
 
581
+ #: classes/class-cartflows-wizard.php:411
582
  msgid "Skip this step"
583
  msgstr ""
584
 
585
+ #: classes/class-cartflows-wizard.php:412
586
  msgid "Next »"
587
  msgstr ""
588
 
589
+ #: classes/class-cartflows-wizard.php:431
590
  msgid "Choose a checkout"
591
  msgstr ""
592
 
593
+ #: classes/class-cartflows-wizard.php:434
594
  msgid ""
595
  "While CartFlows is designed to use WooCommerce sell digital and physical "
596
  "products, not all funnels need a checkout system."
597
  msgstr ""
598
 
599
+ #: classes/class-cartflows-wizard.php:436
600
  msgid ""
601
  "Would you like to install WooCommerce to sell digital and physical products "
602
  "in your funnels?"
603
  msgstr ""
604
 
605
+ #: classes/class-cartflows-wizard.php:443
606
  msgid "The following plugin will be installed and activated for you:"
607
  msgstr ""
608
 
609
+ #: classes/class-cartflows-wizard.php:444
610
  msgid "WooCommerce"
611
  msgstr ""
612
 
613
+ #: classes/class-cartflows-wizard.php:445
614
  msgid "WooCommerce Cart Abandonment Recovery"
615
  msgstr ""
616
 
617
+ #: classes/class-cartflows-wizard.php:456
618
+ #: classes/class-cartflows-wizard.php:643
619
  msgid "No thanks"
620
  msgstr ""
621
 
622
+ #: classes/class-cartflows-wizard.php:457
623
  msgid "Yes"
624
  msgstr ""
625
 
626
+ #: classes/class-cartflows-wizard.php:576
627
  msgid "Congratulations, You Did It!"
628
  msgstr ""
629
 
630
+ #: classes/class-cartflows-wizard.php:583
631
  msgid ""
632
  "CartFlows is ready to use on your website. You've successfully completed "
633
  "the setup process and all that is left for you to do is create your first "
634
  "flow."
635
  msgstr ""
636
 
637
+ #: classes/class-cartflows-wizard.php:597
638
  msgid "Create a flow"
639
  msgstr ""
640
 
641
+ #: classes/class-cartflows-wizard.php:614
642
  msgid "Exclusive CartFlows Training Course Offer"
643
  msgstr ""
644
 
645
+ #: classes/class-cartflows-wizard.php:625
646
  msgid ""
647
  "We want you to get off to a great start using CartFlows, so we would like "
648
  "to give access to our exclusive training course."
649
  msgstr ""
650
 
651
+ #: classes/class-cartflows-wizard.php:626
652
  msgid "Get access to this couse, for free, by entering your email below."
653
  msgstr ""
654
 
655
+ #: classes/class-cartflows-wizard.php:628
656
  msgid "Enter Email address"
657
  msgstr ""
658
 
659
+ #: classes/class-cartflows-wizard.php:644
660
  msgid "Allow"
661
  msgstr ""
662
 
663
+ #: classes/lib/notices/class-astra-notices.php:125
664
+ msgid "WordPress Nonce not validated."
665
+ msgstr ""
666
+
667
  #: classes/logger/class-cartflows-log-handler-file.php:351
668
  #: classes/logger/class-cartflows-log-handler-file.php:371
669
  msgid "This method should not be called before plugins_loaded."
761
 
762
  #: includes/admin/cartflows-general.php:134
763
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
764
+ #: modules/optin/classes/class-cartflows-optin-meta.php:381
765
  msgid "Default"
766
  msgstr ""
767
 
996
  msgid "Create Product"
997
  msgstr ""
998
 
999
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:284
1000
  #: modules/optin/classes/class-cartflows-optin-markup.php:146
1001
  #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
1002
  msgid ""
1004
  "it."
1005
  msgstr ""
1006
 
1007
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:285
1008
  #: modules/optin/classes/class-cartflows-optin-markup.php:147
1009
  #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
1010
  msgid "Click Here to Reload"
1011
  msgstr ""
1012
 
1013
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:303
1014
  msgid "Checkout ID not found"
1015
  msgstr ""
1016
 
1017
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:366
1018
  #: modules/checkout/templates/embed/checkout-template-simple.php:25
1019
  #: modules/checkout/templates/wcf-template.php:36
1020
  #: modules/optin/templates/optin-template-simple.php:25
1021
  msgid "Your cart is currently empty."
1022
  msgstr ""
1023
 
1024
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:432
1025
  msgid ""
1026
  "No product is selected. Please select products from the checkout meta "
1027
  "settings to continue."
1028
  msgstr ""
1029
 
1030
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:521
1031
  msgid "Variations Not set"
1032
  msgstr ""
1033
 
1034
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:529
1035
  msgid "This product can't be purchased"
1036
  msgstr ""
1037
 
1038
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:974
1039
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1017
1040
  msgid "Coupon Code"
1041
  msgstr ""
1042
 
1043
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:975
1044
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1026
1045
  msgid "Apply"
1046
  msgstr ""
1047
 
1048
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1182
1049
  msgid "Sorry there was a problem removing this coupon."
1050
  msgstr ""
1051
 
1052
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1185
1053
  msgid "Coupon has been removed."
1054
  msgstr ""
1055
 
1056
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1204
1057
  msgid "Sorry there was a problem removing "
1058
  msgstr ""
1059
 
1060
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1207
1061
  msgid " has been removed."
1062
  msgstr ""
1063
 
1152
  msgstr ""
1153
 
1154
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1155
+ #: modules/optin/classes/class-cartflows-optin-meta.php:268
1156
  #. translators: %s: link
1157
  msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1158
  msgstr ""
1203
  msgstr ""
1204
 
1205
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1206
+ #: modules/optin/classes/class-cartflows-optin-meta.php:344
1207
  msgid "Primary Color"
1208
  msgstr ""
1209
 
1211
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1212
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1213
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1214
+ #: modules/optin/classes/class-cartflows-optin-meta.php:353
1215
+ #: modules/optin/classes/class-cartflows-optin-meta.php:392
1216
+ #: modules/optin/classes/class-cartflows-optin-meta.php:504
1217
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1218
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1219
  msgid "Font Family"
1235
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1236
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1237
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1238
+ #: modules/optin/classes/class-cartflows-optin-meta.php:401
1239
+ #: modules/optin/classes/class-cartflows-optin-meta.php:513
1240
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1241
  msgid "Font Weight"
1242
  msgstr ""
1243
 
1244
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1245
+ #: modules/optin/classes/class-cartflows-optin-meta.php:364
1246
  msgid "Input Fields"
1247
  msgstr ""
1248
 
1249
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1250
+ #: modules/optin/classes/class-cartflows-optin-meta.php:371
1251
  msgid "Floating Labels (Available in CartFlows Pro)"
1252
  msgstr ""
1253
 
1254
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1255
+ #: modules/optin/classes/class-cartflows-optin-meta.php:377
1256
  msgid "Style"
1257
  msgstr ""
1258
 
1259
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1260
+ #: modules/optin/classes/class-cartflows-optin-meta.php:382
1261
  msgid "Floating Labels"
1262
  msgstr ""
1263
 
1264
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1265
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1266
+ #: modules/optin/classes/class-cartflows-optin-meta.php:409
1267
+ #: modules/optin/classes/class-cartflows-optin-meta.php:521
1268
  msgid "Size"
1269
  msgstr ""
1270
 
1271
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1272
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1273
+ #: modules/optin/classes/class-cartflows-optin-meta.php:413
1274
+ #: modules/optin/classes/class-cartflows-optin-meta.php:525
1275
  msgid "Extra Small"
1276
  msgstr ""
1277
 
1278
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1279
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1280
+ #: modules/optin/classes/class-cartflows-optin-meta.php:414
1281
+ #: modules/optin/classes/class-cartflows-optin-meta.php:526
1282
  msgid "Small"
1283
  msgstr ""
1284
 
1285
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1286
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1287
+ #: modules/optin/classes/class-cartflows-optin-meta.php:415
1288
+ #: modules/optin/classes/class-cartflows-optin-meta.php:527
1289
  msgid "Medium"
1290
  msgstr ""
1291
 
1292
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1293
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1294
+ #: modules/optin/classes/class-cartflows-optin-meta.php:416
1295
+ #: modules/optin/classes/class-cartflows-optin-meta.php:528
1296
  msgid "Large"
1297
  msgstr ""
1298
 
1299
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1300
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1301
+ #: modules/optin/classes/class-cartflows-optin-meta.php:417
1302
+ #: modules/optin/classes/class-cartflows-optin-meta.php:529
1303
  msgid "Extra Large"
1304
  msgstr ""
1305
 
1306
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1307
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1308
+ #: modules/optin/classes/class-cartflows-optin-meta.php:418
1309
+ #: modules/optin/classes/class-cartflows-optin-meta.php:530
1310
  msgid "Custom"
1311
  msgstr ""
1312
 
1313
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1314
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1315
+ #: modules/optin/classes/class-cartflows-optin-meta.php:425
1316
+ #: modules/optin/classes/class-cartflows-optin-meta.php:537
1317
  msgid "Top Bottom Spacing"
1318
  msgstr ""
1319
 
1320
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1321
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1322
+ #: modules/optin/classes/class-cartflows-optin-meta.php:433
1323
+ #: modules/optin/classes/class-cartflows-optin-meta.php:545
1324
  msgid "Left Right Spacing"
1325
  msgstr ""
1326
 
1327
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1328
+ #: modules/optin/classes/class-cartflows-optin-meta.php:449
1329
  msgid "Text / Placeholder Color"
1330
  msgstr ""
1331
 
1332
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1333
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1334
+ #: modules/optin/classes/class-cartflows-optin-meta.php:457
1335
+ #: modules/optin/classes/class-cartflows-optin-meta.php:582
1336
  msgid "Background Color"
1337
  msgstr ""
1338
 
1339
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1340
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1341
+ #: modules/optin/classes/class-cartflows-optin-meta.php:465
1342
+ #: modules/optin/classes/class-cartflows-optin-meta.php:598
1343
  msgid "Border Color"
1344
  msgstr ""
1345
 
1346
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1347
+ #: modules/optin/classes/class-cartflows-optin-meta.php:441
1348
  msgid "Label Color"
1349
  msgstr ""
1350
 
1353
  msgstr ""
1354
 
1355
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1356
+ #: modules/optin/classes/class-cartflows-optin-meta.php:566
1357
  msgid "Text Color"
1358
  msgstr ""
1359
 
1360
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1361
+ #: modules/optin/classes/class-cartflows-optin-meta.php:574
1362
  msgid "Text Hover Color"
1363
  msgstr ""
1364
 
1365
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1366
+ #: modules/optin/classes/class-cartflows-optin-meta.php:590
1367
  msgid "Background Hover Color"
1368
  msgstr ""
1369
 
1370
  #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1371
+ #: modules/optin/classes/class-cartflows-optin-meta.php:606
1372
  msgid "Border Hover Color"
1373
  msgstr ""
1374
 
1497
 
1498
  #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1499
  #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1500
+ #: modules/flow/classes/class-cartflows-step-post-type.php:401
1501
+ #: modules/flow/classes/class-cartflows-step-post-type.php:407
1502
  #. translators: %s: singular custom post type name
1503
  msgid "%s updated."
1504
  msgstr ""
1505
 
1506
  #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1507
+ #: modules/flow/classes/class-cartflows-step-post-type.php:403
1508
  #. translators: %s: singular custom post type name
1509
  msgid "Custom %s updated."
1510
  msgstr ""
1511
 
1512
  #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1513
+ #: modules/flow/classes/class-cartflows-step-post-type.php:405
1514
  #. translators: %s: singular custom post type name
1515
  msgid "Custom %s deleted."
1516
  msgstr ""
1517
 
1518
  #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1519
+ #: modules/flow/classes/class-cartflows-step-post-type.php:409
1520
  #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1521
  #. the revision
1522
  msgid "%1$s restored to revision from %2$s"
1523
  msgstr ""
1524
 
1525
  #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1526
+ #: modules/flow/classes/class-cartflows-step-post-type.php:411
1527
  #. translators: %s: singular custom post type name
1528
  msgid "%s published."
1529
  msgstr ""
1530
 
1531
  #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1532
+ #: modules/flow/classes/class-cartflows-step-post-type.php:413
1533
  #. translators: %s: singular custom post type name
1534
  msgid "%s saved."
1535
  msgstr ""
1536
 
1537
  #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1538
+ #: modules/flow/classes/class-cartflows-step-post-type.php:415
1539
  #. translators: %s: singular custom post type name
1540
  msgid "%s submitted."
1541
  msgstr ""
1542
 
1543
  #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1544
+ #: modules/flow/classes/class-cartflows-step-post-type.php:417
1545
  #. translators: %s: singular custom post type name
1546
  msgid "%s scheduled for."
1547
  msgstr ""
1548
 
1549
  #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1550
+ #: modules/flow/classes/class-cartflows-step-post-type.php:419
1551
  #. translators: %s: singular custom post type name
1552
  msgid "%s draft updated."
1553
  msgstr ""
1694
  msgid "Select Free and Virtual product only."
1695
  msgstr ""
1696
 
1697
+ #: modules/optin/classes/class-cartflows-optin-meta.php:291
1698
  msgid "Pass Fields as URL Parameters"
1699
  msgstr ""
1700
 
1701
+ #: modules/optin/classes/class-cartflows-optin-meta.php:294
1702
  msgid "Enable"
1703
  msgstr ""
1704
 
1705
+ #: modules/optin/classes/class-cartflows-optin-meta.php:295
1706
  msgid ""
1707
  "You can pass specific fields from the form to next step as URL query "
1708
  "parameters."
1709
  msgstr ""
1710
 
1711
+ #: modules/optin/classes/class-cartflows-optin-meta.php:306
1712
  msgid "Enter form field"
1713
  msgstr ""
1714
 
1715
+ #: modules/optin/classes/class-cartflows-optin-meta.php:309
1716
+ #: modules/optin/classes/class-cartflows-optin-meta.php:319
1717
  msgid "Enter comma seprated field name. E.g. first_name, last_name"
1718
  msgstr ""
1719
 
1720
+ #: modules/optin/classes/class-cartflows-optin-meta.php:311
1721
  msgid "Fields to pass, separated by commas"
1722
  msgstr ""
1723
 
1724
+ #: modules/optin/classes/class-cartflows-optin-meta.php:321
1725
  #. translators: %s: link
1726
  msgid ""
1727
  "You can pass field value as a URL parameter to the next step. %1$sClick "
1728
  "here%2$s for more information."
1729
  msgstr ""
1730
 
1731
+ #: modules/optin/classes/class-cartflows-optin-meta.php:478
1732
  msgid "Submit Button"
1733
  msgstr ""
1734
 
1735
+ #: modules/optin/classes/class-cartflows-optin-meta.php:484
1736
  msgid "Button Text"
1737
  msgstr ""
1738
 
1739
+ #: modules/optin/classes/class-cartflows-optin-meta.php:495
1740
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1741
  msgid "Font Size"
1742
  msgstr ""
1743
 
1744
+ #: modules/optin/classes/class-cartflows-optin-meta.php:553
1745
  msgid "Position"
1746
  msgstr ""
1747
 
1748
+ #: modules/optin/classes/class-cartflows-optin-meta.php:557
1749
  msgid "Left"
1750
  msgstr ""
1751
 
1752
+ #: modules/optin/classes/class-cartflows-optin-meta.php:558
1753
  msgid "Center"
1754
  msgstr ""
1755
 
1756
+ #: modules/optin/classes/class-cartflows-optin-meta.php:559
1757
  msgid "Right"
1758
  msgstr ""
1759
 
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1260 +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_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
80
-
81
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
82
- }
83
-
84
- /**
85
- * Modify WooCommerce paypal arguments.
86
- *
87
- * @param array $args argumenets for payment.
88
- * @param WC_Order $order order data.
89
- * @return array
90
- */
91
- public function modify_paypal_args( $args, $order ) {
92
-
93
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
94
-
95
- if ( ! $checkout_id ) {
96
- return $args;
97
- }
98
-
99
- // Set cancel return URL.
100
- $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
101
-
102
- return $args;
103
- }
104
-
105
- /**
106
- * Modify WooCommerce paypal arguments.
107
- *
108
- * @param string $product_name product name.
109
- * @param object $cart_item cart item.
110
- * @param string $cart_item_key cart item key.
111
- * @return string
112
- */
113
- public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
114
-
115
- $checkout_id = get_the_ID();
116
- if ( ! $checkout_id ) {
117
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
118
- }
119
-
120
- if ( ! empty( $checkout_id ) ) {
121
- $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
122
- if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
123
- $remove_label = apply_filters(
124
- 'woocommerce_cart_item_remove_link',
125
- sprintf(
126
- '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
127
- esc_attr( $cart_item['product_id'] ),
128
- $cart_item_key
129
- ),
130
- $cart_item_key
131
- );
132
-
133
- $product_name = $remove_label . $product_name;
134
- }
135
- }
136
-
137
- return $product_name;
138
-
139
- }
140
-
141
- /**
142
- * Change order button text .
143
- *
144
- * @param string $woo_button_text place order.
145
- * @return string
146
- */
147
- public function place_order_button_text( $woo_button_text ) {
148
-
149
- $checkout_id = get_the_ID();
150
- if ( ! $checkout_id ) {
151
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
152
- }
153
-
154
- $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
155
-
156
- if ( ! empty( $wcf_order_button_text ) ) {
157
- $woo_button_text = $wcf_order_button_text;
158
- }
159
-
160
- return $woo_button_text;
161
- }
162
-
163
- /**
164
- * Display all WooCommerce notices.
165
- *
166
- * @since 1.1.5
167
- */
168
- public function display_woo_notices() {
169
-
170
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
171
- woocommerce_output_all_notices();
172
- }
173
- }
174
-
175
-
176
- /**
177
- * Redirect from default to the global checkout page
178
- *
179
- * @since 1.0.0
180
- */
181
- public function global_checkout_template_redirect() {
182
-
183
- if ( ! is_checkout() ) {
184
- return;
185
- }
186
-
187
- if ( wcf()->utils->is_step_post_type() ) {
188
- return;
189
- }
190
-
191
- // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
192
- if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
193
- return;
194
- }
195
-
196
- // redirect only for cartflows checkout pages.
197
- $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
198
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
199
-
200
- $common = Cartflows_Helper::get_common_settings();
201
-
202
- $global_checkout = $common['global_checkout'];
203
-
204
- if (
205
- isset( $_SERVER['REQUEST_URI'] ) &&
206
- // ignore on order-pay.
207
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
208
- // ignore on TY page.
209
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
210
- // ignore if order-pay in query param.
211
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
212
- ) {
213
-
214
- if ( '' !== $global_checkout ) {
215
-
216
- $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
217
-
218
- if ( ! empty( $link ) ) {
219
-
220
- wp_safe_redirect( $link );
221
- die();
222
- }
223
- }
224
- }
225
- }
226
-
227
- /**
228
- * Check for checkout flag
229
- *
230
- * @param bool $is_checkout is checkout.
231
- *
232
- * @return bool
233
- */
234
- public function woo_checkout_flag( $is_checkout ) {
235
-
236
- if ( ! is_admin() ) {
237
-
238
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
239
-
240
- $is_checkout = true;
241
- }
242
- }
243
-
244
- return $is_checkout;
245
- }
246
-
247
- /**
248
- * Render checkout shortcode markup.
249
- *
250
- * @param array $atts attributes.
251
- * @return string
252
- */
253
- public function checkout_shortcode_markup( $atts ) {
254
-
255
- if ( ! function_exists( 'wc_print_notices' ) ) {
256
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
257
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
258
-
259
- return $notice_out;
260
- }
261
-
262
- $atts = shortcode_atts(
263
- array(
264
- 'id' => 0,
265
- ),
266
- $atts
267
- );
268
-
269
- $checkout_id = intval( $atts['id'] );
270
-
271
- if ( empty( $checkout_id ) ) {
272
-
273
- if ( ! _is_wcf_checkout_type() ) {
274
-
275
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
276
- }
277
-
278
- global $post;
279
-
280
- $checkout_id = intval( $post->ID );
281
- }
282
-
283
- $output = '';
284
-
285
- ob_start();
286
-
287
- do_action( 'cartflows_checkout_form_before', $checkout_id );
288
-
289
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
290
-
291
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
292
-
293
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
294
-
295
- if ( file_exists( $template_layout ) ) {
296
- include $template_layout;
297
- } else {
298
- include $template_default;
299
- }
300
-
301
- $output .= ob_get_clean();
302
-
303
- return $output;
304
- }
305
-
306
- /**
307
- * Configure Cart Data.
308
- *
309
- * @since 1.0.0
310
- *
311
- * @return void
312
- */
313
- public function preconfigured_cart_data() {
314
-
315
- if ( is_admin() ) {
316
- return;
317
- }
318
-
319
- global $post;
320
-
321
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
322
-
323
- if ( wp_doing_ajax() ) {
324
- return;
325
- } else {
326
-
327
- if ( _is_wcf_checkout_type() ) {
328
- $checkout_id = $post->ID;
329
- } else {
330
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
331
- }
332
-
333
- $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
334
-
335
- if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
336
-
337
- if ( WC()->cart->is_empty() ) {
338
- wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
339
- }
340
-
341
- return;
342
- }
343
-
344
- if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
345
- return;
346
- }
347
-
348
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
349
-
350
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
351
-
352
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
353
- $products = 'dummy';
354
- } else {
355
- $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
356
- }
357
-
358
- if ( ! is_array( $products ) ) {
359
-
360
- if ( 'dummy' === $products ) {
361
-
362
- $args = array(
363
- 'posts_per_page' => 1,
364
- 'orderby' => 'rand',
365
- 'post_type' => 'product',
366
- 'meta_query' => array( //phpcs:ignore
367
- // Exclude out of stock products.
368
- array(
369
- 'key' => '_stock_status',
370
- 'value' => 'outofstock',
371
- 'compare' => 'NOT IN',
372
- ),
373
- ),
374
- 'tax_query' => array( //phpcs:ignore
375
- array(
376
- 'taxonomy' => 'product_type',
377
- 'field' => 'slug',
378
- 'terms' => 'simple',
379
- ),
380
- ),
381
- );
382
-
383
- $random_product = get_posts( $args );
384
-
385
- if ( isset( $random_product[0]->ID ) ) {
386
- $products = array(
387
- array(
388
- 'product' => $random_product[0]->ID,
389
- 'add_to_cart' => true,
390
- ),
391
- );
392
- } else {
393
- return;
394
- }
395
- } else {
396
- return;
397
- }
398
- }
399
-
400
- /* Empty the current cart */
401
- WC()->cart->empty_cart();
402
-
403
- if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
404
- wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
405
- return;
406
- }
407
-
408
- /* Set customer session if not set */
409
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
410
- WC()->session->set_customer_session_cookie( true );
411
- }
412
-
413
- $cart_product_count = 0;
414
- $cart_key = '';
415
- $products_new = array();
416
-
417
- $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
418
-
419
- foreach ( $products as $index => $data ) {
420
-
421
- if ( ! isset( $data['product'] ) ) {
422
- continue;
423
- }
424
-
425
- if ( empty( $data['add_to_cart'] ) ) {
426
- continue;
427
- }
428
-
429
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
430
- break;
431
- }
432
-
433
- $product_id = $data['product'];
434
- $_product = wc_get_product( $product_id );
435
-
436
- if ( ! empty( $_product ) ) {
437
-
438
- $quantity = 1;
439
-
440
- if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
441
- $quantity = $data['quantity'];
442
- }
443
-
444
- $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
445
- $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
446
- $_product_price = $_product->get_price( $data['product'] );
447
-
448
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
449
-
450
- $cart_item_data = array();
451
-
452
- if ( ! empty( $custom_price ) ) {
453
-
454
- $cart_item_data = array(
455
- 'custom_price' => $custom_price,
456
- );
457
- }
458
-
459
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
460
-
461
- if ( $_product->is_type( 'variable' ) ) {
462
-
463
- $default_attributes = $_product->get_default_attributes();
464
-
465
- if ( ! empty( $default_attributes ) ) {
466
-
467
- foreach ( $_product->get_children() as $variation_id ) {
468
-
469
- $single_variation = new WC_Product_Variation( $variation_id );
470
-
471
- if ( $default_attributes == $single_variation->get_attributes() ) {
472
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
473
- $cart_product_count++;
474
- }
475
- }
476
- } else {
477
-
478
- $product_childrens = $_product->get_children();
479
-
480
- if ( isset( $product_childrens[0] ) ) {
481
- $variation = wc_get_product( $product_childrens[0] );
482
- $_product_price = $variation->get_price();
483
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
484
- if ( ! empty( $custom_price ) ) {
485
- $cart_item_data = array(
486
- 'custom_price' => $custom_price,
487
- 'data' => $data,
488
- );
489
- }
490
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
491
- $cart_product_count++;
492
- } else {
493
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
494
- }
495
- }
496
- } else {
497
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
498
- $cart_product_count++;
499
- }
500
- } else {
501
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
502
- wc_add_notice( $wrong_product_notice );
503
- /**
504
- WC()->cart->add_to_cart( $product_id, $quantity );.
505
- */
506
- }
507
- }
508
- $products_new[ $index ] = array(
509
- 'cart_item_key' => $cart_key,
510
- );
511
- }
512
-
513
- /* Set checkout products data */
514
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
515
-
516
- /* Since 1.2.2 */
517
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
518
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
519
- }
520
- }
521
- }
522
-
523
- /**
524
- * Load shortcode data.
525
- *
526
- * @return void
527
- */
528
- public function shortcode_load_data() {
529
-
530
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
531
-
532
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
533
-
534
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
535
-
536
- /* Show notices if cart has errors */
537
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
538
-
539
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
540
-
541
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
542
-
543
- // Outputting the hidden field in checkout page.
544
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
545
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
546
-
547
- remove_all_actions( 'woocommerce_checkout_billing' );
548
- remove_all_actions( 'woocommerce_checkout_shipping' );
549
-
550
- // Hook in actions once.
551
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
552
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
553
-
554
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
555
-
556
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
557
-
558
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
559
-
560
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
561
-
562
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
563
-
564
- global $post;
565
-
566
- if ( _is_wcf_checkout_type() ) {
567
- $checkout_id = $post->ID;
568
- } else {
569
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
570
- }
571
-
572
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
573
- }
574
- }
575
-
576
- /**
577
- * Render checkout ID hidden field.
578
- *
579
- * @param array $checkout checkout session data.
580
- * @return void
581
- */
582
- public function checkout_shortcode_post_id( $checkout ) {
583
-
584
- global $post;
585
-
586
- if ( _is_wcf_checkout_type() ) {
587
- $checkout_id = $post->ID;
588
- } else {
589
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
590
- }
591
-
592
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
593
-
594
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
595
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
596
- }
597
-
598
- /**
599
- * Load shortcode scripts.
600
- *
601
- * @return void
602
- */
603
- public function shortcode_scripts() {
604
-
605
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
606
-
607
- wp_enqueue_script(
608
- 'wcf-checkout-template',
609
- wcf()->utils->get_js_url( 'checkout-template' ),
610
- array( 'jquery' ),
611
- CARTFLOWS_VER,
612
- true
613
- );
614
-
615
- do_action( 'cartflows_checkout_scripts' );
616
-
617
- $style = $this->generate_style();
618
-
619
- wp_add_inline_style( 'wcf-checkout-template', $style );
620
-
621
- }
622
-
623
- /**
624
- * Load compatibility scripts.
625
- *
626
- * @return void
627
- */
628
- public function compatibility_scripts() {
629
-
630
- global $post;
631
-
632
- if ( _is_wcf_checkout_type() ) {
633
- $checkout_id = $post->ID;
634
- } else {
635
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
636
- }
637
-
638
- // Add DIVI Compatibility css if DIVI theme is enabled.
639
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
640
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
641
- ) {
642
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
643
- }
644
-
645
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
646
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
647
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
648
- }
649
-
650
- // Add The7 Compatibility css if The7 theme is enabled.
651
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
652
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
653
- }
654
- }
655
-
656
- /**
657
- * Generate styles.
658
- *
659
- * @return string
660
- */
661
- public function generate_style() {
662
-
663
- global $post;
664
-
665
- if ( _is_wcf_checkout_type() ) {
666
- $checkout_id = $post->ID;
667
- } else {
668
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
669
- }
670
-
671
- /*Output css variable */
672
- $output = '';
673
-
674
- CartFlows_Font_Families::render_fonts( $checkout_id );
675
-
676
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
677
-
678
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
679
-
680
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
681
-
682
- /**
683
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
684
- $r = '';
685
- $g = '';
686
- $b = '';
687
-
688
- $field_tb_padding = '';
689
- $field_lr_padding = '';
690
-
691
- $field_heading_color = '';
692
- $field_color = '';
693
- $field_bg_color = '';
694
- $field_border_color = '';
695
- $field_label_color = '';
696
- $submit_tb_padding = '';
697
- $submit_lr_padding = '';
698
- $hl_bg_color = '';
699
- $field_input_size = '';
700
- $box_border_color = '';
701
- $section_bg_color = '';
702
- $submit_button_height = '';
703
- $submit_color = '';
704
- $submit_bg_color = $primary_color;
705
- $submit_border_color = $primary_color;
706
-
707
- $submit_hover_color = '';
708
- $submit_bg_hover_color = $primary_color;
709
- $submit_border_hover_color = $primary_color;
710
-
711
- $section_heading_color = '';
712
-
713
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
714
-
715
- $button_font_family = '';
716
- $button_font_weight = '';
717
- $input_font_family = '';
718
- $input_font_weight = '';
719
- $heading_font_family = '';
720
- $heading_font_weight = '';
721
- $base_font_family = $base_font_family;
722
- /**
723
- $base_font_weight = $base_font_weight;*/
724
-
725
- if ( 'yes' == $is_advance_option ) {
726
-
727
- /**
728
- * Get Font Family and Font Weight weight values
729
- */
730
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
731
-
732
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
733
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
734
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
735
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
736
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
737
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
738
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
739
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
740
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
741
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
742
-
743
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
744
-
745
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
746
-
747
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
748
-
749
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
750
-
751
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
752
-
753
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
754
-
755
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
756
-
757
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
758
-
759
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
760
-
761
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
762
-
763
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
764
-
765
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
766
-
767
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
768
-
769
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
770
-
771
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
772
-
773
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
774
-
775
- /**
776
- * Get font values
777
- */
778
-
779
- if ( 'custom' == $submit_button_height ) {
780
- $submit_button_height = '38px';
781
- }
782
-
783
- if ( 'custom' == $field_input_size ) {
784
- $field_input_size = '38px';
785
- }
786
- }
787
- if ( isset( $primary_color ) ) {
788
-
789
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
790
- }
791
-
792
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
793
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
794
-
795
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
796
-
797
- } else {
798
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
799
- }
800
-
801
- return $output;
802
- }
803
-
804
- /**
805
- * Get ajax end points.
806
- *
807
- * @param string $endpoint_url end point URL.
808
- * @param string $request end point request.
809
- * @return string
810
- */
811
- public function get_ajax_endpoint( $endpoint_url, $request ) {
812
-
813
- global $post;
814
-
815
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
816
-
817
- if ( _is_wcf_checkout_type() ) {
818
-
819
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
820
-
821
- if ( '' === $request ) {
822
- $query_args = array(
823
- 'wc-ajax' => '%%endpoint%%',
824
- );
825
- } else {
826
- $query_args = array(
827
- 'wc-ajax' => $request,
828
- );
829
- }
830
-
831
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
832
- $uri = $uri[0];
833
-
834
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
835
- }
836
- }
837
- }
838
-
839
- return $endpoint_url;
840
- }
841
-
842
-
843
- /**
844
- * Save checkout fields.
845
- *
846
- * @param int $order_id order id.
847
- * @param array $posted posted data.
848
- * @return void
849
- */
850
- public function save_checkout_fields( $order_id, $posted ) {
851
-
852
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
853
-
854
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
855
-
856
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
857
-
858
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
859
-
860
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
861
-
862
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
863
- }
864
- }
865
-
866
- }
867
-
868
- /**
869
- * Enable Logo In Header Of Checkout Page
870
- *
871
- * @return void
872
- */
873
- public function enable_logo_in_header() {
874
- global $post;
875
-
876
- if ( _is_wcf_checkout_type() ) {
877
- $checkout_id = $post->ID;
878
- } else {
879
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
880
- }
881
-
882
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
883
- $add_image_markup = '';
884
-
885
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
886
- $add_image_markup = '<div class="wcf-checkout-header-image">';
887
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
888
- $add_image_markup .= '</div>';
889
- }
890
-
891
- echo $add_image_markup;
892
- }
893
-
894
- /**
895
- * Add text to the bootom of the checkout page.
896
- *
897
- * @return void
898
- */
899
- public function show_cartflows_copyright_message() {
900
- $output_string = '';
901
-
902
- $output_string .= '<div class="wcf-footer-primary">';
903
- $output_string .= '<div class="wcf-footer-content">';
904
- $output_string .= '<p class="wcf-footer-message">';
905
- $output_string .= 'Checkout powered by CartFlows';
906
- $output_string .= '</p>';
907
- $output_string .= '</div>';
908
- $output_string .= '</div>';
909
-
910
- echo $output_string;
911
- }
912
-
913
- /**
914
- * Redirect users to our checkout if hidden param
915
- *
916
- * @param string $redirect redirect url.
917
- * @param object $user user.
918
- * @return string
919
- */
920
- public function after_login_redirect( $redirect, $user ) {
921
-
922
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
923
-
924
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
925
-
926
- $redirect = get_permalink( $checkout_id );
927
- }
928
-
929
- return $redirect;
930
- }
931
-
932
- /**
933
- * Display coupon code field after review order fields.
934
- */
935
- public function display_custom_coupon_field() {
936
-
937
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
938
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
939
-
940
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
941
- return;
942
-
943
- }
944
-
945
- $coupon_field = array(
946
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
947
- 'button_text' => __( 'Apply', 'cartflows' ),
948
- 'class' => '',
949
- );
950
-
951
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
952
-
953
- ob_start();
954
- ?>
955
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
956
- <div class="wcf-coupon-col-1">
957
- <span>
958
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
959
- </span>
960
- </div>
961
- <div class="wcf-coupon-col-2">
962
- <span>
963
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
964
- </span>
965
- </div>
966
- </div>
967
- <?php
968
- echo ob_get_clean();
969
- }
970
-
971
- /**
972
- * Apply filter to change class of remove coupon field.
973
- *
974
- * @param string $coupon coupon.
975
- * @return string
976
- */
977
- public function remove_coupon_text( $coupon ) {
978
-
979
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
980
- return $coupon;
981
-
982
- }
983
- /**
984
- * Apply filter to change the placeholder text of coupon field.
985
- *
986
- * @return string
987
- */
988
- public function coupon_field_placeholder() {
989
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
990
- }
991
-
992
- /**
993
- * Apply filter to change the button text of coupon field.
994
- *
995
- * @return string
996
- */
997
- public function coupon_button_text() {
998
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
999
- }
1000
-
1001
- /**
1002
- * Apply coupon on submit of custom coupon form.
1003
- */
1004
- public function apply_coupon() {
1005
-
1006
- $response = '';
1007
-
1008
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1009
- if ( ! empty( $_POST['coupon_code'] ) ) {
1010
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1011
- } else {
1012
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1013
- }
1014
-
1015
- $response = array(
1016
- 'status' => $result,
1017
- 'msg' => wc_print_notices( true ),
1018
- );
1019
-
1020
- echo wp_json_encode( $response );
1021
-
1022
- die();
1023
- }
1024
-
1025
-
1026
- /**
1027
- * Added ajax nonce to localize variable.
1028
- *
1029
- * @param array $vars localize variables.
1030
- */
1031
- public function add_localize_vars( $vars ) {
1032
-
1033
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1034
-
1035
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1036
-
1037
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1038
-
1039
- $vars['allow_persistance'] = apply_filters( 'cartflows_allow_persistace', 'yes' );
1040
-
1041
- return $vars;
1042
- }
1043
-
1044
- /**
1045
- * Add custom class to the fields to change the UI to three column.
1046
- *
1047
- * @param array $fields fields.
1048
- */
1049
- public function add_three_column_layout_fields( $fields ) {
1050
-
1051
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
1052
-
1053
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1054
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1055
- }
1056
- }
1057
-
1058
- if ( ! empty( $fields['billing']['billing_company'] ) ) {
1059
-
1060
- if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1061
- $fields['billing']['billing_company']['class'][] = 'form-row-full';
1062
- }
1063
- }
1064
-
1065
- if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1066
-
1067
- if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1068
- $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1069
- }
1070
- }
1071
-
1072
- if ( ! empty( $fields['billing']['billing_country'] ) ) {
1073
-
1074
- if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1075
- $fields['billing']['billing_country']['class'][] = 'form-row-full';
1076
- }
1077
- }
1078
-
1079
- if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1080
-
1081
- if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1082
- $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1083
- }
1084
- }
1085
-
1086
- if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1087
-
1088
- if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1089
- $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1090
- }
1091
- }
1092
-
1093
- if ( ! empty( $fields['billing']['billing_email'] ) ) {
1094
-
1095
- if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1096
- $fields['billing']['billing_email']['class'][] = 'form-row-full';
1097
- }
1098
- }
1099
-
1100
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1101
-
1102
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1103
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1104
- }
1105
- }
1106
-
1107
- if ( isset( $fields['billing']['billing_city'] ) &&
1108
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1109
-
1110
- $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1111
- $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1112
- $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1113
- }
1114
-
1115
- if ( isset( $fields['shipping']['shipping_city'] ) &&
1116
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1117
-
1118
- $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1119
- $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1120
- $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1121
- }
1122
-
1123
- return $fields;
1124
- }
1125
-
1126
- /**
1127
- * Add opening dev
1128
- *
1129
- * @since 1.0.0
1130
- */
1131
- public function order_wrap_div_start() {
1132
-
1133
- echo "<div class='wcf-order-wrap'> ";
1134
- }
1135
-
1136
- /**
1137
- * Add closing dev
1138
- *
1139
- * @since 1.0.0
1140
- */
1141
- public function order_wrap_div_end() {
1142
-
1143
- echo '</div> ';
1144
- }
1145
- /**
1146
- * Remove coupon.
1147
- */
1148
- public function remove_coupon() {
1149
-
1150
- check_ajax_referer( 'wcf-remove-coupon', 'security' );
1151
- $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1152
-
1153
- if ( empty( $coupon ) ) {
1154
- echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1155
- } else {
1156
- WC()->cart->remove_coupon( $coupon );
1157
- echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1158
- }
1159
- wc_print_notices();
1160
- wp_die();
1161
- }
1162
-
1163
- /**
1164
- * Remove cart item.
1165
- */
1166
- public function wcf_woo_remove_cart_product() {
1167
-
1168
- check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1169
- $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1170
- $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1171
- $product_title = get_the_title( $product_id );
1172
-
1173
- $needs_shipping = false;
1174
-
1175
- if ( empty( $product_key ) ) {
1176
- $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1177
- } else {
1178
- WC()->cart->remove_cart_item( $product_key );
1179
- $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1180
- }
1181
-
1182
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1183
- if ( $values['data']->needs_shipping() ) {
1184
- $needs_shipping = true;
1185
- break;
1186
- }
1187
- }
1188
-
1189
- $response = array(
1190
- 'need_shipping' => $needs_shipping,
1191
- 'msg' => $msg,
1192
- );
1193
-
1194
- echo wp_json_encode( $response );
1195
- wp_die();
1196
- }
1197
-
1198
- /**
1199
- * Calculate discount for product.
1200
- *
1201
- * @param string $discount_coupon discount coupon.
1202
- * @param string $discount_type discount type.
1203
- * @param int $discount_value discount value.
1204
- * @param int $_product_price product price.
1205
- * @return int
1206
- * @since 1.1.5
1207
- */
1208
- public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1209
-
1210
- $custom_price = '';
1211
-
1212
- if ( ! empty( $discount_type ) ) {
1213
- if ( 'discount_percent' === $discount_type ) {
1214
-
1215
- if ( $discount_value > 0 ) {
1216
- $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1217
- }
1218
- } elseif ( 'discount_price' === $discount_type ) {
1219
-
1220
- if ( $discount_value > 0 ) {
1221
- $custom_price = $_product_price - $discount_value;
1222
- }
1223
- } elseif ( 'coupon' === $discount_type ) {
1224
-
1225
- if ( ! empty( $discount_coupon ) ) {
1226
- WC()->cart->add_discount( $discount_coupon );
1227
- }
1228
- }
1229
- }
1230
-
1231
- return $custom_price;
1232
- }
1233
-
1234
- /**
1235
- * Preserve the custom item price added by Variations & Quantity feature
1236
- *
1237
- * @param array $cart_object cart object.
1238
- * @since 1.0.0
1239
- */
1240
- public function custom_price_to_cart_item( $cart_object ) {
1241
-
1242
- if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1243
-
1244
- foreach ( $cart_object->cart_contents as $key => $value ) {
1245
-
1246
- if ( isset( $value['custom_price'] ) ) {
1247
-
1248
- $custom_price = floatval( $value['custom_price'] );
1249
- $value['data']->set_price( $custom_price );
1250
- }
1251
- }
1252
- }
1253
- }
1254
-
1255
- }
1256
-
1257
- /**
1258
- * Kicking this off by calling 'get_instance()' method
1259
- */
1260
- 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_persistance'] = apply_filters( 'cartflows_allow_persistace', 'yes' );
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/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/classes/class-cartflows-permalink.php CHANGED
@@ -1,158 +1,158 @@
1
- <?php
2
- /**
3
- * Step post type.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Permalink {
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_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
39
- add_action( 'init', array( $this, 'rewrite_step_rule' ) );
40
- add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ), 20 );
41
- }
42
-
43
- /**
44
- * Modify permalink
45
- *
46
- * @param string $post_link post link.
47
- * @param array $post post data.
48
- * @param string $leavename leave name.
49
- * @return string
50
- */
51
- public function post_type_permalinks( $post_link, $post, $leavename ) {
52
-
53
- if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
54
-
55
- $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
56
- $flow_name = get_post_field( 'post_name', $flow_id );
57
- $cf_permalink = Cartflows_Helper::get_permalink_settings();
58
-
59
- if ( isset( $cf_permalink['permalink_structure'] ) && ! empty( $cf_permalink['permalink_structure'] ) ) {
60
-
61
- $sep = '/';
62
- $search = array( $sep . 'cartflows_flow', $sep . '%flowname%', $sep . 'cartflows_step' );
63
- $replace = array( $sep . $cf_permalink['permalink_flow_base'], $sep . $flow_name, $sep . $cf_permalink['permalink'] );
64
- $post_link = str_replace( $search, $replace, $post_link );
65
- } else {
66
-
67
- // If elementor page preview, return post link as it is.
68
- if ( isset( $_REQUEST['elementor-preview'] ) ) { //phpcs:ignore
69
- return $post_link;
70
- }
71
-
72
- $structure = get_option( 'permalink_structure' );
73
-
74
- if ( '/%postname%/' === $structure ) {
75
-
76
- $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
77
-
78
- }
79
- }
80
- }
81
-
82
- return $post_link;
83
- }
84
-
85
- /**
86
- * Reqrite rules for acrtflows step.
87
- */
88
- public function rewrite_step_rule() {
89
-
90
- $cf_permalink = Cartflows_Helper::get_permalink_settings();
91
-
92
- if ( isset( $cf_permalink['permalink_structure'] ) ) {
93
- switch ( $cf_permalink['permalink_structure'] ) {
94
- case '/cartflows_flow/%flowname%/cartflows_step':
95
- add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
96
- break;
97
-
98
- case '/cartflows_flow/%flowname%':
99
- add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/([^/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
100
- break;
101
-
102
- case '/%flowname%/cartflows_step':
103
- add_rewrite_rule( '([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
104
-
105
- break;
106
-
107
- default:
108
- break;
109
- }
110
- }
111
-
112
- }
113
-
114
- /**
115
- * Have WordPress match postname to any of our public post types.
116
- * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
117
- * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
118
- *
119
- * @param string $query query statement.
120
- */
121
- public function add_cpt_post_names_to_main_query( $query ) {
122
-
123
- // Bail if this is not the main query.
124
- if ( ! $query->is_main_query() ) {
125
- return;
126
- }
127
-
128
- // Bail if this query doesn't match our very specific rewrite rule.
129
- if ( ! isset( $query->query['thrive-variations'] ) && ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
130
- return;
131
- }
132
-
133
- // Bail if we're not querying based on the post name.
134
- if ( empty( $query->query['name'] ) ) {
135
- return;
136
- }
137
-
138
- // Add cartflows step post type to existing post type array.
139
- if ( isset( $query->query_vars['post_type'] ) && is_array( $query->query_vars['post_type'] ) ) {
140
-
141
- $post_types = $query->query_vars['post_type'];
142
-
143
- $post_types[] = CARTFLOWS_STEP_POST_TYPE;
144
-
145
- $query->set( 'post_type', $post_types );
146
-
147
- } else {
148
-
149
- // Add CPT to the list of post types WP will include when it queries based on the post name.
150
- $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
151
- }
152
- }
153
- }
154
-
155
- /**
156
- * Kicking this off by calling 'get_instance()' method
157
- */
158
- Cartflows_Permalink::get_instance();
1
+ <?php
2
+ /**
3
+ * Step post type.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Permalink {
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_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
39
+ add_action( 'init', array( $this, 'rewrite_step_rule' ) );
40
+ add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ), 20 );
41
+ }
42
+
43
+ /**
44
+ * Modify permalink
45
+ *
46
+ * @param string $post_link post link.
47
+ * @param array $post post data.
48
+ * @param string $leavename leave name.
49
+ * @return string
50
+ */
51
+ public function post_type_permalinks( $post_link, $post, $leavename ) {
52
+
53
+ if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
54
+
55
+ $flow_id = get_post_meta( $post->ID, 'wcf-flow-id', true );
56
+ $flow_name = get_post_field( 'post_name', $flow_id );
57
+ $cf_permalink = Cartflows_Helper::get_permalink_settings();
58
+
59
+ if ( isset( $cf_permalink['permalink_structure'] ) && ! empty( $cf_permalink['permalink_structure'] ) ) {
60
+
61
+ $sep = '/';
62
+ $search = array( $sep . 'cartflows_flow', $sep . '%flowname%', $sep . 'cartflows_step' );
63
+ $replace = array( $sep . $cf_permalink['permalink_flow_base'], $sep . $flow_name, $sep . $cf_permalink['permalink'] );
64
+ $post_link = str_replace( $search, $replace, $post_link );
65
+ } else {
66
+
67
+ // If elementor page preview, return post link as it is.
68
+ if ( isset( $_REQUEST['elementor-preview'] ) ) { //phpcs:ignore
69
+ return $post_link;
70
+ }
71
+
72
+ $structure = get_option( 'permalink_structure' );
73
+
74
+ if ( '/%postname%/' === $structure ) {
75
+
76
+ $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
77
+
78
+ }
79
+ }
80
+ }
81
+
82
+ return $post_link;
83
+ }
84
+
85
+ /**
86
+ * Reqrite rules for acrtflows step.
87
+ */
88
+ public function rewrite_step_rule() {
89
+
90
+ $cf_permalink = Cartflows_Helper::get_permalink_settings();
91
+
92
+ if ( isset( $cf_permalink['permalink_structure'] ) ) {
93
+ switch ( $cf_permalink['permalink_structure'] ) {
94
+ case '/cartflows_flow/%flowname%/cartflows_step':
95
+ add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
96
+ break;
97
+
98
+ case '/cartflows_flow/%flowname%':
99
+ add_rewrite_rule( '^' . $cf_permalink['permalink_flow_base'] . '/([^/]*)/([^/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
100
+ break;
101
+
102
+ case '/%flowname%/cartflows_step':
103
+ add_rewrite_rule( '([^/]*)/' . $cf_permalink['permalink'] . '/([^\/]*)/?', 'index.php?cartflows_step=$matches[2]', 'top' );
104
+
105
+ break;
106
+
107
+ default:
108
+ break;
109
+ }
110
+ }
111
+
112
+ }
113
+
114
+ /**
115
+ * Have WordPress match postname to any of our public post types.
116
+ * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
117
+ * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
118
+ *
119
+ * @param string $query query statement.
120
+ */
121
+ public function add_cpt_post_names_to_main_query( $query ) {
122
+
123
+ // Bail if this is not the main query.
124
+ if ( ! $query->is_main_query() ) {
125
+ return;
126
+ }
127
+
128
+ // Bail if this query doesn't match our very specific rewrite rule.
129
+ if ( ! isset( $query->query['thrive-variations'] ) && ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
130
+ return;
131
+ }
132
+
133
+ // Bail if we're not querying based on the post name.
134
+ if ( empty( $query->query['name'] ) ) {
135
+ return;
136
+ }
137
+
138
+ // Add cartflows step post type to existing post type array.
139
+ if ( isset( $query->query_vars['post_type'] ) && is_array( $query->query_vars['post_type'] ) ) {
140
+
141
+ $post_types = $query->query_vars['post_type'];
142
+
143
+ $post_types[] = CARTFLOWS_STEP_POST_TYPE;
144
+
145
+ $query->set( 'post_type', $post_types );
146
+
147
+ } else {
148
+
149
+ // Add CPT to the list of post types WP will include when it queries based on the post name.
150
+ $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
151
+ }
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Kicking this off by calling 'get_instance()' method
157
+ */
158
+ Cartflows_Permalink::get_instance();
modules/flow/classes/class-cartflows-step-post-type.php CHANGED
@@ -1,496 +1,500 @@
1
- <?php
2
- /**
3
- * Step post type.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Step_Post_Type {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var body_classes
27
- */
28
- private $body_classes = array();
29
-
30
- /**
31
- * Initiator
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- */
43
- public function __construct() {
44
-
45
- add_action( 'init', array( $this, 'step_post_type' ) );
46
- add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
- add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
-
49
- add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
-
51
- add_filter( 'template_include', array( $this, 'load_page_template' ), 90 );
52
- add_filter( 'template_redirect', array( $this, 'query_fix' ), 3 );
53
-
54
- add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
55
- }
56
-
57
- /**
58
- * Trys to load page.php for a header, footer or part theme layout.
59
- *
60
- * @since 1.0.0
61
- * @param string $template The current template to be loaded.
62
- * @return string
63
- */
64
- public function load_page_template( $template ) {
65
-
66
- global $post;
67
-
68
- if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
69
-
70
- /**
71
- * Remove Next/Prev Navigation
72
- * add_filter('next_post_link', '__return_empty_string');
73
- * add_filter('previous_post_link', '__return_empty_string');
74
- *
75
- * $page = locate_template( array( 'page.php' ) );
76
- *
77
- * if ( ! empty( $page ) ) {
78
- * return $page;
79
- * }
80
- */
81
-
82
- /* Remove Next / Previous Rel Link */
83
- remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
84
- add_filter( 'next_post_rel_link', '__return_empty_string' );
85
- add_filter( 'previous_post_rel_link', '__return_empty_string' );
86
-
87
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
88
-
89
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
90
-
91
- $file = '';
92
-
93
- switch ( $page_template ) {
94
-
95
- case 'cartflows-default':
96
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
97
- $this->body_classes[] = $page_template;
98
- break;
99
- case 'cartflows-canvas':
100
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
101
- $this->body_classes[] = $page_template;
102
- break;
103
- default:
104
- /**
105
- * Remove Next/Prev Navigation
106
- */
107
- add_filter( 'next_post_link', '__return_empty_string' );
108
- add_filter( 'previous_post_link', '__return_empty_string' );
109
-
110
- $page = locate_template( array( 'page.php' ) );
111
-
112
- if ( ! empty( $page ) ) {
113
- $file = $page;
114
- }
115
-
116
- break;
117
-
118
- /**
119
- * Default:
120
- * $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
121
- * $this->body_classes[] = 'cartflows-default';
122
- * break;
123
- */
124
- }
125
-
126
- // Just to be safe, we check if the file exist first.
127
- if ( file_exists( $file ) ) {
128
-
129
- /* Add Body Class */
130
- add_filter( 'body_class', array( $this, 'body_class' ) );
131
-
132
- return $file;
133
- } else {
134
- echo $file;
135
- }
136
- }
137
-
138
- return $template;
139
- }
140
-
141
- /**
142
- * Body classes.
143
- *
144
- * @since 1.0.0
145
- * @param array $classes Body classes.
146
- * @return array
147
- */
148
- public function body_class( $classes = array() ) {
149
-
150
- $classes = array_merge( $classes, $this->body_classes );
151
-
152
- return $classes;
153
- }
154
-
155
- /**
156
- * Create custom post type
157
- */
158
- public function step_post_type() {
159
-
160
- $labels = array(
161
- 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
162
- 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
163
- 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
164
- 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
165
- 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
166
- 'view_item' => esc_html__( 'View Step', 'cartflows' ),
167
- 'add_new' => esc_html__( 'Add New', 'cartflows' ),
168
- 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
169
- 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
170
- 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
171
- );
172
-
173
- $permalink_settings = Cartflows_Helper::get_permalink_settings();
174
-
175
- $args = array(
176
- 'labels' => $labels,
177
- 'public' => true,
178
- 'query_var' => true,
179
- 'can_export' => true,
180
- 'exclude_from_search' => true,
181
- 'show_ui' => true,
182
- 'show_in_menu' => false,
183
- 'show_in_admin_bar' => true,
184
- 'show_in_rest' => true,
185
- 'supports' => array( 'title', 'editor', 'elementor', 'revisions' ),
186
- 'capability_type' => 'post',
187
- 'capabilities' => array(
188
- 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
189
- ),
190
- 'map_meta_cap' => true,
191
- );
192
-
193
- if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
194
- $args['rewrite'] = array(
195
- 'slug' => $permalink_settings['permalink_structure'],
196
- 'with_front' => false,
197
- );
198
-
199
- } elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {
200
-
201
- $args['rewrite'] = array(
202
- 'slug' => $permalink_settings['permalink'],
203
- 'with_front' => false,
204
- );
205
- }
206
-
207
- register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
208
-
209
- // Step Type.
210
- $args = array(
211
- 'label' => __( 'Step Type', 'cartflows' ),
212
- 'public' => false,
213
- 'rewrite' => false,
214
- 'hierarchical' => false,
215
- );
216
-
217
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
218
-
219
- // Step Flow.
220
- $args = array(
221
- 'label' => __( 'Step Flow', 'cartflows' ),
222
- 'public' => false,
223
- 'rewrite' => false,
224
- 'hierarchical' => false,
225
- );
226
-
227
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
228
-
229
- if ( is_admin() ) {
230
- /**
231
- * Register 'Elementor' & 'Beaver Builder' site types.
232
- *
233
- * @see self::add_terms();
234
- */
235
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
236
-
237
- $terms = array(
238
- array(
239
- 'name' => __( 'Landing', 'cartflows' ),
240
- 'slug' => 'landing',
241
- 'args' => array(
242
- 'slug' => 'landing',
243
- ),
244
- ),
245
- array(
246
- 'name' => __( 'Optin (Woo)', 'cartflows' ),
247
- 'slug' => 'optin',
248
- 'args' => array(
249
- 'slug' => 'optin',
250
- ),
251
- ),
252
- array(
253
- 'name' => __( 'Checkout (Woo)', 'cartflows' ),
254
- 'slug' => 'checkout',
255
- 'args' => array(
256
- 'slug' => 'checkout',
257
- ),
258
- ),
259
- array(
260
- 'name' => __( 'Thank You (Woo)', 'cartflows' ),
261
- 'slug' => 'thankyou',
262
- 'args' => array(
263
- 'slug' => 'thankyou',
264
- ),
265
- ),
266
- array(
267
- 'name' => __( 'Upsell (Woo)', 'cartflows' ),
268
- 'slug' => 'upsell',
269
- 'args' => array(
270
- 'slug' => 'upsell',
271
- ),
272
- ),
273
- array(
274
- 'name' => __( 'Downsell (Woo)', 'cartflows' ),
275
- 'slug' => 'downsell',
276
- 'args' => array(
277
- 'slug' => 'downsell',
278
- ),
279
- ),
280
- );
281
-
282
- $this->add_terms( $taxonomy, $terms );
283
-
284
- }
285
- }
286
-
287
- /**
288
- * Add WordPress templates.
289
- *
290
- * Adds Cartflows templates to steps
291
- *
292
- * @since 1.0.0
293
- * @access public
294
- */
295
- public function add_wp_templates_support() {
296
- add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
297
- }
298
-
299
- /**
300
- * Add page templates.
301
- *
302
- * @since 1.0.0
303
- * @access public
304
- *
305
- * @param array $page_templates Array of page templates.
306
- *
307
- * @param object $wp_theme wp theme.
308
- * @param object $post post.
309
- *
310
- * @return array Page templates.
311
- */
312
- public function add_page_templates( $page_templates, $wp_theme, $post ) {
313
-
314
- $page_templates = array(
315
- 'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
316
- 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
317
- );
318
-
319
- return $page_templates;
320
- }
321
-
322
- /**
323
- * Query fixe throwing error on 404 page due our post type changes.
324
- * We are setting post_type as empty array to fix the issue.
325
- * Ther error was throwing due to redirect_canonical function
326
- * This fix is apply for 404 page only
327
- */
328
- public function query_fix() {
329
-
330
- global $wp_query;
331
-
332
- if ( $wp_query->is_404() ) {
333
- $wp_query->set( 'post_type', array() );
334
- }
335
- }
336
-
337
- /**
338
- * Prevent slug duplicated
339
- *
340
- * @param string $slug post slug.
341
- * @param int $post_ID post id.
342
- * @param string $post_status post status.
343
- * @param string $post_type post type.
344
- * @param int $post_parent post parent id.
345
- * @param string $original_slug original slug.
346
- * @return string
347
- */
348
- public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
349
-
350
- $check_post_types = array(
351
- 'post',
352
- 'page',
353
- CARTFLOWS_STEP_POST_TYPE,
354
- );
355
-
356
- if ( ! in_array( $post_type, $check_post_types, true ) ) {
357
- return $slug;
358
- }
359
-
360
- if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
361
- // Saving a post, check for duplicates in POST or PAGE post types.
362
- $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
363
- $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
364
-
365
- if ( $post_match || $page_match ) {
366
- $slug .= '-2';
367
- }
368
- } else {
369
-
370
- // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
371
- $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
372
-
373
- if ( $custom_post_type_match ) {
374
- $slug .= '-2';
375
- }
376
- }
377
-
378
- return $slug;
379
- }
380
-
381
- /**
382
- * Add Update messages for any custom post type
383
- *
384
- * @param array $messages Array of default messages.
385
- */
386
- public function post_update_messages( $messages ) {
387
-
388
- $custom_post_type = get_post_type( get_the_ID() );
389
-
390
- if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
391
-
392
- $obj = get_post_type_object( $custom_post_type );
393
- $singular_name = $obj->labels->singular_name;
394
- $messages[ $custom_post_type ] = array(
395
- 0 => '', // Unused. Messages start at index 1.
396
- /* translators: %s: singular custom post type name */
397
- 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
398
- /* translators: %s: singular custom post type name */
399
- 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
400
- /* translators: %s: singular custom post type name */
401
- 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
402
- /* translators: %s: singular custom post type name */
403
- 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
404
- /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
405
- 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
406
- /* translators: %s: singular custom post type name */
407
- 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
408
- /* translators: %s: singular custom post type name */
409
- 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
410
- /* translators: %s: singular custom post type name */
411
- 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
412
- /* translators: %s: singular custom post type name */
413
- 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
414
- /* translators: %s: singular custom post type name */
415
- 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
416
- );
417
- }
418
-
419
- return $messages;
420
- }
421
-
422
- /**
423
- * Add Terms for Taxonomy.
424
- *
425
- * => Example.
426
- *
427
- * $taxonomy = '{taxonomy}';
428
- * $terms = array(
429
- * array(
430
- * 'name' => 'Landing',
431
- * 'slug' => 'landing',
432
- * ),
433
- * array(
434
- * 'name' => 'Checkout',
435
- * 'slug' => 'checkout',
436
- * ),
437
- * );
438
- *
439
- * self::add_terms( $taxonomy, $terms );
440
- *
441
- * @since 1.0.0
442
- * @param string $taxonomy Taxonomy Name.
443
- * @param array $terms Terms list.
444
- * @return void
445
- */
446
- public function add_terms( $taxonomy = '', $terms = array() ) {
447
-
448
- foreach ( $terms as $key => $term ) {
449
-
450
- $term_exist = term_exists( $term['slug'], $taxonomy );
451
-
452
- if ( empty( $term_exist ) ) {
453
-
454
- /**
455
- * Add additional args if passed from request.
456
- *
457
- * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
458
- */
459
- if ( array_key_exists( 'args', $term ) ) {
460
- wp_insert_term( $term['name'], $taxonomy, $term['args'] );
461
- } else {
462
-
463
- $term['args'] = array( $term['slug'] );
464
-
465
- wp_insert_term( $term['name'], $taxonomy, $term['args'] );
466
- }
467
- }
468
- }
469
- }
470
-
471
- /**
472
- * Redirect admin pages.
473
- *
474
- * @return void
475
- */
476
- public function disallowed_admin_all_steps_view() {
477
-
478
- global $pagenow;
479
-
480
- // Check current admin page. If step post type view redirect it to flow.
481
- if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore
482
-
483
- if ( isset( $_GET['debug'] ) && $_GET['debug'] ) { //phpcs:ignore
484
- return;
485
- }
486
-
487
- wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
488
- exit;
489
- }
490
- }
491
- }
492
-
493
- /**
494
- * Kicking this off by calling 'get_instance()' method
495
- */
496
- Cartflows_Step_Post_Type::get_instance();
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Step post type.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Step_Post_Type {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var body_classes
27
+ */
28
+ private $body_classes = array();
29
+
30
+ /**
31
+ * Initiator
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+
45
+ add_action( 'init', array( $this, 'step_post_type' ) );
46
+ add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
+ add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
+
49
+ add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
+
51
+ add_filter( 'template_include', array( $this, 'load_page_template' ), 90 );
52
+ add_filter( 'template_redirect', array( $this, 'query_fix' ), 3 );
53
+
54
+ add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
55
+ }
56
+
57
+ /**
58
+ * Trys to load page.php for a header, footer or part theme layout.
59
+ *
60
+ * @since 1.0.0
61
+ * @param string $template The current template to be loaded.
62
+ * @return string
63
+ */
64
+ public function load_page_template( $template ) {
65
+
66
+ global $post;
67
+
68
+ if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
69
+
70
+ /**
71
+ * Remove Next/Prev Navigation
72
+ * add_filter('next_post_link', '__return_empty_string');
73
+ * add_filter('previous_post_link', '__return_empty_string');
74
+ *
75
+ * $page = locate_template( array( 'page.php' ) );
76
+ *
77
+ * if ( ! empty( $page ) ) {
78
+ * return $page;
79
+ * }
80
+ */
81
+
82
+ /* Remove Next / Previous Rel Link */
83
+ remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
84
+ add_filter( 'next_post_rel_link', '__return_empty_string' );
85
+ add_filter( 'previous_post_rel_link', '__return_empty_string' );
86
+
87
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
88
+
89
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
90
+
91
+ $file = '';
92
+
93
+ switch ( $page_template ) {
94
+
95
+ case 'cartflows-default':
96
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
97
+ $this->body_classes[] = $page_template;
98
+ break;
99
+ case 'cartflows-canvas':
100
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
101
+ $this->body_classes[] = $page_template;
102
+ break;
103
+ default:
104
+ /**
105
+ * Remove Next/Prev Navigation
106
+ */
107
+ add_filter( 'next_post_link', '__return_empty_string' );
108
+ add_filter( 'previous_post_link', '__return_empty_string' );
109
+
110
+ $page = locate_template( array( 'page.php' ) );
111
+
112
+ if ( ! empty( $page ) ) {
113
+ $file = $page;
114
+ }
115
+
116
+ break;
117
+
118
+ /**
119
+ * Default:
120
+ * $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
121
+ * $this->body_classes[] = 'cartflows-default';
122
+ * break;
123
+ */
124
+ }
125
+
126
+ // Just to be safe, we check if the file exist first.
127
+ if ( file_exists( $file ) ) {
128
+
129
+ /* Add Body Class */
130
+ add_filter( 'body_class', array( $this, 'body_class' ) );
131
+
132
+ return $file;
133
+ } else {
134
+ echo $file;
135
+ }
136
+ }
137
+
138
+ return $template;
139
+ }
140
+
141
+ /**
142
+ * Body classes.
143
+ *
144
+ * @since 1.0.0
145
+ * @param array $classes Body classes.
146
+ * @return array
147
+ */
148
+ public function body_class( $classes = array() ) {
149
+
150
+ $classes = array_merge( $classes, $this->body_classes );
151
+
152
+ return $classes;
153
+ }
154
+
155
+ /**
156
+ * Create custom post type
157
+ */
158
+ public function step_post_type() {
159
+
160
+ $labels = array(
161
+ 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
162
+ 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
163
+ 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
164
+ 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
165
+ 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
166
+ 'view_item' => esc_html__( 'View Step', 'cartflows' ),
167
+ 'add_new' => esc_html__( 'Add New', 'cartflows' ),
168
+ 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
169
+ 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
170
+ 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
171
+ );
172
+
173
+ $permalink_settings = Cartflows_Helper::get_permalink_settings();
174
+
175
+ $args = array(
176
+ 'labels' => $labels,
177
+ 'public' => true,
178
+ 'query_var' => true,
179
+ 'can_export' => true,
180
+ 'exclude_from_search' => true,
181
+ 'show_ui' => true,
182
+ 'show_in_menu' => false,
183
+ 'show_in_admin_bar' => true,
184
+ 'show_in_rest' => true,
185
+ 'supports' => array( 'title', 'editor', 'elementor', 'revisions' ),
186
+ 'capability_type' => 'post',
187
+ 'capabilities' => array(
188
+ 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
189
+ ),
190
+ 'map_meta_cap' => true,
191
+ );
192
+
193
+ if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
194
+ $args['rewrite'] = array(
195
+ 'slug' => $permalink_settings['permalink_structure'],
196
+ 'with_front' => false,
197
+ );
198
+
199
+ } elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {
200
+
201
+ $args['rewrite'] = array(
202
+ 'slug' => $permalink_settings['permalink'],
203
+ 'with_front' => false,
204
+ );
205
+ }
206
+
207
+ register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
208
+
209
+ // Step Type.
210
+ $args = array(
211
+ 'label' => __( 'Step Type', 'cartflows' ),
212
+ 'public' => false,
213
+ 'rewrite' => false,
214
+ 'hierarchical' => false,
215
+ );
216
+
217
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
218
+
219
+ // Step Flow.
220
+ $args = array(
221
+ 'label' => __( 'Step Flow', 'cartflows' ),
222
+ 'public' => false,
223
+ 'rewrite' => false,
224
+ 'hierarchical' => false,
225
+ );
226
+
227
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
228
+
229
+ if ( is_admin() ) {
230
+ /**
231
+ * Register 'Elementor' & 'Beaver Builder' site types.
232
+ *
233
+ * @see self::add_terms();
234
+ */
235
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
236
+
237
+ $terms = array(
238
+ array(
239
+ 'name' => __( 'Landing', 'cartflows' ),
240
+ 'slug' => 'landing',
241
+ 'args' => array(
242
+ 'slug' => 'landing',
243
+ ),
244
+ ),
245
+ array(
246
+ 'name' => __( 'Optin (Woo)', 'cartflows' ),
247
+ 'slug' => 'optin',
248
+ 'args' => array(
249
+ 'slug' => 'optin',
250
+ ),
251
+ ),
252
+ array(
253
+ 'name' => __( 'Checkout (Woo)', 'cartflows' ),
254
+ 'slug' => 'checkout',
255
+ 'args' => array(
256
+ 'slug' => 'checkout',
257
+ ),
258
+ ),
259
+ array(
260
+ 'name' => __( 'Thank You (Woo)', 'cartflows' ),
261
+ 'slug' => 'thankyou',
262
+ 'args' => array(
263
+ 'slug' => 'thankyou',
264
+ ),
265
+ ),
266
+ array(
267
+ 'name' => __( 'Upsell (Woo)', 'cartflows' ),
268
+ 'slug' => 'upsell',
269
+ 'args' => array(
270
+ 'slug' => 'upsell',
271
+ ),
272
+ ),
273
+ array(
274
+ 'name' => __( 'Downsell (Woo)', 'cartflows' ),
275
+ 'slug' => 'downsell',
276
+ 'args' => array(
277
+ 'slug' => 'downsell',
278
+ ),
279
+ ),
280
+ );
281
+
282
+ $this->add_terms( $taxonomy, $terms );
283
+
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Add WordPress templates.
289
+ *
290
+ * Adds Cartflows templates to steps
291
+ *
292
+ * @since 1.0.0
293
+ * @access public
294
+ */
295
+ public function add_wp_templates_support() {
296
+ add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
297
+ }
298
+
299
+ /**
300
+ * Add page templates.
301
+ *
302
+ * @since 1.0.0
303
+ * @access public
304
+ *
305
+ * @param array $page_templates Array of page templates.
306
+ *
307
+ * @param object $wp_theme wp theme.
308
+ * @param object $post post.
309
+ *
310
+ * @return array Page templates.
311
+ */
312
+ public function add_page_templates( $page_templates, $wp_theme, $post ) {
313
+
314
+ $cartflows_templates = array(
315
+ 'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
316
+ 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
317
+ );
318
+
319
+ if ( apply_filters( 'cartflows_show_all_page_templates', false ) ) {
320
+ $cartflows_templates = array_merge( $cartflows_templates, $page_templates );
321
+ }
322
+
323
+ return $cartflows_templates;
324
+ }
325
+
326
+ /**
327
+ * Query fixe throwing error on 404 page due our post type changes.
328
+ * We are setting post_type as empty array to fix the issue.
329
+ * Ther error was throwing due to redirect_canonical function
330
+ * This fix is apply for 404 page only
331
+ */
332
+ public function query_fix() {
333
+
334
+ global $wp_query;
335
+
336
+ if ( $wp_query->is_404() ) {
337
+ $wp_query->set( 'post_type', array() );
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Prevent slug duplicated
343
+ *
344
+ * @param string $slug post slug.
345
+ * @param int $post_ID post id.
346
+ * @param string $post_status post status.
347
+ * @param string $post_type post type.
348
+ * @param int $post_parent post parent id.
349
+ * @param string $original_slug original slug.
350
+ * @return string
351
+ */
352
+ public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
353
+
354
+ $check_post_types = array(
355
+ 'post',
356
+ 'page',
357
+ CARTFLOWS_STEP_POST_TYPE,
358
+ );
359
+
360
+ if ( ! in_array( $post_type, $check_post_types, true ) ) {
361
+ return $slug;
362
+ }
363
+
364
+ if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
365
+ // Saving a post, check for duplicates in POST or PAGE post types.
366
+ $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
367
+ $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
368
+
369
+ if ( $post_match || $page_match ) {
370
+ $slug .= '-2';
371
+ }
372
+ } else {
373
+
374
+ // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
375
+ $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
376
+
377
+ if ( $custom_post_type_match ) {
378
+ $slug .= '-2';
379
+ }
380
+ }
381
+
382
+ return $slug;
383
+ }
384
+
385
+ /**
386
+ * Add Update messages for any custom post type
387
+ *
388
+ * @param array $messages Array of default messages.
389
+ */
390
+ public function post_update_messages( $messages ) {
391
+
392
+ $custom_post_type = get_post_type( get_the_ID() );
393
+
394
+ if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
395
+
396
+ $obj = get_post_type_object( $custom_post_type );
397
+ $singular_name = $obj->labels->singular_name;
398
+ $messages[ $custom_post_type ] = array(
399
+ 0 => '', // Unused. Messages start at index 1.
400
+ /* translators: %s: singular custom post type name */
401
+ 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
402
+ /* translators: %s: singular custom post type name */
403
+ 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
404
+ /* translators: %s: singular custom post type name */
405
+ 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
406
+ /* translators: %s: singular custom post type name */
407
+ 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
408
+ /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
409
+ 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
410
+ /* translators: %s: singular custom post type name */
411
+ 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
412
+ /* translators: %s: singular custom post type name */
413
+ 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
414
+ /* translators: %s: singular custom post type name */
415
+ 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
416
+ /* translators: %s: singular custom post type name */
417
+ 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
418
+ /* translators: %s: singular custom post type name */
419
+ 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
420
+ );
421
+ }
422
+
423
+ return $messages;
424
+ }
425
+
426
+ /**
427
+ * Add Terms for Taxonomy.
428
+ *
429
+ * => Example.
430
+ *
431
+ * $taxonomy = '{taxonomy}';
432
+ * $terms = array(
433
+ * array(
434
+ * 'name' => 'Landing',
435
+ * 'slug' => 'landing',
436
+ * ),
437
+ * array(
438
+ * 'name' => 'Checkout',
439
+ * 'slug' => 'checkout',
440
+ * ),
441
+ * );
442
+ *
443
+ * self::add_terms( $taxonomy, $terms );
444
+ *
445
+ * @since 1.0.0
446
+ * @param string $taxonomy Taxonomy Name.
447
+ * @param array $terms Terms list.
448
+ * @return void
449
+ */
450
+ public function add_terms( $taxonomy = '', $terms = array() ) {
451
+
452
+ foreach ( $terms as $key => $term ) {
453
+
454
+ $term_exist = term_exists( $term['slug'], $taxonomy );
455
+
456
+ if ( empty( $term_exist ) ) {
457
+
458
+ /**
459
+ * Add additional args if passed from request.
460
+ *
461
+ * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
462
+ */
463
+ if ( array_key_exists( 'args', $term ) ) {
464
+ wp_insert_term( $term['name'], $taxonomy, $term['args'] );
465
+ } else {
466
+
467
+ $term['args'] = array( $term['slug'] );
468
+
469
+ wp_insert_term( $term['name'], $taxonomy, $term['args'] );
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Redirect admin pages.
477
+ *
478
+ * @return void
479
+ */
480
+ public function disallowed_admin_all_steps_view() {
481
+
482
+ global $pagenow;
483
+
484
+ // Check current admin page. If step post type view redirect it to flow.
485
+ if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore
486
+
487
+ if ( isset( $_GET['debug'] ) && $_GET['debug'] ) { //phpcs:ignore
488
+ return;
489
+ }
490
+
491
+ wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
492
+ exit;
493
+ }
494
+ }
495
+ }
496
+
497
+ /**
498
+ * Kicking this off by calling 'get_instance()' method
499
+ */
500
+ Cartflows_Step_Post_Type::get_instance();
modules/optin/classes/class-cartflows-optin-meta.php CHANGED
@@ -1,672 +1,673 @@
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
- )
243
- );
244
-
245
- ?>
246
- </div>
247
- <?php
248
- }
249
-
250
- /**
251
- * Tab custom fields
252
- *
253
- * @param array $options options.
254
- * @param int $post_id post ID.
255
- */
256
- public function tab_custom_fields( $options, $post_id ) {
257
- ?>
258
- <div class="wcf-optin-custom-fields wcf-tab-content widefat">
259
- <?php
260
- /* Custom Checkout Fields Section */
261
-
262
- if ( ! _is_cartflows_pro() ) {
263
- echo wcf()->meta->get_description_field(
264
- array(
265
- 'name' => 'wcf-upgrade-to-pro',
266
- /* translators: %s: link */
267
- '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>',
268
- )
269
- );
270
- }
271
- ?>
272
- <?php do_action( 'cartflows_optin_custom_fields_tab_content', $options, $post_id ); ?>
273
- </div>
274
- <?php
275
- }
276
-
277
- /**
278
- * Tab custom settings
279
- *
280
- * @param array $options options.
281
- * @param int $post_id post ID.
282
- */
283
- public function tab_custom_settings( $options, $post_id ) {
284
- ?>
285
- <div class="wcf-optin-custom-settings wcf-tab-content widefat">
286
- <div class="wcf-custom-settings-fields">
287
- <?php
288
- echo wcf()->meta->get_checkbox_field(
289
- array(
290
- 'label' => __( 'Pass Fields as URL Parameters', 'cartflows' ),
291
- 'name' => 'wcf-optin-pass-fields',
292
- 'value' => $options['wcf-optin-pass-fields'],
293
- 'after' => __( 'Enable', 'cartflows' ),
294
- 'help' => __( 'You can pass specific fields from the form to next step as URL query parameters.', 'cartflows' ),
295
- 'toggle' => array(
296
- 'fields' => array(
297
- 'yes' => array( 'wcf-optin-pass-specific-fields' ),
298
- ),
299
- ),
300
- )
301
- );
302
-
303
- echo wcf()->meta->get_text_field(
304
- array(
305
- 'label' => __( 'Enter form field', 'cartflows' ),
306
- 'name' => 'wcf-optin-pass-specific-fields',
307
- 'value' => $options['wcf-optin-pass-specific-fields'],
308
- 'help' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
309
- 'attr' => array(
310
- 'placeholder' => __( 'Fields to pass, separated by commas', 'cartflows' ),
311
- ),
312
- )
313
- );
314
-
315
- echo wcf()->meta->get_description_field(
316
- array(
317
- 'name' => 'wcf-optin-pass-fields-doc',
318
- 'content' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
319
- /* translators: %s: link */
320
- '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>' ),
321
- )
322
- );
323
-
324
- ?>
325
- </div>
326
- </div>
327
- <?php
328
- }
329
-
330
- /**
331
- * Tab style
332
- *
333
- * @param array $options options.
334
- * @param int $post_id post ID.
335
- */
336
- public function tab_style( $options, $post_id ) {
337
- ?>
338
-
339
- <div class="wcf-optin-style wcf-tab-content widefat">
340
- <?php
341
- echo wcf()->meta->get_color_picker_field(
342
- array(
343
- 'label' => __( 'Primary Color', 'cartflows' ),
344
- 'name' => 'wcf-primary-color',
345
- 'value' => $options['wcf-primary-color'],
346
- )
347
- );
348
-
349
- echo wcf()->meta->get_font_family_field(
350
- array(
351
- 'for' => 'wcf-base',
352
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
353
- 'name' => 'wcf-base-font-family',
354
- 'value' => $options['wcf-base-font-family'],
355
- )
356
- );
357
- ?>
358
- <div class="wcf-cs-fields">
359
- <div class="wcf-cs-fields-options">
360
- <?php
361
- echo wcf()->meta->get_section(
362
- array(
363
- 'label' => __( 'Input Fields', 'cartflows' ),
364
- )
365
- );
366
-
367
- $fields_skin_pro_option = array();
368
- if ( ! _is_cartflows_pro() ) {
369
- $fields_skin_pro_option = array(
370
- 'floating-labels' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
371
- );
372
- }
373
-
374
- echo wcf()->meta->get_select_field(
375
- array(
376
- 'label' => __( 'Style', 'cartflows' ),
377
- 'name' => 'wcf-input-fields-skins',
378
- 'value' => $options['wcf-input-fields-skins'],
379
- 'options' => array(
380
- 'default' => esc_html__( 'Default', 'cartflows' ),
381
- 'floating-labels' => esc_html__( 'Floating Labels', 'cartflows' ),
382
- ),
383
- 'pro-options' => $fields_skin_pro_option,
384
-
385
- )
386
- );
387
-
388
- echo wcf()->meta->get_font_family_field(
389
- array(
390
- 'for' => 'wcf-input',
391
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
392
- 'name' => 'wcf-input-font-family',
393
- 'value' => $options['wcf-input-font-family'],
394
- )
395
- );
396
-
397
- echo wcf()->meta->get_font_weight_field(
398
- array(
399
- 'for' => 'wcf-input',
400
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
401
- 'name' => 'wcf-input-font-weight',
402
- 'value' => $options['wcf-input-font-weight'],
403
- )
404
- );
405
-
406
- echo wcf()->meta->get_select_field(
407
- array(
408
- 'label' => __( 'Size', 'cartflows' ),
409
- 'name' => 'wcf-input-field-size',
410
- 'value' => $options['wcf-input-field-size'],
411
- 'options' => array(
412
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
413
- '38px' => esc_html__( 'Small', 'cartflows' ),
414
- '44px' => esc_html__( 'Medium', 'cartflows' ),
415
- '58px' => esc_html__( 'Large', 'cartflows' ),
416
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
417
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
418
- ),
419
- )
420
- );
421
-
422
- echo wcf()->meta->get_number_field(
423
- array(
424
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
425
- 'name' => 'wcf-field-tb-padding',
426
- 'value' => $options['wcf-field-tb-padding'],
427
- )
428
- );
429
-
430
- echo wcf()->meta->get_number_field(
431
- array(
432
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
433
- 'name' => 'wcf-field-lr-padding',
434
- 'value' => $options['wcf-field-lr-padding'],
435
- )
436
- );
437
-
438
- echo wcf()->meta->get_color_picker_field(
439
- array(
440
- 'label' => __( 'Label Color', 'cartflows' ),
441
- 'name' => 'wcf-field-label-color',
442
- 'value' => $options['wcf-field-label-color'],
443
- )
444
- );
445
-
446
- echo wcf()->meta->get_color_picker_field(
447
- array(
448
- 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
449
- 'name' => 'wcf-field-color',
450
- 'value' => $options['wcf-field-color'],
451
- )
452
- );
453
-
454
- echo wcf()->meta->get_color_picker_field(
455
- array(
456
- 'label' => __( 'Background Color', 'cartflows' ),
457
- 'name' => 'wcf-field-bg-color',
458
- 'value' => $options['wcf-field-bg-color'],
459
- )
460
- );
461
-
462
- echo wcf()->meta->get_color_picker_field(
463
- array(
464
- 'label' => __( 'Border Color', 'cartflows' ),
465
- 'name' => 'wcf-field-border-color',
466
- 'value' => $options['wcf-field-border-color'],
467
- )
468
- );
469
-
470
- ?>
471
- </div>
472
- <div class="wcf-cs-button-options">
473
- <?php
474
-
475
- echo wcf()->meta->get_section(
476
- array(
477
- 'label' => __( 'Submit Button', 'cartflows' ),
478
- )
479
- );
480
-
481
- echo wcf()->meta->get_text_field(
482
- array(
483
- 'label' => __( 'Button Text', 'cartflows' ),
484
- 'name' => 'wcf-submit-button-text',
485
- 'value' => $options['wcf-submit-button-text'],
486
- 'attr' => array(
487
- 'placeholder' => __( 'Submit', 'cartflows' ),
488
- ),
489
- )
490
- );
491
-
492
- echo wcf()->meta->get_number_field(
493
- array(
494
- 'label' => __( 'Font Size', 'cartflows' ),
495
- 'name' => 'wcf-submit-font-size',
496
- 'value' => $options['wcf-submit-font-size'],
497
- )
498
- );
499
-
500
- echo wcf()->meta->get_font_family_field(
501
- array(
502
- 'for' => 'wcf-button',
503
- 'label' => esc_html__( 'Font Family', 'cartflows' ),
504
- 'name' => 'wcf-button-font-family',
505
- 'value' => $options['wcf-button-font-family'],
506
- )
507
- );
508
-
509
- echo wcf()->meta->get_font_weight_field(
510
- array(
511
- 'for' => 'wcf-button',
512
- 'label' => esc_html__( 'Font Weight', 'cartflows' ),
513
- 'name' => 'wcf-button-font-weight',
514
- 'value' => $options['wcf-button-font-weight'],
515
- )
516
- );
517
-
518
- echo wcf()->meta->get_select_field(
519
- array(
520
- 'label' => __( 'Size', 'cartflows' ),
521
- 'name' => 'wcf-submit-button-size',
522
- 'value' => $options['wcf-submit-button-size'],
523
- 'options' => array(
524
- '33px' => esc_html__( 'Extra Small', 'cartflows' ),
525
- '38px' => esc_html__( 'Small', 'cartflows' ),
526
- '44px' => esc_html__( 'Medium', 'cartflows' ),
527
- '58px' => esc_html__( 'Large', 'cartflows' ),
528
- '68px' => esc_html__( 'Extra Large', 'cartflows' ),
529
- 'custom' => esc_html__( 'Custom', 'cartflows' ),
530
- ),
531
- )
532
- );
533
-
534
- echo wcf()->meta->get_number_field(
535
- array(
536
- 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
537
- 'name' => 'wcf-submit-tb-padding',
538
- 'value' => $options['wcf-submit-tb-padding'],
539
- )
540
- );
541
-
542
- echo wcf()->meta->get_number_field(
543
- array(
544
- 'label' => __( 'Left Right Spacing', 'cartflows' ),
545
- 'name' => 'wcf-submit-lr-padding',
546
- 'value' => $options['wcf-submit-lr-padding'],
547
- )
548
- );
549
-
550
- echo wcf()->meta->get_select_field(
551
- array(
552
- 'label' => __( 'Position', 'cartflows' ),
553
- 'name' => 'wcf-submit-button-position',
554
- 'value' => $options['wcf-submit-button-position'],
555
- 'options' => array(
556
- 'left' => esc_html__( 'Left', 'cartflows' ),
557
- 'center' => esc_html__( 'Center', 'cartflows' ),
558
- 'right' => esc_html__( 'Right', 'cartflows' ),
559
- ),
560
- )
561
- );
562
-
563
- echo wcf()->meta->get_color_picker_field(
564
- array(
565
- 'label' => __( 'Text Color', 'cartflows' ),
566
- 'name' => 'wcf-submit-color',
567
- 'value' => $options['wcf-submit-color'],
568
- )
569
- );
570
-
571
- echo wcf()->meta->get_color_picker_field(
572
- array(
573
- 'label' => __( 'Text Hover Color', 'cartflows' ),
574
- 'name' => 'wcf-submit-hover-color',
575
- 'value' => $options['wcf-submit-hover-color'],
576
- )
577
- );
578
-
579
- echo wcf()->meta->get_color_picker_field(
580
- array(
581
- 'label' => __( 'Background Color', 'cartflows' ),
582
- 'name' => 'wcf-submit-bg-color',
583
- 'value' => $options['wcf-submit-bg-color'],
584
- )
585
- );
586
-
587
- echo wcf()->meta->get_color_picker_field(
588
- array(
589
- 'label' => __( 'Background Hover Color', 'cartflows' ),
590
- 'name' => 'wcf-submit-bg-hover-color',
591
- 'value' => $options['wcf-submit-bg-hover-color'],
592
- )
593
- );
594
-
595
- echo wcf()->meta->get_color_picker_field(
596
- array(
597
- 'label' => __( 'Border Color', 'cartflows' ),
598
- 'name' => 'wcf-submit-border-color',
599
- 'value' => $options['wcf-submit-border-color'],
600
- )
601
- );
602
-
603
- echo wcf()->meta->get_color_picker_field(
604
- array(
605
- 'label' => __( 'Border Hover Color', 'cartflows' ),
606
- 'name' => 'wcf-submit-border-hover-color',
607
- 'value' => $options['wcf-submit-border-hover-color'],
608
- )
609
- );
610
-
611
- ?>
612
- </div>
613
- </div>
614
- <?php
615
- echo wcf()->meta->get_hidden_field(
616
- array(
617
- 'name' => 'wcf-field-google-font-url',
618
- 'value' => $options['wcf-field-google-font-url'],
619
- )
620
- );
621
- ?>
622
- </div>
623
- <?php
624
- }
625
-
626
- /**
627
- * Get metabox options
628
- *
629
- * @param int $post_id post ID.
630
- */
631
- public static function get_meta_option( $post_id ) {
632
-
633
- if ( null === self::$meta_option ) {
634
-
635
- /**
636
- * Set metabox options
637
- *
638
- * @see http://php.net/manual/en/filter.filters.sanitize.php
639
- */
640
- self::$meta_option = wcf()->options->get_optin_fields( $post_id );
641
- }
642
-
643
- return self::$meta_option;
644
- }
645
-
646
- /**
647
- * Metabox Save
648
- *
649
- * @param number $post_id Post ID.
650
- * @return void
651
- */
652
- public function save_meta_box( $post_id ) {
653
-
654
- // Checks save status.
655
- $is_autosave = wp_is_post_autosave( $post_id );
656
- $is_revision = wp_is_post_revision( $post_id );
657
-
658
- $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;
659
-
660
- // Exits script depending on save status.
661
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
662
- return;
663
- }
664
-
665
- wcf()->options->save_optin_fields( $post_id );
666
- }
667
- }
668
-
669
- /**
670
- * Kicking this off by calling 'get_instance()' method
671
- */
672
- 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
+ 'excluded_product_types' => array( 'variation', 'variable', 'subscription', 'variable-subscription', 'grouped' ),
243
+ )
244
+ );
245
+
246
+ ?>
247
+ </div>
248
+ <?php
249
+ }
250
+
251
+ /**
252
+ * Tab custom fields
253
+ *
254
+ * @param array $options options.
255
+ * @param int $post_id post ID.
256
+ */
257
+ public function tab_custom_fields( $options, $post_id ) {
258
+ ?>
259
+ <div class="wcf-optin-custom-fields wcf-tab-content widefat">
260
+ <?php
261
+ /* Custom Checkout Fields Section */
262
+
263
+ if ( ! _is_cartflows_pro() ) {
264
+ echo wcf()->meta->get_description_field(
265
+ array(
266
+ 'name' => 'wcf-upgrade-to-pro',
267
+ /* translators: %s: link */
268
+ '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>',
269
+ )
270
+ );
271
+ }
272
+ ?>
273
+ <?php do_action( 'cartflows_optin_custom_fields_tab_content', $options, $post_id ); ?>
274
+ </div>
275
+ <?php
276
+ }
277
+
278
+ /**
279
+ * Tab custom settings
280
+ *
281
+ * @param array $options options.
282
+ * @param int $post_id post ID.
283
+ */
284
+ public function tab_custom_settings( $options, $post_id ) {
285
+ ?>
286
+ <div class="wcf-optin-custom-settings wcf-tab-content widefat">
287
+ <div class="wcf-custom-settings-fields">
288
+ <?php
289
+ echo wcf()->meta->get_checkbox_field(
290
+ array(
291
+ 'label' => __( 'Pass Fields as URL Parameters', 'cartflows' ),
292
+ 'name' => 'wcf-optin-pass-fields',
293
+ 'value' => $options['wcf-optin-pass-fields'],
294
+ 'after' => __( 'Enable', 'cartflows' ),
295
+ 'help' => __( 'You can pass specific fields from the form to next step as URL query parameters.', 'cartflows' ),
296
+ 'toggle' => array(
297
+ 'fields' => array(
298
+ 'yes' => array( 'wcf-optin-pass-specific-fields' ),
299
+ ),
300
+ ),
301
+ )
302
+ );
303
+
304
+ echo wcf()->meta->get_text_field(
305
+ array(
306
+ 'label' => __( 'Enter form field', 'cartflows' ),
307
+ 'name' => 'wcf-optin-pass-specific-fields',
308
+ 'value' => $options['wcf-optin-pass-specific-fields'],
309
+ 'help' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
310
+ 'attr' => array(
311
+ 'placeholder' => __( 'Fields to pass, separated by commas', 'cartflows' ),
312
+ ),
313
+ )
314
+ );
315
+
316
+ echo wcf()->meta->get_description_field(
317
+ array(
318
+ 'name' => 'wcf-optin-pass-fields-doc',
319
+ 'content' => __( 'Enter comma seprated field name. E.g. first_name, last_name', 'cartflows' ),
320
+ /* translators: %s: link */
321
+ '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>' ),
322
+ )
323
+ );
324
+
325
+ ?>
326
+ </div>
327
+ </div>
328
+ <?php
329
+ }
330
+
331
+ /**
332
+ * Tab style
333
+ *
334
+ * @param array $options options.
335
+ * @param int $post_id post ID.
336
+ */
337
+ public function tab_style( $options, $post_id ) {
338
+ ?>
339
+
340
+ <div class="wcf-optin-style wcf-tab-content widefat">
341
+ <?php
342
+ echo wcf()->meta->get_color_picker_field(
343
+ array(
344
+ 'label' => __( 'Primary Color', 'cartflows' ),
345
+ 'name' => 'wcf-primary-color',
346
+ 'value' => $options['wcf-primary-color'],
347
+ )
348
+ );
349
+
350
+ echo wcf()->meta->get_font_family_field(
351
+ array(
352
+ 'for' => 'wcf-base',
353
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
354
+ 'name' => 'wcf-base-font-family',
355
+ 'value' => $options['wcf-base-font-family'],
356
+ )
357
+ );
358
+ ?>
359
+ <div class="wcf-cs-fields">
360
+ <div class="wcf-cs-fields-options">
361
+ <?php
362
+ echo wcf()->meta->get_section(
363
+ array(
364
+ 'label' => __( 'Input Fields', 'cartflows' ),
365
+ )
366
+ );
367
+
368
+ $fields_skin_pro_option = array();
369
+ if ( ! _is_cartflows_pro() ) {
370
+ $fields_skin_pro_option = array(
371
+ 'floating-labels' => __( 'Floating Labels (Available in CartFlows Pro)', 'cartflows' ),
372
+ );
373
+ }
374
+
375
+ echo wcf()->meta->get_select_field(
376
+ array(
377
+ 'label' => __( 'Style', 'cartflows' ),
378
+ 'name' => 'wcf-input-fields-skins',
379
+ 'value' => $options['wcf-input-fields-skins'],
380
+ 'options' => array(
381
+ 'default' => esc_html__( 'Default', 'cartflows' ),
382
+ 'floating-labels' => esc_html__( 'Floating Labels', 'cartflows' ),
383
+ ),
384
+ 'pro-options' => $fields_skin_pro_option,
385
+
386
+ )
387
+ );
388
+
389
+ echo wcf()->meta->get_font_family_field(
390
+ array(
391
+ 'for' => 'wcf-input',
392
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
393
+ 'name' => 'wcf-input-font-family',
394
+ 'value' => $options['wcf-input-font-family'],
395
+ )
396
+ );
397
+
398
+ echo wcf()->meta->get_font_weight_field(
399
+ array(
400
+ 'for' => 'wcf-input',
401
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
402
+ 'name' => 'wcf-input-font-weight',
403
+ 'value' => $options['wcf-input-font-weight'],
404
+ )
405
+ );
406
+
407
+ echo wcf()->meta->get_select_field(
408
+ array(
409
+ 'label' => __( 'Size', 'cartflows' ),
410
+ 'name' => 'wcf-input-field-size',
411
+ 'value' => $options['wcf-input-field-size'],
412
+ 'options' => array(
413
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
414
+ '38px' => esc_html__( 'Small', 'cartflows' ),
415
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
416
+ '58px' => esc_html__( 'Large', 'cartflows' ),
417
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
418
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
419
+ ),
420
+ )
421
+ );
422
+
423
+ echo wcf()->meta->get_number_field(
424
+ array(
425
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
426
+ 'name' => 'wcf-field-tb-padding',
427
+ 'value' => $options['wcf-field-tb-padding'],
428
+ )
429
+ );
430
+
431
+ echo wcf()->meta->get_number_field(
432
+ array(
433
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
434
+ 'name' => 'wcf-field-lr-padding',
435
+ 'value' => $options['wcf-field-lr-padding'],
436
+ )
437
+ );
438
+
439
+ echo wcf()->meta->get_color_picker_field(
440
+ array(
441
+ 'label' => __( 'Label Color', 'cartflows' ),
442
+ 'name' => 'wcf-field-label-color',
443
+ 'value' => $options['wcf-field-label-color'],
444
+ )
445
+ );
446
+
447
+ echo wcf()->meta->get_color_picker_field(
448
+ array(
449
+ 'label' => __( 'Text / Placeholder Color', 'cartflows' ),
450
+ 'name' => 'wcf-field-color',
451
+ 'value' => $options['wcf-field-color'],
452
+ )
453
+ );
454
+
455
+ echo wcf()->meta->get_color_picker_field(
456
+ array(
457
+ 'label' => __( 'Background Color', 'cartflows' ),
458
+ 'name' => 'wcf-field-bg-color',
459
+ 'value' => $options['wcf-field-bg-color'],
460
+ )
461
+ );
462
+
463
+ echo wcf()->meta->get_color_picker_field(
464
+ array(
465
+ 'label' => __( 'Border Color', 'cartflows' ),
466
+ 'name' => 'wcf-field-border-color',
467
+ 'value' => $options['wcf-field-border-color'],
468
+ )
469
+ );
470
+
471
+ ?>
472
+ </div>
473
+ <div class="wcf-cs-button-options">
474
+ <?php
475
+
476
+ echo wcf()->meta->get_section(
477
+ array(
478
+ 'label' => __( 'Submit Button', 'cartflows' ),
479
+ )
480
+ );
481
+
482
+ echo wcf()->meta->get_text_field(
483
+ array(
484
+ 'label' => __( 'Button Text', 'cartflows' ),
485
+ 'name' => 'wcf-submit-button-text',
486
+ 'value' => $options['wcf-submit-button-text'],
487
+ 'attr' => array(
488
+ 'placeholder' => __( 'Submit', 'cartflows' ),
489
+ ),
490
+ )
491
+ );
492
+
493
+ echo wcf()->meta->get_number_field(
494
+ array(
495
+ 'label' => __( 'Font Size', 'cartflows' ),
496
+ 'name' => 'wcf-submit-font-size',
497
+ 'value' => $options['wcf-submit-font-size'],
498
+ )
499
+ );
500
+
501
+ echo wcf()->meta->get_font_family_field(
502
+ array(
503
+ 'for' => 'wcf-button',
504
+ 'label' => esc_html__( 'Font Family', 'cartflows' ),
505
+ 'name' => 'wcf-button-font-family',
506
+ 'value' => $options['wcf-button-font-family'],
507
+ )
508
+ );
509
+
510
+ echo wcf()->meta->get_font_weight_field(
511
+ array(
512
+ 'for' => 'wcf-button',
513
+ 'label' => esc_html__( 'Font Weight', 'cartflows' ),
514
+ 'name' => 'wcf-button-font-weight',
515
+ 'value' => $options['wcf-button-font-weight'],
516
+ )
517
+ );
518
+
519
+ echo wcf()->meta->get_select_field(
520
+ array(
521
+ 'label' => __( 'Size', 'cartflows' ),
522
+ 'name' => 'wcf-submit-button-size',
523
+ 'value' => $options['wcf-submit-button-size'],
524
+ 'options' => array(
525
+ '33px' => esc_html__( 'Extra Small', 'cartflows' ),
526
+ '38px' => esc_html__( 'Small', 'cartflows' ),
527
+ '44px' => esc_html__( 'Medium', 'cartflows' ),
528
+ '58px' => esc_html__( 'Large', 'cartflows' ),
529
+ '68px' => esc_html__( 'Extra Large', 'cartflows' ),
530
+ 'custom' => esc_html__( 'Custom', 'cartflows' ),
531
+ ),
532
+ )
533
+ );
534
+
535
+ echo wcf()->meta->get_number_field(
536
+ array(
537
+ 'label' => __( 'Top Bottom Spacing', 'cartflows' ),
538
+ 'name' => 'wcf-submit-tb-padding',
539
+ 'value' => $options['wcf-submit-tb-padding'],
540
+ )
541
+ );
542
+
543
+ echo wcf()->meta->get_number_field(
544
+ array(
545
+ 'label' => __( 'Left Right Spacing', 'cartflows' ),
546
+ 'name' => 'wcf-submit-lr-padding',
547
+ 'value' => $options['wcf-submit-lr-padding'],
548
+ )
549
+ );
550
+
551
+ echo wcf()->meta->get_select_field(
552
+ array(
553
+ 'label' => __( 'Position', 'cartflows' ),
554
+ 'name' => 'wcf-submit-button-position',
555
+ 'value' => $options['wcf-submit-button-position'],
556
+ 'options' => array(
557
+ 'left' => esc_html__( 'Left', 'cartflows' ),
558
+ 'center' => esc_html__( 'Center', 'cartflows' ),
559
+ 'right' => esc_html__( 'Right', 'cartflows' ),
560
+ ),
561
+ )
562
+ );
563
+
564
+ echo wcf()->meta->get_color_picker_field(
565
+ array(
566
+ 'label' => __( 'Text Color', 'cartflows' ),
567
+ 'name' => 'wcf-submit-color',
568
+ 'value' => $options['wcf-submit-color'],
569
+ )
570
+ );
571
+
572
+ echo wcf()->meta->get_color_picker_field(
573
+ array(
574
+ 'label' => __( 'Text Hover Color', 'cartflows' ),
575
+ 'name' => 'wcf-submit-hover-color',
576
+ 'value' => $options['wcf-submit-hover-color'],
577
+ )
578
+ );
579
+
580
+ echo wcf()->meta->get_color_picker_field(
581
+ array(
582
+ 'label' => __( 'Background Color', 'cartflows' ),
583
+ 'name' => 'wcf-submit-bg-color',
584
+ 'value' => $options['wcf-submit-bg-color'],
585
+ )
586
+ );
587
+
588
+ echo wcf()->meta->get_color_picker_field(
589
+ array(
590
+ 'label' => __( 'Background Hover Color', 'cartflows' ),
591
+ 'name' => 'wcf-submit-bg-hover-color',
592
+ 'value' => $options['wcf-submit-bg-hover-color'],
593
+ )
594
+ );
595
+
596
+ echo wcf()->meta->get_color_picker_field(
597
+ array(
598
+ 'label' => __( 'Border Color', 'cartflows' ),
599
+ 'name' => 'wcf-submit-border-color',
600
+ 'value' => $options['wcf-submit-border-color'],
601
+ )
602
+ );
603
+
604
+ echo wcf()->meta->get_color_picker_field(
605
+ array(
606
+ 'label' => __( 'Border Hover Color', 'cartflows' ),
607
+ 'name' => 'wcf-submit-border-hover-color',
608
+ 'value' => $options['wcf-submit-border-hover-color'],
609
+ )
610
+ );
611
+
612
+ ?>
613
+ </div>
614
+ </div>
615
+ <?php
616
+ echo wcf()->meta->get_hidden_field(
617
+ array(
618
+ 'name' => 'wcf-field-google-font-url',
619
+ 'value' => $options['wcf-field-google-font-url'],
620
+ )
621
+ );
622
+ ?>
623
+ </div>
624
+ <?php
625
+ }
626
+
627
+ /**
628
+ * Get metabox options
629
+ *
630
+ * @param int $post_id post ID.
631
+ */
632
+ public static function get_meta_option( $post_id ) {
633
+
634
+ if ( null === self::$meta_option ) {
635
+
636
+ /**
637
+ * Set metabox options
638
+ *
639
+ * @see http://php.net/manual/en/filter.filters.sanitize.php
640
+ */
641
+ self::$meta_option = wcf()->options->get_optin_fields( $post_id );
642
+ }
643
+
644
+ return self::$meta_option;
645
+ }
646
+
647
+ /**
648
+ * Metabox Save
649
+ *
650
+ * @param number $post_id Post ID.
651
+ * @return void
652
+ */
653
+ public function save_meta_box( $post_id ) {
654
+
655
+ // Checks save status.
656
+ $is_autosave = wp_is_post_autosave( $post_id );
657
+ $is_revision = wp_is_post_revision( $post_id );
658
+
659
+ $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;
660
+
661
+ // Exits script depending on save status.
662
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
663
+ return;
664
+ }
665
+
666
+ wcf()->options->save_optin_fields( $post_id );
667
+ }
668
+ }
669
+
670
+ /**
671
+ * Kicking this off by calling 'get_instance()' method
672
+ */
673
+ Cartflows_Optin_Meta::get_instance();
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.1
7
- Stable tag: 1.5.10
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -126,6 +126,11 @@ Glad you asked! Most normal users have less than 3 funnels on a single website,
126
  5. Easily edit anything with your page builder.
127
 
128
  == Changelog ==
 
 
 
 
 
129
 
130
  = Version 1.5.10 - Wednesday, 3rd June 2020 =
131
  * New: Gutenberg templates added.
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4.1
7
+ Stable tag: 1.5.11
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
126
  5. Easily edit anything with your page builder.
127
 
128
  == Changelog ==
129
+ = Version 1.5.11 - Tuesday, 16th June 2020 =
130
+ * New: Users can now share [non-personal usage data](https://store.brainstormforce.com/usage-tracking/?utm_source=wp_repo&utm_medium=changelog&utm_campaign=usage_tracking) to help us test and develop better products.
131
+ * Fix: CartFlows setup wizard.
132
+ * Fix: Showing notice 'Remove selected product from checkout' even there is no product selected in Global checkout.
133
+ * Fix: Redirected to the cart when the order canceled by a user for PayPal checkout gateway.
134
 
135
  = Version 1.5.10 - Wednesday, 3rd June 2020 =
136
  * New: Gutenberg templates added.