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

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

Code changes from version 1.5.11 to 1.5.12

admin/bsf-analytics/class-bsf-analytics-stats.php CHANGED
@@ -1,256 +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
- }
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 CHANGED
@@ -1,528 +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
- }
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
+ }
assets/css/frontend-rtl.css CHANGED
@@ -185,7 +185,9 @@ body.cartflows-default {
185
 
186
  /* Order Details - ThankYou page */
187
  .woocommerce-order ul.order_details::before,
188
- .woocommerce-order ul.order_details::after {
 
 
189
  content: ' ';
190
  display: table;
191
  }
@@ -225,13 +227,16 @@ body.cartflows-default {
225
  .woocommerce-order .woocommerce-customer-details,
226
  .woocommerce-order .woocommerce-order-details,
227
  .woocommerce-order .woocommerce-order-downloads,
228
- .woocommerce-order .woocommerce-bacs-bank-details {
 
229
  margin: 0 0 2em;
230
  -webkit-border-radius: 3px;
231
  border-radius: 3px;
 
232
  width: 100%;
233
  display: block;
234
  }
 
235
  .woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{
236
  padding: 0px;
237
  }
@@ -364,6 +369,12 @@ body.cartflows-default {
364
  margin: 0;
365
  }
366
 
 
 
 
 
 
 
367
  @media only screen and (max-width: 768px){
368
 
369
  .woocommerce-order .woocommerce-thankyou-order-received {
185
 
186
  /* Order Details - ThankYou page */
187
  .woocommerce-order ul.order_details::before,
188
+ .woocommerce-order ul.order_details::after,
189
+ .woocommerce-order-details.mollie-instructions::before,
190
+ .woocommerce-order-details.mollie-instructions::after {
191
  content: ' ';
192
  display: table;
193
  }
227
  .woocommerce-order .woocommerce-customer-details,
228
  .woocommerce-order .woocommerce-order-details,
229
  .woocommerce-order .woocommerce-order-downloads,
230
+ .woocommerce-order .woocommerce-bacs-bank-details,
231
+ .woocommerce-order-details.mollie-instructions {
232
  margin: 0 0 2em;
233
  -webkit-border-radius: 3px;
234
  border-radius: 3px;
235
+ border: none;
236
  width: 100%;
237
  display: block;
238
  }
239
+
240
  .woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{
241
  padding: 0px;
242
  }
369
  margin: 0;
370
  }
371
 
372
+ .woocommerce-order-details.mollie-instructions p{
373
+ margin: 0.5em 0em;
374
+ }
375
+
376
+
377
+
378
  @media only screen and (max-width: 768px){
379
 
380
  .woocommerce-order .woocommerce-thankyou-order-received {
assets/css/frontend.css CHANGED
@@ -185,7 +185,9 @@ body.cartflows-default {
185
 
186
  /* Order Details - ThankYou page */
187
  .woocommerce-order ul.order_details::before,
188
- .woocommerce-order ul.order_details::after {
 
 
189
  content: ' ';
190
  display: table;
191
  }
@@ -225,13 +227,16 @@ body.cartflows-default {
225
  .woocommerce-order .woocommerce-customer-details,
226
  .woocommerce-order .woocommerce-order-details,
227
  .woocommerce-order .woocommerce-order-downloads,
228
- .woocommerce-order .woocommerce-bacs-bank-details {
 
229
  margin: 0 0 2em;
230
  -webkit-border-radius: 3px;
231
  border-radius: 3px;
 
232
  width: 100%;
233
  display: block;
234
  }
 
235
  .woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{
236
  padding: 0px;
237
  }
@@ -364,6 +369,12 @@ body.cartflows-default {
364
  margin: 0;
365
  }
366
 
 
 
 
 
 
 
367
  @media only screen and (max-width: 768px){
368
 
369
  .woocommerce-order .woocommerce-thankyou-order-received {
185
 
186
  /* Order Details - ThankYou page */
187
  .woocommerce-order ul.order_details::before,
188
+ .woocommerce-order ul.order_details::after,
189
+ .woocommerce-order-details.mollie-instructions::before,
190
+ .woocommerce-order-details.mollie-instructions::after {
191
  content: ' ';
192
  display: table;
193
  }
227
  .woocommerce-order .woocommerce-customer-details,
228
  .woocommerce-order .woocommerce-order-details,
229
  .woocommerce-order .woocommerce-order-downloads,
230
+ .woocommerce-order .woocommerce-bacs-bank-details,
231
+ .woocommerce-order-details.mollie-instructions {
232
  margin: 0 0 2em;
233
  -webkit-border-radius: 3px;
234
  border-radius: 3px;
235
+ border: none;
236
  width: 100%;
237
  display: block;
238
  }
239
+
240
  .woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{
241
  padding: 0px;
242
  }
369
  margin: 0;
370
  }
371
 
372
+ .woocommerce-order-details.mollie-instructions p{
373
+ margin: 0.5em 0em;
374
+ }
375
+
376
+
377
+
378
  @media only screen and (max-width: 768px){
379
 
380
  .woocommerce-order .woocommerce-thankyou-order-received {
assets/js/rest-api.js CHANGED
@@ -154,13 +154,10 @@
154
  url : CartFlowsAPI._api_url + args.slug,
155
  args : args,
156
  callback : callback,
157
-
158
  author : 'brainstormforce',
159
  };
160
-
161
- // Set headers.
162
- data.headers = CartFlowsImportVars.headers;
163
-
164
  $.ajax( data )
165
  .done(function( items, status, XHR ) {
166
 
154
  url : CartFlowsAPI._api_url + args.slug,
155
  args : args,
156
  callback : callback,
157
+ headers : CartFlowsImportVars.headers,
158
  author : 'brainstormforce',
159
  };
160
+
 
 
 
161
  $.ajax( data )
162
  .done(function( items, status, XHR ) {
163
 
assets/min-css/frontend-rtl.min.css CHANGED
@@ -1 +1 @@
1
- @font-face{font-family:cartflows-icon;src:url(../fonts/cartflows-icon.eot?81m15v);src:url(../fonts/cartflows-icon.eot?81m15v#iefix) format('embedded-opentype'),url(../fonts/cartflows-icon.ttf?81m15v) format('truetype'),url(../fonts/cartflows-icon.woff?81m15v) format('woff'),url(../fonts/cartflows-icon.svg?81m15v#cartflows-icon) format('svg');font-weight:400;font-style:normal}.cartflows-icon{font-family:cartflows-icon!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.cartflows-icon-close:before{content:"\e602";font-family:cartflows-icon}.cartflows-icon-cross:before{content:"\e601"}.cartflows-icon-check:before{content:"\e600"}.cartflows-icon-arrow-thin-right:before{content:"\e901"}.alignleft{display:inline;float:right;margin-left:1.5em}.alignright{display:inline;float:left;margin-right:1.5em}.aligncenter{clear:both;display:block;margin-right:auto;margin-left:auto}.clear:after,.clear:before{content:"";display:table;table-layout:fixed}.clear:after{clear:both}.wcf-button{display:inline-block;padding:12px 24px;background:#ccc;text-decoration:none;margin:5px}body.cartflows-default{background-color:#f5f5f5}.cartflows-default .cartflows-container{max-width:1200px;width:100%;padding:0 20px;margin:60px auto}.cartflows-default .cartflows-primary{background-color:#fff;padding:70px;overflow:hidden;max-width:100%}@media (max-width:768px){.cartflows-default .cartflows-container{padding:0;margin:0}.cartflows-default .cartflows-primary{padding:20px 30px}}@media (max-width:544px){.cartflows-default .cartflows-primary{padding:20px 15px}}.wcf-preview-mode{background:#f16334;position:fixed;bottom:0;right:0;width:100%;height:2.6em;color:#fff;text-align:center;font-size:14px;line-height:2.6em;pointer-events:all;z-index:9999999}.wcf-preview-mode a{color:#fff}@media only screen and (max-width:768px){.wcf-preview-mode{font-size:13px;line-height:18px;padding:4px 10px;height:auto}}.wcf-footer-primary .wcf-footer-content p{margin:1.5em 0;text-align:center}.wcf-thankyou-wrap{padding:0;margin:0 auto;width:100%;max-width:55em;font-size:13px}.woocommerce-order ul.order_details::after,.woocommerce-order ul.order_details::before{content:' ';display:table}.woocommerce-order ul.order_details::after{clear:both}.woocommerce-order ul.order_details,.woocommerce-order ul.order_details li{list-style:none;line-height:1}.woocommerce-order ul.order_details li{display:inline-block;border-left:1px dashed #ccc;padding:.5em 0 .5em 1em;margin:.5em 0 .5em .5em;list-style-type:none}.woocommerce-order ul.order_details li:first-child{padding-right:0}.woocommerce-order ul.order_details li:last-child{border-left:0;padding-left:0}.woocommerce-order ul.order_details li strong{display:block;margin-top:.7em}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{margin:0 0 2em;-webkit-border-radius:3px;border-radius:3px;width:100%;display:block}.woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{padding:0}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{background:#f1f1f1;padding:1.5em 2.5em}.woocommerce-order .woocommerce-order-downloads__title,.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.wc-bacs-bank-details-heading,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.8em 0;margin:0 0 .5em;font-size:1.5em;font-weight:600;color:#404040}.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1.5em;padding:0 .5em;text-align:center}.woocommerce-order-details table.shop_table,.woocommerce-order-downloads table.shop_table{border:none;border-bottom:0;background-color:inherit;-webkit-border-radius:0;border-radius:0;font-family:inherit;font-weight:inherit;font-size:.95em;margin:0!important;border-collapse:collapse;text-align:right}.woocommerce-order-details table.shop_table #shipping_method{margin:0;padding:0;list-style:none}.woocommerce-order-details table.shop_table th,.woocommerce-order-downloads table.shop_table th{border:none;font-weight:600;padding:9px 0;line-height:1.2em}.woocommerce-order-details table.shop_table tfoot tr:last-child .woocommerce-Price-amount{font-size:1em}.woocommerce-order-details table.shop_table td,.woocommerce-order-details table.shop_table th{padding:.6em 0;line-height:1.4em;border:none}.woocommerce-order-details table.shop_table tbody th,.woocommerce-order-details table.shop_table tfoot td,.woocommerce-order-details table.shop_table tfoot th{font-weight:400;border:none}.woocommerce-order-details table.shop_table tbody{border-top:1px dashed #ccc;border-bottom:1px dashed #ccc}.woocommerce-order-details table.shop_table th.product-name,.woocommerce-order-details table.shop_table th.product-total{font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) td,.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) th{font-weight:600;border-top:1px dashed #ccc}.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{padding-top:1.8em;font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.recurring-total td,.woocommerce-order-details table.shop_table tfoot tr.recurring-total th,.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{vertical-align:top}.woocommerce-order .wcf-col2-set{-js-display:flex;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.woocommerce-order .wcf-col2-set .wcf-col-1{margin-left:2%}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:49%;display:inline-block}.woocommerce-order .woocommerce-customer-details address{border-left-width:1px;border-bottom-width:1px;-webkit-border-radius:0;border-radius:0;font-style:normal}.woocommerce-order .woocommerce-customer-details address p{margin:0}@media only screen and (max-width:768px){.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1em}.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.5em 0;font-size:1.5em}.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order ul.order_details{padding:1.5em 2em}.woocommerce-order .woocommerce-order-downloads{overflow-x:auto}.woocommerce-order-downloads table.shop_table td,.woocommerce-order-downloads table.shop_table th{padding:.5em .8em}.woocommerce-order ul.order_details li{display:block;width:100%;border-left:none;padding:.5em 0 1em 1em;border-bottom:1px dashed #ccc}.woocommerce-order ul.order_details li:last-child{border:none}.woocommerce-order .wcf-col2-set{display:block}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:100%;display:block}}
1
+ @font-face{font-family:cartflows-icon;src:url(../fonts/cartflows-icon.eot?81m15v);src:url(../fonts/cartflows-icon.eot?81m15v#iefix) format('embedded-opentype'),url(../fonts/cartflows-icon.ttf?81m15v) format('truetype'),url(../fonts/cartflows-icon.woff?81m15v) format('woff'),url(../fonts/cartflows-icon.svg?81m15v#cartflows-icon) format('svg');font-weight:400;font-style:normal}.cartflows-icon{font-family:cartflows-icon!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.cartflows-icon-close:before{content:"\e602";font-family:cartflows-icon}.cartflows-icon-cross:before{content:"\e601"}.cartflows-icon-check:before{content:"\e600"}.cartflows-icon-arrow-thin-right:before{content:"\e901"}.alignleft{display:inline;float:right;margin-left:1.5em}.alignright{display:inline;float:left;margin-right:1.5em}.aligncenter{clear:both;display:block;margin-right:auto;margin-left:auto}.clear:after,.clear:before{content:"";display:table;table-layout:fixed}.clear:after{clear:both}.wcf-button{display:inline-block;padding:12px 24px;background:#ccc;text-decoration:none;margin:5px}body.cartflows-default{background-color:#f5f5f5}.cartflows-default .cartflows-container{max-width:1200px;width:100%;padding:0 20px;margin:60px auto}.cartflows-default .cartflows-primary{background-color:#fff;padding:70px;overflow:hidden;max-width:100%}@media (max-width:768px){.cartflows-default .cartflows-container{padding:0;margin:0}.cartflows-default .cartflows-primary{padding:20px 30px}}@media (max-width:544px){.cartflows-default .cartflows-primary{padding:20px 15px}}.wcf-preview-mode{background:#f16334;position:fixed;bottom:0;right:0;width:100%;height:2.6em;color:#fff;text-align:center;font-size:14px;line-height:2.6em;pointer-events:all;z-index:9999999}.wcf-preview-mode a{color:#fff}@media only screen and (max-width:768px){.wcf-preview-mode{font-size:13px;line-height:18px;padding:4px 10px;height:auto}}.wcf-footer-primary .wcf-footer-content p{margin:1.5em 0;text-align:center}.wcf-thankyou-wrap{padding:0;margin:0 auto;width:100%;max-width:55em;font-size:13px}.woocommerce-order ul.order_details::after,.woocommerce-order ul.order_details::before,.woocommerce-order-details.mollie-instructions::after,.woocommerce-order-details.mollie-instructions::before{content:' ';display:table}.woocommerce-order ul.order_details::after{clear:both}.woocommerce-order ul.order_details,.woocommerce-order ul.order_details li{list-style:none;line-height:1}.woocommerce-order ul.order_details li{display:inline-block;border-left:1px dashed #ccc;padding:.5em 0 .5em 1em;margin:.5em 0 .5em .5em;list-style-type:none}.woocommerce-order ul.order_details li:first-child{padding-right:0}.woocommerce-order ul.order_details li:last-child{border-left:0;padding-left:0}.woocommerce-order ul.order_details li strong{display:block;margin-top:.7em}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details,.woocommerce-order-details.mollie-instructions{margin:0 0 2em;-webkit-border-radius:3px;border-radius:3px;border:none;width:100%;display:block}.woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{padding:0}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{background:#f1f1f1;padding:1.5em 2.5em}.woocommerce-order .woocommerce-order-downloads__title,.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.wc-bacs-bank-details-heading,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.8em 0;margin:0 0 .5em;font-size:1.5em;font-weight:600;color:#404040}.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1.5em;padding:0 .5em;text-align:center}.woocommerce-order-details table.shop_table,.woocommerce-order-downloads table.shop_table{border:none;border-bottom:0;background-color:inherit;-webkit-border-radius:0;border-radius:0;font-family:inherit;font-weight:inherit;font-size:.95em;margin:0!important;border-collapse:collapse;text-align:right}.woocommerce-order-details table.shop_table #shipping_method{margin:0;padding:0;list-style:none}.woocommerce-order-details table.shop_table th,.woocommerce-order-downloads table.shop_table th{border:none;font-weight:600;padding:9px 0;line-height:1.2em}.woocommerce-order-details table.shop_table tfoot tr:last-child .woocommerce-Price-amount{font-size:1em}.woocommerce-order-details table.shop_table td,.woocommerce-order-details table.shop_table th{padding:.6em 0;line-height:1.4em;border:none}.woocommerce-order-details table.shop_table tbody th,.woocommerce-order-details table.shop_table tfoot td,.woocommerce-order-details table.shop_table tfoot th{font-weight:400;border:none}.woocommerce-order-details table.shop_table tbody{border-top:1px dashed #ccc;border-bottom:1px dashed #ccc}.woocommerce-order-details table.shop_table th.product-name,.woocommerce-order-details table.shop_table th.product-total{font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) td,.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) th{font-weight:600;border-top:1px dashed #ccc}.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{padding-top:1.8em;font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.recurring-total td,.woocommerce-order-details table.shop_table tfoot tr.recurring-total th,.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{vertical-align:top}.woocommerce-order .wcf-col2-set{-js-display:flex;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.woocommerce-order .wcf-col2-set .wcf-col-1{margin-left:2%}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:49%;display:inline-block}.woocommerce-order .woocommerce-customer-details address{border-left-width:1px;border-bottom-width:1px;-webkit-border-radius:0;border-radius:0;font-style:normal}.woocommerce-order .woocommerce-customer-details address p{margin:0}.woocommerce-order-details.mollie-instructions p{margin:.5em 0}@media only screen and (max-width:768px){.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1em}.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.5em 0;font-size:1.5em}.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order ul.order_details{padding:1.5em 2em}.woocommerce-order .woocommerce-order-downloads{overflow-x:auto}.woocommerce-order-downloads table.shop_table td,.woocommerce-order-downloads table.shop_table th{padding:.5em .8em}.woocommerce-order ul.order_details li{display:block;width:100%;border-left:none;padding:.5em 0 1em 1em;border-bottom:1px dashed #ccc}.woocommerce-order ul.order_details li:last-child{border:none}.woocommerce-order .wcf-col2-set{display:block}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:100%;display:block}}
assets/min-css/frontend.min.css CHANGED
@@ -1 +1 @@
1
- @font-face{font-family:cartflows-icon;src:url(../fonts/cartflows-icon.eot?81m15v);src:url(../fonts/cartflows-icon.eot?81m15v#iefix) format('embedded-opentype'),url(../fonts/cartflows-icon.ttf?81m15v) format('truetype'),url(../fonts/cartflows-icon.woff?81m15v) format('woff'),url(../fonts/cartflows-icon.svg?81m15v#cartflows-icon) format('svg');font-weight:400;font-style:normal}.cartflows-icon{font-family:cartflows-icon!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.cartflows-icon-close:before{content:"\e602";font-family:cartflows-icon}.cartflows-icon-cross:before{content:"\e601"}.cartflows-icon-check:before{content:"\e600"}.cartflows-icon-arrow-thin-right:before{content:"\e901"}.alignleft{display:inline;float:left;margin-right:1.5em}.alignright{display:inline;float:right;margin-left:1.5em}.aligncenter{clear:both;display:block;margin-left:auto;margin-right:auto}.clear:after,.clear:before{content:"";display:table;table-layout:fixed}.clear:after{clear:both}.wcf-button{display:inline-block;padding:12px 24px;background:#ccc;text-decoration:none;margin:5px}body.cartflows-default{background-color:#f5f5f5}.cartflows-default .cartflows-container{max-width:1200px;width:100%;padding:0 20px;margin:60px auto}.cartflows-default .cartflows-primary{background-color:#fff;padding:70px;overflow:hidden;max-width:100%}@media (max-width:768px){.cartflows-default .cartflows-container{padding:0;margin:0}.cartflows-default .cartflows-primary{padding:20px 30px}}@media (max-width:544px){.cartflows-default .cartflows-primary{padding:20px 15px}}.wcf-preview-mode{background:#f16334;position:fixed;bottom:0;left:0;width:100%;height:2.6em;color:#fff;text-align:center;font-size:14px;line-height:2.6em;pointer-events:all;z-index:9999999}.wcf-preview-mode a{color:#fff}@media only screen and (max-width:768px){.wcf-preview-mode{font-size:13px;line-height:18px;padding:4px 10px;height:auto}}.wcf-footer-primary .wcf-footer-content p{margin:1.5em 0;text-align:center}.wcf-thankyou-wrap{padding:0;margin:0 auto;width:100%;max-width:55em;font-size:13px}.woocommerce-order ul.order_details::after,.woocommerce-order ul.order_details::before{content:' ';display:table}.woocommerce-order ul.order_details::after{clear:both}.woocommerce-order ul.order_details,.woocommerce-order ul.order_details li{list-style:none;line-height:1}.woocommerce-order ul.order_details li{display:inline-block;border-right:1px dashed #ccc;padding:.5em 1em .5em 0;margin:.5em .5em .5em 0;list-style-type:none}.woocommerce-order ul.order_details li:first-child{padding-left:0}.woocommerce-order ul.order_details li:last-child{border-right:0;padding-right:0}.woocommerce-order ul.order_details li strong{display:block;margin-top:.7em}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{margin:0 0 2em;-webkit-border-radius:3px;border-radius:3px;width:100%;display:block}.woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{padding:0}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{background:#f1f1f1;padding:1.5em 2.5em}.woocommerce-order .woocommerce-order-downloads__title,.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.wc-bacs-bank-details-heading,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.8em 0;margin:0 0 .5em;font-size:1.5em;font-weight:600;color:#404040}.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1.5em;padding:0 .5em;text-align:center}.woocommerce-order-details table.shop_table,.woocommerce-order-downloads table.shop_table{border:none;border-bottom:0;background-color:inherit;-webkit-border-radius:0;border-radius:0;font-family:inherit;font-weight:inherit;font-size:.95em;margin:0!important;border-collapse:collapse;text-align:left}.woocommerce-order-details table.shop_table #shipping_method{margin:0;padding:0;list-style:none}.woocommerce-order-details table.shop_table th,.woocommerce-order-downloads table.shop_table th{border:none;font-weight:600;padding:9px 0;line-height:1.2em}.woocommerce-order-details table.shop_table tfoot tr:last-child .woocommerce-Price-amount{font-size:1em}.woocommerce-order-details table.shop_table td,.woocommerce-order-details table.shop_table th{padding:.6em 0;line-height:1.4em;border:none}.woocommerce-order-details table.shop_table tbody th,.woocommerce-order-details table.shop_table tfoot td,.woocommerce-order-details table.shop_table tfoot th{font-weight:400;border:none}.woocommerce-order-details table.shop_table tbody{border-top:1px dashed #ccc;border-bottom:1px dashed #ccc}.woocommerce-order-details table.shop_table th.product-name,.woocommerce-order-details table.shop_table th.product-total{font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) td,.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) th{font-weight:600;border-top:1px dashed #ccc}.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{padding-top:1.8em;font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.recurring-total td,.woocommerce-order-details table.shop_table tfoot tr.recurring-total th,.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{vertical-align:top}.woocommerce-order .wcf-col2-set{-js-display:flex;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.woocommerce-order .wcf-col2-set .wcf-col-1{margin-right:2%}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:49%;display:inline-block}.woocommerce-order .woocommerce-customer-details address{border-right-width:1px;border-bottom-width:1px;-webkit-border-radius:0;border-radius:0;font-style:normal}.woocommerce-order .woocommerce-customer-details address p{margin:0}@media only screen and (max-width:768px){.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1em}.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.5em 0;font-size:1.5em}.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order ul.order_details{padding:1.5em 2em}.woocommerce-order .woocommerce-order-downloads{overflow-x:auto}.woocommerce-order-downloads table.shop_table td,.woocommerce-order-downloads table.shop_table th{padding:.5em .8em}.woocommerce-order ul.order_details li{display:block;width:100%;border-right:none;padding:.5em 1em 1em 0;border-bottom:1px dashed #ccc}.woocommerce-order ul.order_details li:last-child{border:none}.woocommerce-order .wcf-col2-set{display:block}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:100%;display:block}}
1
+ @font-face{font-family:cartflows-icon;src:url(../fonts/cartflows-icon.eot?81m15v);src:url(../fonts/cartflows-icon.eot?81m15v#iefix) format('embedded-opentype'),url(../fonts/cartflows-icon.ttf?81m15v) format('truetype'),url(../fonts/cartflows-icon.woff?81m15v) format('woff'),url(../fonts/cartflows-icon.svg?81m15v#cartflows-icon) format('svg');font-weight:400;font-style:normal}.cartflows-icon{font-family:cartflows-icon!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.cartflows-icon-close:before{content:"\e602";font-family:cartflows-icon}.cartflows-icon-cross:before{content:"\e601"}.cartflows-icon-check:before{content:"\e600"}.cartflows-icon-arrow-thin-right:before{content:"\e901"}.alignleft{display:inline;float:left;margin-right:1.5em}.alignright{display:inline;float:right;margin-left:1.5em}.aligncenter{clear:both;display:block;margin-left:auto;margin-right:auto}.clear:after,.clear:before{content:"";display:table;table-layout:fixed}.clear:after{clear:both}.wcf-button{display:inline-block;padding:12px 24px;background:#ccc;text-decoration:none;margin:5px}body.cartflows-default{background-color:#f5f5f5}.cartflows-default .cartflows-container{max-width:1200px;width:100%;padding:0 20px;margin:60px auto}.cartflows-default .cartflows-primary{background-color:#fff;padding:70px;overflow:hidden;max-width:100%}@media (max-width:768px){.cartflows-default .cartflows-container{padding:0;margin:0}.cartflows-default .cartflows-primary{padding:20px 30px}}@media (max-width:544px){.cartflows-default .cartflows-primary{padding:20px 15px}}.wcf-preview-mode{background:#f16334;position:fixed;bottom:0;left:0;width:100%;height:2.6em;color:#fff;text-align:center;font-size:14px;line-height:2.6em;pointer-events:all;z-index:9999999}.wcf-preview-mode a{color:#fff}@media only screen and (max-width:768px){.wcf-preview-mode{font-size:13px;line-height:18px;padding:4px 10px;height:auto}}.wcf-footer-primary .wcf-footer-content p{margin:1.5em 0;text-align:center}.wcf-thankyou-wrap{padding:0;margin:0 auto;width:100%;max-width:55em;font-size:13px}.woocommerce-order ul.order_details::after,.woocommerce-order ul.order_details::before,.woocommerce-order-details.mollie-instructions::after,.woocommerce-order-details.mollie-instructions::before{content:' ';display:table}.woocommerce-order ul.order_details::after{clear:both}.woocommerce-order ul.order_details,.woocommerce-order ul.order_details li{list-style:none;line-height:1}.woocommerce-order ul.order_details li{display:inline-block;border-right:1px dashed #ccc;padding:.5em 1em .5em 0;margin:.5em .5em .5em 0;list-style-type:none}.woocommerce-order ul.order_details li:first-child{padding-left:0}.woocommerce-order ul.order_details li:last-child{border-right:0;padding-right:0}.woocommerce-order ul.order_details li strong{display:block;margin-top:.7em}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details,.woocommerce-order-details.mollie-instructions{margin:0 0 2em;-webkit-border-radius:3px;border-radius:3px;border:none;width:100%;display:block}.woocommerce-order .woocommerce-bacs-bank-details ul.bacs_details{padding:0}.woocommerce-order .woocommerce-bacs-bank-details,.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order .woocommerce-order-downloads,.woocommerce-order ul.order_details{background:#f1f1f1;padding:1.5em 2.5em}.woocommerce-order .woocommerce-order-downloads__title,.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.wc-bacs-bank-details-heading,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.8em 0;margin:0 0 .5em;font-size:1.5em;font-weight:600;color:#404040}.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1.5em;padding:0 .5em;text-align:center}.woocommerce-order-details table.shop_table,.woocommerce-order-downloads table.shop_table{border:none;border-bottom:0;background-color:inherit;-webkit-border-radius:0;border-radius:0;font-family:inherit;font-weight:inherit;font-size:.95em;margin:0!important;border-collapse:collapse;text-align:left}.woocommerce-order-details table.shop_table #shipping_method{margin:0;padding:0;list-style:none}.woocommerce-order-details table.shop_table th,.woocommerce-order-downloads table.shop_table th{border:none;font-weight:600;padding:9px 0;line-height:1.2em}.woocommerce-order-details table.shop_table tfoot tr:last-child .woocommerce-Price-amount{font-size:1em}.woocommerce-order-details table.shop_table td,.woocommerce-order-details table.shop_table th{padding:.6em 0;line-height:1.4em;border:none}.woocommerce-order-details table.shop_table tbody th,.woocommerce-order-details table.shop_table tfoot td,.woocommerce-order-details table.shop_table tfoot th{font-weight:400;border:none}.woocommerce-order-details table.shop_table tbody{border-top:1px dashed #ccc;border-bottom:1px dashed #ccc}.woocommerce-order-details table.shop_table th.product-name,.woocommerce-order-details table.shop_table th.product-total{font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) td,.woocommerce-order-details table.shop_table tfoot tr.order-total:not(.recurring-total) th{font-weight:600;border-top:1px dashed #ccc}.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{padding-top:1.8em;font-weight:600}.woocommerce-order-details table.shop_table tfoot tr.recurring-total td,.woocommerce-order-details table.shop_table tfoot tr.recurring-total th,.woocommerce-order-details table.shop_table tfoot tr.recurring-totals th{vertical-align:top}.woocommerce-order .wcf-col2-set{-js-display:flex;display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex}.woocommerce-order .wcf-col2-set .wcf-col-1{margin-right:2%}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:49%;display:inline-block}.woocommerce-order .woocommerce-customer-details address{border-right-width:1px;border-bottom-width:1px;-webkit-border-radius:0;border-radius:0;font-style:normal}.woocommerce-order .woocommerce-customer-details address p{margin:0}.woocommerce-order-details.mollie-instructions p{margin:.5em 0}@media only screen and (max-width:768px){.woocommerce-order .woocommerce-thankyou-order-received{margin:0 0 1em}.woocommerce-order .woocommerce-thankyou-order-received,.woocommerce-order h2.woocommerce-column__title,.woocommerce-order h2.woocommerce-order-details__title{padding:.5em 0;font-size:1.5em}.woocommerce-order .woocommerce-customer-details,.woocommerce-order .woocommerce-order-details,.woocommerce-order ul.order_details{padding:1.5em 2em}.woocommerce-order .woocommerce-order-downloads{overflow-x:auto}.woocommerce-order-downloads table.shop_table td,.woocommerce-order-downloads table.shop_table th{padding:.5em .8em}.woocommerce-order ul.order_details li{display:block;width:100%;border-right:none;padding:.5em 1em 1em 0;border-bottom:1px dashed #ccc}.woocommerce-order ul.order_details li:last-child{border:none}.woocommerce-order .wcf-col2-set{display:block}.woocommerce-order .wcf-col2-set .wcf-col-1,.woocommerce-order .wcf-col2-set .wcf-col-2{width:100%;display:block}}
assets/min-js/rest-api.min.js CHANGED
@@ -1 +1 @@
1
- !function(i){var n={timeout:3e5,data:{},remove:function(e){delete n.data[e]},exist:function(e){return!!n.data[e]&&(new Date).getTime()-n.data[e]._<n.timeout},get:function(e){return n.data[e].data},set:function(e,t,r){n.remove(e),n.data[e]={_:(new Date).getTime(),data:t},r&&"function"==typeof r&&r(t)}};i.ajaxPrefilter(function(a,e,t){if("brainstormforce"===a.author){var o=e.complete||i.noop,s=e.url;a.beforeSend=function(){if(n.exist(s)){var e=n.get(s);return CartFlowsAPI._api_cached_request(e),!1}return!0},a.complete=function(e,t){var r={args:a.args,items:e.responseText?JSON.parse(e.responseText):"",items_count:e.getResponseHeader("x-wp-total")||0,callback:a.callback,status:t,XHR:e};n.set(s,r,o)}}}),CartFlowsAPI={_log:function(e,t){if(CartFlowsImportVars.debug&&"table"!==t)(new Date).toLocaleTimeString()},_api_url:CartFlowsImportVars.server_rest_url,_api_cached_request:function(e){CartFlowsAPI._log(n.data,"table"),CartFlowsAPI._log("Current time "+(new Date).getTime()),CartFlowsAPI._log("Cache expired in "+parseInt(n.timeout)/1e3+" seconds."),void 0!==e.args.trigger&&""!==e.args.trigger&&i(document).trigger(e.args.trigger,[e]),e.callback&&"function"==typeof e.callback&&e.callback(e)},_api_request:function(o,s){var r={url:CartFlowsAPI._api_url+o.slug,args:o,callback:s,author:"brainstormforce"};r.headers=CartFlowsImportVars.headers,i.ajax(r).done(function(e,t,r){if("success"===t&&r.getResponseHeader("x-wp-total")){var a={args:o,items:e,items_count:r.getResponseHeader("x-wp-total")||0,callback:s,status:t,XHR:r};void 0!==o.trigger&&""!==o.trigger&&i(document).trigger(o.trigger,[a])}else i(document).trigger("cartflows-api-request-error");s&&"function"==typeof s&&s(a)}).fail(function(e,t){i(document).trigger("cartflows-api-request-fail",[r,e,t])}).always(function(){i(document).trigger("cartflows-api-request-always")})}}}(jQuery);
1
+ !function(i){var n={timeout:3e5,data:{},remove:function(e){delete n.data[e]},exist:function(e){return!!n.data[e]&&(new Date).getTime()-n.data[e]._<n.timeout},get:function(e){return n.data[e].data},set:function(e,t,r){n.remove(e),n.data[e]={_:(new Date).getTime(),data:t},r&&"function"==typeof r&&r(t)}};i.ajaxPrefilter(function(a,e,t){if("brainstormforce"===a.author){var o=e.complete||i.noop,s=e.url;a.beforeSend=function(){if(n.exist(s)){var e=n.get(s);return CartFlowsAPI._api_cached_request(e),!1}return!0},a.complete=function(e,t){var r={args:a.args,items:e.responseText?JSON.parse(e.responseText):"",items_count:e.getResponseHeader("x-wp-total")||0,callback:a.callback,status:t,XHR:e};n.set(s,r,o)}}}),CartFlowsAPI={_log:function(e,t){if(CartFlowsImportVars.debug&&"table"!==t)(new Date).toLocaleTimeString()},_api_url:CartFlowsImportVars.server_rest_url,_api_cached_request:function(e){CartFlowsAPI._log(n.data,"table"),CartFlowsAPI._log("Current time "+(new Date).getTime()),CartFlowsAPI._log("Cache expired in "+parseInt(n.timeout)/1e3+" seconds."),void 0!==e.args.trigger&&""!==e.args.trigger&&i(document).trigger(e.args.trigger,[e]),e.callback&&"function"==typeof e.callback&&e.callback(e)},_api_request:function(o,s){var r={url:CartFlowsAPI._api_url+o.slug,args:o,callback:s,headers:CartFlowsImportVars.headers,author:"brainstormforce"};i.ajax(r).done(function(e,t,r){if("success"===t&&r.getResponseHeader("x-wp-total")){var a={args:o,items:e,items_count:r.getResponseHeader("x-wp-total")||0,callback:s,status:t,XHR:r};void 0!==o.trigger&&""!==o.trigger&&i(document).trigger(o.trigger,[a])}else i(document).trigger("cartflows-api-request-error");s&&"function"==typeof s&&s(a)}).fail(function(e,t){i(document).trigger("cartflows-api-request-fail",[r,e,t])}).always(function(){i(document).trigger("cartflows-api-request-always")})}}}(jQuery);
cartflows.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.5.11
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.12
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,3 +1,7 @@
 
 
 
 
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.
1
+ Version 1.5.12 - Wednesday, 1st July 2020
2
+ - Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
3
+ - Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.
4
+
5
  Version 1.5.11 - Tuesday, 16th June 2020
6
  - 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 )
7
  - Fix: CartFlows setup wizard.
classes/class-cartflows-default-meta.php CHANGED
@@ -1,871 +1,871 @@
1
- <?php
2
- /**
3
- * Cartflow default options.
4
- *
5
- * @package Cartflows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Default_Meta {
14
-
15
-
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_fields
28
- */
29
- private static $checkout_fields = null;
30
-
31
- /**
32
- * Member Variable
33
- *
34
- * @var checkout_fields
35
- */
36
- private static $thankyou_fields = null;
37
-
38
- /**
39
- * Member Variable
40
- *
41
- * @var flow_fields
42
- */
43
- private static $flow_fields = null;
44
-
45
- /**
46
- * Member Variable
47
- *
48
- * @var landing_fields
49
- */
50
- private static $landing_fields = null;
51
-
52
- /**
53
- * Member Variable
54
- *
55
- * @var optin_fields
56
- */
57
- private static $optin_fields = null;
58
-
59
- /**
60
- * Initiator
61
- */
62
- public static function get_instance() {
63
- if ( ! isset( self::$instance ) ) {
64
- self::$instance = new self();
65
- }
66
- return self::$instance;
67
- }
68
-
69
- /**
70
- * Constructor
71
- */
72
- public function __construct() {
73
- }
74
-
75
- /**
76
- * Checkout Default fields.
77
- *
78
- * @param int $post_id post id.
79
- * @return array
80
- */
81
- public function get_checkout_fields( $post_id ) {
82
-
83
- if ( null === self::$checkout_fields ) {
84
- self::$checkout_fields = array(
85
- 'wcf-field-google-font-url' => array(
86
- 'default' => '',
87
- 'sanitize' => 'FILTER_DEFAULT',
88
- ),
89
- 'wcf-checkout-products' => array(
90
- 'default' => array(),
91
- 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
- ),
93
- 'wcf-checkout-layout' => array(
94
- 'default' => 'two-column',
95
- 'sanitize' => 'FILTER_DEFAULT',
96
- ),
97
- 'wcf-input-font-family' => array(
98
- 'default' => '',
99
- 'sanitize' => 'FILTER_DEFAULT',
100
- ),
101
- 'wcf-input-font-weight' => array(
102
- 'default' => '',
103
- 'sanitize' => 'FILTER_DEFAULT',
104
- ),
105
- 'wcf-heading-font-family' => array(
106
- 'default' => '',
107
- 'sanitize' => 'FILTER_DEFAULT',
108
- ),
109
- 'wcf-heading-font-weight' => array(
110
- 'default' => '',
111
- 'sanitize' => 'FILTER_DEFAULT',
112
- ),
113
- 'wcf-base-font-family' => array(
114
- 'default' => '',
115
- 'sanitize' => 'FILTER_DEFAULT',
116
- ),
117
- 'wcf-advance-options-fields' => array(
118
- 'default' => '',
119
- 'sanitize' => 'FILTER_DEFAULT',
120
- ),
121
- 'wcf-remove-product-field' => array(
122
- 'default' => '',
123
- 'sanitize' => 'FILTER_DEFAULT',
124
- ),
125
- 'wcf-checkout-place-order-button-text' => array(
126
- 'default' => '',
127
- 'sanitize' => 'FILTER_SANITIZE_STRING',
128
- ),
129
- 'wcf-base-font-weight' => array(
130
- 'default' => '',
131
- 'sanitize' => 'FILTER_DEFAULT',
132
- ),
133
- 'wcf-button-font-family' => array(
134
- 'default' => '',
135
- 'sanitize' => 'FILTER_DEFAULT',
136
- ),
137
- 'wcf-button-font-weight' => array(
138
- 'default' => '',
139
- 'sanitize' => 'FILTER_DEFAULT',
140
- ),
141
- 'wcf-primary-color' => array(
142
- 'default' => '',
143
- 'sanitize' => 'FILTER_DEFAULT',
144
- ),
145
- 'wcf-heading-color' => array(
146
- 'default' => '',
147
- 'sanitize' => 'FILTER_DEFAULT',
148
- ),
149
- 'wcf-section-bg-color' => array(
150
- 'default' => '',
151
- 'sanitize' => 'FILTER_DEFAULT',
152
- ),
153
- 'wcf-hl-bg-color' => array(
154
- 'default' => '',
155
- 'sanitize' => 'FILTER_DEFAULT',
156
- ),
157
- 'wcf-field-tb-padding' => array(
158
- 'default' => '',
159
- 'sanitize' => 'FILTER_DEFAULT',
160
- ),
161
- 'wcf-field-lr-padding' => array(
162
- 'default' => '',
163
- 'sanitize' => 'FILTER_DEFAULT',
164
- ),
165
- 'wcf-fields-skins' => array(
166
- 'default' => '',
167
- 'sanitize' => 'FILTER_DEFAULT',
168
- ),
169
- 'wcf-input-field-size' => array(
170
- 'default' => '33px',
171
- 'sanitize' => 'FILTER_DEFAULT',
172
- ),
173
- 'wcf-field-color' => array(
174
- 'default' => '',
175
- 'sanitize' => 'FILTER_DEFAULT',
176
- ),
177
- 'wcf-field-bg-color' => array(
178
- 'default' => '',
179
- 'sanitize' => 'FILTER_DEFAULT',
180
- ),
181
- 'wcf-field-border-color' => array(
182
- 'default' => '',
183
- 'sanitize' => 'FILTER_DEFAULT',
184
- ),
185
- 'wcf-box-border-color' => array(
186
- 'default' => '',
187
- 'sanitize' => 'FILTER_DEFAULT',
188
- ),
189
- 'wcf-field-label-color' => array(
190
- 'default' => '',
191
- 'sanitize' => 'FILTER_DEFAULT',
192
- ),
193
- 'wcf-submit-tb-padding' => array(
194
- 'default' => '',
195
- 'sanitize' => 'FILTER_DEFAULT',
196
- ),
197
- 'wcf-submit-lr-padding' => array(
198
- 'default' => '',
199
- 'sanitize' => 'FILTER_DEFAULT',
200
- ),
201
- 'wcf-input-button-size' => array(
202
- 'default' => '33px',
203
- 'sanitize' => 'FILTER_DEFAULT',
204
- ),
205
- 'wcf-submit-color' => array(
206
- 'default' => '',
207
- 'sanitize' => 'FILTER_DEFAULT',
208
- ),
209
- 'wcf-submit-hover-color' => array(
210
- 'default' => '',
211
- 'sanitize' => 'FILTER_DEFAULT',
212
- ),
213
- 'wcf-submit-bg-color' => array(
214
- 'default' => '',
215
- 'sanitize' => 'FILTER_DEFAULT',
216
- ),
217
- 'wcf-submit-bg-hover-color' => array(
218
- 'default' => '',
219
- 'sanitize' => 'FILTER_DEFAULT',
220
- ),
221
- 'wcf-submit-border-color' => array(
222
- 'default' => '',
223
- 'sanitize' => 'FILTER_DEFAULT',
224
- ),
225
- 'wcf-submit-border-hover-color' => array(
226
- 'default' => '',
227
- 'sanitize' => 'FILTER_DEFAULT',
228
- ),
229
- 'wcf-active-tab' => array(
230
- 'default' => '',
231
- 'sanitize' => 'FILTER_DEFAULT',
232
- ),
233
- 'wcf-header-logo-image' => array(
234
- 'default' => '',
235
- 'sanitize' => 'FILTER_DEFAULT',
236
- ),
237
- 'wcf-header-logo-width' => array(
238
- 'default' => '',
239
- 'sanitize' => 'FILTER_DEFAULT',
240
- ),
241
- 'wcf-custom-script' => array(
242
- 'default' => '',
243
- 'sanitize' => 'FILTER_DEFAULT',
244
- ),
245
- );
246
-
247
- self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
- }
249
-
250
- return self::$checkout_fields;
251
- }
252
-
253
- /**
254
- * Save Checkout Meta fields.
255
- *
256
- * @param int $post_id post id.
257
- * @return void
258
- */
259
- public function save_checkout_fields( $post_id ) {
260
-
261
- $post_meta = $this->get_checkout_fields( $post_id );
262
-
263
- $this->save_meta_fields( $post_id, $post_meta );
264
- }
265
-
266
- /**
267
- * Save Landing Meta fields.
268
- *
269
- * @param int $post_id post id.
270
- * @return void
271
- */
272
- public function save_landing_fields( $post_id ) {
273
-
274
- $post_meta = $this->get_landing_fields( $post_id );
275
-
276
- $this->save_meta_fields( $post_id, $post_meta );
277
- }
278
-
279
- /**
280
- * Save ThankYou Meta fields.
281
- *
282
- * @param int $post_id post id.
283
- * @return void
284
- */
285
- public function save_thankyou_fields( $post_id ) {
286
-
287
- $post_meta = $this->get_thankyou_fields( $post_id );
288
-
289
- $this->save_meta_fields( $post_id, $post_meta );
290
- }
291
-
292
- /**
293
- * Flow Default fields.
294
- *
295
- * @param int $post_id post id.
296
- * @return array
297
- */
298
- public function get_flow_fields( $post_id ) {
299
-
300
- if ( null === self::$flow_fields ) {
301
- self::$flow_fields = array(
302
- 'wcf-steps' => array(
303
- 'default' => array(),
304
- 'sanitize' => 'FILTER_DEFAULT',
305
- ),
306
-
307
- 'wcf-testing' => array(
308
- 'default' => 'no',
309
- 'sanitize' => 'FILTER_DEFAULT',
310
- ),
311
- );
312
- }
313
-
314
- return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
- }
316
-
317
- /**
318
- * Save Flow Meta fields.
319
- *
320
- * @param int $post_id post id.
321
- * @return void
322
- */
323
- public function save_flow_fields( $post_id ) {
324
-
325
- $post_meta = $this->get_flow_fields( $post_id );
326
-
327
- if ( isset( $post_meta['wcf-steps'] ) ) {
328
- unset( $post_meta['wcf-steps'] );
329
- }
330
-
331
- $this->save_meta_fields( $post_id, $post_meta );
332
- }
333
-
334
- /**
335
- * Save Meta fields - Common Function.
336
- *
337
- * @param int $post_id post id.
338
- * @param array $post_meta options to store.
339
- * @return void
340
- */
341
- public function save_meta_fields( $post_id, $post_meta ) {
342
-
343
- if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
- return;
345
- }
346
-
347
- foreach ( $post_meta as $key => $data ) {
348
- $meta_value = false;
349
-
350
- // Sanitize values.
351
- $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
-
353
- switch ( $sanitize_filter ) {
354
- case 'FILTER_SANITIZE_STRING':
355
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
- break;
357
-
358
- case 'FILTER_SANITIZE_URL':
359
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
- break;
361
-
362
- case 'FILTER_SANITIZE_NUMBER_INT':
363
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
- break;
365
-
366
- case 'FILTER_CARTFLOWS_ARRAY':
367
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
- $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
- }
370
- break;
371
-
372
- case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
- $i = 0;
375
- $q = 0;
376
-
377
- foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
- if ( ! array_key_exists( 'product', $p_data ) ) {
379
- continue;
380
- }
381
- foreach ( $p_data as $i_key => $i_value ) {
382
-
383
- if ( is_array( $i_value ) ) {
384
- foreach ( $i_value as $q_key => $q_value ) {
385
- $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
-
387
- $q++;
388
- }
389
- } else {
390
- $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
- }
392
- }
393
-
394
- $i++;
395
- }
396
- }
397
- break;
398
-
399
- case 'FILTER_CARTFLOWS_IMAGES':
400
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
-
402
- if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
-
404
- if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
-
406
- $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
- $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
-
409
- $image_data = array(
410
- 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
- 'url' => array(
412
- 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
- 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
- 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
- ),
416
- );
417
-
418
- $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
- update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
- }
421
- }
422
-
423
- break;
424
-
425
- default:
426
- if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
- } else {
429
- $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
- }
431
-
432
- break;
433
- }
434
-
435
- if ( false !== $meta_value ) {
436
- update_post_meta( $post_id, $key, $meta_value );
437
- } else {
438
- delete_post_meta( $post_id, $key );
439
- }
440
- }
441
- }
442
-
443
- /**
444
- * Get checkout meta.
445
- *
446
- * @param int $post_id post id.
447
- * @param string $key options key.
448
- * @param mix $default options default value.
449
- * @return string
450
- */
451
- public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
-
453
- $value = $this->get_save_meta( $post_id, $key );
454
-
455
- if ( ! $value ) {
456
- if ( $default ) {
457
- $value = $default;
458
- } else {
459
- $fields = $this->get_flow_fields( $post_id );
460
-
461
- if ( isset( $fields[ $key ]['default'] ) ) {
462
- $value = $fields[ $key ]['default'];
463
- }
464
- }
465
- }
466
-
467
- return $value;
468
- }
469
-
470
- /**
471
- * Get checkout meta.
472
- *
473
- * @param int $post_id post id.
474
- * @param string $key options key.
475
- * @param mix $default options default value.
476
- * @return string
477
- */
478
- public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
-
480
- $value = $this->get_save_meta( $post_id, $key );
481
-
482
- if ( ! $value ) {
483
- if ( false !== $default ) {
484
- $value = $default;
485
- } else {
486
- $fields = $this->get_checkout_fields( $post_id );
487
-
488
- if ( isset( $fields[ $key ]['default'] ) ) {
489
- $value = $fields[ $key ]['default'];
490
- }
491
- }
492
- }
493
-
494
- return $value;
495
- }
496
-
497
- /**
498
- * Get post meta.
499
- *
500
- * @param int $post_id post id.
501
- * @param string $key options key.
502
- * @return string
503
- */
504
- public function get_save_meta( $post_id, $key ) {
505
-
506
- $value = get_post_meta( $post_id, $key, true );
507
-
508
- return $value;
509
- }
510
-
511
- /**
512
- * Thank You Default fields.
513
- *
514
- * @param int $post_id post id.
515
- * @return array
516
- */
517
- public function get_thankyou_fields( $post_id ) {
518
-
519
- if ( null === self::$thankyou_fields ) {
520
- self::$thankyou_fields = array(
521
- 'wcf-field-google-font-url' => array(
522
- 'default' => '',
523
- 'sanitize' => 'FILTER_DEFAULT',
524
- ),
525
- 'wcf-active-tab' => array(
526
- 'default' => '',
527
- 'sanitize' => 'FILTER_DEFAULT',
528
- ),
529
- 'wcf-tq-text-color' => array(
530
- 'default' => '',
531
- 'sanitize' => 'FILTER_DEFAULT',
532
- ),
533
- 'wcf-tq-font-family' => array(
534
- 'default' => '',
535
- 'sanitize' => 'FILTER_DEFAULT',
536
- ),
537
- 'wcf-tq-font-size' => array(
538
- 'default' => '',
539
- 'sanitize' => 'FILTER_DEFAULT',
540
- ),
541
- 'wcf-tq-heading-color' => array(
542
- 'default' => '',
543
- 'sanitize' => 'FILTER_DEFAULT',
544
- ),
545
- 'wcf-tq-heading-font-family' => array(
546
- 'default' => '',
547
- 'sanitize' => 'FILTER_DEFAULT',
548
- ),
549
- 'wcf-tq-heading-font-wt' => array(
550
- 'default' => '',
551
- 'sanitize' => 'FILTER_DEFAULT',
552
- ),
553
- 'wcf-tq-container-width' => array(
554
- 'default' => '',
555
- 'sanitize' => 'FILTER_DEFAULT',
556
- ),
557
- 'wcf-tq-section-bg-color' => array(
558
- 'default' => '',
559
- 'sanitize' => 'FILTER_DEFAULT',
560
- ),
561
- 'wcf-tq-advance-options-fields' => array(
562
- 'default' => '',
563
- 'sanitize' => 'FILTER_DEFAULT',
564
- ),
565
- 'wcf-show-overview-section' => array(
566
- 'default' => 'yes',
567
- 'sanitize' => 'FILTER_DEFAULT',
568
- ),
569
- 'wcf-show-details-section' => array(
570
- 'default' => 'yes',
571
- 'sanitize' => 'FILTER_DEFAULT',
572
- ),
573
- 'wcf-show-billing-section' => array(
574
- 'default' => 'yes',
575
- 'sanitize' => 'FILTER_DEFAULT',
576
- ),
577
- 'wcf-show-shipping-section' => array(
578
- 'default' => 'yes',
579
- 'sanitize' => 'FILTER_DEFAULT',
580
- ),
581
- 'wcf-show-tq-redirect-section' => array(
582
- 'default' => '',
583
- 'sanitize' => 'FILTER_DEFAULT',
584
- ),
585
- 'wcf-tq-redirect-link' => array(
586
- 'default' => '',
587
- 'sanitize' => 'FILTER_SANITIZE_URL',
588
- ),
589
- 'wcf-tq-text' => array(
590
- 'default' => '',
591
- 'sanitize' => 'FILTER_DEFAULT',
592
- ),
593
- 'wcf-custom-script' => array(
594
- 'default' => '',
595
- 'sanitize' => 'FILTER_DEFAULT',
596
- ),
597
- );
598
- }
599
-
600
- return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
- }
602
-
603
- /**
604
- * Get Thank you section meta.
605
- *
606
- * @param int $post_id post id.
607
- * @param string $key options key.
608
- * @param mix $default options default value.
609
- * @return string
610
- */
611
- public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
-
613
- $value = $this->get_save_meta( $post_id, $key );
614
-
615
- if ( ! $value ) {
616
- if ( $default ) {
617
- $value = $default;
618
- } else {
619
- $fields = $this->get_thankyou_fields( $post_id );
620
-
621
- if ( isset( $fields[ $key ]['default'] ) ) {
622
- $value = $fields[ $key ]['default'];
623
- }
624
- }
625
- }
626
-
627
- return $value;
628
- }
629
-
630
- /**
631
- * Get Landing section meta.
632
- *
633
- * @param int $post_id post id.
634
- * @param string $key options key.
635
- * @param mix $default options default value.
636
- * @return string
637
- */
638
- public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
-
640
- $value = $this->get_save_meta( $post_id, $key );
641
- if ( ! $value ) {
642
- if ( $default ) {
643
- $value = $default;
644
- } else {
645
- $fields = $this->get_landing_fields( $post_id );
646
-
647
- if ( isset( $fields[ $key ]['default'] ) ) {
648
- $value = $fields[ $key ]['default'];
649
- }
650
- }
651
- }
652
-
653
- return $value;
654
- }
655
-
656
- /**
657
- * Landing Default fields.
658
- *
659
- * @param int $post_id post id.
660
- * @return array
661
- */
662
- public function get_landing_fields( $post_id ) {
663
-
664
- if ( null === self::$landing_fields ) {
665
- self::$landing_fields = array(
666
- 'wcf-custom-script' => array(
667
- 'default' => '',
668
- 'sanitize' => 'FILTER_DEFAULT',
669
- ),
670
- );
671
- }
672
- return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
- }
674
-
675
- /**
676
- * Optin Default fields.
677
- *
678
- * @param int $post_id post id.
679
- * @return array
680
- */
681
- public function get_optin_fields( $post_id ) {
682
-
683
- if ( null === self::$optin_fields ) {
684
- self::$optin_fields = array(
685
-
686
- 'wcf-optin-product' => array(
687
- 'default' => array(),
688
- 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
- ),
690
-
691
- /* Style */
692
- 'wcf-field-google-font-url' => array(
693
- 'default' => '',
694
- 'sanitize' => 'FILTER_DEFAULT',
695
- ),
696
- 'wcf-primary-color' => array(
697
- 'default' => '',
698
- 'sanitize' => 'FILTER_DEFAULT',
699
- ),
700
- 'wcf-base-font-family' => array(
701
- 'default' => '',
702
- 'sanitize' => 'FILTER_DEFAULT',
703
- ),
704
- 'wcf-input-fields-skins' => array(
705
- 'default' => '',
706
- 'sanitize' => 'FILTER_DEFAULT',
707
- ),
708
- 'wcf-input-font-family' => array(
709
- 'default' => '',
710
- 'sanitize' => 'FILTER_DEFAULT',
711
- ),
712
- 'wcf-input-font-weight' => array(
713
- 'default' => '',
714
- 'sanitize' => 'FILTER_DEFAULT',
715
- ),
716
- 'wcf-input-field-size' => array(
717
- 'default' => '33px',
718
- 'sanitize' => 'FILTER_DEFAULT',
719
- ),
720
- 'wcf-field-tb-padding' => array(
721
- 'default' => '',
722
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
- ),
724
- 'wcf-field-lr-padding' => array(
725
- 'default' => '',
726
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
- ),
728
- 'wcf-field-color' => array(
729
- 'default' => '',
730
- 'sanitize' => 'FILTER_DEFAULT',
731
- ),
732
- 'wcf-field-bg-color' => array(
733
- 'default' => '',
734
- 'sanitize' => 'FILTER_DEFAULT',
735
- ),
736
- 'wcf-field-border-color' => array(
737
- 'default' => '',
738
- 'sanitize' => 'FILTER_DEFAULT',
739
- ),
740
- 'wcf-field-label-color' => array(
741
- 'default' => '',
742
- 'sanitize' => 'FILTER_DEFAULT',
743
- ),
744
- 'wcf-submit-button-text' => array(
745
- 'default' => __( 'Submit', 'cartflows' ),
746
- 'sanitize' => 'FILTER_DEFAULT',
747
- ),
748
- 'wcf-submit-font-size' => array(
749
- 'default' => '',
750
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
- ),
752
- 'wcf-button-font-family' => array(
753
- 'default' => '',
754
- 'sanitize' => 'FILTER_DEFAULT',
755
- ),
756
- 'wcf-button-font-weight' => array(
757
- 'default' => '',
758
- 'sanitize' => 'FILTER_DEFAULT',
759
- ),
760
- 'wcf-submit-button-size' => array(
761
- 'default' => '33px',
762
- 'sanitize' => 'FILTER_DEFAULT',
763
- ),
764
- 'wcf-submit-tb-padding' => array(
765
- 'default' => '',
766
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
- ),
768
- 'wcf-submit-lr-padding' => array(
769
- 'default' => '',
770
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
- ),
772
- 'wcf-submit-button-position' => array(
773
- 'default' => 'center',
774
- 'sanitize' => 'FILTER_DEFAULT',
775
- ),
776
- 'wcf-submit-color' => array(
777
- 'default' => '',
778
- 'sanitize' => 'FILTER_DEFAULT',
779
- ),
780
- 'wcf-submit-hover-color' => array(
781
- 'default' => '',
782
- 'sanitize' => 'FILTER_DEFAULT',
783
- ),
784
- 'wcf-submit-bg-color' => array(
785
- 'default' => '',
786
- 'sanitize' => 'FILTER_DEFAULT',
787
- ),
788
- 'wcf-submit-bg-hover-color' => array(
789
- 'default' => '',
790
- 'sanitize' => 'FILTER_DEFAULT',
791
- ),
792
- 'wcf-submit-border-color' => array(
793
- 'default' => '',
794
- 'sanitize' => 'FILTER_DEFAULT',
795
- ),
796
- 'wcf-submit-border-hover-color' => array(
797
- 'default' => '',
798
- 'sanitize' => 'FILTER_DEFAULT',
799
- ),
800
-
801
- /* Settings */
802
- 'wcf-optin-pass-fields' => array(
803
- 'default' => '',
804
- 'sanitize' => 'FILTER_DEFAULT',
805
- ),
806
- 'wcf-optin-pass-specific-fields' => array(
807
- 'default' => 'first_name',
808
- 'sanitize' => 'FILTER_DEFAULT',
809
- ),
810
-
811
- /* Script */
812
- 'wcf-custom-script' => array(
813
- 'default' => '',
814
- 'sanitize' => 'FILTER_DEFAULT',
815
- ),
816
-
817
- /* Hidden */
818
- 'wcf-active-tab' => array(
819
- 'default' => '',
820
- 'sanitize' => 'FILTER_DEFAULT',
821
- ),
822
- );
823
- }
824
- return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
- }
826
-
827
- /**
828
- * Save Optin Meta fields.
829
- *
830
- * @param int $post_id post id.
831
- * @return void
832
- */
833
- public function save_optin_fields( $post_id ) {
834
-
835
- $post_meta = $this->get_optin_fields( $post_id );
836
-
837
- $this->save_meta_fields( $post_id, $post_meta );
838
- }
839
-
840
- /**
841
- * Get optin meta.
842
- *
843
- * @param int $post_id post id.
844
- * @param string $key options key.
845
- * @param mix $default options default value.
846
- * @return string
847
- */
848
- public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
-
850
- $value = $this->get_save_meta( $post_id, $key );
851
-
852
- if ( ! $value ) {
853
- if ( false !== $default ) {
854
- $value = $default;
855
- } else {
856
- $fields = $this->get_optin_fields( $post_id );
857
-
858
- if ( isset( $fields[ $key ]['default'] ) ) {
859
- $value = $fields[ $key ]['default'];
860
- }
861
- }
862
- }
863
-
864
- return $value;
865
- }
866
- }
867
-
868
- /**
869
- * Kicking this off by calling 'get_instance()' method
870
- */
871
- Cartflows_Default_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Cartflow default options.
4
+ *
5
+ * @package Cartflows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Default_Meta {
14
+
15
+
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_fields
28
+ */
29
+ private static $checkout_fields = null;
30
+
31
+ /**
32
+ * Member Variable
33
+ *
34
+ * @var checkout_fields
35
+ */
36
+ private static $thankyou_fields = null;
37
+
38
+ /**
39
+ * Member Variable
40
+ *
41
+ * @var flow_fields
42
+ */
43
+ private static $flow_fields = null;
44
+
45
+ /**
46
+ * Member Variable
47
+ *
48
+ * @var landing_fields
49
+ */
50
+ private static $landing_fields = null;
51
+
52
+ /**
53
+ * Member Variable
54
+ *
55
+ * @var optin_fields
56
+ */
57
+ private static $optin_fields = null;
58
+
59
+ /**
60
+ * Initiator
61
+ */
62
+ public static function get_instance() {
63
+ if ( ! isset( self::$instance ) ) {
64
+ self::$instance = new self();
65
+ }
66
+ return self::$instance;
67
+ }
68
+
69
+ /**
70
+ * Constructor
71
+ */
72
+ public function __construct() {
73
+ }
74
+
75
+ /**
76
+ * Checkout Default fields.
77
+ *
78
+ * @param int $post_id post id.
79
+ * @return array
80
+ */
81
+ public function get_checkout_fields( $post_id ) {
82
+
83
+ if ( null === self::$checkout_fields ) {
84
+ self::$checkout_fields = array(
85
+ 'wcf-field-google-font-url' => array(
86
+ 'default' => '',
87
+ 'sanitize' => 'FILTER_DEFAULT',
88
+ ),
89
+ 'wcf-checkout-products' => array(
90
+ 'default' => array(),
91
+ 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
+ ),
93
+ 'wcf-checkout-layout' => array(
94
+ 'default' => 'two-column',
95
+ 'sanitize' => 'FILTER_DEFAULT',
96
+ ),
97
+ 'wcf-input-font-family' => array(
98
+ 'default' => '',
99
+ 'sanitize' => 'FILTER_DEFAULT',
100
+ ),
101
+ 'wcf-input-font-weight' => array(
102
+ 'default' => '',
103
+ 'sanitize' => 'FILTER_DEFAULT',
104
+ ),
105
+ 'wcf-heading-font-family' => array(
106
+ 'default' => '',
107
+ 'sanitize' => 'FILTER_DEFAULT',
108
+ ),
109
+ 'wcf-heading-font-weight' => array(
110
+ 'default' => '',
111
+ 'sanitize' => 'FILTER_DEFAULT',
112
+ ),
113
+ 'wcf-base-font-family' => array(
114
+ 'default' => '',
115
+ 'sanitize' => 'FILTER_DEFAULT',
116
+ ),
117
+ 'wcf-advance-options-fields' => array(
118
+ 'default' => '',
119
+ 'sanitize' => 'FILTER_DEFAULT',
120
+ ),
121
+ 'wcf-remove-product-field' => array(
122
+ 'default' => '',
123
+ 'sanitize' => 'FILTER_DEFAULT',
124
+ ),
125
+ 'wcf-checkout-place-order-button-text' => array(
126
+ 'default' => '',
127
+ 'sanitize' => 'FILTER_SANITIZE_STRING',
128
+ ),
129
+ 'wcf-base-font-weight' => array(
130
+ 'default' => '',
131
+ 'sanitize' => 'FILTER_DEFAULT',
132
+ ),
133
+ 'wcf-button-font-family' => array(
134
+ 'default' => '',
135
+ 'sanitize' => 'FILTER_DEFAULT',
136
+ ),
137
+ 'wcf-button-font-weight' => array(
138
+ 'default' => '',
139
+ 'sanitize' => 'FILTER_DEFAULT',
140
+ ),
141
+ 'wcf-primary-color' => array(
142
+ 'default' => '',
143
+ 'sanitize' => 'FILTER_DEFAULT',
144
+ ),
145
+ 'wcf-heading-color' => array(
146
+ 'default' => '',
147
+ 'sanitize' => 'FILTER_DEFAULT',
148
+ ),
149
+ 'wcf-section-bg-color' => array(
150
+ 'default' => '',
151
+ 'sanitize' => 'FILTER_DEFAULT',
152
+ ),
153
+ 'wcf-hl-bg-color' => array(
154
+ 'default' => '',
155
+ 'sanitize' => 'FILTER_DEFAULT',
156
+ ),
157
+ 'wcf-field-tb-padding' => array(
158
+ 'default' => '',
159
+ 'sanitize' => 'FILTER_DEFAULT',
160
+ ),
161
+ 'wcf-field-lr-padding' => array(
162
+ 'default' => '',
163
+ 'sanitize' => 'FILTER_DEFAULT',
164
+ ),
165
+ 'wcf-fields-skins' => array(
166
+ 'default' => '',
167
+ 'sanitize' => 'FILTER_DEFAULT',
168
+ ),
169
+ 'wcf-input-field-size' => array(
170
+ 'default' => '33px',
171
+ 'sanitize' => 'FILTER_DEFAULT',
172
+ ),
173
+ 'wcf-field-color' => array(
174
+ 'default' => '',
175
+ 'sanitize' => 'FILTER_DEFAULT',
176
+ ),
177
+ 'wcf-field-bg-color' => array(
178
+ 'default' => '',
179
+ 'sanitize' => 'FILTER_DEFAULT',
180
+ ),
181
+ 'wcf-field-border-color' => array(
182
+ 'default' => '',
183
+ 'sanitize' => 'FILTER_DEFAULT',
184
+ ),
185
+ 'wcf-box-border-color' => array(
186
+ 'default' => '',
187
+ 'sanitize' => 'FILTER_DEFAULT',
188
+ ),
189
+ 'wcf-field-label-color' => array(
190
+ 'default' => '',
191
+ 'sanitize' => 'FILTER_DEFAULT',
192
+ ),
193
+ 'wcf-submit-tb-padding' => array(
194
+ 'default' => '',
195
+ 'sanitize' => 'FILTER_DEFAULT',
196
+ ),
197
+ 'wcf-submit-lr-padding' => array(
198
+ 'default' => '',
199
+ 'sanitize' => 'FILTER_DEFAULT',
200
+ ),
201
+ 'wcf-input-button-size' => array(
202
+ 'default' => '33px',
203
+ 'sanitize' => 'FILTER_DEFAULT',
204
+ ),
205
+ 'wcf-submit-color' => array(
206
+ 'default' => '',
207
+ 'sanitize' => 'FILTER_DEFAULT',
208
+ ),
209
+ 'wcf-submit-hover-color' => array(
210
+ 'default' => '',
211
+ 'sanitize' => 'FILTER_DEFAULT',
212
+ ),
213
+ 'wcf-submit-bg-color' => array(
214
+ 'default' => '',
215
+ 'sanitize' => 'FILTER_DEFAULT',
216
+ ),
217
+ 'wcf-submit-bg-hover-color' => array(
218
+ 'default' => '',
219
+ 'sanitize' => 'FILTER_DEFAULT',
220
+ ),
221
+ 'wcf-submit-border-color' => array(
222
+ 'default' => '',
223
+ 'sanitize' => 'FILTER_DEFAULT',
224
+ ),
225
+ 'wcf-submit-border-hover-color' => array(
226
+ 'default' => '',
227
+ 'sanitize' => 'FILTER_DEFAULT',
228
+ ),
229
+ 'wcf-active-tab' => array(
230
+ 'default' => '',
231
+ 'sanitize' => 'FILTER_DEFAULT',
232
+ ),
233
+ 'wcf-header-logo-image' => array(
234
+ 'default' => '',
235
+ 'sanitize' => 'FILTER_DEFAULT',
236
+ ),
237
+ 'wcf-header-logo-width' => array(
238
+ 'default' => '',
239
+ 'sanitize' => 'FILTER_DEFAULT',
240
+ ),
241
+ 'wcf-custom-script' => array(
242
+ 'default' => '',
243
+ 'sanitize' => 'FILTER_DEFAULT',
244
+ ),
245
+ );
246
+
247
+ self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
+ }
249
+
250
+ return self::$checkout_fields;
251
+ }
252
+
253
+ /**
254
+ * Save Checkout Meta fields.
255
+ *
256
+ * @param int $post_id post id.
257
+ * @return void
258
+ */
259
+ public function save_checkout_fields( $post_id ) {
260
+
261
+ $post_meta = $this->get_checkout_fields( $post_id );
262
+
263
+ $this->save_meta_fields( $post_id, $post_meta );
264
+ }
265
+
266
+ /**
267
+ * Save Landing Meta fields.
268
+ *
269
+ * @param int $post_id post id.
270
+ * @return void
271
+ */
272
+ public function save_landing_fields( $post_id ) {
273
+
274
+ $post_meta = $this->get_landing_fields( $post_id );
275
+
276
+ $this->save_meta_fields( $post_id, $post_meta );
277
+ }
278
+
279
+ /**
280
+ * Save ThankYou Meta fields.
281
+ *
282
+ * @param int $post_id post id.
283
+ * @return void
284
+ */
285
+ public function save_thankyou_fields( $post_id ) {
286
+
287
+ $post_meta = $this->get_thankyou_fields( $post_id );
288
+
289
+ $this->save_meta_fields( $post_id, $post_meta );
290
+ }
291
+
292
+ /**
293
+ * Flow Default fields.
294
+ *
295
+ * @param int $post_id post id.
296
+ * @return array
297
+ */
298
+ public function get_flow_fields( $post_id ) {
299
+
300
+ if ( null === self::$flow_fields ) {
301
+ self::$flow_fields = array(
302
+ 'wcf-steps' => array(
303
+ 'default' => array(),
304
+ 'sanitize' => 'FILTER_DEFAULT',
305
+ ),
306
+
307
+ 'wcf-testing' => array(
308
+ 'default' => 'no',
309
+ 'sanitize' => 'FILTER_DEFAULT',
310
+ ),
311
+ );
312
+ }
313
+
314
+ return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
+ }
316
+
317
+ /**
318
+ * Save Flow Meta fields.
319
+ *
320
+ * @param int $post_id post id.
321
+ * @return void
322
+ */
323
+ public function save_flow_fields( $post_id ) {
324
+
325
+ $post_meta = $this->get_flow_fields( $post_id );
326
+
327
+ if ( isset( $post_meta['wcf-steps'] ) ) {
328
+ unset( $post_meta['wcf-steps'] );
329
+ }
330
+
331
+ $this->save_meta_fields( $post_id, $post_meta );
332
+ }
333
+
334
+ /**
335
+ * Save Meta fields - Common Function.
336
+ *
337
+ * @param int $post_id post id.
338
+ * @param array $post_meta options to store.
339
+ * @return void
340
+ */
341
+ public function save_meta_fields( $post_id, $post_meta ) {
342
+
343
+ if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
+ return;
345
+ }
346
+
347
+ foreach ( $post_meta as $key => $data ) {
348
+ $meta_value = false;
349
+
350
+ // Sanitize values.
351
+ $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
+
353
+ switch ( $sanitize_filter ) {
354
+ case 'FILTER_SANITIZE_STRING':
355
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
+ break;
357
+
358
+ case 'FILTER_SANITIZE_URL':
359
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
+ break;
361
+
362
+ case 'FILTER_SANITIZE_NUMBER_INT':
363
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
+ break;
365
+
366
+ case 'FILTER_CARTFLOWS_ARRAY':
367
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
+ $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
+ }
370
+ break;
371
+
372
+ case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
+ $i = 0;
375
+ $q = 0;
376
+
377
+ foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
+ if ( ! array_key_exists( 'product', $p_data ) ) {
379
+ continue;
380
+ }
381
+ foreach ( $p_data as $i_key => $i_value ) {
382
+
383
+ if ( is_array( $i_value ) ) {
384
+ foreach ( $i_value as $q_key => $q_value ) {
385
+ $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
+
387
+ $q++;
388
+ }
389
+ } else {
390
+ $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
+ }
392
+ }
393
+
394
+ $i++;
395
+ }
396
+ }
397
+ break;
398
+
399
+ case 'FILTER_CARTFLOWS_IMAGES':
400
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
+
402
+ if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
+
404
+ if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
+
406
+ $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
+ $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
+
409
+ $image_data = array(
410
+ 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
+ 'url' => array(
412
+ 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
+ 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
+ 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
+ ),
416
+ );
417
+
418
+ $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
+ update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
+ }
421
+ }
422
+
423
+ break;
424
+
425
+ default:
426
+ if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
+ } else {
429
+ $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
+ }
431
+
432
+ break;
433
+ }
434
+
435
+ if ( false !== $meta_value ) {
436
+ update_post_meta( $post_id, $key, $meta_value );
437
+ } else {
438
+ delete_post_meta( $post_id, $key );
439
+ }
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Get checkout meta.
445
+ *
446
+ * @param int $post_id post id.
447
+ * @param string $key options key.
448
+ * @param mix $default options default value.
449
+ * @return string
450
+ */
451
+ public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
+
453
+ $value = $this->get_save_meta( $post_id, $key );
454
+
455
+ if ( ! $value ) {
456
+ if ( $default ) {
457
+ $value = $default;
458
+ } else {
459
+ $fields = $this->get_flow_fields( $post_id );
460
+
461
+ if ( isset( $fields[ $key ]['default'] ) ) {
462
+ $value = $fields[ $key ]['default'];
463
+ }
464
+ }
465
+ }
466
+
467
+ return $value;
468
+ }
469
+
470
+ /**
471
+ * Get checkout meta.
472
+ *
473
+ * @param int $post_id post id.
474
+ * @param string $key options key.
475
+ * @param mix $default options default value.
476
+ * @return string
477
+ */
478
+ public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
+
480
+ $value = $this->get_save_meta( $post_id, $key );
481
+
482
+ if ( ! $value ) {
483
+ if ( false !== $default ) {
484
+ $value = $default;
485
+ } else {
486
+ $fields = $this->get_checkout_fields( $post_id );
487
+
488
+ if ( isset( $fields[ $key ]['default'] ) ) {
489
+ $value = $fields[ $key ]['default'];
490
+ }
491
+ }
492
+ }
493
+
494
+ return $value;
495
+ }
496
+
497
+ /**
498
+ * Get post meta.
499
+ *
500
+ * @param int $post_id post id.
501
+ * @param string $key options key.
502
+ * @return string
503
+ */
504
+ public function get_save_meta( $post_id, $key ) {
505
+
506
+ $value = get_post_meta( $post_id, $key, true );
507
+
508
+ return $value;
509
+ }
510
+
511
+ /**
512
+ * Thank You Default fields.
513
+ *
514
+ * @param int $post_id post id.
515
+ * @return array
516
+ */
517
+ public function get_thankyou_fields( $post_id ) {
518
+
519
+ if ( null === self::$thankyou_fields ) {
520
+ self::$thankyou_fields = array(
521
+ 'wcf-field-google-font-url' => array(
522
+ 'default' => '',
523
+ 'sanitize' => 'FILTER_DEFAULT',
524
+ ),
525
+ 'wcf-active-tab' => array(
526
+ 'default' => '',
527
+ 'sanitize' => 'FILTER_DEFAULT',
528
+ ),
529
+ 'wcf-tq-text-color' => array(
530
+ 'default' => '',
531
+ 'sanitize' => 'FILTER_DEFAULT',
532
+ ),
533
+ 'wcf-tq-font-family' => array(
534
+ 'default' => '',
535
+ 'sanitize' => 'FILTER_DEFAULT',
536
+ ),
537
+ 'wcf-tq-font-size' => array(
538
+ 'default' => '',
539
+ 'sanitize' => 'FILTER_DEFAULT',
540
+ ),
541
+ 'wcf-tq-heading-color' => array(
542
+ 'default' => '',
543
+ 'sanitize' => 'FILTER_DEFAULT',
544
+ ),
545
+ 'wcf-tq-heading-font-family' => array(
546
+ 'default' => '',
547
+ 'sanitize' => 'FILTER_DEFAULT',
548
+ ),
549
+ 'wcf-tq-heading-font-wt' => array(
550
+ 'default' => '',
551
+ 'sanitize' => 'FILTER_DEFAULT',
552
+ ),
553
+ 'wcf-tq-container-width' => array(
554
+ 'default' => '',
555
+ 'sanitize' => 'FILTER_DEFAULT',
556
+ ),
557
+ 'wcf-tq-section-bg-color' => array(
558
+ 'default' => '',
559
+ 'sanitize' => 'FILTER_DEFAULT',
560
+ ),
561
+ 'wcf-tq-advance-options-fields' => array(
562
+ 'default' => '',
563
+ 'sanitize' => 'FILTER_DEFAULT',
564
+ ),
565
+ 'wcf-show-overview-section' => array(
566
+ 'default' => 'yes',
567
+ 'sanitize' => 'FILTER_DEFAULT',
568
+ ),
569
+ 'wcf-show-details-section' => array(
570
+ 'default' => 'yes',
571
+ 'sanitize' => 'FILTER_DEFAULT',
572
+ ),
573
+ 'wcf-show-billing-section' => array(
574
+ 'default' => 'yes',
575
+ 'sanitize' => 'FILTER_DEFAULT',
576
+ ),
577
+ 'wcf-show-shipping-section' => array(
578
+ 'default' => 'yes',
579
+ 'sanitize' => 'FILTER_DEFAULT',
580
+ ),
581
+ 'wcf-show-tq-redirect-section' => array(
582
+ 'default' => '',
583
+ 'sanitize' => 'FILTER_DEFAULT',
584
+ ),
585
+ 'wcf-tq-redirect-link' => array(
586
+ 'default' => '',
587
+ 'sanitize' => 'FILTER_SANITIZE_URL',
588
+ ),
589
+ 'wcf-tq-text' => array(
590
+ 'default' => '',
591
+ 'sanitize' => 'FILTER_DEFAULT',
592
+ ),
593
+ 'wcf-custom-script' => array(
594
+ 'default' => '',
595
+ 'sanitize' => 'FILTER_DEFAULT',
596
+ ),
597
+ );
598
+ }
599
+
600
+ return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
+ }
602
+
603
+ /**
604
+ * Get Thank you section meta.
605
+ *
606
+ * @param int $post_id post id.
607
+ * @param string $key options key.
608
+ * @param mix $default options default value.
609
+ * @return string
610
+ */
611
+ public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
+
613
+ $value = $this->get_save_meta( $post_id, $key );
614
+
615
+ if ( ! $value ) {
616
+ if ( $default ) {
617
+ $value = $default;
618
+ } else {
619
+ $fields = $this->get_thankyou_fields( $post_id );
620
+
621
+ if ( isset( $fields[ $key ]['default'] ) ) {
622
+ $value = $fields[ $key ]['default'];
623
+ }
624
+ }
625
+ }
626
+
627
+ return $value;
628
+ }
629
+
630
+ /**
631
+ * Get Landing section meta.
632
+ *
633
+ * @param int $post_id post id.
634
+ * @param string $key options key.
635
+ * @param mix $default options default value.
636
+ * @return string
637
+ */
638
+ public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
+
640
+ $value = $this->get_save_meta( $post_id, $key );
641
+ if ( ! $value ) {
642
+ if ( $default ) {
643
+ $value = $default;
644
+ } else {
645
+ $fields = $this->get_landing_fields( $post_id );
646
+
647
+ if ( isset( $fields[ $key ]['default'] ) ) {
648
+ $value = $fields[ $key ]['default'];
649
+ }
650
+ }
651
+ }
652
+
653
+ return $value;
654
+ }
655
+
656
+ /**
657
+ * Landing Default fields.
658
+ *
659
+ * @param int $post_id post id.
660
+ * @return array
661
+ */
662
+ public function get_landing_fields( $post_id ) {
663
+
664
+ if ( null === self::$landing_fields ) {
665
+ self::$landing_fields = array(
666
+ 'wcf-custom-script' => array(
667
+ 'default' => '',
668
+ 'sanitize' => 'FILTER_DEFAULT',
669
+ ),
670
+ );
671
+ }
672
+ return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
+ }
674
+
675
+ /**
676
+ * Optin Default fields.
677
+ *
678
+ * @param int $post_id post id.
679
+ * @return array
680
+ */
681
+ public function get_optin_fields( $post_id ) {
682
+
683
+ if ( null === self::$optin_fields ) {
684
+ self::$optin_fields = array(
685
+
686
+ 'wcf-optin-product' => array(
687
+ 'default' => array(),
688
+ 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
+ ),
690
+
691
+ /* Style */
692
+ 'wcf-field-google-font-url' => array(
693
+ 'default' => '',
694
+ 'sanitize' => 'FILTER_DEFAULT',
695
+ ),
696
+ 'wcf-primary-color' => array(
697
+ 'default' => '',
698
+ 'sanitize' => 'FILTER_DEFAULT',
699
+ ),
700
+ 'wcf-base-font-family' => array(
701
+ 'default' => '',
702
+ 'sanitize' => 'FILTER_DEFAULT',
703
+ ),
704
+ 'wcf-input-fields-skins' => array(
705
+ 'default' => '',
706
+ 'sanitize' => 'FILTER_DEFAULT',
707
+ ),
708
+ 'wcf-input-font-family' => array(
709
+ 'default' => '',
710
+ 'sanitize' => 'FILTER_DEFAULT',
711
+ ),
712
+ 'wcf-input-font-weight' => array(
713
+ 'default' => '',
714
+ 'sanitize' => 'FILTER_DEFAULT',
715
+ ),
716
+ 'wcf-input-field-size' => array(
717
+ 'default' => '33px',
718
+ 'sanitize' => 'FILTER_DEFAULT',
719
+ ),
720
+ 'wcf-field-tb-padding' => array(
721
+ 'default' => '',
722
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
+ ),
724
+ 'wcf-field-lr-padding' => array(
725
+ 'default' => '',
726
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
+ ),
728
+ 'wcf-field-color' => array(
729
+ 'default' => '',
730
+ 'sanitize' => 'FILTER_DEFAULT',
731
+ ),
732
+ 'wcf-field-bg-color' => array(
733
+ 'default' => '',
734
+ 'sanitize' => 'FILTER_DEFAULT',
735
+ ),
736
+ 'wcf-field-border-color' => array(
737
+ 'default' => '',
738
+ 'sanitize' => 'FILTER_DEFAULT',
739
+ ),
740
+ 'wcf-field-label-color' => array(
741
+ 'default' => '',
742
+ 'sanitize' => 'FILTER_DEFAULT',
743
+ ),
744
+ 'wcf-submit-button-text' => array(
745
+ 'default' => __( 'Submit', 'cartflows' ),
746
+ 'sanitize' => 'FILTER_DEFAULT',
747
+ ),
748
+ 'wcf-submit-font-size' => array(
749
+ 'default' => '',
750
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
+ ),
752
+ 'wcf-button-font-family' => array(
753
+ 'default' => '',
754
+ 'sanitize' => 'FILTER_DEFAULT',
755
+ ),
756
+ 'wcf-button-font-weight' => array(
757
+ 'default' => '',
758
+ 'sanitize' => 'FILTER_DEFAULT',
759
+ ),
760
+ 'wcf-submit-button-size' => array(
761
+ 'default' => '33px',
762
+ 'sanitize' => 'FILTER_DEFAULT',
763
+ ),
764
+ 'wcf-submit-tb-padding' => array(
765
+ 'default' => '',
766
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
+ ),
768
+ 'wcf-submit-lr-padding' => array(
769
+ 'default' => '',
770
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
+ ),
772
+ 'wcf-submit-button-position' => array(
773
+ 'default' => 'center',
774
+ 'sanitize' => 'FILTER_DEFAULT',
775
+ ),
776
+ 'wcf-submit-color' => array(
777
+ 'default' => '',
778
+ 'sanitize' => 'FILTER_DEFAULT',
779
+ ),
780
+ 'wcf-submit-hover-color' => array(
781
+ 'default' => '',
782
+ 'sanitize' => 'FILTER_DEFAULT',
783
+ ),
784
+ 'wcf-submit-bg-color' => array(
785
+ 'default' => '',
786
+ 'sanitize' => 'FILTER_DEFAULT',
787
+ ),
788
+ 'wcf-submit-bg-hover-color' => array(
789
+ 'default' => '',
790
+ 'sanitize' => 'FILTER_DEFAULT',
791
+ ),
792
+ 'wcf-submit-border-color' => array(
793
+ 'default' => '',
794
+ 'sanitize' => 'FILTER_DEFAULT',
795
+ ),
796
+ 'wcf-submit-border-hover-color' => array(
797
+ 'default' => '',
798
+ 'sanitize' => 'FILTER_DEFAULT',
799
+ ),
800
+
801
+ /* Settings */
802
+ 'wcf-optin-pass-fields' => array(
803
+ 'default' => '',
804
+ 'sanitize' => 'FILTER_DEFAULT',
805
+ ),
806
+ 'wcf-optin-pass-specific-fields' => array(
807
+ 'default' => 'first_name',
808
+ 'sanitize' => 'FILTER_DEFAULT',
809
+ ),
810
+
811
+ /* Script */
812
+ 'wcf-custom-script' => array(
813
+ 'default' => '',
814
+ 'sanitize' => 'FILTER_DEFAULT',
815
+ ),
816
+
817
+ /* Hidden */
818
+ 'wcf-active-tab' => array(
819
+ 'default' => '',
820
+ 'sanitize' => 'FILTER_DEFAULT',
821
+ ),
822
+ );
823
+ }
824
+ return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
+ }
826
+
827
+ /**
828
+ * Save Optin Meta fields.
829
+ *
830
+ * @param int $post_id post id.
831
+ * @return void
832
+ */
833
+ public function save_optin_fields( $post_id ) {
834
+
835
+ $post_meta = $this->get_optin_fields( $post_id );
836
+
837
+ $this->save_meta_fields( $post_id, $post_meta );
838
+ }
839
+
840
+ /**
841
+ * Get optin meta.
842
+ *
843
+ * @param int $post_id post id.
844
+ * @param string $key options key.
845
+ * @param mix $default options default value.
846
+ * @return string
847
+ */
848
+ public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
+
850
+ $value = $this->get_save_meta( $post_id, $key );
851
+
852
+ if ( ! $value ) {
853
+ if ( false !== $default ) {
854
+ $value = $default;
855
+ } else {
856
+ $fields = $this->get_optin_fields( $post_id );
857
+
858
+ if ( isset( $fields[ $key ]['default'] ) ) {
859
+ $value = $fields[ $key ]['default'];
860
+ }
861
+ }
862
+ }
863
+
864
+ return $value;
865
+ }
866
+ }
867
+
868
+ /**
869
+ * Kicking this off by calling 'get_instance()' method
870
+ */
871
+ Cartflows_Default_Meta::get_instance();
classes/class-cartflows-flow-frontend.php CHANGED
@@ -1,247 +1,247 @@
1
- <?php
2
- /**
3
- * Frontend & Markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Frontend {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- /* Analytics */
39
- add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
- }
41
-
42
- /**
43
- * Footer markup
44
- */
45
- public function footer_markup() {
46
-
47
- if ( wcf()->utils->is_step_post_type() ) {
48
- // @codingStandardsIgnoreStart
49
- $flow_id = wcf()->utils->get_flow_id();
50
- ?>
51
- <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
- <div class="wcf-preview-mode">
53
- <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
- <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
- <?php
56
- $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
- ?>
58
- <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
- <?php } ?>
60
- </div>
61
- <?php } ?>
62
- <?php
63
- // @codingStandardsIgnoreEnd
64
- }
65
- }
66
-
67
- /**
68
- * Check if flow test mode is enable.
69
- *
70
- * @since 1.0.0
71
- * @param int $flow_id flow ID.
72
- *
73
- * @return boolean
74
- */
75
- public function is_flow_testmode( $flow_id = '' ) {
76
-
77
- if ( ! $flow_id ) {
78
- $flow_id = wcf()->utils->get_flow_id();
79
- }
80
-
81
- $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
-
83
- if ( 'no' === $test_mode ) {
84
- return false;
85
- }
86
-
87
- return true;
88
- }
89
-
90
- /**
91
- * Get steps data.
92
- *
93
- * @since 1.0.0
94
- * @param int $flow_id flow ID.
95
- *
96
- * @return array
97
- */
98
- public function get_steps( $flow_id ) {
99
-
100
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
-
102
- if ( ! is_array( $steps ) ) {
103
-
104
- $steps = array();
105
- }
106
-
107
- return $steps;
108
- }
109
-
110
- /**
111
- * Check thank you page exists.
112
- *
113
- * @since 1.0.0
114
- * @param array $order order data.
115
- *
116
- * @return bool
117
- */
118
- public function is_thankyou_page_exists( $order ) {
119
-
120
- $thankyou_step_exist = false;
121
-
122
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
-
124
- if ( $flow_id ) {
125
-
126
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
-
129
- if ( is_array( $flow_steps ) ) {
130
-
131
- $current_step_found = false;
132
-
133
- foreach ( $flow_steps as $index => $data ) {
134
-
135
- if ( $current_step_found ) {
136
-
137
- if ( 'thankyou' === $data['type'] ) {
138
-
139
- $thankyou_step_exist = true;
140
- break;
141
- }
142
- } else {
143
-
144
- if ( intval( $data['id'] ) === $step_id ) {
145
-
146
- $current_step_found = true;
147
- }
148
- }
149
- }
150
- }
151
- }
152
-
153
- return $thankyou_step_exist;
154
- }
155
-
156
- /**
157
- * Check thank you page exists.
158
- *
159
- * @since 1.0.0
160
- * @param array $order order data.
161
- *
162
- * @return bool
163
- */
164
- public function get_thankyou_page_id( $order ) {
165
-
166
- $thankyou_step_id = false;
167
-
168
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
-
170
- if ( $flow_id ) {
171
-
172
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
-
175
- if ( is_array( $flow_steps ) ) {
176
-
177
- $current_step_found = false;
178
-
179
- foreach ( $flow_steps as $index => $data ) {
180
-
181
- if ( $current_step_found ) {
182
-
183
- if ( 'thankyou' === $data['type'] ) {
184
-
185
- $thankyou_step_id = intval( $data['id'] );
186
- break;
187
- }
188
- } else {
189
-
190
- if ( intval( $data['id'] ) === $step_id ) {
191
-
192
- $current_step_found = true;
193
- }
194
- }
195
- }
196
- }
197
- }
198
-
199
- return $thankyou_step_id;
200
- }
201
-
202
- /**
203
- * Check thank you page exists.
204
- *
205
- * @since 1.0.0
206
- * @param array $order order data.
207
- *
208
- * @return bool
209
- */
210
- public function get_next_step_id( $order ) {
211
-
212
- $next_step_id = false;
213
-
214
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
-
216
- if ( $flow_id ) {
217
-
218
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
- $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
-
221
- if ( is_array( $flow_steps ) ) {
222
-
223
- foreach ( $flow_steps as $index => $data ) {
224
-
225
- if ( intval( $data['id'] ) === $step_id ) {
226
-
227
- $next_step_index = $index + 1;
228
-
229
- if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
-
231
- $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
- }
233
-
234
- break;
235
- }
236
- }
237
- }
238
- }
239
-
240
- return $next_step_id;
241
- }
242
- }
243
-
244
- /**
245
- * Kicking this off by calling 'get_instance()' method
246
- */
247
- Cartflows_Flow_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * Frontend & Markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Frontend {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ /* Analytics */
39
+ add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
+ }
41
+
42
+ /**
43
+ * Footer markup
44
+ */
45
+ public function footer_markup() {
46
+
47
+ if ( wcf()->utils->is_step_post_type() ) {
48
+ // @codingStandardsIgnoreStart
49
+ $flow_id = wcf()->utils->get_flow_id();
50
+ ?>
51
+ <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
+ <div class="wcf-preview-mode">
53
+ <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
+ <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
+ <?php
56
+ $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
+ ?>
58
+ <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
+ <?php } ?>
60
+ </div>
61
+ <?php } ?>
62
+ <?php
63
+ // @codingStandardsIgnoreEnd
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Check if flow test mode is enable.
69
+ *
70
+ * @since 1.0.0
71
+ * @param int $flow_id flow ID.
72
+ *
73
+ * @return boolean
74
+ */
75
+ public function is_flow_testmode( $flow_id = '' ) {
76
+
77
+ if ( ! $flow_id ) {
78
+ $flow_id = wcf()->utils->get_flow_id();
79
+ }
80
+
81
+ $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
+
83
+ if ( 'no' === $test_mode ) {
84
+ return false;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ /**
91
+ * Get steps data.
92
+ *
93
+ * @since 1.0.0
94
+ * @param int $flow_id flow ID.
95
+ *
96
+ * @return array
97
+ */
98
+ public function get_steps( $flow_id ) {
99
+
100
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
+
102
+ if ( ! is_array( $steps ) ) {
103
+
104
+ $steps = array();
105
+ }
106
+
107
+ return $steps;
108
+ }
109
+
110
+ /**
111
+ * Check thank you page exists.
112
+ *
113
+ * @since 1.0.0
114
+ * @param array $order order data.
115
+ *
116
+ * @return bool
117
+ */
118
+ public function is_thankyou_page_exists( $order ) {
119
+
120
+ $thankyou_step_exist = false;
121
+
122
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
+
124
+ if ( $flow_id ) {
125
+
126
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
+
129
+ if ( is_array( $flow_steps ) ) {
130
+
131
+ $current_step_found = false;
132
+
133
+ foreach ( $flow_steps as $index => $data ) {
134
+
135
+ if ( $current_step_found ) {
136
+
137
+ if ( 'thankyou' === $data['type'] ) {
138
+
139
+ $thankyou_step_exist = true;
140
+ break;
141
+ }
142
+ } else {
143
+
144
+ if ( intval( $data['id'] ) === $step_id ) {
145
+
146
+ $current_step_found = true;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ return $thankyou_step_exist;
154
+ }
155
+
156
+ /**
157
+ * Check thank you page exists.
158
+ *
159
+ * @since 1.0.0
160
+ * @param array $order order data.
161
+ *
162
+ * @return bool
163
+ */
164
+ public function get_thankyou_page_id( $order ) {
165
+
166
+ $thankyou_step_id = false;
167
+
168
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
+
170
+ if ( $flow_id ) {
171
+
172
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
+
175
+ if ( is_array( $flow_steps ) ) {
176
+
177
+ $current_step_found = false;
178
+
179
+ foreach ( $flow_steps as $index => $data ) {
180
+
181
+ if ( $current_step_found ) {
182
+
183
+ if ( 'thankyou' === $data['type'] ) {
184
+
185
+ $thankyou_step_id = intval( $data['id'] );
186
+ break;
187
+ }
188
+ } else {
189
+
190
+ if ( intval( $data['id'] ) === $step_id ) {
191
+
192
+ $current_step_found = true;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ return $thankyou_step_id;
200
+ }
201
+
202
+ /**
203
+ * Check thank you page exists.
204
+ *
205
+ * @since 1.0.0
206
+ * @param array $order order data.
207
+ *
208
+ * @return bool
209
+ */
210
+ public function get_next_step_id( $order ) {
211
+
212
+ $next_step_id = false;
213
+
214
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
+
216
+ if ( $flow_id ) {
217
+
218
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
+ $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
+
221
+ if ( is_array( $flow_steps ) ) {
222
+
223
+ foreach ( $flow_steps as $index => $data ) {
224
+
225
+ if ( intval( $data['id'] ) === $step_id ) {
226
+
227
+ $next_step_index = $index + 1;
228
+
229
+ if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
+
231
+ $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
+ }
233
+
234
+ break;
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ return $next_step_id;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Kicking this off by calling 'get_instance()' method
246
+ */
247
+ Cartflows_Flow_Frontend::get_instance();
classes/class-cartflows-frontend.php CHANGED
@@ -1,654 +1,654 @@
1
- <?php
2
- /**
3
- * CartFlows Frontend.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Frontend.
10
- */
11
- class Cartflows_Frontend {
12
-
13
- /**
14
- * Member Variable
15
- *
16
- * @var instance
17
- */
18
- private static $instance;
19
-
20
- /**
21
- * Initiator
22
- */
23
- public static function get_instance() {
24
- if ( ! isset( self::$instance ) ) {
25
- self::$instance = new self();
26
- }
27
- return self::$instance;
28
- }
29
-
30
- /**
31
- * Constructor
32
- */
33
- public function __construct() {
34
-
35
- /* Set / Destroy Flow Sessions. Set data */
36
- add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
-
38
- add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
- add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
- /* Enqueue global required scripts */
41
- add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
-
43
- /* Modify the checkout order received url to go thank you page in our flow */
44
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
-
46
- add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
-
48
- }
49
-
50
- /**
51
- * Redirect to thank page if upsell not exists
52
- *
53
- * @param string $order_recieve_url url.
54
- * @param object $order order object.
55
- * @since 1.0.0
56
- */
57
- public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
-
59
- /* Only for thank you page */
60
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
- wcf()->logger->log( 'Only for thank you page' );
62
-
63
- if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
-
65
- if ( _is_wcf_doing_checkout_ajax() ) {
66
-
67
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
-
69
- if ( ! $checkout_id ) {
70
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
- }
72
- } else {
73
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
- }
75
-
76
- wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
-
78
- if ( $checkout_id ) {
79
-
80
- $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
-
82
- if ( $thankyou_step_id ) {
83
-
84
- $order_recieve_url = get_permalink( $thankyou_step_id );
85
-
86
- $order_recieve_url = add_query_arg(
87
- array(
88
- 'wcf-key' => $order->get_order_key(),
89
- 'wcf-order' => $order->get_id(),
90
- ),
91
- $order_recieve_url
92
- );
93
- }
94
- }
95
- }
96
-
97
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
-
99
- Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
-
101
- Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
-
103
- return $order_recieve_url;
104
- }
105
-
106
- /**
107
- * Cancel and redirect to checkout
108
- *
109
- * @param string $return_url url.
110
- * @since 1.0.0
111
- */
112
- public function redirect_to_checkout_on_cancel( $return_url ) {
113
-
114
- if ( _is_wcf_doing_checkout_ajax() ) {
115
-
116
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
-
118
- if ( ! $checkout_id ) {
119
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
- }
121
- } else {
122
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
- }
124
-
125
- if ( $checkout_id ) {
126
-
127
- $return_url = add_query_arg(
128
- array(
129
- 'cancel_order' => 'true',
130
- '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
- ),
132
- get_permalink( $checkout_id )
133
- );
134
- }
135
-
136
- return $return_url;
137
- }
138
-
139
-
140
- /**
141
- * Remove theme styles.
142
- *
143
- * @since 1.0.0
144
- */
145
- public function remove_theme_styles() {
146
-
147
- if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
- return;
149
- }
150
-
151
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
-
153
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
-
155
- if ( ! _wcf_supported_template( $page_template ) ) {
156
- return;
157
- }
158
-
159
- // get all styles data.
160
- global $wp_styles;
161
- global $wp_scripts;
162
-
163
- $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
- $get_template = 'themes/' . get_template() . '/';
165
-
166
- $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
-
168
- if ( $remove_styles ) {
169
-
170
- // loop over all of the registered scripts..
171
- foreach ( $wp_styles->registered as $handle => $data ) {
172
-
173
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
-
175
- // remove it.
176
- wp_deregister_style( $handle );
177
- wp_dequeue_style( $handle );
178
- }
179
- }
180
- }
181
-
182
- $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
-
184
- if ( $remove_scripts ) {
185
-
186
- // loop over all of the registered scripts.
187
- foreach ( $wp_scripts->registered as $handle => $data ) {
188
-
189
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
-
191
- // remove it.
192
- wp_deregister_script( $handle );
193
- wp_dequeue_script( $handle );
194
- }
195
- }
196
- }
197
-
198
- }
199
-
200
- /**
201
- * Update main order data in transient.
202
- *
203
- * @param array $woo_styles new styles array.
204
- * @since 1.0.0
205
- * @return array.
206
- */
207
- public function woo_default_css( $woo_styles ) {
208
-
209
- $woo_styles = array(
210
- 'woocommerce-layout' => array(
211
- 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
- 'deps' => '',
213
- 'version' => WC_VERSION,
214
- 'media' => 'all',
215
- 'has_rtl' => true,
216
- ),
217
- 'woocommerce-smallscreen' => array(
218
- 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
- 'deps' => 'woocommerce-layout',
220
- 'version' => WC_VERSION,
221
- 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
- 'has_rtl' => true,
223
- ),
224
- 'woocommerce-general' => array(
225
- 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
- 'deps' => '',
227
- 'version' => WC_VERSION,
228
- 'media' => 'all',
229
- 'has_rtl' => true,
230
- ),
231
- );
232
-
233
- return $woo_styles;
234
- }
235
-
236
- /**
237
- * Init Actions.
238
- *
239
- * @since 1.0.0
240
- */
241
- public function init_actions() {
242
-
243
- $this->set_flow_session();
244
- }
245
-
246
- /**
247
- * Set flow session.
248
- *
249
- * @since 1.0.0
250
- */
251
- public function set_flow_session() {
252
-
253
- if ( wcf()->utils->is_step_post_type() ) {
254
- global $wp;
255
- add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
-
257
- wcf()->utils->do_not_cache();
258
-
259
- if ( _is_wcf_thankyou_type() ) {
260
- /* Set key to support pixel */
261
- if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
-
263
- $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
-
265
- $_GET['key'] = $wcf_key;
266
- $_REQUEST['key'] = $wcf_key;
267
- }
268
-
269
- if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
-
271
- $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
-
273
- $_GET['order'] = $wcf_order;
274
- $_REQUEST['order'] = $wcf_order;
275
- $_GET['order-received'] = $wcf_order;
276
- $_REQUEST['order-received'] = $wcf_order;
277
-
278
- $wp->set_query_var( 'order-received', $wcf_order );
279
- }
280
- }
281
- }
282
- }
283
-
284
- /**
285
- * Add noindex, nofollow.
286
- *
287
- * @since 1.0.0
288
- */
289
- public function noindex_flow() {
290
-
291
- $common = Cartflows_Helper::get_common_settings();
292
-
293
- if ( 'enable' === $common['disallow_indexing'] ) {
294
- echo '<meta name="robots" content="noindex,nofollow">';
295
- }
296
- }
297
-
298
- /**
299
- * WP Actions.
300
- *
301
- * @since 1.0.0
302
- */
303
- public function wp_actions() {
304
-
305
- if ( wcf()->utils->is_step_post_type() ) {
306
-
307
- if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
- wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
- }
310
-
311
- /* CSS Compatibility for All theme */
312
- add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
-
314
- add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
- add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
-
317
- /* Load woo templates from plugin */
318
- add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
-
320
- /* Add version class to body in frontend. */
321
- add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
-
323
- /* Custom Script Option */
324
- add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
-
326
- /* Remove the action applied by the Flatsome theme */
327
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
- $this->remove_flatsome_action();
329
- }
330
- }
331
- }
332
-
333
- /**
334
- * Function for facebook pixel.
335
- */
336
- public function facebook_pixel_init() {
337
-
338
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
-
341
- $facebook_id = $facebook_settings['facebook_pixel_id'];
342
- echo '<!-- Facebook Pixel Script By CartFlows -->';
343
- $fb_script = "<script type='text/javascript'>
344
- !function(f,b,e,v,n,t,s)
345
- {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
- n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
- if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
- n.queue=[];t=b.createElement(e);t.async=!0;
349
- t.src=v;s=b.getElementsByTagName(e)[0];
350
- s.parentNode.insertBefore(t,s)}(window, document,'script',
351
- 'https://connect.facebook.net/en_US/fbevents.js');
352
- </script>
353
- <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
-
355
- $fb_page_view = "<script type='text/javascript'>
356
- fbq('init', $facebook_id);
357
- fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
- </script>";
359
-
360
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
- echo $fb_script;
362
- echo $fb_page_view;
363
- } else {
364
- echo $fb_script;
365
- }
366
- echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
- }
368
-
369
- }
370
-
371
- /**
372
- * Debug Data Setting Actions.
373
- *
374
- * @since 1.1.14
375
- */
376
- public function debug_data_setting_actions() {
377
-
378
- add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
- }
380
-
381
- /**
382
- * Get/Set the allow minify option.
383
- *
384
- * @since 1.1.14
385
- */
386
- public function allow_load_minify() {
387
- $debug_data = Cartflows_Helper::get_debug_settings();
388
- $allow_minified = $debug_data['allow_minified_files'];
389
- $allow_minify = false;
390
-
391
- if ( 'enable' === $allow_minified ) {
392
- $allow_minify = true;
393
- }
394
-
395
- return $allow_minify;
396
- }
397
-
398
- /**
399
- * Global flow scripts.
400
- *
401
- * @since 1.0.0
402
- */
403
- public function global_flow_scripts() {
404
-
405
- global $post;
406
-
407
- $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
- $current_step = $post->ID;
409
- $next_step_link = '';
410
- $compatibility = Cartflows_Compatibility::get_instance();
411
-
412
- if ( _is_wcf_landing_type() ) {
413
-
414
- $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
- $next_step_link = get_permalink( $next_step_id );
416
- }
417
-
418
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
-
420
- $fb_active = Cartflows_Helper::get_facebook_settings();
421
- $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
- $params = array();
423
- $ga_param = array();
424
-
425
- if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
-
427
- $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
- }
429
-
430
- if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
- $ga_param = Cartflows_Tracking::get_ga_items_list();
432
- }
433
-
434
- $localize = array(
435
- 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
- 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
- 'current_theme' => $compatibility->get_current_theme(),
438
- 'current_flow' => $flow,
439
- 'current_step' => $current_step,
440
- 'next_step' => $next_step_link,
441
- 'page_template' => $page_template,
442
- 'is_checkout_page' => _is_wcf_checkout_type(),
443
- 'params' => $params,
444
- 'fb_active' => $fb_active,
445
- 'wcf_ga_active' => $wcf_ga_active,
446
- 'ga_param' => $ga_param,
447
- );
448
-
449
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
-
451
- if ( _wcf_supported_template( $page_template ) ) {
452
-
453
- wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
- }
455
-
456
- wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
-
458
- wp_enqueue_script(
459
- 'wcf-frontend-global',
460
- wcf()->utils->get_js_url( 'frontend' ),
461
- array( 'jquery', 'jquery-cookie' ),
462
- CARTFLOWS_VER,
463
- false
464
- );
465
- }
466
-
467
- /**
468
- * Custom Script in head.
469
- *
470
- * @since 1.0.0
471
- */
472
- public function custom_script_option() {
473
-
474
- /* Add custom script to header in frontend. */
475
- $script = $this->get_custom_script();
476
- if ( '' !== $script ) {
477
- if ( false === strpos( $script, '<script' ) ) {
478
- $script = '<script>' . $script . '</script>';
479
- }
480
- echo '<!-- Custom CartFlows Script -->';
481
- echo $script;
482
- echo '<!-- End Custom CartFlows Script -->';
483
- }
484
- }
485
-
486
- /**
487
- * Override woo templates.
488
- *
489
- * @param string $template new Template full path.
490
- * @param string $template_name Template name.
491
- * @param string $template_path Template Path.
492
- * @since 1.1.5
493
- * @return string.
494
- */
495
- public function override_woo_template( $template, $template_name, $template_path ) {
496
-
497
- global $woocommerce;
498
-
499
- $_template = $template;
500
-
501
- $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
-
503
- if ( file_exists( $plugin_path . $template_name ) ) {
504
- $template = $plugin_path . $template_name;
505
- }
506
-
507
- if ( ! $template ) {
508
- $template = $_template;
509
- }
510
-
511
- return $template;
512
- }
513
-
514
- /**
515
- * Remove the action applied by the Flatsome theme.
516
- *
517
- * @since 1.1.5
518
- * @return void.
519
- */
520
- public function remove_flatsome_action() {
521
-
522
- // Remove action where flatsome dequeued the woocommerce's default styles.
523
- remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
- }
525
-
526
- /**
527
- * Add version class to body in frontend.
528
- *
529
- * @since 1.1.5
530
- * @param array $classes classes.
531
- * @return array $classes classes.
532
- */
533
- public function add_cartflows_lite_version_to_body( $classes ) {
534
-
535
- $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
-
537
- return $classes;
538
-
539
- }
540
-
541
- /**
542
- * Get custom script data.
543
- *
544
- * @since 1.0.0
545
- */
546
- public function get_custom_script() {
547
-
548
- global $post;
549
-
550
- $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
-
552
- return $script;
553
- }
554
-
555
-
556
- /**
557
- * Set appropriate filter sctions.
558
- *
559
- * @since 1.1.14
560
- */
561
- public function setup_optin_checkout_filter() {
562
-
563
- if ( _is_wcf_doing_optin_ajax() ) {
564
- /* Modify the optin order received url to go next step */
565
- remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
- }
568
- }
569
-
570
- /**
571
- * Redirect to thank page if upsell not exists
572
- *
573
- * @param string $order_recieve_url url.
574
- * @param object $order order object.
575
- * @since 1.0.0
576
- */
577
- public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
-
579
- /* Only for optin page */
580
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
- wcf()->logger->log( 'Only for optin page' );
582
-
583
- if ( _is_wcf_doing_optin_ajax() ) {
584
-
585
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
-
587
- if ( ! $optin_id ) {
588
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
- }
590
- } else {
591
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
- }
593
-
594
- wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
-
596
- if ( $optin_id ) {
597
-
598
- $next_step_id = wcf()->flow->get_next_step_id( $order );
599
-
600
- if ( $next_step_id ) {
601
-
602
- $order_recieve_url = get_permalink( $next_step_id );
603
- $query_param = array(
604
- 'wcf-key' => $order->get_order_key(),
605
- 'wcf-order' => $order->get_id(),
606
- );
607
-
608
- if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
-
610
- $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
-
612
- $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
-
614
- if ( is_array( $fields ) ) {
615
-
616
- $order_id = $order->get_id();
617
-
618
- foreach ( $fields as $in => $key ) {
619
- switch ( $key ) {
620
- case 'first_name':
621
- $query_param[ $key ] = $order->get_billing_first_name();
622
- break;
623
- case 'last_name':
624
- $query_param[ $key ] = $order->get_billing_last_name();
625
- break;
626
- case 'email':
627
- $query_param[ $key ] = $order->get_billing_email();
628
- break;
629
- default:
630
- $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
- break;
632
- }
633
- }
634
- }
635
- }
636
-
637
- $order_recieve_url = add_query_arg(
638
- $query_param,
639
- $order_recieve_url
640
- );
641
- }
642
- }
643
-
644
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
-
646
- return $order_recieve_url;
647
- }
648
- }
649
-
650
- /**
651
- * Prepare if class 'Cartflows_Frontend' exist.
652
- * Kicking this off by calling 'get_instance()' method
653
- */
654
- Cartflows_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * CartFlows Frontend.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Frontend.
10
+ */
11
+ class Cartflows_Frontend {
12
+
13
+ /**
14
+ * Member Variable
15
+ *
16
+ * @var instance
17
+ */
18
+ private static $instance;
19
+
20
+ /**
21
+ * Initiator
22
+ */
23
+ public static function get_instance() {
24
+ if ( ! isset( self::$instance ) ) {
25
+ self::$instance = new self();
26
+ }
27
+ return self::$instance;
28
+ }
29
+
30
+ /**
31
+ * Constructor
32
+ */
33
+ public function __construct() {
34
+
35
+ /* Set / Destroy Flow Sessions. Set data */
36
+ add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
+
38
+ add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
+ add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
+ /* Enqueue global required scripts */
41
+ add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
+
43
+ /* Modify the checkout order received url to go thank you page in our flow */
44
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
+
46
+ add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
+
48
+ }
49
+
50
+ /**
51
+ * Redirect to thank page if upsell not exists
52
+ *
53
+ * @param string $order_recieve_url url.
54
+ * @param object $order order object.
55
+ * @since 1.0.0
56
+ */
57
+ public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
+
59
+ /* Only for thank you page */
60
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
+ wcf()->logger->log( 'Only for thank you page' );
62
+
63
+ if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
+
65
+ if ( _is_wcf_doing_checkout_ajax() ) {
66
+
67
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
+
69
+ if ( ! $checkout_id ) {
70
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
+ }
72
+ } else {
73
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
+ }
75
+
76
+ wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
+
78
+ if ( $checkout_id ) {
79
+
80
+ $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
+
82
+ if ( $thankyou_step_id ) {
83
+
84
+ $order_recieve_url = get_permalink( $thankyou_step_id );
85
+
86
+ $order_recieve_url = add_query_arg(
87
+ array(
88
+ 'wcf-key' => $order->get_order_key(),
89
+ 'wcf-order' => $order->get_id(),
90
+ ),
91
+ $order_recieve_url
92
+ );
93
+ }
94
+ }
95
+ }
96
+
97
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
+
99
+ Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
+
101
+ Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
+
103
+ return $order_recieve_url;
104
+ }
105
+
106
+ /**
107
+ * Cancel and redirect to checkout
108
+ *
109
+ * @param string $return_url url.
110
+ * @since 1.0.0
111
+ */
112
+ public function redirect_to_checkout_on_cancel( $return_url ) {
113
+
114
+ if ( _is_wcf_doing_checkout_ajax() ) {
115
+
116
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
+
118
+ if ( ! $checkout_id ) {
119
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
+ }
121
+ } else {
122
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
+ }
124
+
125
+ if ( $checkout_id ) {
126
+
127
+ $return_url = add_query_arg(
128
+ array(
129
+ 'cancel_order' => 'true',
130
+ '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
+ ),
132
+ get_permalink( $checkout_id )
133
+ );
134
+ }
135
+
136
+ return $return_url;
137
+ }
138
+
139
+
140
+ /**
141
+ * Remove theme styles.
142
+ *
143
+ * @since 1.0.0
144
+ */
145
+ public function remove_theme_styles() {
146
+
147
+ if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
+ return;
149
+ }
150
+
151
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
+
153
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
+
155
+ if ( ! _wcf_supported_template( $page_template ) ) {
156
+ return;
157
+ }
158
+
159
+ // get all styles data.
160
+ global $wp_styles;
161
+ global $wp_scripts;
162
+
163
+ $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
+ $get_template = 'themes/' . get_template() . '/';
165
+
166
+ $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
+
168
+ if ( $remove_styles ) {
169
+
170
+ // loop over all of the registered scripts..
171
+ foreach ( $wp_styles->registered as $handle => $data ) {
172
+
173
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
+
175
+ // remove it.
176
+ wp_deregister_style( $handle );
177
+ wp_dequeue_style( $handle );
178
+ }
179
+ }
180
+ }
181
+
182
+ $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
+
184
+ if ( $remove_scripts ) {
185
+
186
+ // loop over all of the registered scripts.
187
+ foreach ( $wp_scripts->registered as $handle => $data ) {
188
+
189
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
+
191
+ // remove it.
192
+ wp_deregister_script( $handle );
193
+ wp_dequeue_script( $handle );
194
+ }
195
+ }
196
+ }
197
+
198
+ }
199
+
200
+ /**
201
+ * Update main order data in transient.
202
+ *
203
+ * @param array $woo_styles new styles array.
204
+ * @since 1.0.0
205
+ * @return array.
206
+ */
207
+ public function woo_default_css( $woo_styles ) {
208
+
209
+ $woo_styles = array(
210
+ 'woocommerce-layout' => array(
211
+ 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
+ 'deps' => '',
213
+ 'version' => WC_VERSION,
214
+ 'media' => 'all',
215
+ 'has_rtl' => true,
216
+ ),
217
+ 'woocommerce-smallscreen' => array(
218
+ 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
+ 'deps' => 'woocommerce-layout',
220
+ 'version' => WC_VERSION,
221
+ 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
+ 'has_rtl' => true,
223
+ ),
224
+ 'woocommerce-general' => array(
225
+ 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
+ 'deps' => '',
227
+ 'version' => WC_VERSION,
228
+ 'media' => 'all',
229
+ 'has_rtl' => true,
230
+ ),
231
+ );
232
+
233
+ return $woo_styles;
234
+ }
235
+
236
+ /**
237
+ * Init Actions.
238
+ *
239
+ * @since 1.0.0
240
+ */
241
+ public function init_actions() {
242
+
243
+ $this->set_flow_session();
244
+ }
245
+
246
+ /**
247
+ * Set flow session.
248
+ *
249
+ * @since 1.0.0
250
+ */
251
+ public function set_flow_session() {
252
+
253
+ if ( wcf()->utils->is_step_post_type() ) {
254
+ global $wp;
255
+ add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
+
257
+ wcf()->utils->do_not_cache();
258
+
259
+ if ( _is_wcf_thankyou_type() ) {
260
+ /* Set key to support pixel */
261
+ if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
+
263
+ $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
+
265
+ $_GET['key'] = $wcf_key;
266
+ $_REQUEST['key'] = $wcf_key;
267
+ }
268
+
269
+ if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
+
271
+ $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
+
273
+ $_GET['order'] = $wcf_order;
274
+ $_REQUEST['order'] = $wcf_order;
275
+ $_GET['order-received'] = $wcf_order;
276
+ $_REQUEST['order-received'] = $wcf_order;
277
+
278
+ $wp->set_query_var( 'order-received', $wcf_order );
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Add noindex, nofollow.
286
+ *
287
+ * @since 1.0.0
288
+ */
289
+ public function noindex_flow() {
290
+
291
+ $common = Cartflows_Helper::get_common_settings();
292
+
293
+ if ( 'enable' === $common['disallow_indexing'] ) {
294
+ echo '<meta name="robots" content="noindex,nofollow">';
295
+ }
296
+ }
297
+
298
+ /**
299
+ * WP Actions.
300
+ *
301
+ * @since 1.0.0
302
+ */
303
+ public function wp_actions() {
304
+
305
+ if ( wcf()->utils->is_step_post_type() ) {
306
+
307
+ if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
+ wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
+ }
310
+
311
+ /* CSS Compatibility for All theme */
312
+ add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
+
314
+ add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
+ add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
+
317
+ /* Load woo templates from plugin */
318
+ add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
+
320
+ /* Add version class to body in frontend. */
321
+ add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
+
323
+ /* Custom Script Option */
324
+ add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
+
326
+ /* Remove the action applied by the Flatsome theme */
327
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
+ $this->remove_flatsome_action();
329
+ }
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Function for facebook pixel.
335
+ */
336
+ public function facebook_pixel_init() {
337
+
338
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
+
341
+ $facebook_id = $facebook_settings['facebook_pixel_id'];
342
+ echo '<!-- Facebook Pixel Script By CartFlows -->';
343
+ $fb_script = "<script type='text/javascript'>
344
+ !function(f,b,e,v,n,t,s)
345
+ {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
+ if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
+ n.queue=[];t=b.createElement(e);t.async=!0;
349
+ t.src=v;s=b.getElementsByTagName(e)[0];
350
+ s.parentNode.insertBefore(t,s)}(window, document,'script',
351
+ 'https://connect.facebook.net/en_US/fbevents.js');
352
+ </script>
353
+ <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
+
355
+ $fb_page_view = "<script type='text/javascript'>
356
+ fbq('init', $facebook_id);
357
+ fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
+ </script>";
359
+
360
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
+ echo $fb_script;
362
+ echo $fb_page_view;
363
+ } else {
364
+ echo $fb_script;
365
+ }
366
+ echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
+ }
368
+
369
+ }
370
+
371
+ /**
372
+ * Debug Data Setting Actions.
373
+ *
374
+ * @since 1.1.14
375
+ */
376
+ public function debug_data_setting_actions() {
377
+
378
+ add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
+ }
380
+
381
+ /**
382
+ * Get/Set the allow minify option.
383
+ *
384
+ * @since 1.1.14
385
+ */
386
+ public function allow_load_minify() {
387
+ $debug_data = Cartflows_Helper::get_debug_settings();
388
+ $allow_minified = $debug_data['allow_minified_files'];
389
+ $allow_minify = false;
390
+
391
+ if ( 'enable' === $allow_minified ) {
392
+ $allow_minify = true;
393
+ }
394
+
395
+ return $allow_minify;
396
+ }
397
+
398
+ /**
399
+ * Global flow scripts.
400
+ *
401
+ * @since 1.0.0
402
+ */
403
+ public function global_flow_scripts() {
404
+
405
+ global $post;
406
+
407
+ $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
+ $current_step = $post->ID;
409
+ $next_step_link = '';
410
+ $compatibility = Cartflows_Compatibility::get_instance();
411
+
412
+ if ( _is_wcf_landing_type() ) {
413
+
414
+ $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
+ $next_step_link = get_permalink( $next_step_id );
416
+ }
417
+
418
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
+
420
+ $fb_active = Cartflows_Helper::get_facebook_settings();
421
+ $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
+ $params = array();
423
+ $ga_param = array();
424
+
425
+ if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
+
427
+ $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
+ }
429
+
430
+ if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
+ $ga_param = Cartflows_Tracking::get_ga_items_list();
432
+ }
433
+
434
+ $localize = array(
435
+ 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
+ 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
+ 'current_theme' => $compatibility->get_current_theme(),
438
+ 'current_flow' => $flow,
439
+ 'current_step' => $current_step,
440
+ 'next_step' => $next_step_link,
441
+ 'page_template' => $page_template,
442
+ 'is_checkout_page' => _is_wcf_checkout_type(),
443
+ 'params' => $params,
444
+ 'fb_active' => $fb_active,
445
+ 'wcf_ga_active' => $wcf_ga_active,
446
+ 'ga_param' => $ga_param,
447
+ );
448
+
449
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
+
451
+ if ( _wcf_supported_template( $page_template ) ) {
452
+
453
+ wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
+ }
455
+
456
+ wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
+
458
+ wp_enqueue_script(
459
+ 'wcf-frontend-global',
460
+ wcf()->utils->get_js_url( 'frontend' ),
461
+ array( 'jquery', 'jquery-cookie' ),
462
+ CARTFLOWS_VER,
463
+ false
464
+ );
465
+ }
466
+
467
+ /**
468
+ * Custom Script in head.
469
+ *
470
+ * @since 1.0.0
471
+ */
472
+ public function custom_script_option() {
473
+
474
+ /* Add custom script to header in frontend. */
475
+ $script = $this->get_custom_script();
476
+ if ( '' !== $script ) {
477
+ if ( false === strpos( $script, '<script' ) ) {
478
+ $script = '<script>' . $script . '</script>';
479
+ }
480
+ echo '<!-- Custom CartFlows Script -->';
481
+ echo $script;
482
+ echo '<!-- End Custom CartFlows Script -->';
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Override woo templates.
488
+ *
489
+ * @param string $template new Template full path.
490
+ * @param string $template_name Template name.
491
+ * @param string $template_path Template Path.
492
+ * @since 1.1.5
493
+ * @return string.
494
+ */
495
+ public function override_woo_template( $template, $template_name, $template_path ) {
496
+
497
+ global $woocommerce;
498
+
499
+ $_template = $template;
500
+
501
+ $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
+
503
+ if ( file_exists( $plugin_path . $template_name ) ) {
504
+ $template = $plugin_path . $template_name;
505
+ }
506
+
507
+ if ( ! $template ) {
508
+ $template = $_template;
509
+ }
510
+
511
+ return $template;
512
+ }
513
+
514
+ /**
515
+ * Remove the action applied by the Flatsome theme.
516
+ *
517
+ * @since 1.1.5
518
+ * @return void.
519
+ */
520
+ public function remove_flatsome_action() {
521
+
522
+ // Remove action where flatsome dequeued the woocommerce's default styles.
523
+ remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
+ }
525
+
526
+ /**
527
+ * Add version class to body in frontend.
528
+ *
529
+ * @since 1.1.5
530
+ * @param array $classes classes.
531
+ * @return array $classes classes.
532
+ */
533
+ public function add_cartflows_lite_version_to_body( $classes ) {
534
+
535
+ $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
+
537
+ return $classes;
538
+
539
+ }
540
+
541
+ /**
542
+ * Get custom script data.
543
+ *
544
+ * @since 1.0.0
545
+ */
546
+ public function get_custom_script() {
547
+
548
+ global $post;
549
+
550
+ $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
+
552
+ return $script;
553
+ }
554
+
555
+
556
+ /**
557
+ * Set appropriate filter sctions.
558
+ *
559
+ * @since 1.1.14
560
+ */
561
+ public function setup_optin_checkout_filter() {
562
+
563
+ if ( _is_wcf_doing_optin_ajax() ) {
564
+ /* Modify the optin order received url to go next step */
565
+ remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
+ }
568
+ }
569
+
570
+ /**
571
+ * Redirect to thank page if upsell not exists
572
+ *
573
+ * @param string $order_recieve_url url.
574
+ * @param object $order order object.
575
+ * @since 1.0.0
576
+ */
577
+ public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
+
579
+ /* Only for optin page */
580
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
+ wcf()->logger->log( 'Only for optin page' );
582
+
583
+ if ( _is_wcf_doing_optin_ajax() ) {
584
+
585
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
+
587
+ if ( ! $optin_id ) {
588
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
+ }
590
+ } else {
591
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
+ }
593
+
594
+ wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
+
596
+ if ( $optin_id ) {
597
+
598
+ $next_step_id = wcf()->flow->get_next_step_id( $order );
599
+
600
+ if ( $next_step_id ) {
601
+
602
+ $order_recieve_url = get_permalink( $next_step_id );
603
+ $query_param = array(
604
+ 'wcf-key' => $order->get_order_key(),
605
+ 'wcf-order' => $order->get_id(),
606
+ );
607
+
608
+ if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
+
610
+ $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
+
612
+ $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
+
614
+ if ( is_array( $fields ) ) {
615
+
616
+ $order_id = $order->get_id();
617
+
618
+ foreach ( $fields as $in => $key ) {
619
+ switch ( $key ) {
620
+ case 'first_name':
621
+ $query_param[ $key ] = $order->get_billing_first_name();
622
+ break;
623
+ case 'last_name':
624
+ $query_param[ $key ] = $order->get_billing_last_name();
625
+ break;
626
+ case 'email':
627
+ $query_param[ $key ] = $order->get_billing_email();
628
+ break;
629
+ default:
630
+ $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
+ break;
632
+ }
633
+ }
634
+ }
635
+ }
636
+
637
+ $order_recieve_url = add_query_arg(
638
+ $query_param,
639
+ $order_recieve_url
640
+ );
641
+ }
642
+ }
643
+
644
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
+
646
+ return $order_recieve_url;
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Prepare if class 'Cartflows_Frontend' exist.
652
+ * Kicking this off by calling 'get_instance()' method
653
+ */
654
+ Cartflows_Frontend::get_instance();
classes/class-cartflows-functions.php CHANGED
@@ -1,539 +1,539 @@
1
- <?php
2
- /**
3
- * CartFlows Functions.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Fatal error mb_strpos fallback.
14
- *
15
- * @param string $string string where to find.
16
- * @param string $search string to search.
17
- * @since 1.0.0
18
- */
19
- function wcf_mb_strpos( $string, $search ) {
20
-
21
- if ( function_exists( 'mb_strpos' ) ) {
22
- return mb_strpos( $string, $search, 0, 'utf-8' );
23
- } else {
24
- return strpos( $string, $search );
25
- }
26
- }
27
-
28
- /**
29
- * Check if cartflows pro activated.
30
- *
31
- * @since 1.0.0
32
- */
33
- function _is_cartflows_pro() {
34
-
35
- if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
- return true;
37
- }
38
-
39
- return false;
40
-
41
- }
42
-
43
- /**
44
- * Returns pro version number.
45
- *
46
- * @param int $version version number.
47
- * @since 1.0.0
48
- */
49
- function _is_cartflows_pro_ver_less_than( $version ) {
50
-
51
- if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
- return true;
53
- }
54
-
55
- return false;
56
- }
57
-
58
- /**
59
- * Returns step id.
60
- *
61
- * @since 1.0.0
62
- */
63
- function _get_wcf_post_id() {
64
-
65
- global $post;
66
-
67
- if ( isset( $post->ID ) ) {
68
- return $post->ID;
69
- }
70
-
71
- return 0;
72
- }
73
-
74
- /**
75
- * Returns step id.
76
- *
77
- * @since 1.0.0
78
- */
79
- function _get_wcf_step_id() {
80
-
81
- if ( wcf()->utils->is_step_post_type() ) {
82
-
83
- global $post;
84
-
85
- return $post->ID;
86
- }
87
-
88
- return false;
89
- }
90
-
91
- /**
92
- * Check if it is a landing page?
93
- *
94
- * @since 1.0.0
95
- */
96
- function _is_wcf_landing_type() {
97
-
98
- if ( wcf()->utils->is_step_post_type() ) {
99
-
100
- global $post;
101
-
102
- if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
-
104
- return true;
105
- }
106
- }
107
-
108
- return false;
109
- }
110
-
111
- /**
112
- * Returns landing id.
113
- *
114
- * @since 1.0.0
115
- */
116
- function _get_wcf_landing_id() {
117
-
118
- if ( _is_wcf_landing_type() ) {
119
-
120
- global $post;
121
-
122
- return $post->ID;
123
- }
124
-
125
- return false;
126
- }
127
-
128
- /**
129
- * Is custom checkout?
130
- *
131
- * @param int $checkout_id checkout ID.
132
- * @since 1.0.0
133
- */
134
- function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
-
136
- $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
-
138
- if ( 'yes' === $is_custom ) {
139
-
140
- return true;
141
- }
142
-
143
- return false;
144
- }
145
-
146
- /**
147
- * Check if page is cartflow checkout.
148
- *
149
- * @since 1.0.0
150
- * @return bool
151
- */
152
- function _is_wcf_checkout_type() {
153
-
154
- if ( wcf()->utils->is_step_post_type() ) {
155
-
156
- global $post;
157
-
158
- if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
-
160
- return true;
161
- }
162
- }
163
-
164
- return false;
165
- }
166
-
167
- /**
168
- * Check if AJAX call is in progress.
169
- *
170
- * @since 1.0.0
171
- * @return bool
172
- */
173
- function _is_wcf_doing_checkout_ajax() {
174
-
175
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
-
177
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
- isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
- ) {
180
- return true;
181
- }
182
- }
183
-
184
- return false;
185
- }
186
-
187
- /**
188
- * Check if optin AJAX call is in progress.
189
- *
190
- * @since 1.0.0
191
- * @return bool
192
- */
193
- function _is_wcf_doing_optin_ajax() {
194
-
195
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
-
197
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
- isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
- ) {
200
- return true;
201
- }
202
- }
203
-
204
- return false;
205
- }
206
-
207
- /**
208
- * Returns checkout ID.
209
- *
210
- * @since 1.0.0
211
- * @return int/bool
212
- */
213
- function _get_wcf_checkout_id() {
214
-
215
- if ( _is_wcf_checkout_type() ) {
216
-
217
- global $post;
218
-
219
- return $post->ID;
220
- }
221
-
222
- return false;
223
- }
224
-
225
- /**
226
- * Check if it is checkout shortcode.
227
- *
228
- * @since 1.0.0
229
- * @return bool
230
- */
231
- function _is_wcf_checkout_shortcode() {
232
-
233
- global $post;
234
-
235
- if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
-
237
- return true;
238
- }
239
-
240
- return false;
241
- }
242
-
243
- /**
244
- * Check if it is checkout shortcode.
245
- *
246
- * @since 1.0.0
247
- * @param string $content shortcode content.
248
- * @return bool
249
- */
250
- function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
-
252
- $checkout_id = 0;
253
-
254
- if ( ! empty( $content ) ) {
255
-
256
- $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
-
258
- preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
-
260
- if ( ! empty( $regex_matches ) ) {
261
-
262
- if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
-
264
- $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
- $attribure_str = str_replace( '"', '', $attribure_str );
266
-
267
- $attributes = wp_parse_args( $attribure_str );
268
-
269
- if ( isset( $attributes['id'] ) ) {
270
- $checkout_id = $attributes['id'];
271
- }
272
- }
273
- }
274
- }
275
-
276
- return $checkout_id;
277
- }
278
-
279
- /**
280
- * Check if post type is upsell.
281
- *
282
- * @since 1.0.0
283
- * @return bool
284
- */
285
- function _is_wcf_upsell_type() {
286
-
287
- if ( wcf()->utils->is_step_post_type() ) {
288
-
289
- global $post;
290
-
291
- if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
-
293
- return true;
294
- }
295
- }
296
-
297
- return false;
298
- }
299
-
300
- /**
301
- * Returns upsell ID.
302
- *
303
- * @since 1.0.0
304
- * @return int/bool
305
- */
306
- function _get_wcf_upsell_id() {
307
-
308
- if ( _is_wcf_upsell_type() ) {
309
-
310
- global $post;
311
-
312
- return $post->ID;
313
- }
314
-
315
- return false;
316
- }
317
-
318
- /**
319
- * Check if post is of type downsell.
320
- *
321
- * @since 1.0.0
322
- * @return int/bool
323
- */
324
- function _is_wcf_downsell_type() {
325
-
326
- if ( wcf()->utils->is_step_post_type() ) {
327
-
328
- global $post;
329
-
330
- if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
-
332
- return true;
333
- }
334
- }
335
-
336
- return false;
337
- }
338
-
339
- /**
340
- * Get downsell page ID.
341
- *
342
- * @since 1.0.0
343
- * @return int/bool
344
- */
345
- function _get_wcf_downsell_id() {
346
-
347
- if ( _is_wcf_downsell_type() ) {
348
-
349
- global $post;
350
-
351
- return $post->ID;
352
- }
353
-
354
- return false;
355
- }
356
-
357
- /**
358
- * Check if page is of thank you type.
359
- *
360
- * @since 1.0.0
361
- * @return int/bool
362
- */
363
- function _is_wcf_thankyou_type() {
364
-
365
- if ( wcf()->utils->is_step_post_type() ) {
366
-
367
- global $post;
368
-
369
- if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
-
371
- return true;
372
- }
373
- }
374
-
375
- return false;
376
- }
377
-
378
- /**
379
- * Get thank you page ID.
380
- *
381
- * @since 1.0.0
382
- * @return int/bool
383
- */
384
- function _get_wcf_thankyou_id() {
385
-
386
- if ( _is_wcf_thankyou_type() ) {
387
-
388
- global $post;
389
-
390
- return $post->ID;
391
- }
392
-
393
- return false;
394
- }
395
-
396
-
397
- /**
398
- * Check if post type is upsell.
399
- *
400
- * @since 1.0.0
401
- * @return bool
402
- */
403
- function _is_wcf_base_offer_type() {
404
-
405
- if ( wcf()->utils->is_step_post_type() ) {
406
-
407
- global $post;
408
-
409
- $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
-
411
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
-
413
- return true;
414
- }
415
- }
416
-
417
- return false;
418
- }
419
-
420
- /**
421
- * Returns upsell ID.
422
- *
423
- * @since 1.0.0
424
- * @return int/bool
425
- */
426
- function _get_wcf_base_offer_id() {
427
-
428
- if ( _is_wcf_base_offer_type() ) {
429
-
430
- global $post;
431
-
432
- return $post->ID;
433
- }
434
-
435
- return false;
436
- }
437
-
438
- /**
439
- * Check if page is of optin type.
440
- *
441
- * @since 1.0.0
442
- * @return int/bool
443
- */
444
- function _is_wcf_optin_type() {
445
-
446
- if ( wcf()->utils->is_step_post_type() ) {
447
-
448
- global $post;
449
-
450
- if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
-
452
- return true;
453
- }
454
- }
455
-
456
- return false;
457
- }
458
-
459
- /**
460
- * Get optin page ID.
461
- *
462
- * @since 1.0.0
463
- * @return int/bool
464
- */
465
- function _get_wcf_optin_id() {
466
-
467
- if ( _is_wcf_optin_type() ) {
468
-
469
- global $post;
470
-
471
- return $post->ID;
472
- }
473
-
474
- return false;
475
- }
476
-
477
- /**
478
- * Define a constant if it is not already defined.
479
- *
480
- * @since 3.0.0
481
- * @param string $name Constant name.
482
- * @param mixed $value Value.
483
- */
484
- function wcf_maybe_define_constant( $name, $value ) {
485
- if ( ! defined( $name ) ) {
486
- define( $name, $value );
487
- }
488
- }
489
-
490
-
491
- if ( ! function_exists( 'wp_body_open' ) ) {
492
- /**
493
- * Fire the wp_body_open action.
494
- *
495
- * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
- */
497
- function wp_body_open() {
498
- /**
499
- * Triggered after the opening <body> tag.
500
- */
501
- do_action( 'wp_body_open' );
502
- }
503
- }
504
-
505
- /**
506
- * Check if type is optin by id.
507
- *
508
- * @param int $post_id post id.
509
- *
510
- * @return int/bool
511
- * @since 1.0.0
512
- */
513
- function _wcf_check_is_optin_by_id( $post_id ) {
514
-
515
- if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
-
517
- return true;
518
- }
519
-
520
- return false;
521
- }
522
-
523
- /**
524
- * Supported Page Template
525
- *
526
- * @param string $page_template current page template.
527
- *
528
- * @return int/bool
529
- * @since 1.5.7
530
- */
531
- function _wcf_supported_template( $page_template ) {
532
-
533
- if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
-
535
- return true;
536
- }
537
-
538
- return false;
539
- }
1
+ <?php
2
+ /**
3
+ * CartFlows Functions.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Fatal error mb_strpos fallback.
14
+ *
15
+ * @param string $string string where to find.
16
+ * @param string $search string to search.
17
+ * @since 1.0.0
18
+ */
19
+ function wcf_mb_strpos( $string, $search ) {
20
+
21
+ if ( function_exists( 'mb_strpos' ) ) {
22
+ return mb_strpos( $string, $search, 0, 'utf-8' );
23
+ } else {
24
+ return strpos( $string, $search );
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Check if cartflows pro activated.
30
+ *
31
+ * @since 1.0.0
32
+ */
33
+ function _is_cartflows_pro() {
34
+
35
+ if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Returns pro version number.
45
+ *
46
+ * @param int $version version number.
47
+ * @since 1.0.0
48
+ */
49
+ function _is_cartflows_pro_ver_less_than( $version ) {
50
+
51
+ if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
+ return true;
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Returns step id.
60
+ *
61
+ * @since 1.0.0
62
+ */
63
+ function _get_wcf_post_id() {
64
+
65
+ global $post;
66
+
67
+ if ( isset( $post->ID ) ) {
68
+ return $post->ID;
69
+ }
70
+
71
+ return 0;
72
+ }
73
+
74
+ /**
75
+ * Returns step id.
76
+ *
77
+ * @since 1.0.0
78
+ */
79
+ function _get_wcf_step_id() {
80
+
81
+ if ( wcf()->utils->is_step_post_type() ) {
82
+
83
+ global $post;
84
+
85
+ return $post->ID;
86
+ }
87
+
88
+ return false;
89
+ }
90
+
91
+ /**
92
+ * Check if it is a landing page?
93
+ *
94
+ * @since 1.0.0
95
+ */
96
+ function _is_wcf_landing_type() {
97
+
98
+ if ( wcf()->utils->is_step_post_type() ) {
99
+
100
+ global $post;
101
+
102
+ if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
+
104
+ return true;
105
+ }
106
+ }
107
+
108
+ return false;
109
+ }
110
+
111
+ /**
112
+ * Returns landing id.
113
+ *
114
+ * @since 1.0.0
115
+ */
116
+ function _get_wcf_landing_id() {
117
+
118
+ if ( _is_wcf_landing_type() ) {
119
+
120
+ global $post;
121
+
122
+ return $post->ID;
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Is custom checkout?
130
+ *
131
+ * @param int $checkout_id checkout ID.
132
+ * @since 1.0.0
133
+ */
134
+ function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
+
136
+ $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
+
138
+ if ( 'yes' === $is_custom ) {
139
+
140
+ return true;
141
+ }
142
+
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Check if page is cartflow checkout.
148
+ *
149
+ * @since 1.0.0
150
+ * @return bool
151
+ */
152
+ function _is_wcf_checkout_type() {
153
+
154
+ if ( wcf()->utils->is_step_post_type() ) {
155
+
156
+ global $post;
157
+
158
+ if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
+
160
+ return true;
161
+ }
162
+ }
163
+
164
+ return false;
165
+ }
166
+
167
+ /**
168
+ * Check if AJAX call is in progress.
169
+ *
170
+ * @since 1.0.0
171
+ * @return bool
172
+ */
173
+ function _is_wcf_doing_checkout_ajax() {
174
+
175
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
+
177
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
+ isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
+ ) {
180
+ return true;
181
+ }
182
+ }
183
+
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * Check if optin AJAX call is in progress.
189
+ *
190
+ * @since 1.0.0
191
+ * @return bool
192
+ */
193
+ function _is_wcf_doing_optin_ajax() {
194
+
195
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
+
197
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
+ isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
+ ) {
200
+ return true;
201
+ }
202
+ }
203
+
204
+ return false;
205
+ }
206
+
207
+ /**
208
+ * Returns checkout ID.
209
+ *
210
+ * @since 1.0.0
211
+ * @return int/bool
212
+ */
213
+ function _get_wcf_checkout_id() {
214
+
215
+ if ( _is_wcf_checkout_type() ) {
216
+
217
+ global $post;
218
+
219
+ return $post->ID;
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Check if it is checkout shortcode.
227
+ *
228
+ * @since 1.0.0
229
+ * @return bool
230
+ */
231
+ function _is_wcf_checkout_shortcode() {
232
+
233
+ global $post;
234
+
235
+ if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
+
237
+ return true;
238
+ }
239
+
240
+ return false;
241
+ }
242
+
243
+ /**
244
+ * Check if it is checkout shortcode.
245
+ *
246
+ * @since 1.0.0
247
+ * @param string $content shortcode content.
248
+ * @return bool
249
+ */
250
+ function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
+
252
+ $checkout_id = 0;
253
+
254
+ if ( ! empty( $content ) ) {
255
+
256
+ $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
+
258
+ preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
+
260
+ if ( ! empty( $regex_matches ) ) {
261
+
262
+ if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
+
264
+ $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
+ $attribure_str = str_replace( '"', '', $attribure_str );
266
+
267
+ $attributes = wp_parse_args( $attribure_str );
268
+
269
+ if ( isset( $attributes['id'] ) ) {
270
+ $checkout_id = $attributes['id'];
271
+ }
272
+ }
273
+ }
274
+ }
275
+
276
+ return $checkout_id;
277
+ }
278
+
279
+ /**
280
+ * Check if post type is upsell.
281
+ *
282
+ * @since 1.0.0
283
+ * @return bool
284
+ */
285
+ function _is_wcf_upsell_type() {
286
+
287
+ if ( wcf()->utils->is_step_post_type() ) {
288
+
289
+ global $post;
290
+
291
+ if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
+
293
+ return true;
294
+ }
295
+ }
296
+
297
+ return false;
298
+ }
299
+
300
+ /**
301
+ * Returns upsell ID.
302
+ *
303
+ * @since 1.0.0
304
+ * @return int/bool
305
+ */
306
+ function _get_wcf_upsell_id() {
307
+
308
+ if ( _is_wcf_upsell_type() ) {
309
+
310
+ global $post;
311
+
312
+ return $post->ID;
313
+ }
314
+
315
+ return false;
316
+ }
317
+
318
+ /**
319
+ * Check if post is of type downsell.
320
+ *
321
+ * @since 1.0.0
322
+ * @return int/bool
323
+ */
324
+ function _is_wcf_downsell_type() {
325
+
326
+ if ( wcf()->utils->is_step_post_type() ) {
327
+
328
+ global $post;
329
+
330
+ if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
+
332
+ return true;
333
+ }
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ /**
340
+ * Get downsell page ID.
341
+ *
342
+ * @since 1.0.0
343
+ * @return int/bool
344
+ */
345
+ function _get_wcf_downsell_id() {
346
+
347
+ if ( _is_wcf_downsell_type() ) {
348
+
349
+ global $post;
350
+
351
+ return $post->ID;
352
+ }
353
+
354
+ return false;
355
+ }
356
+
357
+ /**
358
+ * Check if page is of thank you type.
359
+ *
360
+ * @since 1.0.0
361
+ * @return int/bool
362
+ */
363
+ function _is_wcf_thankyou_type() {
364
+
365
+ if ( wcf()->utils->is_step_post_type() ) {
366
+
367
+ global $post;
368
+
369
+ if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
+
371
+ return true;
372
+ }
373
+ }
374
+
375
+ return false;
376
+ }
377
+
378
+ /**
379
+ * Get thank you page ID.
380
+ *
381
+ * @since 1.0.0
382
+ * @return int/bool
383
+ */
384
+ function _get_wcf_thankyou_id() {
385
+
386
+ if ( _is_wcf_thankyou_type() ) {
387
+
388
+ global $post;
389
+
390
+ return $post->ID;
391
+ }
392
+
393
+ return false;
394
+ }
395
+
396
+
397
+ /**
398
+ * Check if post type is upsell.
399
+ *
400
+ * @since 1.0.0
401
+ * @return bool
402
+ */
403
+ function _is_wcf_base_offer_type() {
404
+
405
+ if ( wcf()->utils->is_step_post_type() ) {
406
+
407
+ global $post;
408
+
409
+ $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
+
411
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
+
413
+ return true;
414
+ }
415
+ }
416
+
417
+ return false;
418
+ }
419
+
420
+ /**
421
+ * Returns upsell ID.
422
+ *
423
+ * @since 1.0.0
424
+ * @return int/bool
425
+ */
426
+ function _get_wcf_base_offer_id() {
427
+
428
+ if ( _is_wcf_base_offer_type() ) {
429
+
430
+ global $post;
431
+
432
+ return $post->ID;
433
+ }
434
+
435
+ return false;
436
+ }
437
+
438
+ /**
439
+ * Check if page is of optin type.
440
+ *
441
+ * @since 1.0.0
442
+ * @return int/bool
443
+ */
444
+ function _is_wcf_optin_type() {
445
+
446
+ if ( wcf()->utils->is_step_post_type() ) {
447
+
448
+ global $post;
449
+
450
+ if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
+
452
+ return true;
453
+ }
454
+ }
455
+
456
+ return false;
457
+ }
458
+
459
+ /**
460
+ * Get optin page ID.
461
+ *
462
+ * @since 1.0.0
463
+ * @return int/bool
464
+ */
465
+ function _get_wcf_optin_id() {
466
+
467
+ if ( _is_wcf_optin_type() ) {
468
+
469
+ global $post;
470
+
471
+ return $post->ID;
472
+ }
473
+
474
+ return false;
475
+ }
476
+
477
+ /**
478
+ * Define a constant if it is not already defined.
479
+ *
480
+ * @since 3.0.0
481
+ * @param string $name Constant name.
482
+ * @param mixed $value Value.
483
+ */
484
+ function wcf_maybe_define_constant( $name, $value ) {
485
+ if ( ! defined( $name ) ) {
486
+ define( $name, $value );
487
+ }
488
+ }
489
+
490
+
491
+ if ( ! function_exists( 'wp_body_open' ) ) {
492
+ /**
493
+ * Fire the wp_body_open action.
494
+ *
495
+ * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
+ */
497
+ function wp_body_open() {
498
+ /**
499
+ * Triggered after the opening <body> tag.
500
+ */
501
+ do_action( 'wp_body_open' );
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Check if type is optin by id.
507
+ *
508
+ * @param int $post_id post id.
509
+ *
510
+ * @return int/bool
511
+ * @since 1.0.0
512
+ */
513
+ function _wcf_check_is_optin_by_id( $post_id ) {
514
+
515
+ if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
+
517
+ return true;
518
+ }
519
+
520
+ return false;
521
+ }
522
+
523
+ /**
524
+ * Supported Page Template
525
+ *
526
+ * @param string $page_template current page template.
527
+ *
528
+ * @return int/bool
529
+ * @since 1.5.7
530
+ */
531
+ function _wcf_supported_template( $page_template ) {
532
+
533
+ if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
+
535
+ return true;
536
+ }
537
+
538
+ return false;
539
+ }
classes/class-cartflows-helper.php CHANGED
@@ -1,793 +1,793 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Helper.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Helper.
14
- */
15
- class Cartflows_Helper {
16
-
17
- /**
18
- * Common global data
19
- *
20
- * @var zapier
21
- */
22
- private static $common = null;
23
-
24
- /**
25
- * Common Debug data
26
- *
27
- * @var zapier
28
- */
29
- private static $debug_data = null;
30
-
31
-
32
- /**
33
- * Permalink settings
34
- *
35
- * @var permalink_setting
36
- */
37
- private static $permalink_setting = null;
38
-
39
- /**
40
- * Google Analytics Settings
41
- *
42
- * @var permalink_setting
43
- */
44
- private static $google_analytics_settings = null;
45
-
46
- /**
47
- * Installed Plugins
48
- *
49
- * @since 1.1.4
50
- *
51
- * @access private
52
- * @var array Installed plugins list.
53
- */
54
- private static $installed_plugins = null;
55
-
56
- /**
57
- * Checkout Fields
58
- *
59
- * @var checkout_fields
60
- */
61
- private static $checkout_fields = null;
62
-
63
- /**
64
- * Facebook pixel global data
65
- *
66
- * @var faceboook
67
- */
68
- private static $facebook = null;
69
-
70
-
71
- /**
72
- * Returns an option from the database for
73
- * the admin settings page.
74
- *
75
- * @param string $key The option key.
76
- * @param mixed $default Option default value if option is not available.
77
- * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
78
- * @return string Return the option value
79
- */
80
- public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
81
-
82
- // Get the site-wide option if we're in the network admin.
83
- if ( $network_override && is_multisite() ) {
84
- $value = get_site_option( $key, $default );
85
- } else {
86
- $value = get_option( $key, $default );
87
- }
88
-
89
- return $value;
90
- }
91
-
92
- /**
93
- * Updates an option from the admin settings page.
94
- *
95
- * @param string $key The option key.
96
- * @param mixed $value The value to update.
97
- * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
98
- * @return mixed
99
- */
100
- public static function update_admin_settings_option( $key, $value, $network = false ) {
101
-
102
- // Update the site-wide option since we're in the network admin.
103
- if ( $network && is_multisite() ) {
104
- update_site_option( $key, $value );
105
- } else {
106
- update_option( $key, $value );
107
- }
108
-
109
- }
110
-
111
- /**
112
- * Get single setting
113
- *
114
- * @since 1.1.4
115
- *
116
- * @param string $key Option key.
117
- * @param string $default Option default value if not exist.
118
- * @return mixed
119
- */
120
- public static function get_common_setting( $key = '', $default = '' ) {
121
- $settings = self::get_common_settings();
122
-
123
- if ( $settings && array_key_exists( $key, $settings ) ) {
124
- return $settings[ $key ];
125
- }
126
-
127
- return $default;
128
- }
129
-
130
- /**
131
- * Get single debug options
132
- *
133
- * @since 1.1.4
134
- *
135
- * @param string $key Option key.
136
- * @param string $default Option default value if not exist.
137
- * @return mixed
138
- */
139
- public static function get_debug_setting( $key = '', $default = '' ) {
140
- $debug_data = self::get_debug_settings();
141
-
142
- if ( $debug_data && array_key_exists( $key, $debug_data ) ) {
143
- return $debug_data[ $key ];
144
- }
145
-
146
- return $default;
147
- }
148
-
149
- /**
150
- * Get required plugins for page builder
151
- *
152
- * @since 1.1.4
153
- *
154
- * @param string $page_builder_slug Page builder slug.
155
- * @param string $default Default page builder.
156
- * @return array selected page builder required plugins list.
157
- */
158
- public static function get_required_plugins_for_page_builder( $page_builder_slug = '', $default = 'elementor' ) {
159
- $plugins = self::get_plugins_groupby_page_builders();
160
-
161
- if ( array_key_exists( $page_builder_slug, $plugins ) ) {
162
- return $plugins[ $page_builder_slug ];
163
- }
164
-
165
- return $plugins[ $default ];
166
- }
167
-
168
- /**
169
- * Get Plugins list by page builder.
170
- *
171
- * @since 1.1.4
172
- *
173
- * @return array Required Plugins list.
174
- */
175
- public static function get_plugins_groupby_page_builders() {
176
-
177
- $divi_status = self::get_plugin_status( 'divi-builder/divi-builder.php' );
178
- $theme_status = 'not-installed';
179
- if ( $divi_status ) {
180
- if ( true === Cartflows_Compatibility::get_instance()->is_divi_theme_installed() ) {
181
- $theme_status = 'installed';
182
- if ( false === Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
183
- $theme_status = 'deactivate';
184
- $divi_status = 'activate';
185
- } else {
186
- $divi_status = '';
187
- }
188
- }
189
- }
190
-
191
- $plugins = array(
192
- 'elementor' => array(
193
- 'title' => 'Elementor',
194
- 'plugins' => array(
195
- array(
196
- 'slug' => 'elementor', // For download from wp.org.
197
- 'init' => 'elementor/elementor.php',
198
- 'status' => self::get_plugin_status( 'elementor/elementor.php' ),
199
- ),
200
- ),
201
- ),
202
- 'gutenberg' => array(
203
- 'title' => 'Ultimate Addons for Gutenberg',
204
- 'plugins' => array(
205
- array(
206
- 'slug' => 'ultimate-addons-for-gutenberg', // For download from wp.org.
207
- 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
208
- 'status' => self::get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ),
209
- ),
210
- ),
211
- ),
212
- 'divi' => array(
213
- 'title' => 'Divi',
214
- 'theme-status' => $theme_status,
215
- 'plugin-status' => $divi_status,
216
- 'plugins' => array(
217
- array(
218
- 'slug' => 'divi-builder', // For download from wp.org.
219
- 'init' => 'divi-builder/divi-builder.php',
220
- 'status' => $divi_status,
221
- ),
222
- ),
223
- ),
224
- );
225
-
226
- $plugins['beaver-builder'] = array(
227
- 'title' => 'Beaver Builder',
228
- 'plugins' => array(),
229
- );
230
-
231
- // Check Pro Exist.
232
- if ( file_exists( WP_PLUGIN_DIR . '/bb-plugin/fl-builder.php' ) && ! is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ) {
233
- $plugins['beaver-builder']['plugins'][] = array(
234
- 'slug' => 'bb-plugin',
235
- 'init' => 'bb-plugin/fl-builder.php',
236
- 'status' => self::get_plugin_status( 'bb-plugin/fl-builder.php' ),
237
- );
238
- } else {
239
- $plugins['beaver-builder']['plugins'][] = array(
240
- 'slug' => 'beaver-builder-lite-version', // For download from wp.org.
241
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
242
- 'status' => self::get_plugin_status( 'beaver-builder-lite-version/fl-builder.php' ),
243
- );
244
- }
245
-
246
- if ( file_exists( WP_PLUGIN_DIR . '/bb-ultimate-addon/bb-ultimate-addon.php' ) && ! is_plugin_active( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ) ) {
247
- $plugins['beaver-builder']['plugins'][] = array(
248
- 'slug' => 'bb-ultimate-addon',
249
- 'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
250
- 'status' => self::get_plugin_status( 'bb-ultimate-addon/bb-ultimate-addon.php' ),
251
- );
252
- } else {
253
- $plugins['beaver-builder']['plugins'][] = array(
254
- 'slug' => 'ultimate-addons-for-beaver-builder-lite', // For download from wp.org.
255
- 'init' => 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php',
256
- 'status' => self::get_plugin_status( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ),
257
- );
258
- }
259
-
260
- return $plugins;
261
- }
262
-
263
- /**
264
- * Get plugin status
265
- *
266
- * @since 1.1.4
267
- *
268
- * @param string $plugin_init_file Plguin init file.
269
- * @return mixed
270
- */
271
- public static function get_plugin_status( $plugin_init_file ) {
272
-
273
- if ( null == self::$installed_plugins ) {
274
- self::$installed_plugins = get_plugins();
275
- }
276
-
277
- if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
278
- return 'install';
279
- } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
280
- return 'activate';
281
- } else {
282
- return;
283
- }
284
- }
285
-
286
- /**
287
- * Get zapier settings.
288
- *
289
- * @return array.
290
- */
291
- public static function get_common_settings() {
292
-
293
- if ( null === self::$common ) {
294
-
295
- $common_default = apply_filters(
296
- 'cartflows_common_settings_default',
297
- array(
298
- 'disallow_indexing' => 'disable',
299
- 'global_checkout' => '',
300
- 'default_page_builder' => 'elementor',
301
- )
302
- );
303
-
304
- $common = self::get_admin_settings_option( '_cartflows_common', false, false );
305
-
306
- $common = wp_parse_args( $common, $common_default );
307
-
308
- if ( ! did_action( 'wp' ) ) {
309
- return $common;
310
- } else {
311
- self::$common = $common;
312
- }
313
- }
314
-
315
- return self::$common;
316
- }
317
-
318
- /**
319
- * Get debug settings data.
320
- *
321
- * @return array.
322
- */
323
- public static function get_debug_settings() {
324
-
325
- if ( null === self::$debug_data ) {
326
-
327
- $debug_data_default = apply_filters(
328
- 'cartflows_debug_settings_default',
329
- array(
330
- 'allow_minified_files' => 'disable',
331
- )
332
- );
333
-
334
- $debug_data = self::get_admin_settings_option( '_cartflows_debug_data', false, false );
335
-
336
- $debug_data = wp_parse_args( $debug_data, $debug_data_default );
337
-
338
- if ( ! did_action( 'wp' ) ) {
339
- return $debug_data;
340
- } else {
341
- self::$debug_data = $debug_data;
342
- }
343
- }
344
-
345
- return self::$debug_data;
346
- }
347
-
348
-
349
- /**
350
- * Get debug settings data.
351
- *
352
- * @return array.
353
- */
354
- public static function get_permalink_settings() {
355
-
356
- if ( null === self::$permalink_setting ) {
357
-
358
- $permalink_default = apply_filters(
359
- 'cartflows_permalink_settings_default',
360
- array(
361
- 'permalink' => CARTFLOWS_STEP_POST_TYPE,
362
- 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
363
- 'permalink_structure' => '',
364
-
365
- )
366
- );
367
-
368
- $permalink_data = self::get_admin_settings_option( '_cartflows_permalink', false, false );
369
-
370
- $permalink_data = wp_parse_args( $permalink_data, $permalink_default );
371
-
372
- if ( ! did_action( 'wp' ) ) {
373
- return $permalink_data;
374
- } else {
375
- self::$permalink_setting = $permalink_data;
376
- }
377
- }
378
-
379
- return self::$permalink_setting;
380
- }
381
-
382
-
383
- /**
384
- * Get debug settings data.
385
- *
386
- * @return array.
387
- */
388
- public static function get_google_analytics_settings() {
389
-
390
- if ( null === self::$google_analytics_settings ) {
391
-
392
- $google_analytics_settings_default = apply_filters(
393
- 'cartflows_google_analytics_settings_default',
394
- array(
395
- 'enable_google_analytics' => 'disable',
396
- 'enable_google_analytics_for_site' => 'disable',
397
- 'google_analytics_id' => '',
398
- 'enable_begin_checkout' => 'disable',
399
- 'enable_add_to_cart' => 'disable',
400
- 'enable_add_payment_info' => 'disable',
401
- 'enable_purchase_event' => 'disable',
402
- )
403
- );
404
-
405
- $google_analytics_settings_data = self::get_admin_settings_option( '_cartflows_google_analytics', false, true );
406
-
407
- $google_analytics_settings_data = wp_parse_args( $google_analytics_settings_data, $google_analytics_settings_default );
408
-
409
- if ( ! did_action( 'wp' ) ) {
410
- return $google_analytics_settings_data;
411
- } else {
412
- self::$google_analytics_settings = $google_analytics_settings_data;
413
- }
414
- }
415
-
416
- return self::$google_analytics_settings = $google_analytics_settings_data; //phpcs:ignore
417
- }
418
-
419
- /**
420
- * Get Checkout field.
421
- *
422
- * @param string $key Field key.
423
- * @param int $post_id Post id.
424
- * @return array.
425
- */
426
- public static function get_checkout_fields( $key, $post_id ) {
427
-
428
- $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
429
-
430
- if ( ! $saved_fields ) {
431
- $saved_fields = array();
432
- }
433
-
434
- $fields = array_filter( $saved_fields );
435
-
436
- if ( empty( $fields ) ) {
437
- if ( 'billing' === $key || 'shipping' === $key ) {
438
-
439
- $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
440
-
441
- update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
442
- }
443
- }
444
-
445
- return $fields;
446
- }
447
-
448
- /**
449
- * Add Checkout field.
450
- *
451
- * @param string $type Field type.
452
- * @param string $field_key Field key.
453
- * @param array $field_data Field data.
454
- * @param int $post_id Post id.
455
- * @return boolean.
456
- */
457
- public static function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
458
-
459
- $fields = self::get_checkout_fields( $type, $post_id );
460
-
461
- $fields[ $field_key ] = $field_data;
462
-
463
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
464
-
465
- return true;
466
- }
467
-
468
- /**
469
- * Get checkout fields settings.
470
- *
471
- * @param string $type Field type.
472
- * @param string $field_key Field key.
473
- * @param int $post_id Post id.
474
- * @return array.
475
- */
476
- public static function delete_checkout_field( $type, $field_key, $post_id ) {
477
-
478
- $fields = self::get_checkout_fields( $type, $post_id );
479
-
480
- if ( isset( $fields[ $field_key ] ) ) {
481
- unset( $fields[ $field_key ] );
482
- }
483
-
484
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
485
-
486
- return true;
487
- }
488
-
489
- /**
490
- * Get checkout fields settings.
491
- *
492
- * @return array.
493
- */
494
- public static function get_checkout_fields_settings() {
495
-
496
- if ( null === self::$checkout_fields ) {
497
- $checkout_fields_default = array(
498
- 'enable_customization' => 'disable',
499
- 'enable_billing_fields' => 'disable',
500
- );
501
-
502
- $billing_fields = self::get_checkout_fields( 'billing' );
503
-
504
- if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
505
-
506
- foreach ( $billing_fields as $key => $value ) {
507
-
508
- $checkout_fields_default[ $key ] = 'enable';
509
- }
510
- }
511
-
512
- $checkout_fields = self::get_admin_settings_option( '_wcf_checkout_fields', false, false );
513
-
514
- self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
515
- }
516
-
517
- return self::$checkout_fields;
518
- }
519
-
520
- /**
521
- * Get meta options
522
- *
523
- * @since 1.0.0
524
- * @param int $post_id Product ID.
525
- * @param string $key Meta Key.
526
- * @param string $default Default value.
527
- * @return string Meta Value.
528
- */
529
- public static function get_meta_option( $post_id, $key, $default = '' ) {
530
-
531
- $value = get_post_meta( $post_id, $key, true );
532
-
533
- if ( ! $value ) {
534
- $value = $default;
535
- }
536
-
537
- return $value;
538
- }
539
-
540
- /**
541
- * Save meta option
542
- *
543
- * @since 1.0.0
544
- * @param int $post_id Product ID.
545
- * @param array $args Arguments array.
546
- */
547
- public static function save_meta_option( $post_id, $args = array() ) {
548
-
549
- if ( is_array( $args ) && ! empty( $args ) ) {
550
-
551
- foreach ( $args as $key => $value ) {
552
-
553
- update_post_meta( $post_id, $key, $value );
554
- }
555
- }
556
- }
557
-
558
- /**
559
- * Check if Elementor page builder is installed
560
- *
561
- * @since 1.0.0
562
- *
563
- * @access public
564
- */
565
- public static function is_elementor_installed() {
566
- $path = 'elementor/elementor.php';
567
- $plugins = get_plugins();
568
-
569
- return isset( $plugins[ $path ] );
570
- }
571
-
572
- /**
573
- * Check if Step has product assigned.
574
- *
575
- * @since 1.0.0
576
- * @param int $step_id step ID.
577
- *
578
- * @access public
579
- */
580
- public static function has_product_assigned( $step_id ) {
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
-
603
- /**
604
- * Get attributes for cartflows wrap.
605
- *
606
- * @since 1.1.4
607
- *
608
- * @access public
609
- */
610
- public static function get_cartflows_container_atts() {
611
-
612
- $attributes = apply_filters( 'cartflows_container_atts', array() );
613
- $atts_string = '';
614
-
615
- foreach ( $attributes as $key => $value ) {
616
-
617
- if ( ! $value ) {
618
- continue;
619
- }
620
-
621
- if ( true === $value ) {
622
- $atts_string .= esc_html( $key ) . ' ';
623
- } else {
624
- $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
625
- }
626
- }
627
-
628
- return $atts_string;
629
- }
630
-
631
- /**
632
- * Get facebook pixel settings.
633
- *
634
- * @return facebook array.
635
- */
636
- public static function get_facebook_settings() {
637
-
638
- if ( null === self::$facebook ) {
639
-
640
- $facebook_default = array(
641
- 'facebook_pixel_id' => '',
642
- 'facebook_pixel_add_to_cart' => 'enable',
643
- 'facebook_pixel_initiate_checkout' => 'enable',
644
- 'facebook_pixel_add_payment_info' => 'enable',
645
- 'facebook_pixel_purchase_complete' => 'enable',
646
- 'facebook_pixel_tracking' => 'disable',
647
- 'facebook_pixel_tracking_for_site' => 'disable',
648
- );
649
-
650
- $facebook = self::get_admin_settings_option( '_cartflows_facebook', false, false );
651
-
652
- $facebook = wp_parse_args( $facebook, $facebook_default );
653
-
654
- self::$facebook = apply_filters( 'cartflows_facebook_settings_default', $facebook );
655
-
656
- }
657
-
658
- return self::$facebook;
659
- }
660
-
661
-
662
- /**
663
- * Prepare response data for facebook.
664
- *
665
- * @param int $order_id order_id.
666
- * @param array $offer_data offer data.
667
- */
668
- public static function send_fb_response_if_enabled( $order_id, $offer_data = array() ) {
669
-
670
- // Stop Execution if WooCommerce is not installed & don't set the cookie.
671
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
672
- return;
673
- }
674
-
675
- $fb_settings = self::get_facebook_settings();
676
- if ( 'enable' === $fb_settings['facebook_pixel_tracking'] ) {
677
- setcookie( 'wcf_order_details', wp_json_encode( self::prepare_purchase_data_fb_response( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
678
- }
679
-
680
- }
681
-
682
- /**
683
- * Prepare purchase response for facebook purcase event.
684
- *
685
- * @param integer $order_id order id.
686
- * @param array $offer_data offer data.
687
- * @return mixed
688
- */
689
- public static function prepare_purchase_data_fb_response( $order_id, $offer_data = array() ) {
690
-
691
- $thankyou = array();
692
-
693
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
694
- return $thankyou;
695
- }
696
-
697
- $thankyou['order_id'] = $order_id;
698
- $thankyou['content_type'] = 'product';
699
- $thankyou['currency'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_currency' );
700
- $thankyou['userAgent'] = wcf()->options->get_checkout_meta_value( $order_id, '_customer_user_agent' );
701
- $thankyou['plugin'] = 'CartFlows';
702
- $order = wc_get_order( $order_id );
703
- if ( empty( $offer_data ) ) {
704
- // Iterating through each WC_Order_Item_Product objects.
705
- foreach ( $order->get_items() as $item_key => $item ) {
706
- $product = $item->get_product(); // Get the WC_Product object.
707
- $thankyou['content_ids'][] = (string) $product->get_id();
708
- }
709
- $thankyou['value'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_total' );
710
- } else {
711
- $thankyou['content_ids'][] = (string) $offer_data['id'];
712
- $thankyou['value'] = $offer_data['total'];
713
- }
714
-
715
- return $thankyou;
716
- }
717
-
718
- /**
719
- * Prepare cart data for fb response.
720
- *
721
- * @return array
722
- */
723
- public static function prepare_cart_data_fb_response() {
724
-
725
- $params = array();
726
-
727
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
728
- return $params;
729
- }
730
-
731
- $cart_total = WC()->cart->get_cart_contents_total();
732
- $cart_items_count = WC()->cart->get_cart_contents_count();
733
- $items = WC()->cart->get_cart();
734
- $product_names = '';
735
- $category_names = '';
736
- $cart_contents = array();
737
- foreach ( $items as $item => $value ) {
738
-
739
- $_product = wc_get_product( $value['product_id'] );
740
- $params['content_ids'][] = (string) $_product->get_id();
741
- $product_names = $product_names . ', ' . $_product->get_title();
742
- $category_names = $category_names . ', ' . wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) );
743
- array_push(
744
- $cart_contents,
745
- array(
746
- 'id' => $_product->get_id(),
747
- 'name' => $_product->get_title(),
748
- 'quantity' => $value['quantity'],
749
- 'item_price' => $_product->get_price(),
750
- )
751
- );
752
- }
753
-
754
- $user = wp_get_current_user();
755
- $roles = implode( ', ', $user->roles );
756
- $params['content_name'] = substr( $product_names, 2 );
757
- $params['categoey_name'] = substr( $category_names, 2 );
758
- $params['user_roles'] = $roles;
759
- $params['plugin'] = 'CartFlows';
760
- $params['contents'] = wp_json_encode( $cart_contents );
761
- $params['content_type'] = 'product';
762
- $params['value'] = $cart_total;
763
- $params['num_items'] = $cart_items_count;
764
- $params['currency'] = get_woocommerce_currency();
765
- $params['language'] = get_bloginfo( 'language' );
766
- $params['userAgent'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); //phpcs:ignore
767
- $params['product_catalog_id'] = '';
768
- $params['domain'] = get_site_url();
769
- return $params;
770
- }
771
-
772
- /**
773
- * Get the image url of size.
774
- *
775
- * @param int $post_id post id.
776
- * @param array $key key.
777
- * @param string $size image size.
778
- *
779
- * @return array
780
- */
781
- public static function get_image_url( $post_id, $key, $size = false ) {
782
-
783
- $url = get_post_meta( $post_id, $key, true );
784
- $img_obj = get_post_meta( $post_id, $key . '-obj', true );
785
- if ( is_array( $img_obj ) && ! empty( $img_obj ) && false !== $size ) {
786
-
787
- $url = ! empty( $img_obj['url'][ $size ] ) ? $img_obj['url'][ $size ] : $url;
788
- }
789
-
790
- return $url;
791
- }
792
-
793
- }
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Helper.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Helper.
14
+ */
15
+ class Cartflows_Helper {
16
+
17
+ /**
18
+ * Common global data
19
+ *
20
+ * @var zapier
21
+ */
22
+ private static $common = null;
23
+
24
+ /**
25
+ * Common Debug data
26
+ *
27
+ * @var zapier
28
+ */
29
+ private static $debug_data = null;
30
+
31
+
32
+ /**
33
+ * Permalink settings
34
+ *
35
+ * @var permalink_setting
36
+ */
37
+ private static $permalink_setting = null;
38
+
39
+ /**
40
+ * Google Analytics Settings
41
+ *
42
+ * @var permalink_setting
43
+ */
44
+ private static $google_analytics_settings = null;
45
+
46
+ /**
47
+ * Installed Plugins
48
+ *
49
+ * @since 1.1.4
50
+ *
51
+ * @access private
52
+ * @var array Installed plugins list.
53
+ */
54
+ private static $installed_plugins = null;
55
+
56
+ /**
57
+ * Checkout Fields
58
+ *
59
+ * @var checkout_fields
60
+ */
61
+ private static $checkout_fields = null;
62
+
63
+ /**
64
+ * Facebook pixel global data
65
+ *
66
+ * @var faceboook
67
+ */
68
+ private static $facebook = null;
69
+
70
+
71
+ /**
72
+ * Returns an option from the database for
73
+ * the admin settings page.
74
+ *
75
+ * @param string $key The option key.
76
+ * @param mixed $default Option default value if option is not available.
77
+ * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
78
+ * @return string Return the option value
79
+ */
80
+ public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
81
+
82
+ // Get the site-wide option if we're in the network admin.
83
+ if ( $network_override && is_multisite() ) {
84
+ $value = get_site_option( $key, $default );
85
+ } else {
86
+ $value = get_option( $key, $default );
87
+ }
88
+
89
+ return $value;
90
+ }
91
+
92
+ /**
93
+ * Updates an option from the admin settings page.
94
+ *
95
+ * @param string $key The option key.
96
+ * @param mixed $value The value to update.
97
+ * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
98
+ * @return mixed
99
+ */
100
+ public static function update_admin_settings_option( $key, $value, $network = false ) {
101
+
102
+ // Update the site-wide option since we're in the network admin.
103
+ if ( $network && is_multisite() ) {
104
+ update_site_option( $key, $value );
105
+ } else {
106
+ update_option( $key, $value );
107
+ }
108
+
109
+ }
110
+
111
+ /**
112
+ * Get single setting
113
+ *
114
+ * @since 1.1.4
115
+ *
116
+ * @param string $key Option key.
117
+ * @param string $default Option default value if not exist.
118
+ * @return mixed
119
+ */
120
+ public static function get_common_setting( $key = '', $default = '' ) {
121
+ $settings = self::get_common_settings();
122
+
123
+ if ( $settings && array_key_exists( $key, $settings ) ) {
124
+ return $settings[ $key ];
125
+ }
126
+
127
+ return $default;
128
+ }
129
+
130
+ /**
131
+ * Get single debug options
132
+ *
133
+ * @since 1.1.4
134
+ *
135
+ * @param string $key Option key.
136
+ * @param string $default Option default value if not exist.
137
+ * @return mixed
138
+ */
139
+ public static function get_debug_setting( $key = '', $default = '' ) {
140
+ $debug_data = self::get_debug_settings();
141
+
142
+ if ( $debug_data && array_key_exists( $key, $debug_data ) ) {
143
+ return $debug_data[ $key ];
144
+ }
145
+
146
+ return $default;
147
+ }
148
+
149
+ /**
150
+ * Get required plugins for page builder
151
+ *
152
+ * @since 1.1.4
153
+ *
154
+ * @param string $page_builder_slug Page builder slug.
155
+ * @param string $default Default page builder.
156
+ * @return array selected page builder required plugins list.
157
+ */
158
+ public static function get_required_plugins_for_page_builder( $page_builder_slug = '', $default = 'elementor' ) {
159
+ $plugins = self::get_plugins_groupby_page_builders();
160
+
161
+ if ( array_key_exists( $page_builder_slug, $plugins ) ) {
162
+ return $plugins[ $page_builder_slug ];
163
+ }
164
+
165
+ return $plugins[ $default ];
166
+ }
167
+
168
+ /**
169
+ * Get Plugins list by page builder.
170
+ *
171
+ * @since 1.1.4
172
+ *
173
+ * @return array Required Plugins list.
174
+ */
175
+ public static function get_plugins_groupby_page_builders() {
176
+
177
+ $divi_status = self::get_plugin_status( 'divi-builder/divi-builder.php' );
178
+ $theme_status = 'not-installed';
179
+ if ( $divi_status ) {
180
+ if ( true === Cartflows_Compatibility::get_instance()->is_divi_theme_installed() ) {
181
+ $theme_status = 'installed';
182
+ if ( false === Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
183
+ $theme_status = 'deactivate';
184
+ $divi_status = 'activate';
185
+ } else {
186
+ $divi_status = '';
187
+ }
188
+ }
189
+ }
190
+
191
+ $plugins = array(
192
+ 'elementor' => array(
193
+ 'title' => 'Elementor',
194
+ 'plugins' => array(
195
+ array(
196
+ 'slug' => 'elementor', // For download from wp.org.
197
+ 'init' => 'elementor/elementor.php',
198
+ 'status' => self::get_plugin_status( 'elementor/elementor.php' ),
199
+ ),
200
+ ),
201
+ ),
202
+ 'gutenberg' => array(
203
+ 'title' => 'Ultimate Addons for Gutenberg',
204
+ 'plugins' => array(
205
+ array(
206
+ 'slug' => 'ultimate-addons-for-gutenberg', // For download from wp.org.
207
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
208
+ 'status' => self::get_plugin_status( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ),
209
+ ),
210
+ ),
211
+ ),
212
+ 'divi' => array(
213
+ 'title' => 'Divi',
214
+ 'theme-status' => $theme_status,
215
+ 'plugin-status' => $divi_status,
216
+ 'plugins' => array(
217
+ array(
218
+ 'slug' => 'divi-builder', // For download from wp.org.
219
+ 'init' => 'divi-builder/divi-builder.php',
220
+ 'status' => $divi_status,
221
+ ),
222
+ ),
223
+ ),
224
+ );
225
+
226
+ $plugins['beaver-builder'] = array(
227
+ 'title' => 'Beaver Builder',
228
+ 'plugins' => array(),
229
+ );
230
+
231
+ // Check Pro Exist.
232
+ if ( file_exists( WP_PLUGIN_DIR . '/bb-plugin/fl-builder.php' ) && ! is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ) {
233
+ $plugins['beaver-builder']['plugins'][] = array(
234
+ 'slug' => 'bb-plugin',
235
+ 'init' => 'bb-plugin/fl-builder.php',
236
+ 'status' => self::get_plugin_status( 'bb-plugin/fl-builder.php' ),
237
+ );
238
+ } else {
239
+ $plugins['beaver-builder']['plugins'][] = array(
240
+ 'slug' => 'beaver-builder-lite-version', // For download from wp.org.
241
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
242
+ 'status' => self::get_plugin_status( 'beaver-builder-lite-version/fl-builder.php' ),
243
+ );
244
+ }
245
+
246
+ if ( file_exists( WP_PLUGIN_DIR . '/bb-ultimate-addon/bb-ultimate-addon.php' ) && ! is_plugin_active( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ) ) {
247
+ $plugins['beaver-builder']['plugins'][] = array(
248
+ 'slug' => 'bb-ultimate-addon',
249
+ 'init' => 'bb-ultimate-addon/bb-ultimate-addon.php',
250
+ 'status' => self::get_plugin_status( 'bb-ultimate-addon/bb-ultimate-addon.php' ),
251
+ );
252
+ } else {
253
+ $plugins['beaver-builder']['plugins'][] = array(
254
+ 'slug' => 'ultimate-addons-for-beaver-builder-lite', // For download from wp.org.
255
+ 'init' => 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php',
256
+ 'status' => self::get_plugin_status( 'ultimate-addons-for-beaver-builder-lite/bb-ultimate-addon.php' ),
257
+ );
258
+ }
259
+
260
+ return $plugins;
261
+ }
262
+
263
+ /**
264
+ * Get plugin status
265
+ *
266
+ * @since 1.1.4
267
+ *
268
+ * @param string $plugin_init_file Plguin init file.
269
+ * @return mixed
270
+ */
271
+ public static function get_plugin_status( $plugin_init_file ) {
272
+
273
+ if ( null == self::$installed_plugins ) {
274
+ self::$installed_plugins = get_plugins();
275
+ }
276
+
277
+ if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
278
+ return 'install';
279
+ } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
280
+ return 'activate';
281
+ } else {
282
+ return;
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Get zapier settings.
288
+ *
289
+ * @return array.
290
+ */
291
+ public static function get_common_settings() {
292
+
293
+ if ( null === self::$common ) {
294
+
295
+ $common_default = apply_filters(
296
+ 'cartflows_common_settings_default',
297
+ array(
298
+ 'disallow_indexing' => 'disable',
299
+ 'global_checkout' => '',
300
+ 'default_page_builder' => 'elementor',
301
+ )
302
+ );
303
+
304
+ $common = self::get_admin_settings_option( '_cartflows_common', false, false );
305
+
306
+ $common = wp_parse_args( $common, $common_default );
307
+
308
+ if ( ! did_action( 'wp' ) ) {
309
+ return $common;
310
+ } else {
311
+ self::$common = $common;
312
+ }
313
+ }
314
+
315
+ return self::$common;
316
+ }
317
+
318
+ /**
319
+ * Get debug settings data.
320
+ *
321
+ * @return array.
322
+ */
323
+ public static function get_debug_settings() {
324
+
325
+ if ( null === self::$debug_data ) {
326
+
327
+ $debug_data_default = apply_filters(
328
+ 'cartflows_debug_settings_default',
329
+ array(
330
+ 'allow_minified_files' => 'disable',
331
+ )
332
+ );
333
+
334
+ $debug_data = self::get_admin_settings_option( '_cartflows_debug_data', false, false );
335
+
336
+ $debug_data = wp_parse_args( $debug_data, $debug_data_default );
337
+
338
+ if ( ! did_action( 'wp' ) ) {
339
+ return $debug_data;
340
+ } else {
341
+ self::$debug_data = $debug_data;
342
+ }
343
+ }
344
+
345
+ return self::$debug_data;
346
+ }
347
+
348
+
349
+ /**
350
+ * Get debug settings data.
351
+ *
352
+ * @return array.
353
+ */
354
+ public static function get_permalink_settings() {
355
+
356
+ if ( null === self::$permalink_setting ) {
357
+
358
+ $permalink_default = apply_filters(
359
+ 'cartflows_permalink_settings_default',
360
+ array(
361
+ 'permalink' => CARTFLOWS_STEP_POST_TYPE,
362
+ 'permalink_flow_base' => CARTFLOWS_FLOW_POST_TYPE,
363
+ 'permalink_structure' => '',
364
+
365
+ )
366
+ );
367
+
368
+ $permalink_data = self::get_admin_settings_option( '_cartflows_permalink', false, false );
369
+
370
+ $permalink_data = wp_parse_args( $permalink_data, $permalink_default );
371
+
372
+ if ( ! did_action( 'wp' ) ) {
373
+ return $permalink_data;
374
+ } else {
375
+ self::$permalink_setting = $permalink_data;
376
+ }
377
+ }
378
+
379
+ return self::$permalink_setting;
380
+ }
381
+
382
+
383
+ /**
384
+ * Get debug settings data.
385
+ *
386
+ * @return array.
387
+ */
388
+ public static function get_google_analytics_settings() {
389
+
390
+ if ( null === self::$google_analytics_settings ) {
391
+
392
+ $google_analytics_settings_default = apply_filters(
393
+ 'cartflows_google_analytics_settings_default',
394
+ array(
395
+ 'enable_google_analytics' => 'disable',
396
+ 'enable_google_analytics_for_site' => 'disable',
397
+ 'google_analytics_id' => '',
398
+ 'enable_begin_checkout' => 'disable',
399
+ 'enable_add_to_cart' => 'disable',
400
+ 'enable_add_payment_info' => 'disable',
401
+ 'enable_purchase_event' => 'disable',
402
+ )
403
+ );
404
+
405
+ $google_analytics_settings_data = self::get_admin_settings_option( '_cartflows_google_analytics', false, true );
406
+
407
+ $google_analytics_settings_data = wp_parse_args( $google_analytics_settings_data, $google_analytics_settings_default );
408
+
409
+ if ( ! did_action( 'wp' ) ) {
410
+ return $google_analytics_settings_data;
411
+ } else {
412
+ self::$google_analytics_settings = $google_analytics_settings_data;
413
+ }
414
+ }
415
+
416
+ return self::$google_analytics_settings = $google_analytics_settings_data; //phpcs:ignore
417
+ }
418
+
419
+ /**
420
+ * Get Checkout field.
421
+ *
422
+ * @param string $key Field key.
423
+ * @param int $post_id Post id.
424
+ * @return array.
425
+ */
426
+ public static function get_checkout_fields( $key, $post_id ) {
427
+
428
+ $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
429
+
430
+ if ( ! $saved_fields ) {
431
+ $saved_fields = array();
432
+ }
433
+
434
+ $fields = array_filter( $saved_fields );
435
+
436
+ if ( empty( $fields ) ) {
437
+ if ( 'billing' === $key || 'shipping' === $key ) {
438
+
439
+ $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
440
+
441
+ update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
442
+ }
443
+ }
444
+
445
+ return $fields;
446
+ }
447
+
448
+ /**
449
+ * Add Checkout field.
450
+ *
451
+ * @param string $type Field type.
452
+ * @param string $field_key Field key.
453
+ * @param array $field_data Field data.
454
+ * @param int $post_id Post id.
455
+ * @return boolean.
456
+ */
457
+ public static function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
458
+
459
+ $fields = self::get_checkout_fields( $type, $post_id );
460
+
461
+ $fields[ $field_key ] = $field_data;
462
+
463
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
464
+
465
+ return true;
466
+ }
467
+
468
+ /**
469
+ * Get checkout fields settings.
470
+ *
471
+ * @param string $type Field type.
472
+ * @param string $field_key Field key.
473
+ * @param int $post_id Post id.
474
+ * @return array.
475
+ */
476
+ public static function delete_checkout_field( $type, $field_key, $post_id ) {
477
+
478
+ $fields = self::get_checkout_fields( $type, $post_id );
479
+
480
+ if ( isset( $fields[ $field_key ] ) ) {
481
+ unset( $fields[ $field_key ] );
482
+ }
483
+
484
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
485
+
486
+ return true;
487
+ }
488
+
489
+ /**
490
+ * Get checkout fields settings.
491
+ *
492
+ * @return array.
493
+ */
494
+ public static function get_checkout_fields_settings() {
495
+
496
+ if ( null === self::$checkout_fields ) {
497
+ $checkout_fields_default = array(
498
+ 'enable_customization' => 'disable',
499
+ 'enable_billing_fields' => 'disable',
500
+ );
501
+
502
+ $billing_fields = self::get_checkout_fields( 'billing' );
503
+
504
+ if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
505
+
506
+ foreach ( $billing_fields as $key => $value ) {
507
+
508
+ $checkout_fields_default[ $key ] = 'enable';
509
+ }
510
+ }
511
+
512
+ $checkout_fields = self::get_admin_settings_option( '_wcf_checkout_fields', false, false );
513
+
514
+ self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
515
+ }
516
+
517
+ return self::$checkout_fields;
518
+ }
519
+
520
+ /**
521
+ * Get meta options
522
+ *
523
+ * @since 1.0.0
524
+ * @param int $post_id Product ID.
525
+ * @param string $key Meta Key.
526
+ * @param string $default Default value.
527
+ * @return string Meta Value.
528
+ */
529
+ public static function get_meta_option( $post_id, $key, $default = '' ) {
530
+
531
+ $value = get_post_meta( $post_id, $key, true );
532
+
533
+ if ( ! $value ) {
534
+ $value = $default;
535
+ }
536
+
537
+ return $value;
538
+ }
539
+
540
+ /**
541
+ * Save meta option
542
+ *
543
+ * @since 1.0.0
544
+ * @param int $post_id Product ID.
545
+ * @param array $args Arguments array.
546
+ */
547
+ public static function save_meta_option( $post_id, $args = array() ) {
548
+
549
+ if ( is_array( $args ) && ! empty( $args ) ) {
550
+
551
+ foreach ( $args as $key => $value ) {
552
+
553
+ update_post_meta( $post_id, $key, $value );
554
+ }
555
+ }
556
+ }
557
+
558
+ /**
559
+ * Check if Elementor page builder is installed
560
+ *
561
+ * @since 1.0.0
562
+ *
563
+ * @access public
564
+ */
565
+ public static function is_elementor_installed() {
566
+ $path = 'elementor/elementor.php';
567
+ $plugins = get_plugins();
568
+
569
+ return isset( $plugins[ $path ] );
570
+ }
571
+
572
+ /**
573
+ * Check if Step has product assigned.
574
+ *
575
+ * @since 1.0.0
576
+ * @param int $step_id step ID.
577
+ *
578
+ * @access public
579
+ */
580
+ public static function has_product_assigned( $step_id ) {
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
+
603
+ /**
604
+ * Get attributes for cartflows wrap.
605
+ *
606
+ * @since 1.1.4
607
+ *
608
+ * @access public
609
+ */
610
+ public static function get_cartflows_container_atts() {
611
+
612
+ $attributes = apply_filters( 'cartflows_container_atts', array() );
613
+ $atts_string = '';
614
+
615
+ foreach ( $attributes as $key => $value ) {
616
+
617
+ if ( ! $value ) {
618
+ continue;
619
+ }
620
+
621
+ if ( true === $value ) {
622
+ $atts_string .= esc_html( $key ) . ' ';
623
+ } else {
624
+ $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
625
+ }
626
+ }
627
+
628
+ return $atts_string;
629
+ }
630
+
631
+ /**
632
+ * Get facebook pixel settings.
633
+ *
634
+ * @return facebook array.
635
+ */
636
+ public static function get_facebook_settings() {
637
+
638
+ if ( null === self::$facebook ) {
639
+
640
+ $facebook_default = array(
641
+ 'facebook_pixel_id' => '',
642
+ 'facebook_pixel_add_to_cart' => 'enable',
643
+ 'facebook_pixel_initiate_checkout' => 'enable',
644
+ 'facebook_pixel_add_payment_info' => 'enable',
645
+ 'facebook_pixel_purchase_complete' => 'enable',
646
+ 'facebook_pixel_tracking' => 'disable',
647
+ 'facebook_pixel_tracking_for_site' => 'disable',
648
+ );
649
+
650
+ $facebook = self::get_admin_settings_option( '_cartflows_facebook', false, false );
651
+
652
+ $facebook = wp_parse_args( $facebook, $facebook_default );
653
+
654
+ self::$facebook = apply_filters( 'cartflows_facebook_settings_default', $facebook );
655
+
656
+ }
657
+
658
+ return self::$facebook;
659
+ }
660
+
661
+
662
+ /**
663
+ * Prepare response data for facebook.
664
+ *
665
+ * @param int $order_id order_id.
666
+ * @param array $offer_data offer data.
667
+ */
668
+ public static function send_fb_response_if_enabled( $order_id, $offer_data = array() ) {
669
+
670
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
671
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
672
+ return;
673
+ }
674
+
675
+ $fb_settings = self::get_facebook_settings();
676
+ if ( 'enable' === $fb_settings['facebook_pixel_tracking'] ) {
677
+ setcookie( 'wcf_order_details', wp_json_encode( self::prepare_purchase_data_fb_response( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
678
+ }
679
+
680
+ }
681
+
682
+ /**
683
+ * Prepare purchase response for facebook purcase event.
684
+ *
685
+ * @param integer $order_id order id.
686
+ * @param array $offer_data offer data.
687
+ * @return mixed
688
+ */
689
+ public static function prepare_purchase_data_fb_response( $order_id, $offer_data = array() ) {
690
+
691
+ $thankyou = array();
692
+
693
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
694
+ return $thankyou;
695
+ }
696
+
697
+ $thankyou['order_id'] = $order_id;
698
+ $thankyou['content_type'] = 'product';
699
+ $thankyou['currency'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_currency' );
700
+ $thankyou['userAgent'] = wcf()->options->get_checkout_meta_value( $order_id, '_customer_user_agent' );
701
+ $thankyou['plugin'] = 'CartFlows';
702
+ $order = wc_get_order( $order_id );
703
+ if ( empty( $offer_data ) ) {
704
+ // Iterating through each WC_Order_Item_Product objects.
705
+ foreach ( $order->get_items() as $item_key => $item ) {
706
+ $product = $item->get_product(); // Get the WC_Product object.
707
+ $thankyou['content_ids'][] = (string) $product->get_id();
708
+ }
709
+ $thankyou['value'] = wcf()->options->get_checkout_meta_value( $order_id, '_order_total' );
710
+ } else {
711
+ $thankyou['content_ids'][] = (string) $offer_data['id'];
712
+ $thankyou['value'] = $offer_data['total'];
713
+ }
714
+
715
+ return $thankyou;
716
+ }
717
+
718
+ /**
719
+ * Prepare cart data for fb response.
720
+ *
721
+ * @return array
722
+ */
723
+ public static function prepare_cart_data_fb_response() {
724
+
725
+ $params = array();
726
+
727
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
728
+ return $params;
729
+ }
730
+
731
+ $cart_total = WC()->cart->get_cart_contents_total();
732
+ $cart_items_count = WC()->cart->get_cart_contents_count();
733
+ $items = WC()->cart->get_cart();
734
+ $product_names = '';
735
+ $category_names = '';
736
+ $cart_contents = array();
737
+ foreach ( $items as $item => $value ) {
738
+
739
+ $_product = wc_get_product( $value['product_id'] );
740
+ $params['content_ids'][] = (string) $_product->get_id();
741
+ $product_names = $product_names . ', ' . $_product->get_title();
742
+ $category_names = $category_names . ', ' . wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) );
743
+ array_push(
744
+ $cart_contents,
745
+ array(
746
+ 'id' => $_product->get_id(),
747
+ 'name' => $_product->get_title(),
748
+ 'quantity' => $value['quantity'],
749
+ 'item_price' => $_product->get_price(),
750
+ )
751
+ );
752
+ }
753
+
754
+ $user = wp_get_current_user();
755
+ $roles = implode( ', ', $user->roles );
756
+ $params['content_name'] = substr( $product_names, 2 );
757
+ $params['categoey_name'] = substr( $category_names, 2 );
758
+ $params['user_roles'] = $roles;
759
+ $params['plugin'] = 'CartFlows';
760
+ $params['contents'] = wp_json_encode( $cart_contents );
761
+ $params['content_type'] = 'product';
762
+ $params['value'] = $cart_total;
763
+ $params['num_items'] = $cart_items_count;
764
+ $params['currency'] = get_woocommerce_currency();
765
+ $params['language'] = get_bloginfo( 'language' );
766
+ $params['userAgent'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ); //phpcs:ignore
767
+ $params['product_catalog_id'] = '';
768
+ $params['domain'] = get_site_url();
769
+ return $params;
770
+ }
771
+
772
+ /**
773
+ * Get the image url of size.
774
+ *
775
+ * @param int $post_id post id.
776
+ * @param array $key key.
777
+ * @param string $size image size.
778
+ *
779
+ * @return array
780
+ */
781
+ public static function get_image_url( $post_id, $key, $size = false ) {
782
+
783
+ $url = get_post_meta( $post_id, $key, true );
784
+ $img_obj = get_post_meta( $post_id, $key . '-obj', true );
785
+ if ( is_array( $img_obj ) && ! empty( $img_obj ) && false !== $size ) {
786
+
787
+ $url = ! empty( $img_obj['url'][ $size ] ) ? $img_obj['url'][ $size ] : $url;
788
+ }
789
+
790
+ return $url;
791
+ }
792
+
793
+ }
classes/class-cartflows-importer.php CHANGED
@@ -1,1739 +1,1742 @@
1
- <?php
2
- /**
3
- * CartFlows Admin
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
-
11
- /**
12
- * CartFlows Import
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Importer {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
-
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.0.0
45
- */
46
- public function __construct() {
47
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
-
49
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
-
55
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
-
58
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
-
60
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
-
62
- add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
- add_action( 'admin_init', array( $this, 'export_json' ) );
64
- add_action( 'admin_init', array( $this, 'import_json' ) );
65
- add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
- add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
- }
68
-
69
- /**
70
- * Add the export link to action list for flows row actions
71
- *
72
- * @since 1.1.4
73
- *
74
- * @param array $actions Actions array.
75
- * @param object $post Post object.
76
- *
77
- * @return array
78
- */
79
- public function export_link( $actions, $post ) {
80
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
- $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
- }
83
- return $actions;
84
- }
85
-
86
- /**
87
- * Add menus
88
- *
89
- * @since 1.1.4
90
- */
91
- public function add_to_menus() {
92
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
- }
95
-
96
- /**
97
- * Export flow with steps and its meta
98
- *
99
- * @since 1.1.4
100
- */
101
- public function export_flow() {
102
-
103
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
- wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
- }
106
-
107
- if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
- return;
109
- }
110
-
111
- // Get the original post id.
112
- $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
-
114
- $flows = array();
115
- $flows[] = $this->get_flow_export_data( $flow_id );
116
- $flows = apply_filters( 'cartflows_export_data', $flows );
117
-
118
- nocache_headers();
119
- header( 'Content-Type: application/json; charset=utf-8' );
120
- header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
- header( 'Expires: 0' );
122
-
123
- echo wp_json_encode( $flows );
124
- exit;
125
- }
126
-
127
- /**
128
- * Export flow markup
129
- *
130
- * @since 1.1.4
131
- */
132
- public function exporter_markup() {
133
- include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
- }
135
-
136
- /**
137
- * Import flow markup
138
- *
139
- * @since 1.1.4
140
- */
141
- public function importer_markup() {
142
- include_once CARTFLOWS_DIR . 'includes/importer.php';
143
- }
144
-
145
- /**
146
- * Export flow
147
- *
148
- * @since 1.1.4
149
- */
150
- public function export_json() {
151
- if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
- return;
153
- }
154
-
155
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! 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
+ // Set API headers for the CartFlows API Calls only.
993
+ 'headers' => array(),
994
+
995
+ // Flow and its rest fields.
996
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
997
+ 'flow_fields' => array(
998
+ 'id',
999
+ 'title',
1000
+ 'flow_type',
1001
+ 'page_builder',
1002
+ 'flow_steps',
1003
+ 'licence_status',
1004
+ 'featured_image_url',
1005
+ 'featured_media', // @required for field `featured_image_url`.
1006
+ ),
1007
+
1008
+ // Flow type and rest fields.
1009
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1010
+ 'flow_type_fields' => array(
1011
+ 'id',
1012
+ 'name',
1013
+ 'slug',
1014
+ ),
1015
+
1016
+ // Flow page builder and rest fields.
1017
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1018
+ 'flow_page_builder_fields' => array(
1019
+ 'id',
1020
+ 'name',
1021
+ 'slug',
1022
+ ),
1023
+
1024
+ // Step page builder and rest fields.
1025
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1026
+ 'step_page_builder_fields' => array(
1027
+ 'id',
1028
+ 'name',
1029
+ 'slug',
1030
+ ),
1031
+
1032
+ // Step and its rest fields.
1033
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1034
+ 'step_fields' => array(
1035
+ 'title',
1036
+ 'featured_image_url',
1037
+ 'featured_media', // @required for field `featured_image_url`.
1038
+ 'id',
1039
+ 'flow_type',
1040
+ 'step_type',
1041
+ 'page_builder',
1042
+ 'licence_status',
1043
+ ),
1044
+
1045
+ // Step type and its rest fields.
1046
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1047
+ 'step_type_fields' => array(
1048
+ 'id',
1049
+ 'name',
1050
+ 'slug',
1051
+ ),
1052
+
1053
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1054
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1055
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1056
+ 'site_url' => site_url(),
1057
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1058
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1059
+ 'admin_url' => admin_url(),
1060
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1061
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1062
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1063
+
1064
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1065
+
1066
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1067
+ );
1068
+
1069
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1070
+
1071
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1072
+ // wp_die( );
1073
+ // Add thickbox.
1074
+ add_thickbox();
1075
+
1076
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1077
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1078
+ }
1079
+
1080
+ /**
1081
+ * Import.
1082
+ *
1083
+ * @since 1.0.0
1084
+ *
1085
+ * @hook wp_ajax_cartflows_import_flow_step
1086
+ * @return void
1087
+ */
1088
+ public function import_flow() {
1089
+
1090
+ if ( ! current_user_can( 'manage_options' ) ) {
1091
+ return;
1092
+ }
1093
+
1094
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1095
+
1096
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1097
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1098
+
1099
+ wcf()->logger->import_log( '------------------------------------' );
1100
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1101
+ wcf()->logger->import_log( '------------------------------------' );
1102
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1103
+
1104
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1105
+
1106
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1107
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1108
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1109
+ $post_content = $response['data']['divi_content'];
1110
+ }
1111
+ }
1112
+
1113
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1114
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1115
+ $post_content = $response['data']['divi_content'];
1116
+ }
1117
+ }
1118
+
1119
+ if ( false === $response['success'] ) {
1120
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1121
+ wp_send_json_error( $response );
1122
+ }
1123
+
1124
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1125
+
1126
+ $new_step_id = wp_insert_post(
1127
+ array(
1128
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1129
+ 'post_title' => $response['title'],
1130
+ 'post_content' => $post_content,
1131
+ 'post_status' => 'publish',
1132
+ )
1133
+ );
1134
+
1135
+ if ( is_wp_error( $new_step_id ) ) {
1136
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1137
+ wp_send_json_error( $new_step_id );
1138
+ }
1139
+
1140
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1141
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1142
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1143
+ }
1144
+ }
1145
+
1146
+ /* Imported Step */
1147
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1148
+
1149
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1150
+ // insert post meta.
1151
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1152
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1153
+
1154
+ /**
1155
+ * Import & Set type.
1156
+ */
1157
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1158
+
1159
+ $term_slug = '';
1160
+ if ( $term ) {
1161
+
1162
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1163
+ $term_exist = term_exists( $term->slug, $taxonomy );
1164
+
1165
+ if ( empty( $term_exist ) ) {
1166
+ $terms = array(
1167
+ array(
1168
+ 'name' => $term->name,
1169
+ 'slug' => $term->slug,
1170
+ ),
1171
+ );
1172
+
1173
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1174
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1175
+ }
1176
+
1177
+ $current_term = term_exists( $term->slug, $taxonomy );
1178
+
1179
+ // Set type object.
1180
+ $data = get_term( $current_term['term_id'], $taxonomy );
1181
+ $term_slug = $data->slug;
1182
+ $term_name = $data->name;
1183
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1184
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1185
+
1186
+ // Set type.
1187
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1188
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1189
+ }
1190
+
1191
+ // Set flow.
1192
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1193
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1194
+
1195
+ /**
1196
+ * Update steps for the current flow.
1197
+ */
1198
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1199
+
1200
+ if ( ! is_array( $flow_steps ) ) {
1201
+ $flow_steps = array();
1202
+ }
1203
+
1204
+ $flow_steps[] = array(
1205
+ 'id' => $new_step_id,
1206
+ 'title' => $response['title'],
1207
+ 'type' => $term_slug,
1208
+ );
1209
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1210
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1211
+
1212
+ // Import Post Meta.
1213
+ self::import_post_meta( $new_step_id, $response );
1214
+
1215
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1216
+ wcf()->logger->import_log( '------------------------------------' );
1217
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1218
+ wcf()->logger->import_log( '------------------------------------' );
1219
+
1220
+ do_action( 'cartflows_import_complete' );
1221
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1222
+
1223
+ // Batch Process.
1224
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1225
+
1226
+ /**
1227
+ * End
1228
+ */
1229
+ wp_send_json_success( $new_step_id );
1230
+ }
1231
+
1232
+ /**
1233
+ * Import Step.
1234
+ *
1235
+ * @since 1.0.0
1236
+ * @hook wp_ajax_cartflows_step_import
1237
+ *
1238
+ * @return void
1239
+ */
1240
+ public function create_default_flow() {
1241
+
1242
+ if ( ! current_user_can( 'manage_options' ) ) {
1243
+ return;
1244
+ }
1245
+
1246
+ check_ajax_referer( 'cf-default-flow', 'security' );
1247
+
1248
+ // Create post object.
1249
+ $new_flow_post = array(
1250
+ 'post_content' => '',
1251
+ 'post_status' => 'publish',
1252
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1253
+ );
1254
+
1255
+ // Insert the post into the database.
1256
+ $flow_id = wp_insert_post( $new_flow_post );
1257
+
1258
+ if ( is_wp_error( $flow_id ) ) {
1259
+ wp_send_json_error( $flow_id->get_error_message() );
1260
+ }
1261
+
1262
+ $flow_steps = array();
1263
+
1264
+ if ( wcf()->is_woo_active ) {
1265
+ $steps_data = array(
1266
+ 'sales' => array(
1267
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1268
+ 'type' => 'landing',
1269
+ ),
1270
+ 'order-form' => array(
1271
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1272
+ 'type' => 'checkout',
1273
+ ),
1274
+ 'order-confirmation' => array(
1275
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1276
+ 'type' => 'thankyou',
1277
+ ),
1278
+ );
1279
+
1280
+ } else {
1281
+ $steps_data = array(
1282
+ 'landing' => array(
1283
+ 'title' => __( 'Landing', 'cartflows' ),
1284
+ 'type' => 'landing',
1285
+ ),
1286
+ 'thankyou' => array(
1287
+ 'title' => __( 'Thank You', 'cartflows' ),
1288
+ 'type' => 'landing',
1289
+ ),
1290
+ );
1291
+ }
1292
+
1293
+ foreach ( $steps_data as $slug => $data ) {
1294
+
1295
+ $post_content = '';
1296
+ $step_type = trim( $data['type'] );
1297
+
1298
+ $step_id = wp_insert_post(
1299
+ array(
1300
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1301
+ 'post_title' => $data['title'],
1302
+ 'post_content' => $post_content,
1303
+ 'post_status' => 'publish',
1304
+ )
1305
+ );
1306
+
1307
+ if ( is_wp_error( $step_id ) ) {
1308
+ wp_send_json_error( $step_id->get_error_message() );
1309
+ }
1310
+
1311
+ if ( $step_id ) {
1312
+
1313
+ $flow_steps[] = array(
1314
+ 'id' => $step_id,
1315
+ 'title' => $data['title'],
1316
+ 'type' => $step_type,
1317
+ );
1318
+
1319
+ // insert post meta.
1320
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1321
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1322
+
1323
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1324
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1325
+
1326
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1327
+ }
1328
+ }
1329
+
1330
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1331
+
1332
+ wp_send_json_success( $flow_id );
1333
+ }
1334
+
1335
+ /**
1336
+ * Create Flow
1337
+ *
1338
+ * @return void
1339
+ */
1340
+ public function create_flow() {
1341
+
1342
+ if ( ! current_user_can( 'manage_options' ) ) {
1343
+ return;
1344
+ }
1345
+
1346
+ check_ajax_referer( 'cf-create-flow', 'security' );
1347
+
1348
+ // Create post object.
1349
+ $new_flow_post = array(
1350
+ 'post_content' => '',
1351
+ 'post_status' => 'publish',
1352
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1353
+ );
1354
+
1355
+ // Insert the post into the database.
1356
+ $flow_id = wp_insert_post( $new_flow_post );
1357
+
1358
+ if ( is_wp_error( $flow_id ) ) {
1359
+ wp_send_json_error( $flow_id->get_error_message() );
1360
+ }
1361
+
1362
+ /* Imported Flow */
1363
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1364
+
1365
+ wp_send_json_success( $flow_id );
1366
+ }
1367
+
1368
+ /**
1369
+ * Create Step
1370
+ *
1371
+ * @return void
1372
+ */
1373
+ public function import_step() {
1374
+
1375
+ if ( ! current_user_can( 'manage_options' ) ) {
1376
+ return;
1377
+ }
1378
+
1379
+ check_ajax_referer( 'cf-step-import', 'security' );
1380
+
1381
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1382
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1383
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1384
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1385
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1386
+
1387
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1388
+
1389
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1390
+
1391
+ wcf()->logger->import_log( '------------------------------------' );
1392
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1393
+ wcf()->logger->import_log( '------------------------------------' );
1394
+
1395
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1396
+ /* translators: %s: template ID */
1397
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1398
+ wcf()->logger->import_log( $data );
1399
+ wp_send_json_error( $data );
1400
+ }
1401
+
1402
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1403
+
1404
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1405
+
1406
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1407
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1408
+
1409
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1410
+
1411
+ wp_update_post(
1412
+ array(
1413
+ 'ID' => $post_id,
1414
+ 'post_content' => $response['data']['divi_content'],
1415
+ )
1416
+ );
1417
+ }
1418
+ }
1419
+
1420
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1421
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1422
+
1423
+ wp_update_post(
1424
+ array(
1425
+ 'ID' => $post_id,
1426
+ 'post_content' => $response['data']['divi_content'],
1427
+ )
1428
+ );
1429
+ }
1430
+ }
1431
+
1432
+ /* Imported Step */
1433
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1434
+
1435
+ // Import Post Meta.
1436
+ self::import_post_meta( $post_id, $response );
1437
+
1438
+ do_action( 'cartflows_import_complete' );
1439
+
1440
+ // Batch Process.
1441
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1442
+
1443
+ wcf()->logger->import_log( '------------------------------------' );
1444
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1445
+ wcf()->logger->import_log( '------------------------------------' );
1446
+
1447
+ wp_send_json_success( $post_id );
1448
+ }
1449
+
1450
+ /**
1451
+ * Import Step.
1452
+ *
1453
+ * @since 1.0.0
1454
+ * @hook wp_ajax_cartflows_step_create_blank
1455
+ *
1456
+ * @return void
1457
+ */
1458
+ public function step_create_blank() {
1459
+
1460
+ if ( ! current_user_can( 'manage_options' ) ) {
1461
+ return;
1462
+ }
1463
+
1464
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1465
+
1466
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1467
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1468
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1469
+
1470
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1471
+ /* translators: %s: flow ID */
1472
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1473
+ wcf()->logger->import_log( $data );
1474
+ wp_send_json_error( $data );
1475
+ }
1476
+
1477
+ wcf()->logger->import_log( '------------------------------------' );
1478
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1479
+
1480
+ $step_type_title = str_replace( '-', ' ', $step_type );
1481
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1482
+
1483
+ $new_step_id = wp_insert_post(
1484
+ array(
1485
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1486
+ 'post_title' => $step_title,
1487
+ 'post_content' => '',
1488
+ 'post_status' => 'publish',
1489
+ )
1490
+ );
1491
+
1492
+ // insert post meta.
1493
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1494
+
1495
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1496
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1497
+
1498
+ if ( empty( $term_exist ) ) {
1499
+ $terms = array(
1500
+ array(
1501
+ 'name' => $step_type_title,
1502
+ 'slug' => $step_type_slug,
1503
+ ),
1504
+ );
1505
+
1506
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1507
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1508
+ }
1509
+
1510
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1511
+
1512
+ // Set type object.
1513
+ $data = get_term( $current_term['term_id'], $taxonomy );
1514
+ $step_slug = $data->slug;
1515
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1516
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1517
+
1518
+ // Set Default page Layout.
1519
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1520
+
1521
+ // Set type.
1522
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1523
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1524
+
1525
+ // Set flow.
1526
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1527
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1528
+
1529
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1530
+
1531
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1532
+ wcf()->logger->import_log( '------------------------------------' );
1533
+
1534
+ wp_send_json_success( $new_step_id );
1535
+ }
1536
+
1537
+ /**
1538
+ * Import Post Meta
1539
+ *
1540
+ * @since 1.0.0
1541
+ *
1542
+ * @param integer $post_id Post ID.
1543
+ * @param array $response Post meta.
1544
+ * @return void
1545
+ */
1546
+ public static function import_post_meta( $post_id, $response ) {
1547
+
1548
+ $metadata = (array) $response['post_meta'];
1549
+
1550
+ foreach ( $metadata as $meta_key => $meta_value ) {
1551
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1552
+
1553
+ if ( $meta_value ) {
1554
+
1555
+ if ( is_serialized( $meta_value, true ) ) {
1556
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1557
+ } elseif ( is_array( $meta_value ) ) {
1558
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1559
+ } else {
1560
+ $raw_data = $meta_value;
1561
+ }
1562
+
1563
+ if ( '_elementor_data' === $meta_key ) {
1564
+ if ( is_array( $raw_data ) ) {
1565
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1566
+ } else {
1567
+ $raw_data = wp_slash( $raw_data );
1568
+ }
1569
+ }
1570
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1571
+ if ( is_array( $raw_data ) ) {
1572
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1573
+ } else {
1574
+ if ( ! is_object( $raw_data ) ) {
1575
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1576
+ }
1577
+ }
1578
+ }
1579
+
1580
+ update_post_meta( $post_id, $meta_key, $raw_data );
1581
+ }
1582
+ }
1583
+ }
1584
+
1585
+ /**
1586
+ * Import Template for Elementor
1587
+ *
1588
+ * @since 1.0.0
1589
+ *
1590
+ * @param integer $post_id Post ID.
1591
+ * @param array $response Post meta.
1592
+ * @param array $page_build_data Page build data.
1593
+ * @return void
1594
+ */
1595
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1596
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1597
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1598
+ wcf()->logger->import_log( $data );
1599
+ wp_send_json_error( $data );
1600
+ }
1601
+
1602
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1603
+
1604
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1605
+
1606
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1607
+ $obj->import_single_template( $post_id );
1608
+
1609
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1610
+ }
1611
+
1612
+ /**
1613
+ * Supported post types
1614
+ *
1615
+ * @since 1.0.0
1616
+ *
1617
+ * @return array Supported post types.
1618
+ */
1619
+ public static function supported_post_types() {
1620
+ return apply_filters(
1621
+ 'cartflows_supported_post_types',
1622
+ array(
1623
+ CARTFLOWS_FLOW_POST_TYPE,
1624
+ )
1625
+ );
1626
+ }
1627
+
1628
+ /**
1629
+ * Check supported post type
1630
+ *
1631
+ * @since 1.0.0
1632
+ *
1633
+ * @param string $post_type Post type.
1634
+ * @return boolean Supported post type status.
1635
+ */
1636
+ public static function is_supported_post( $post_type = '' ) {
1637
+
1638
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1639
+ return true;
1640
+ }
1641
+
1642
+ return false;
1643
+ }
1644
+
1645
+ /**
1646
+ * Set steps to the flow
1647
+ *
1648
+ * @param integer $flow_id Flow ID.
1649
+ * @param integer $new_step_id New step ID.
1650
+ * @param string $step_title Flow Type.
1651
+ * @param string $step_slug Flow Type.
1652
+ */
1653
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1654
+ // Update steps for the current flow.
1655
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1656
+
1657
+ if ( ! is_array( $flow_steps ) ) {
1658
+ $flow_steps = array();
1659
+ }
1660
+
1661
+ $flow_steps[] = array(
1662
+ 'id' => $new_step_id,
1663
+ 'title' => $step_title,
1664
+ 'type' => $step_slug,
1665
+ );
1666
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1667
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1668
+ }
1669
+
1670
+ /**
1671
+ * Localize variables in admin
1672
+ *
1673
+ * @param array $vars variables.
1674
+ */
1675
+ public function localize_vars( $vars ) {
1676
+
1677
+ $ajax_actions = array(
1678
+ 'cf_step_import',
1679
+ 'cf_load_steps',
1680
+ 'cf_create_flow',
1681
+ 'cf_default_flow',
1682
+ 'cf_step_create_blank',
1683
+ 'cf_import_flow_step',
1684
+ );
1685
+
1686
+ foreach ( $ajax_actions as $action ) {
1687
+
1688
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1689
+ }
1690
+
1691
+ return $vars;
1692
+ }
1693
+
1694
+ /**
1695
+ * Ajax action to activate plugin
1696
+ */
1697
+ public function activate_plugin() {
1698
+
1699
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1700
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1701
+ }
1702
+
1703
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1704
+ wp_send_json_error(
1705
+ array(
1706
+ 'success' => false,
1707
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1708
+ )
1709
+ );
1710
+ }
1711
+
1712
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1713
+
1714
+ $activate = activate_plugin( $plugin_init, '', false, true );
1715
+
1716
+ if ( is_wp_error( $activate ) ) {
1717
+ wp_send_json_error(
1718
+ array(
1719
+ 'success' => false,
1720
+ 'message' => $activate->get_error_message(),
1721
+ 'init' => $plugin_init,
1722
+ )
1723
+ );
1724
+ }
1725
+
1726
+ wp_send_json_success(
1727
+ array(
1728
+ 'success' => true,
1729
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1730
+ 'init' => $plugin_init,
1731
+ )
1732
+ );
1733
+ }
1734
+
1735
+ }
1736
+
1737
+ /**
1738
+ * Initialize class object with 'get_instance()' method
1739
+ */
1740
+ CartFlows_Importer::get_instance();
1741
+
1742
+ endif;
classes/class-cartflows-loader.php CHANGED
@@ -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.11' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
+ define( 'CARTFLOWS_VER', '1.5.12' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
classes/class-cartflows-tracking.php CHANGED
@@ -1,277 +1,287 @@
1
- <?php
2
- /**
3
- * Cartflows_Tracking
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Tracking {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var object instance
27
- */
28
- public static $google_analytics_settings = 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( 'wp_head', array( $this, 'wcf_render_gtag' ) );
46
-
47
- // Set Google analytics values.
48
- $this->get_google_analytics_settings( self::$google_analytics_settings );
49
- }
50
-
51
- /**
52
- * Get ga settings.
53
- *
54
- * @param array $google_analytics_settings ga settings.
55
- */
56
- public function get_google_analytics_settings( $google_analytics_settings ) {
57
- self::$google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
58
- }
59
-
60
-
61
- /**
62
- * Render google tag framework.
63
- */
64
- public function wcf_render_gtag() {
65
- $get_tracking_code = $this->wcf_ga_id();
66
-
67
- if ( self::is_wcf_ga_tracking_on() ) {
68
- ?>
69
- <!-- Google Analytics Script By CartFlows -->
70
- <script type="text/javascript">
71
- var tracking_id = '<?php echo $get_tracking_code; ?>';
72
- </script>
73
- <!-- Global site tag (gtag.js) - Google Analytics -->
74
- <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript ?>
75
- <script async src=https://www.googletagmanager.com/gtag/js?id=<?php echo $get_tracking_code; ?>></script>
76
- <script>
77
- window.dataLayer = window.dataLayer || [];
78
- function gtag(){dataLayer.push(arguments);}
79
- gtag('js', new Date());
80
- </script>
81
-
82
- <!-- Google Analytics Script By CartFlows -->
83
- <?php
84
- if ( 'enable' === self::$google_analytics_settings['enable_google_analytics_for_site'] ) {
85
- ?>
86
- <script>
87
- gtag('config', tracking_id);
88
- </script>
89
- <?php
90
- }
91
- }
92
- }
93
-
94
- /**
95
- * Set cookies to send ga data.
96
- *
97
- * @param int $order_id order id.
98
- * @param array $offer_data offer product data.
99
- */
100
- public static function send_ga_data_if_enabled( $order_id, $offer_data = array() ) {
101
-
102
- if ( self::is_wcf_ga_tracking_on() && self::wcf_track_ga_purchase() ) {
103
-
104
- setcookie( 'wcf_ga_trans_data', wp_json_encode( self::get_ga_purchase_transactions_data( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
105
- }
106
- }
107
-
108
-
109
- /**
110
- * Prepare cart data for GA response.
111
- *
112
- * @param int $order_id order id.
113
- * @param array $offer_data offer product data.
114
- * @return array
115
- */
116
- public static function get_ga_purchase_transactions_data( $order_id, $offer_data ) {
117
-
118
- $response = array();
119
-
120
- $order = wc_get_order( $order_id );
121
- $cart_total = WC()->cart->get_cart_contents_total();
122
- $cart_items_count = WC()->cart->get_cart_contents_count();
123
- $items = $order->get_items();
124
- $cart_tax = $order->get_cart_tax();
125
- $response['items'] = array();
126
- $cart_contents = array();
127
-
128
- $response = array(
129
- 'transaction_id' => $order_id,
130
- 'affiliation' => get_bloginfo( 'name' ),
131
- 'value' => $order->get_total(),
132
- 'currency' => $order->get_currency(),
133
- 'tax' => $order->get_cart_tax(),
134
- 'shipping' => $order->get_shipping_total(),
135
- 'coupon' => WC()->cart->get_coupons(),
136
- );
137
- if ( empty( $offer_data ) ) {
138
- // Iterating through each WC_Order_Item_Product objects.
139
- foreach ( $items as $item => $value ) {
140
-
141
- $_product = wc_get_product( $value['product_id'] );
142
-
143
- if ( ! $_product->is_type( 'variable' ) ) {
144
- $product_data = self::get_required_data( $_product );
145
- } else {
146
- $variable_product = wc_get_product( $value['variation_id'] );
147
- $product_data = self::get_required_data( $variable_product );
148
- }
149
- array_push(
150
- $cart_contents,
151
- array(
152
- 'id' => $product_data['id'],
153
- 'name' => $product_data['name'],
154
- 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
155
- 'price' => $product_data['price'],
156
- 'quantity' => $value['quantity'],
157
- )
158
- );
159
- }
160
- } else {
161
- array_push(
162
- $cart_contents,
163
- array(
164
- 'id' => $offer_data['id'],
165
- 'name' => $offer_data['name'],
166
- 'quantity' => $offer_data['qty'],
167
- 'price' => $offer_data['price'],
168
- )
169
- );
170
- }
171
-
172
- $response['items'] = $cart_contents;
173
-
174
- // Prepare the json data to send it to google.
175
- return $response;
176
- }
177
-
178
- /**
179
- * Prepare Ecommerce data for GA response.
180
- *
181
- * @return array
182
- */
183
- public static function get_ga_items_list() {
184
-
185
- $items = WC()->cart->get_cart();
186
- $items_data = array();
187
-
188
- foreach ( $items as $item => $value ) {
189
-
190
- $_product = wc_get_product( $value['product_id'] );
191
-
192
- if ( ! $_product->is_type( 'variable' ) ) {
193
- $product_data = self::get_required_data( $_product );
194
- } else {
195
- $variable_product = wc_get_product( $value['variation_id'] );
196
- $product_data = self::get_required_data( $variable_product );
197
- }
198
-
199
- array_push(
200
- $items_data,
201
- array(
202
- 'id' => $product_data['id'],
203
- 'name' => $product_data['name'],
204
- 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
205
- 'price' => $product_data['price'],
206
- 'quantity' => $value['quantity'],
207
- )
208
- );
209
- }
210
- return $items_data;
211
- }
212
-
213
-
214
-
215
- /**
216
- * Check tracking on.
217
- */
218
- public static function is_wcf_ga_tracking_on() {
219
-
220
- $is_enabled = false;
221
-
222
- if ( 'disable' === self::$google_analytics_settings['enable_google_analytics'] ) {
223
- $is_enabled = false;
224
- } else {
225
- $is_enabled = true;
226
- }
227
-
228
- return apply_filters( 'cartflows_google_analytics_tracking_enabled', $is_enabled );
229
- }
230
-
231
-
232
-
233
- /**
234
- * Check purchase event enable.
235
- */
236
- public static function wcf_track_ga_purchase() {
237
-
238
- $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
239
- $wcf_track_ga_purchase = $google_analytics_settings['enable_purchase_event'];
240
-
241
- if ( is_array( $google_analytics_settings ) && ! empty( $google_analytics_settings ) && 'enable' === $wcf_track_ga_purchase ) {
242
- return true;
243
- }
244
-
245
- return false;
246
- }
247
-
248
- /**
249
- * Get product data.
250
- *
251
- * @param object $_product product data.
252
- */
253
- public static function get_required_data( $_product ) {
254
-
255
- $data = array(
256
- 'id' => $_product->get_id(),
257
- 'name' => $_product->get_name(),
258
- 'price' => $_product->get_price(),
259
- );
260
- return $data;
261
- }
262
-
263
- /**
264
- * Retreive google anlytics ID.
265
- */
266
- public function wcf_ga_id() {
267
-
268
- $get_ga_id = self::$google_analytics_settings['google_analytics_id'];
269
-
270
- return empty( $get_ga_id ) ? false : $get_ga_id;
271
- }
272
- }
273
-
274
- /**
275
- * Kicking this off by calling 'get_instance()' method
276
- */
277
- Cartflows_Tracking::get_instance();
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cartflows_Tracking
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Tracking {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var object instance
27
+ */
28
+ public static $google_analytics_settings = 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( 'wp_head', array( $this, 'wcf_render_gtag' ) );
46
+
47
+ // Set Google analytics values.
48
+ $this->get_google_analytics_settings( self::$google_analytics_settings );
49
+ }
50
+
51
+ /**
52
+ * Get ga settings.
53
+ *
54
+ * @param array $google_analytics_settings ga settings.
55
+ */
56
+ public function get_google_analytics_settings( $google_analytics_settings ) {
57
+ self::$google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
58
+ }
59
+
60
+
61
+ /**
62
+ * Render google tag framework.
63
+ */
64
+ public function wcf_render_gtag() {
65
+ $get_tracking_code = $this->wcf_ga_id();
66
+
67
+ if ( self::is_wcf_ga_tracking_on() ) {
68
+ ?>
69
+ <!-- Google Analytics Script By CartFlows -->
70
+ <script type="text/javascript">
71
+ var tracking_id = '<?php echo $get_tracking_code; ?>';
72
+ </script>
73
+ <!-- Global site tag (gtag.js) - Google Analytics -->
74
+ <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript ?>
75
+ <script async src=https://www.googletagmanager.com/gtag/js?id=<?php echo $get_tracking_code; ?>></script>
76
+ <script>
77
+ window.dataLayer = window.dataLayer || [];
78
+ function gtag(){dataLayer.push(arguments);}
79
+ gtag('js', new Date());
80
+ </script>
81
+
82
+ <!-- Google Analytics Script By CartFlows -->
83
+ <?php
84
+ if ( 'enable' === self::$google_analytics_settings['enable_google_analytics_for_site'] ) {
85
+ ?>
86
+ <script>
87
+ gtag('config', tracking_id);
88
+ </script>
89
+ <?php
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Set cookies to send ga data.
96
+ *
97
+ * @param int $order_id order id.
98
+ * @param array $offer_data offer product data.
99
+ */
100
+ public static function send_ga_data_if_enabled( $order_id, $offer_data = array() ) {
101
+
102
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
103
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
104
+ return;
105
+ }
106
+
107
+ if ( self::is_wcf_ga_tracking_on() && self::wcf_track_ga_purchase() ) {
108
+
109
+ setcookie( 'wcf_ga_trans_data', wp_json_encode( self::get_ga_purchase_transactions_data( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
110
+ }
111
+ }
112
+
113
+
114
+ /**
115
+ * Prepare cart data for GA response.
116
+ *
117
+ * @param int $order_id order id.
118
+ * @param array $offer_data offer product data.
119
+ * @return array
120
+ */
121
+ public static function get_ga_purchase_transactions_data( $order_id, $offer_data ) {
122
+
123
+ $response = array();
124
+
125
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
126
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
127
+ return;
128
+ }
129
+
130
+ $order = wc_get_order( $order_id );
131
+ $cart_total = WC()->cart->get_cart_contents_total();
132
+ $cart_items_count = WC()->cart->get_cart_contents_count();
133
+ $items = $order->get_items();
134
+ $cart_tax = $order->get_cart_tax();
135
+ $response['items'] = array();
136
+ $cart_contents = array();
137
+
138
+ $response = array(
139
+ 'transaction_id' => $order_id,
140
+ 'affiliation' => get_bloginfo( 'name' ),
141
+ 'value' => $order->get_total(),
142
+ 'currency' => $order->get_currency(),
143
+ 'tax' => $order->get_cart_tax(),
144
+ 'shipping' => $order->get_shipping_total(),
145
+ 'coupon' => WC()->cart->get_coupons(),
146
+ );
147
+ if ( empty( $offer_data ) ) {
148
+ // Iterating through each WC_Order_Item_Product objects.
149
+ foreach ( $items as $item => $value ) {
150
+
151
+ $_product = wc_get_product( $value['product_id'] );
152
+
153
+ if ( ! $_product->is_type( 'variable' ) ) {
154
+ $product_data = self::get_required_data( $_product );
155
+ } else {
156
+ $variable_product = wc_get_product( $value['variation_id'] );
157
+ $product_data = self::get_required_data( $variable_product );
158
+ }
159
+ array_push(
160
+ $cart_contents,
161
+ array(
162
+ 'id' => $product_data['id'],
163
+ 'name' => $product_data['name'],
164
+ 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
165
+ 'price' => $product_data['price'],
166
+ 'quantity' => $value['quantity'],
167
+ )
168
+ );
169
+ }
170
+ } else {
171
+ array_push(
172
+ $cart_contents,
173
+ array(
174
+ 'id' => $offer_data['id'],
175
+ 'name' => $offer_data['name'],
176
+ 'quantity' => $offer_data['qty'],
177
+ 'price' => $offer_data['price'],
178
+ )
179
+ );
180
+ }
181
+
182
+ $response['items'] = $cart_contents;
183
+
184
+ // Prepare the json data to send it to google.
185
+ return $response;
186
+ }
187
+
188
+ /**
189
+ * Prepare Ecommerce data for GA response.
190
+ *
191
+ * @return array
192
+ */
193
+ public static function get_ga_items_list() {
194
+
195
+ $items = WC()->cart->get_cart();
196
+ $items_data = array();
197
+
198
+ foreach ( $items as $item => $value ) {
199
+
200
+ $_product = wc_get_product( $value['product_id'] );
201
+
202
+ if ( ! $_product->is_type( 'variable' ) ) {
203
+ $product_data = self::get_required_data( $_product );
204
+ } else {
205
+ $variable_product = wc_get_product( $value['variation_id'] );
206
+ $product_data = self::get_required_data( $variable_product );
207
+ }
208
+
209
+ array_push(
210
+ $items_data,
211
+ array(
212
+ 'id' => $product_data['id'],
213
+ 'name' => $product_data['name'],
214
+ 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
215
+ 'price' => $product_data['price'],
216
+ 'quantity' => $value['quantity'],
217
+ )
218
+ );
219
+ }
220
+ return $items_data;
221
+ }
222
+
223
+
224
+
225
+ /**
226
+ * Check tracking on.
227
+ */
228
+ public static function is_wcf_ga_tracking_on() {
229
+
230
+ $is_enabled = false;
231
+
232
+ if ( 'disable' === self::$google_analytics_settings['enable_google_analytics'] ) {
233
+ $is_enabled = false;
234
+ } else {
235
+ $is_enabled = true;
236
+ }
237
+
238
+ return apply_filters( 'cartflows_google_analytics_tracking_enabled', $is_enabled );
239
+ }
240
+
241
+
242
+
243
+ /**
244
+ * Check purchase event enable.
245
+ */
246
+ public static function wcf_track_ga_purchase() {
247
+
248
+ $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
249
+ $wcf_track_ga_purchase = $google_analytics_settings['enable_purchase_event'];
250
+
251
+ if ( is_array( $google_analytics_settings ) && ! empty( $google_analytics_settings ) && 'enable' === $wcf_track_ga_purchase ) {
252
+ return true;
253
+ }
254
+
255
+ return false;
256
+ }
257
+
258
+ /**
259
+ * Get product data.
260
+ *
261
+ * @param object $_product product data.
262
+ */
263
+ public static function get_required_data( $_product ) {
264
+
265
+ $data = array(
266
+ 'id' => $_product->get_id(),
267
+ 'name' => $_product->get_name(),
268
+ 'price' => $_product->get_price(),
269
+ );
270
+ return $data;
271
+ }
272
+
273
+ /**
274
+ * Retreive google anlytics ID.
275
+ */
276
+ public function wcf_ga_id() {
277
+
278
+ $get_ga_id = self::$google_analytics_settings['google_analytics_id'];
279
+
280
+ return empty( $get_ga_id ) ? false : $get_ga_id;
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Kicking this off by calling 'get_instance()' method
286
+ */
287
+ Cartflows_Tracking::get_instance();
classes/class-cartflows-utils.php CHANGED
@@ -1,591 +1,591 @@
1
- <?php
2
- /**
3
- * Utils.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Utils.
14
- */
15
- class Cartflows_Utils {
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_products
28
- */
29
- public $checkout_products = array();
30
-
31
-
32
- /**
33
- * Initiator
34
- */
35
- public static function get_instance() {
36
- if ( ! isset( self::$instance ) ) {
37
- self::$instance = new self();
38
- }
39
- return self::$instance;
40
- }
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get current post type
50
- *
51
- * @param string $post_type post type.
52
- * @return string
53
- */
54
- public function current_post_type( $post_type = '' ) {
55
-
56
- if ( '' === $post_type ) {
57
- $post_type = get_post_type();
58
- }
59
-
60
- return $post_type;
61
- }
62
-
63
- /**
64
- * Check if post type is of step.
65
- *
66
- * @param string $post_type post type.
67
- * @return bool
68
- */
69
- public function is_step_post_type( $post_type = '' ) {
70
-
71
- if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
-
73
- return true;
74
- }
75
-
76
- return false;
77
- }
78
-
79
- /**
80
- * Check if post type is of flow.
81
- *
82
- * @param string $post_type post type.
83
- * @return bool
84
- */
85
- public function is_flow_post_type( $post_type = '' ) {
86
-
87
- if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
-
89
- return true;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Get post type of step.
97
- *
98
- * @return string
99
- */
100
- public function get_step_post_type() {
101
-
102
- return CARTFLOWS_STEP_POST_TYPE;
103
- }
104
-
105
- /**
106
- * Get post type of flow.
107
- *
108
- * @return string
109
- */
110
- public function get_flow_post_type() {
111
-
112
- return CARTFLOWS_FLOW_POST_TYPE;
113
- }
114
-
115
- /**
116
- * Get flow id
117
- *
118
- * @return int
119
- */
120
- public function get_flow_id() {
121
-
122
- global $post;
123
-
124
- return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
- }
126
-
127
- /**
128
- * Get flow id by step
129
- *
130
- * @param int $step_id step ID.
131
- * @return int
132
- */
133
- public function get_flow_id_from_step_id( $step_id ) {
134
-
135
- return get_post_meta( $step_id, 'wcf-flow-id', true );
136
- }
137
-
138
- /**
139
- * Get flow steps by id
140
- *
141
- * @param int $flow_id flow ID.
142
- * @return int
143
- */
144
- public function get_flow_steps( $flow_id ) {
145
-
146
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
-
148
- if ( is_array( $steps ) && ! empty( $steps ) ) {
149
- return $steps;
150
- }
151
-
152
- return false;
153
- }
154
-
155
- /**
156
- * Get template type of step
157
- *
158
- * @param int $step_id step ID.
159
- * @return int
160
- */
161
- public function get_step_type( $step_id ) {
162
-
163
- return get_post_meta( $step_id, 'wcf-step-type', true );
164
- }
165
-
166
- /**
167
- * Get next id for step
168
- *
169
- * @param int $flow_id flow ID.
170
- * @param int $step_id step ID.
171
- * @return bool
172
- */
173
- public function get_next_step_id( $flow_id, $step_id ) {
174
-
175
- $steps = $this->get_flow_steps( $flow_id );
176
- $step_id = intval( $step_id );
177
-
178
- if ( ! $steps ) {
179
- return false;
180
- }
181
-
182
- foreach ( $steps as $i => $step ) {
183
-
184
- if ( intval( $step['id'] ) === $step_id ) {
185
-
186
- $next_i = $i + 1;
187
-
188
- if ( isset( $steps[ $next_i ] ) ) {
189
-
190
- $navigation = $steps[ $next_i ];
191
-
192
- return intval( $navigation['id'] );
193
- }
194
-
195
- break;
196
- }
197
- }
198
-
199
- return false;
200
- }
201
-
202
- /**
203
- * Get next id for step
204
- *
205
- * @param int $order_id order ID.
206
- * @return int
207
- */
208
- public function get_flow_id_from_order( $order_id ) {
209
-
210
- $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
-
212
- return intval( $flow_id );
213
- }
214
-
215
- /**
216
- * Get checkout id for order
217
- *
218
- * @param int $order_id order ID.
219
- * @return int
220
- */
221
- public function get_checkout_id_from_order( $order_id ) {
222
-
223
- $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
-
225
- return intval( $checkout_id );
226
- }
227
-
228
- /**
229
- * We are using this function mostly in ajax on checkout page
230
- *
231
- * @return bool
232
- */
233
- public function get_checkout_id_from_post_data() {
234
-
235
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
-
237
- $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
-
239
- return intval( $checkout_id );
240
- }
241
-
242
- return false;
243
- }
244
-
245
- /**
246
- * We are using this function mostly in ajax on checkout page
247
- *
248
- * @return bool
249
- */
250
- public function get_flow_id_from_post_data() {
251
-
252
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
-
254
- $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
-
256
- return intval( $flow_id );
257
- }
258
-
259
- return false;
260
- }
261
-
262
- /**
263
- * Get optin id for order
264
- *
265
- * @param int $order_id order ID.
266
- * @return int
267
- */
268
- public function get_optin_id_from_order( $order_id ) {
269
-
270
- $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
-
272
- return intval( $optin_id );
273
- }
274
-
275
- /**
276
- * We are using this function mostly in ajax on checkout page
277
- *
278
- * @return bool
279
- */
280
- public function get_optin_id_from_post_data() {
281
-
282
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
-
284
- $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
-
286
- return intval( $optin_id );
287
- }
288
-
289
- return false;
290
- }
291
-
292
- /**
293
- * Check for thank you page
294
- *
295
- * @param int $step_id step ID.
296
- * @return bool
297
- */
298
- public function check_is_thankyou_page( $step_id ) {
299
-
300
- $step_type = $this->get_step_type( $step_id );
301
-
302
- if ( 'thankyou' === $step_type ) {
303
-
304
- return true;
305
- }
306
-
307
- return false;
308
- }
309
-
310
- /**
311
- * Check for offer page
312
- *
313
- * @param int $step_id step ID.
314
- * @return bool
315
- */
316
- public function check_is_offer_page( $step_id ) {
317
-
318
- $step_type = $this->get_step_type( $step_id );
319
-
320
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
-
322
- return true;
323
- }
324
-
325
- return false;
326
- }
327
-
328
- /**
329
- * Check if loaded page requires woo.
330
- *
331
- * @return bool
332
- */
333
- public function check_is_woo_required_page() {
334
-
335
- global $post;
336
- $step_id = $post->ID;
337
- $woo_not_required_type = array( 'landing' );
338
- $step_type = $this->get_step_type( $step_id );
339
- return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
- }
341
-
342
- /**
343
- * Define constant for cache
344
- *
345
- * @return void
346
- */
347
- public function do_not_cache() {
348
-
349
- global $post;
350
-
351
- if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
- return;
353
- }
354
-
355
- wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
- wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
- wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
-
359
- nocache_headers();
360
- }
361
-
362
- /**
363
- * Get linking url
364
- *
365
- * @param array $args query args.
366
- * @return string
367
- */
368
- public function get_linking_url( $args = array() ) {
369
-
370
- $url = get_home_url();
371
-
372
- $url = add_query_arg( $args, $url );
373
-
374
- return $url;
375
- }
376
-
377
- /**
378
- * Get assets urls
379
- *
380
- * @return array
381
- * @since 1.1.6
382
- */
383
- public function get_assets_path() {
384
-
385
- $rtl = '';
386
-
387
- if ( is_rtl() ) {
388
- $rtl = '-rtl';
389
- }
390
-
391
- $file_prefix = '';
392
- $dir_name = '';
393
-
394
- $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
-
396
- if ( $is_min ) {
397
- $file_prefix = '.min';
398
- $dir_name = 'min-';
399
- }
400
-
401
- $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
- $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
-
404
- return array(
405
- 'css' => $css_gen_path,
406
- 'js' => $js_gen_path,
407
- 'file_prefix' => $file_prefix,
408
- 'rtl' => $rtl,
409
- );
410
- }
411
-
412
- /**
413
- * Get assets css url
414
- *
415
- * @param string $file file name.
416
- * @return string
417
- * @since 1.1.6
418
- */
419
- public function get_css_url( $file ) {
420
-
421
- $assets_vars = wcf()->assets_vars;
422
-
423
- $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
-
425
- return $url;
426
- }
427
-
428
- /**
429
- * Get assets js url
430
- *
431
- * @param string $file file name.
432
- * @return string
433
- * @since 1.1.6
434
- */
435
- public function get_js_url( $file ) {
436
-
437
- $assets_vars = wcf()->assets_vars;
438
-
439
- $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
-
441
- return $url;
442
- }
443
-
444
- /**
445
- * Get unique id.
446
- *
447
- * @param int $length Length.
448
- *
449
- * @return string
450
- */
451
- public function get_unique_id( $length = 8 ) {
452
-
453
- return substr( md5( microtime() ), 0, $length );
454
- }
455
-
456
- /**
457
- * Get selected checkout products and data
458
- *
459
- * @param int $checkout_id Checkout id..
460
- * @param array $saved_products Saved product.
461
- *
462
- * @return array
463
- */
464
- public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
-
466
- if ( empty( $checkout_id ) ) {
467
-
468
- global $post;
469
-
470
- $checkout_id = $post->ID;
471
- }
472
-
473
- if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
-
475
- if ( ! empty( $saved_products ) ) {
476
-
477
- $products = $saved_products;
478
- } else {
479
-
480
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
- }
482
-
483
- $verify_url_data = false;
484
- $default_add_to_cart = false;
485
- $default_ids = array();
486
- $default_add_to_cart = true;
487
-
488
- if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
- //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
- $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
- $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
- $verify_url_data = true;
493
- }
494
-
495
- if ( is_array( $products ) ) {
496
-
497
- foreach ( $products as $in => $data ) {
498
-
499
- if ( $verify_url_data ) {
500
-
501
- $default_add_to_cart = false;
502
- $sequence = $in + 1;
503
-
504
- if ( in_array( $sequence, $default_ids, true ) ) {
505
- $default_add_to_cart = true;
506
- }
507
- }
508
-
509
- $default_data = array(
510
- 'quantity' => 1,
511
- 'discount_type' => '',
512
- 'discount_value' => '',
513
- 'unique_id' => $this->get_unique_id(),
514
- 'add_to_cart' => $default_add_to_cart,
515
- );
516
-
517
- $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
- }
519
- }
520
-
521
- $this->checkout_products[ $checkout_id ] = $products;
522
- }
523
-
524
- return $this->checkout_products[ $checkout_id ];
525
- }
526
-
527
- /**
528
- * Get selected checkout products and data
529
- *
530
- * @param int $checkout_id Checkout id..
531
- * @param array $products_data Saved product.
532
- *
533
- * @return array
534
- */
535
- public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
-
537
- if ( empty( $checkout_id ) ) {
538
-
539
- global $post;
540
-
541
- $checkout_id = $post->ID;
542
- }
543
-
544
- if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
-
546
- $products = $this->checkout_products[ $checkout_id ];
547
- } else {
548
- $products = $this->get_selected_checkout_products( $checkout_id );
549
- }
550
-
551
- if ( is_array( $products ) && ! empty( $products_data ) ) {
552
-
553
- foreach ( $products as $in => $data ) {
554
-
555
- if ( isset( $products_data[ $in ] ) ) {
556
- $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
- }
558
- }
559
- }
560
-
561
- $this->checkout_products[ $checkout_id ] = $products;
562
-
563
- return $this->checkout_products[ $checkout_id ];
564
- }
565
- }
566
-
567
- /**
568
- * Get a specific property of an array without needing to check if that property exists.
569
- *
570
- * Provide a default value if you want to return a specific value if the property is not set.
571
- *
572
- * @param array $array Array from which the property's value should be retrieved.
573
- * @param string $prop Name of the property to be retrieved.
574
- * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
- *
576
- * @return null|string|mixed The value
577
- */
578
- function wcf_get_prop( $array, $prop, $default = null ) {
579
-
580
- if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
- return $default;
582
- }
583
-
584
- if ( isset( $array[ $prop ] ) ) {
585
- $value = $array[ $prop ];
586
- } else {
587
- $value = '';
588
- }
589
-
590
- return empty( $value ) && null !== $default ? $default : $value;
591
- }
1
+ <?php
2
+ /**
3
+ * Utils.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Utils.
14
+ */
15
+ class Cartflows_Utils {
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_products
28
+ */
29
+ public $checkout_products = array();
30
+
31
+
32
+ /**
33
+ * Initiator
34
+ */
35
+ public static function get_instance() {
36
+ if ( ! isset( self::$instance ) ) {
37
+ self::$instance = new self();
38
+ }
39
+ return self::$instance;
40
+ }
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get current post type
50
+ *
51
+ * @param string $post_type post type.
52
+ * @return string
53
+ */
54
+ public function current_post_type( $post_type = '' ) {
55
+
56
+ if ( '' === $post_type ) {
57
+ $post_type = get_post_type();
58
+ }
59
+
60
+ return $post_type;
61
+ }
62
+
63
+ /**
64
+ * Check if post type is of step.
65
+ *
66
+ * @param string $post_type post type.
67
+ * @return bool
68
+ */
69
+ public function is_step_post_type( $post_type = '' ) {
70
+
71
+ if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
+
73
+ return true;
74
+ }
75
+
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * Check if post type is of flow.
81
+ *
82
+ * @param string $post_type post type.
83
+ * @return bool
84
+ */
85
+ public function is_flow_post_type( $post_type = '' ) {
86
+
87
+ if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
+
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Get post type of step.
97
+ *
98
+ * @return string
99
+ */
100
+ public function get_step_post_type() {
101
+
102
+ return CARTFLOWS_STEP_POST_TYPE;
103
+ }
104
+
105
+ /**
106
+ * Get post type of flow.
107
+ *
108
+ * @return string
109
+ */
110
+ public function get_flow_post_type() {
111
+
112
+ return CARTFLOWS_FLOW_POST_TYPE;
113
+ }
114
+
115
+ /**
116
+ * Get flow id
117
+ *
118
+ * @return int
119
+ */
120
+ public function get_flow_id() {
121
+
122
+ global $post;
123
+
124
+ return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
+ }
126
+
127
+ /**
128
+ * Get flow id by step
129
+ *
130
+ * @param int $step_id step ID.
131
+ * @return int
132
+ */
133
+ public function get_flow_id_from_step_id( $step_id ) {
134
+
135
+ return get_post_meta( $step_id, 'wcf-flow-id', true );
136
+ }
137
+
138
+ /**
139
+ * Get flow steps by id
140
+ *
141
+ * @param int $flow_id flow ID.
142
+ * @return int
143
+ */
144
+ public function get_flow_steps( $flow_id ) {
145
+
146
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
+
148
+ if ( is_array( $steps ) && ! empty( $steps ) ) {
149
+ return $steps;
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * Get template type of step
157
+ *
158
+ * @param int $step_id step ID.
159
+ * @return int
160
+ */
161
+ public function get_step_type( $step_id ) {
162
+
163
+ return get_post_meta( $step_id, 'wcf-step-type', true );
164
+ }
165
+
166
+ /**
167
+ * Get next id for step
168
+ *
169
+ * @param int $flow_id flow ID.
170
+ * @param int $step_id step ID.
171
+ * @return bool
172
+ */
173
+ public function get_next_step_id( $flow_id, $step_id ) {
174
+
175
+ $steps = $this->get_flow_steps( $flow_id );
176
+ $step_id = intval( $step_id );
177
+
178
+ if ( ! $steps ) {
179
+ return false;
180
+ }
181
+
182
+ foreach ( $steps as $i => $step ) {
183
+
184
+ if ( intval( $step['id'] ) === $step_id ) {
185
+
186
+ $next_i = $i + 1;
187
+
188
+ if ( isset( $steps[ $next_i ] ) ) {
189
+
190
+ $navigation = $steps[ $next_i ];
191
+
192
+ return intval( $navigation['id'] );
193
+ }
194
+
195
+ break;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Get next id for step
204
+ *
205
+ * @param int $order_id order ID.
206
+ * @return int
207
+ */
208
+ public function get_flow_id_from_order( $order_id ) {
209
+
210
+ $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
+
212
+ return intval( $flow_id );
213
+ }
214
+
215
+ /**
216
+ * Get checkout id for order
217
+ *
218
+ * @param int $order_id order ID.
219
+ * @return int
220
+ */
221
+ public function get_checkout_id_from_order( $order_id ) {
222
+
223
+ $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
+
225
+ return intval( $checkout_id );
226
+ }
227
+
228
+ /**
229
+ * We are using this function mostly in ajax on checkout page
230
+ *
231
+ * @return bool
232
+ */
233
+ public function get_checkout_id_from_post_data() {
234
+
235
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
+
237
+ $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
+
239
+ return intval( $checkout_id );
240
+ }
241
+
242
+ return false;
243
+ }
244
+
245
+ /**
246
+ * We are using this function mostly in ajax on checkout page
247
+ *
248
+ * @return bool
249
+ */
250
+ public function get_flow_id_from_post_data() {
251
+
252
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
+
254
+ $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
+
256
+ return intval( $flow_id );
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Get optin id for order
264
+ *
265
+ * @param int $order_id order ID.
266
+ * @return int
267
+ */
268
+ public function get_optin_id_from_order( $order_id ) {
269
+
270
+ $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
+
272
+ return intval( $optin_id );
273
+ }
274
+
275
+ /**
276
+ * We are using this function mostly in ajax on checkout page
277
+ *
278
+ * @return bool
279
+ */
280
+ public function get_optin_id_from_post_data() {
281
+
282
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
+
284
+ $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
+
286
+ return intval( $optin_id );
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ /**
293
+ * Check for thank you page
294
+ *
295
+ * @param int $step_id step ID.
296
+ * @return bool
297
+ */
298
+ public function check_is_thankyou_page( $step_id ) {
299
+
300
+ $step_type = $this->get_step_type( $step_id );
301
+
302
+ if ( 'thankyou' === $step_type ) {
303
+
304
+ return true;
305
+ }
306
+
307
+ return false;
308
+ }
309
+
310
+ /**
311
+ * Check for offer page
312
+ *
313
+ * @param int $step_id step ID.
314
+ * @return bool
315
+ */
316
+ public function check_is_offer_page( $step_id ) {
317
+
318
+ $step_type = $this->get_step_type( $step_id );
319
+
320
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
+
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * Check if loaded page requires woo.
330
+ *
331
+ * @return bool
332
+ */
333
+ public function check_is_woo_required_page() {
334
+
335
+ global $post;
336
+ $step_id = $post->ID;
337
+ $woo_not_required_type = array( 'landing' );
338
+ $step_type = $this->get_step_type( $step_id );
339
+ return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
+ }
341
+
342
+ /**
343
+ * Define constant for cache
344
+ *
345
+ * @return void
346
+ */
347
+ public function do_not_cache() {
348
+
349
+ global $post;
350
+
351
+ if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
+ return;
353
+ }
354
+
355
+ wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
+ wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
+ wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
+
359
+ nocache_headers();
360
+ }
361
+
362
+ /**
363
+ * Get linking url
364
+ *
365
+ * @param array $args query args.
366
+ * @return string
367
+ */
368
+ public function get_linking_url( $args = array() ) {
369
+
370
+ $url = get_home_url();
371
+
372
+ $url = add_query_arg( $args, $url );
373
+
374
+ return $url;
375
+ }
376
+
377
+ /**
378
+ * Get assets urls
379
+ *
380
+ * @return array
381
+ * @since 1.1.6
382
+ */
383
+ public function get_assets_path() {
384
+
385
+ $rtl = '';
386
+
387
+ if ( is_rtl() ) {
388
+ $rtl = '-rtl';
389
+ }
390
+
391
+ $file_prefix = '';
392
+ $dir_name = '';
393
+
394
+ $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
+
396
+ if ( $is_min ) {
397
+ $file_prefix = '.min';
398
+ $dir_name = 'min-';
399
+ }
400
+
401
+ $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
+ $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
+
404
+ return array(
405
+ 'css' => $css_gen_path,
406
+ 'js' => $js_gen_path,
407
+ 'file_prefix' => $file_prefix,
408
+ 'rtl' => $rtl,
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Get assets css url
414
+ *
415
+ * @param string $file file name.
416
+ * @return string
417
+ * @since 1.1.6
418
+ */
419
+ public function get_css_url( $file ) {
420
+
421
+ $assets_vars = wcf()->assets_vars;
422
+
423
+ $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
+
425
+ return $url;
426
+ }
427
+
428
+ /**
429
+ * Get assets js url
430
+ *
431
+ * @param string $file file name.
432
+ * @return string
433
+ * @since 1.1.6
434
+ */
435
+ public function get_js_url( $file ) {
436
+
437
+ $assets_vars = wcf()->assets_vars;
438
+
439
+ $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
+
441
+ return $url;
442
+ }
443
+
444
+ /**
445
+ * Get unique id.
446
+ *
447
+ * @param int $length Length.
448
+ *
449
+ * @return string
450
+ */
451
+ public function get_unique_id( $length = 8 ) {
452
+
453
+ return substr( md5( microtime() ), 0, $length );
454
+ }
455
+
456
+ /**
457
+ * Get selected checkout products and data
458
+ *
459
+ * @param int $checkout_id Checkout id..
460
+ * @param array $saved_products Saved product.
461
+ *
462
+ * @return array
463
+ */
464
+ public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
+
466
+ if ( empty( $checkout_id ) ) {
467
+
468
+ global $post;
469
+
470
+ $checkout_id = $post->ID;
471
+ }
472
+
473
+ if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
+
475
+ if ( ! empty( $saved_products ) ) {
476
+
477
+ $products = $saved_products;
478
+ } else {
479
+
480
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
+ }
482
+
483
+ $verify_url_data = false;
484
+ $default_add_to_cart = false;
485
+ $default_ids = array();
486
+ $default_add_to_cart = true;
487
+
488
+ if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
+ $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
+ $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
+ $verify_url_data = true;
493
+ }
494
+
495
+ if ( is_array( $products ) ) {
496
+
497
+ foreach ( $products as $in => $data ) {
498
+
499
+ if ( $verify_url_data ) {
500
+
501
+ $default_add_to_cart = false;
502
+ $sequence = $in + 1;
503
+
504
+ if ( in_array( $sequence, $default_ids, true ) ) {
505
+ $default_add_to_cart = true;
506
+ }
507
+ }
508
+
509
+ $default_data = array(
510
+ 'quantity' => 1,
511
+ 'discount_type' => '',
512
+ 'discount_value' => '',
513
+ 'unique_id' => $this->get_unique_id(),
514
+ 'add_to_cart' => $default_add_to_cart,
515
+ );
516
+
517
+ $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
+ }
519
+ }
520
+
521
+ $this->checkout_products[ $checkout_id ] = $products;
522
+ }
523
+
524
+ return $this->checkout_products[ $checkout_id ];
525
+ }
526
+
527
+ /**
528
+ * Get selected checkout products and data
529
+ *
530
+ * @param int $checkout_id Checkout id..
531
+ * @param array $products_data Saved product.
532
+ *
533
+ * @return array
534
+ */
535
+ public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
+
537
+ if ( empty( $checkout_id ) ) {
538
+
539
+ global $post;
540
+
541
+ $checkout_id = $post->ID;
542
+ }
543
+
544
+ if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
+
546
+ $products = $this->checkout_products[ $checkout_id ];
547
+ } else {
548
+ $products = $this->get_selected_checkout_products( $checkout_id );
549
+ }
550
+
551
+ if ( is_array( $products ) && ! empty( $products_data ) ) {
552
+
553
+ foreach ( $products as $in => $data ) {
554
+
555
+ if ( isset( $products_data[ $in ] ) ) {
556
+ $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
+ }
558
+ }
559
+ }
560
+
561
+ $this->checkout_products[ $checkout_id ] = $products;
562
+
563
+ return $this->checkout_products[ $checkout_id ];
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Get a specific property of an array without needing to check if that property exists.
569
+ *
570
+ * Provide a default value if you want to return a specific value if the property is not set.
571
+ *
572
+ * @param array $array Array from which the property's value should be retrieved.
573
+ * @param string $prop Name of the property to be retrieved.
574
+ * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
+ *
576
+ * @return null|string|mixed The value
577
+ */
578
+ function wcf_get_prop( $array, $prop, $default = null ) {
579
+
580
+ if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
+ return $default;
582
+ }
583
+
584
+ if ( isset( $array[ $prop ] ) ) {
585
+ $value = $array[ $prop ];
586
+ } else {
587
+ $value = '';
588
+ }
589
+
590
+ return empty( $value ) && null !== $default ? $default : $value;
591
+ }
classes/class-cartflows-wizard.php CHANGED
@@ -1,706 +1,706 @@
1
- <?php
2
- /**
3
- * CartFlows- Onboarding Wizard
4
- *
5
- * @package cartflows
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit;
10
- }
11
-
12
- if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
-
14
- /**
15
- * CartFlows_Wizard class.
16
- */
17
- class CartFlows_Wizard {
18
-
19
- /**
20
- * Hook in tabs.
21
- */
22
- public function __construct() {
23
-
24
- if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
- add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
- add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
- add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
- add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
- add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
31
- add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
32
-
33
- add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
34
-
35
- add_action( 'admin_init', array( $this, 'hide_notices' ) );
36
-
37
- }
38
- }
39
-
40
-
41
- /**
42
- * Hide a notice if the GET variable is set.
43
- */
44
- public function hide_notices() {
45
-
46
- if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
47
- return;
48
- }
49
-
50
- $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
51
- $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
52
-
53
- if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
54
- update_option( 'wcf_setup_skipped', true );
55
- }
56
- }
57
-
58
- /**
59
- * Disable the woo redirect for new setup.
60
- */
61
- public function disable_woo_setup_redirect() {
62
-
63
- delete_transient( '_wc_activation_redirect' );
64
- }
65
-
66
- /**
67
- * Show action links on the plugin screen.
68
- *
69
- * @since 1.0.0
70
- * @return void
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>
94
- <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
95
- <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
96
- </p>
97
- </div>
98
- <?php
99
- }
100
- }
101
-
102
- /**
103
- * Add admin menus/screens.
104
- */
105
- public function admin_menus() {
106
-
107
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
108
- return;
109
- }
110
-
111
- add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
112
- }
113
-
114
- /**
115
- * Show the setup wizard.
116
- */
117
- public function setup_wizard() {
118
-
119
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
120
- return;
121
- }
122
-
123
- $this->steps = array(
124
- 'basic-config' => array(
125
- 'name' => __( 'Welcome', 'cartflows' ),
126
- 'view' => array( $this, 'welcome_step' ),
127
- 'handler' => array( $this, 'welcome_step_save' ),
128
- ),
129
- 'page-builder' => array(
130
- 'name' => __( 'Page Builder', 'cartflows' ),
131
- 'view' => array( $this, 'page_builder_step' ),
132
- ),
133
- 'checkout' => array(
134
- 'name' => __( 'Checkout', 'cartflows' ),
135
- 'view' => array( $this, 'checkout_step' ),
136
- ),
137
- 'training' => array(
138
- 'name' => __( 'Training', 'cartflows' ),
139
- 'view' => array( $this, 'training_step' ),
140
- ),
141
- 'setup-ready' => array(
142
- 'name' => __( 'Ready!', 'cartflows' ),
143
- 'view' => array( $this, 'ready_step' ),
144
- 'handler' => '',
145
- ),
146
- );
147
-
148
- $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
149
-
150
- wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
151
- wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
152
-
153
- wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
154
-
155
- wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
156
-
157
- wp_enqueue_media();
158
-
159
- if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
160
- call_user_func( $this->steps[ $this->step ]['handler'] );
161
- }
162
-
163
- ob_start();
164
- $this->setup_wizard_header();
165
- $this->setup_wizard_steps();
166
- $this->setup_wizard_content();
167
- $this->setup_wizard_footer();
168
- exit;
169
- }
170
-
171
- /**
172
- * Get current step slug
173
- */
174
- public function get_current_step_slug() {
175
- $keys = array_keys( $this->steps );
176
- return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
177
- }
178
-
179
- /**
180
- * Get previous step link
181
- */
182
- public function get_prev_step_link() {
183
- $keys = array_keys( $this->steps );
184
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
185
- }
186
-
187
- /**
188
- * Get next step link
189
- */
190
- public function get_next_step_link() {
191
- $keys = array_keys( $this->steps );
192
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
193
- }
194
-
195
- /**
196
- * Get next step link
197
- */
198
- public function get_next_step_plain_link() {
199
- $keys = array_keys( $this->steps );
200
- $step_index = array_search( $this->step, $keys, true );
201
- $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
202
- $step = $keys[ $step_index ];
203
- return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
204
- }
205
-
206
- /**
207
- * Setup Wizard Header.
208
- */
209
- public function setup_wizard_header() {
210
- set_current_screen();
211
- ?>
212
- <html <?php language_attributes(); ?>>
213
- <html>
214
- <head>
215
- <meta name="viewport" content="width=device-width" />
216
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
217
- <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
218
-
219
- <script type="text/javascript">
220
- addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
221
- var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
222
- var pagenow = '';
223
- </script>
224
- <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
225
- <?php do_action( 'admin_print_styles' ); ?>
226
- <?php do_action( 'admin_head' ); ?>
227
- </head>
228
- <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
229
- <div id="cartflows-logo">
230
- <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
231
- </div>
232
- <?php
233
- }
234
-
235
- /**
236
- * Setup Wizard Footer.
237
- */
238
- public function setup_wizard_footer() {
239
-
240
- $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
241
- ?>
242
- <div class="close-button-wrapper">
243
- <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
244
- </div>
245
- </body>
246
- </html>
247
- <?php
248
- }
249
-
250
- /**
251
- * Output the steps.
252
- */
253
- public function setup_wizard_steps() {
254
-
255
- $ouput_steps = $this->steps;
256
- ?>
257
- <ol class="cartflows-setup-steps">
258
- <?php
259
- foreach ( $ouput_steps as $step_key => $step ) :
260
- $classes = '';
261
- $activated = false;
262
- if ( $step_key === $this->step ) {
263
- $classes = 'active';
264
- $activated = true;
265
- } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
266
- $classes = 'done';
267
- $activated = true;
268
- }
269
- ?>
270
- <li class="<?php echo esc_attr( $classes ); ?>">
271
- <span><?php echo esc_html( $step['name'] ); ?></span>
272
- </li>
273
- <?php endforeach; ?>
274
- </ol>
275
- <?php
276
- }
277
-
278
- /**
279
- * Output the content for the current step.
280
- */
281
- public function setup_wizard_content() {
282
- ?>
283
- <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
284
- <?php
285
-
286
- echo '<div class="cartflows-setup-content">';
287
- call_user_func( $this->steps[ $this->step ]['view'] );
288
- echo '</div>';
289
- }
290
-
291
- /**
292
- * Introduction step.
293
- */
294
- public function welcome_step() {
295
- ?>
296
- <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
297
- <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
298
- <form method="post">
299
- <div class="cartflows-setup-actions step">
300
- <div class="button-prev-wrap">
301
- </div>
302
- <div class="button-next-wrap">
303
- <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
304
- </div>
305
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
306
- </div>
307
- </form>
308
- <?php
309
- }
310
-
311
- /**
312
- * Save Locale Settings.
313
- */
314
- public function welcome_step_save() {
315
- check_admin_referer( 'cartflow-setup' );
316
-
317
- // Update site title & tagline.
318
- $redirect_url = $this->get_next_step_link();
319
-
320
- wp_safe_redirect( esc_url_raw( $redirect_url ) );
321
- exit;
322
- }
323
-
324
- /**
325
- * Locale settings
326
- */
327
- public function page_builder_step() {
328
- ?>
329
-
330
- <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
331
- <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
332
- <form method="post">
333
- <table class="cartflows-table widefat">
334
- <tr class="cartflows-row">
335
- <td class="cartflows-row-heading">
336
- <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
337
- </td>
338
- <td class="cartflows-row-content">
339
- <?php
340
- $installed_plugins = get_plugins();
341
- $plugins = array(
342
- array(
343
- 'title' => __( 'Elementor', 'cartflows' ),
344
- 'value' => 'elementor',
345
- 'data' => array(
346
- 'slug' => 'elementor',
347
- 'init' => 'elementor/elementor.php',
348
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
349
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
350
- ),
351
- ),
352
- array(
353
- 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
354
- 'value' => 'beaver-builder',
355
- 'data' => array(
356
- 'slug' => 'beaver-builder-lite-version',
357
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
358
- 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
359
- 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
360
- ),
361
- ),
362
- array(
363
- 'title' => __( 'Divi', 'cartflows' ),
364
- 'value' => 'divi',
365
- 'data' => array(
366
- 'slug' => 'divi',
367
- 'init' => 'divi',
368
- 'active' => 'yes',
369
- 'install' => 'NA',
370
- ),
371
- ),
372
- array(
373
- 'title' => __( 'Gutenberg', 'cartflows' ),
374
- 'value' => 'gutenberg',
375
- 'data' => array(
376
- 'slug' => 'ultimate-addons-for-gutenberg',
377
- 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
378
- 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
379
- 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
380
- ),
381
- ),
382
- array(
383
- 'title' => __( 'Other', 'cartflows' ),
384
- 'value' => 'other',
385
- 'data' => array(
386
- 'slug' => 'other',
387
- 'init' => false,
388
- 'active' => 'yes',
389
- 'install' => 'NA',
390
- ),
391
- ),
392
- );
393
- ?>
394
- <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
395
- <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
396
- <?php
397
- foreach ( $plugins as $key => $plugin ) {
398
- echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
399
- }
400
- ?>
401
- </select>
402
- </td>
403
- </tr>
404
- </table>
405
- <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
406
- <div class="cartflows-setup-actions step">
407
- <div class="button-prev-wrap">
408
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
409
- </div>
410
- <div class="button-next-wrap">
411
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
412
- <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
413
- </div>
414
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
415
- </div>
416
- </form>
417
- <?php
418
- }
419
-
420
- /**
421
- * Render checkout step.
422
- */
423
- public function checkout_step() {
424
-
425
- $installed_plugins = get_plugins();
426
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
427
- $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
428
- $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
429
- $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
430
- ?>
431
- <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
432
- <div class="cartflows-setup-message">
433
- <p>
434
- <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
435
- </p>
436
- <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
437
- <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
438
- </div>
439
-
440
- <div class="cartflows-setup-extra-notice">
441
-
442
- <span>
443
- <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
444
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
445
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
446
-
447
- </span>
448
-
449
- </div>
450
-
451
- <div class="cartflows-setup-actions step">
452
- <div class="button-prev-wrap">
453
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
454
- </div>
455
- <div class="button-next-wrap">
456
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
457
- <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
458
- </div>
459
- </div>
460
-
461
- <?php
462
- }
463
-
464
- /**
465
- * Save Locale Settings.
466
- */
467
- public function activate_wc_plugins() {
468
-
469
- check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
470
-
471
- $plugin_slug_arr = array(
472
- 'woocommerce/woocommerce.php' => true,
473
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
474
- );
475
-
476
- $activate = array(
477
- 'woocommerce/woocommerce.php' => false,
478
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
479
- );
480
-
481
- foreach ( $plugin_slug_arr as $slug => $do_silently ) {
482
-
483
- $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
484
- }
485
-
486
- foreach ( $activate as $slug => $data ) {
487
-
488
- if ( is_wp_error( $data ) ) {
489
- wp_send_json_error(
490
- array(
491
- 'success' => false,
492
- 'message' => $data->get_error_message(),
493
- )
494
- );
495
- }
496
- }
497
-
498
- wp_send_json_success();
499
- }
500
-
501
- /**
502
- * Save Locale Settings.
503
- */
504
- public function page_builder_step_save() {
505
-
506
- if ( ! current_user_can( 'manage_options' ) ) {
507
- return;
508
- }
509
-
510
- check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
511
-
512
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
513
- $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
514
- $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
515
-
516
- $do_sliently = true;
517
- if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
518
- $do_sliently = false;
519
- }
520
-
521
- $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
522
-
523
- if ( $save_option ) {
524
- $this->save_page_builder_option();
525
- }
526
-
527
- if ( is_wp_error( $activate ) ) {
528
- wp_send_json_error(
529
- array(
530
- 'success' => false,
531
- 'message' => $activate->get_error_message(),
532
- )
533
- );
534
- }
535
-
536
- wp_send_json_success(
537
- array( 'plugin' => $plugin_slug )
538
- );
539
- }
540
-
541
- /**
542
- * Save selected page builder in options database.
543
- */
544
- public function save_page_builder_option() {
545
-
546
- if ( ! current_user_can( 'manage_options' ) ) {
547
- return;
548
- }
549
-
550
- $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
551
-
552
- $wcf_settings = get_option( '_cartflows_common', array() );
553
-
554
- if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
555
- $page_builder = 'beaver-builder';
556
- }
557
-
558
- $wcf_settings['default_page_builder'] = $page_builder;
559
-
560
- update_option( '_cartflows_common', $wcf_settings );
561
-
562
- wp_send_json_success(
563
- array( 'plugin' => $page_builder )
564
- );
565
-
566
- }
567
-
568
- /**
569
- * Final step.
570
- */
571
- public function ready_step() {
572
-
573
- // Set setup wizard status to complete.
574
- update_option( 'wcf_setup_complete', true );
575
- ?>
576
- <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
577
-
578
- <div class="cartflows-setup-next-steps">
579
- <div class="cartflows-setup-next-steps-last">
580
-
581
- <p class="success">
582
- <?php
583
- esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
584
- ?>
585
- </p>
586
-
587
-
588
- <ul class="wcf-wizard-next-steps">
589
- <li class="wcf-wizard-next-step-item">
590
- <div class="wcf-wizard-next-step-description">
591
- <p class="next-step-heading">Next step</p>
592
- <h3 class="next-step-description">Create First Flow</h3>
593
- <p class="next-step-extra-info">You're ready to add flows to your website.</p>
594
- </div>
595
- <div class="wcf-wizard-next-step-action">
596
- <p class="wc-setup-actions step">
597
- <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
598
- </p>
599
- </div>
600
- </li>
601
- </ul>
602
-
603
- </div>
604
- </div>
605
- <?php
606
- }
607
-
608
- /**
609
- * Training course step.
610
- */
611
- public function training_step() {
612
- $current_user = wp_get_current_user();
613
- ?>
614
- <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
615
-
616
- <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
617
- <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
618
- <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
619
- <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
620
- <div class="mauticform-innerform">
621
- <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
622
- <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
623
- <div class="cartflows-setup-message">
624
- <p>
625
- <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
626
- <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
627
- </p>
628
- <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
629
- </div>
630
- <span class="mauticform-errormsg" style="display: none;"></span>
631
- </div>
632
- </div>
633
- </div>
634
-
635
- <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
636
- <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
637
- <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
638
- <div class="cartflows-setup-actions step">
639
- <div class="button-prev-wrap">
640
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
641
- </div>
642
- <div class="button-next-wrap">
643
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
644
- <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
645
- </div>
646
- </div>
647
- </form>
648
- </div>
649
- <?php
650
- }
651
-
652
- /**
653
- * Localize variables in admin
654
- */
655
- public function localize_vars() {
656
-
657
- $vars = array();
658
-
659
- $ajax_actions = array(
660
- 'wcf_page_builder_step_save',
661
- 'wcf_wc_plugins_activate',
662
- );
663
-
664
- foreach ( $ajax_actions as $action ) {
665
-
666
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
667
- }
668
-
669
- return $vars;
670
- }
671
-
672
- /**
673
- * Add JS script for mautic form
674
- */
675
- public function add_mautic_form_script() {
676
-
677
- if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
678
- return;
679
- }
680
- ?>
681
-
682
- <script type="text/javascript">
683
- /** This section is only needed once per page if manually copying **/
684
- if (typeof MauticSDKLoaded == 'undefined') {
685
- var MauticSDKLoaded = true;
686
- var head = document.getElementsByTagName('head')[0];
687
- var script = document.createElement('script');
688
- script.type = 'text/javascript';
689
- script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
690
- script.onload = function() {
691
- MauticSDK.onLoad();
692
- };
693
- head.appendChild(script);
694
- var MauticDomain = 'https://go.cartflows.com';
695
- var MauticLang = {
696
- 'submittingMessage': "Please wait..."
697
- };
698
- }
699
- </script>
700
- <?php
701
- }
702
- }
703
-
704
- new CartFlows_Wizard();
705
-
706
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows- Onboarding Wizard
4
+ *
5
+ * @package cartflows
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
+
14
+ /**
15
+ * CartFlows_Wizard class.
16
+ */
17
+ class CartFlows_Wizard {
18
+
19
+ /**
20
+ * Hook in tabs.
21
+ */
22
+ public function __construct() {
23
+
24
+ if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
+ add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
+ add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
+ add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
+ add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
+ add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
+ add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
31
+ add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
32
+
33
+ add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
34
+
35
+ add_action( 'admin_init', array( $this, 'hide_notices' ) );
36
+
37
+ }
38
+ }
39
+
40
+
41
+ /**
42
+ * Hide a notice if the GET variable is set.
43
+ */
44
+ public function hide_notices() {
45
+
46
+ if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
47
+ return;
48
+ }
49
+
50
+ $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
51
+ $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
52
+
53
+ if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
54
+ update_option( 'wcf_setup_skipped', true );
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Disable the woo redirect for new setup.
60
+ */
61
+ public function disable_woo_setup_redirect() {
62
+
63
+ delete_transient( '_wc_activation_redirect' );
64
+ }
65
+
66
+ /**
67
+ * Show action links on the plugin screen.
68
+ *
69
+ * @since 1.0.0
70
+ * @return void
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>
94
+ <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
95
+ <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
96
+ </p>
97
+ </div>
98
+ <?php
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Add admin menus/screens.
104
+ */
105
+ public function admin_menus() {
106
+
107
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
108
+ return;
109
+ }
110
+
111
+ add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
112
+ }
113
+
114
+ /**
115
+ * Show the setup wizard.
116
+ */
117
+ public function setup_wizard() {
118
+
119
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
120
+ return;
121
+ }
122
+
123
+ $this->steps = array(
124
+ 'basic-config' => array(
125
+ 'name' => __( 'Welcome', 'cartflows' ),
126
+ 'view' => array( $this, 'welcome_step' ),
127
+ 'handler' => array( $this, 'welcome_step_save' ),
128
+ ),
129
+ 'page-builder' => array(
130
+ 'name' => __( 'Page Builder', 'cartflows' ),
131
+ 'view' => array( $this, 'page_builder_step' ),
132
+ ),
133
+ 'checkout' => array(
134
+ 'name' => __( 'Checkout', 'cartflows' ),
135
+ 'view' => array( $this, 'checkout_step' ),
136
+ ),
137
+ 'training' => array(
138
+ 'name' => __( 'Training', 'cartflows' ),
139
+ 'view' => array( $this, 'training_step' ),
140
+ ),
141
+ 'setup-ready' => array(
142
+ 'name' => __( 'Ready!', 'cartflows' ),
143
+ 'view' => array( $this, 'ready_step' ),
144
+ 'handler' => '',
145
+ ),
146
+ );
147
+
148
+ $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
149
+
150
+ wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
151
+ wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
152
+
153
+ wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
154
+
155
+ wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
156
+
157
+ wp_enqueue_media();
158
+
159
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
160
+ call_user_func( $this->steps[ $this->step ]['handler'] );
161
+ }
162
+
163
+ ob_start();
164
+ $this->setup_wizard_header();
165
+ $this->setup_wizard_steps();
166
+ $this->setup_wizard_content();
167
+ $this->setup_wizard_footer();
168
+ exit;
169
+ }
170
+
171
+ /**
172
+ * Get current step slug
173
+ */
174
+ public function get_current_step_slug() {
175
+ $keys = array_keys( $this->steps );
176
+ return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
177
+ }
178
+
179
+ /**
180
+ * Get previous step link
181
+ */
182
+ public function get_prev_step_link() {
183
+ $keys = array_keys( $this->steps );
184
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
185
+ }
186
+
187
+ /**
188
+ * Get next step link
189
+ */
190
+ public function get_next_step_link() {
191
+ $keys = array_keys( $this->steps );
192
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
193
+ }
194
+
195
+ /**
196
+ * Get next step link
197
+ */
198
+ public function get_next_step_plain_link() {
199
+ $keys = array_keys( $this->steps );
200
+ $step_index = array_search( $this->step, $keys, true );
201
+ $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
202
+ $step = $keys[ $step_index ];
203
+ return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
204
+ }
205
+
206
+ /**
207
+ * Setup Wizard Header.
208
+ */
209
+ public function setup_wizard_header() {
210
+ set_current_screen();
211
+ ?>
212
+ <html <?php language_attributes(); ?>>
213
+ <html>
214
+ <head>
215
+ <meta name="viewport" content="width=device-width" />
216
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
217
+ <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
218
+
219
+ <script type="text/javascript">
220
+ addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
221
+ var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
222
+ var pagenow = '';
223
+ </script>
224
+ <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
225
+ <?php do_action( 'admin_print_styles' ); ?>
226
+ <?php do_action( 'admin_head' ); ?>
227
+ </head>
228
+ <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
229
+ <div id="cartflows-logo">
230
+ <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
231
+ </div>
232
+ <?php
233
+ }
234
+
235
+ /**
236
+ * Setup Wizard Footer.
237
+ */
238
+ public function setup_wizard_footer() {
239
+
240
+ $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
241
+ ?>
242
+ <div class="close-button-wrapper">
243
+ <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
244
+ </div>
245
+ </body>
246
+ </html>
247
+ <?php
248
+ }
249
+
250
+ /**
251
+ * Output the steps.
252
+ */
253
+ public function setup_wizard_steps() {
254
+
255
+ $ouput_steps = $this->steps;
256
+ ?>
257
+ <ol class="cartflows-setup-steps">
258
+ <?php
259
+ foreach ( $ouput_steps as $step_key => $step ) :
260
+ $classes = '';
261
+ $activated = false;
262
+ if ( $step_key === $this->step ) {
263
+ $classes = 'active';
264
+ $activated = true;
265
+ } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
266
+ $classes = 'done';
267
+ $activated = true;
268
+ }
269
+ ?>
270
+ <li class="<?php echo esc_attr( $classes ); ?>">
271
+ <span><?php echo esc_html( $step['name'] ); ?></span>
272
+ </li>
273
+ <?php endforeach; ?>
274
+ </ol>
275
+ <?php
276
+ }
277
+
278
+ /**
279
+ * Output the content for the current step.
280
+ */
281
+ public function setup_wizard_content() {
282
+ ?>
283
+ <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
284
+ <?php
285
+
286
+ echo '<div class="cartflows-setup-content">';
287
+ call_user_func( $this->steps[ $this->step ]['view'] );
288
+ echo '</div>';
289
+ }
290
+
291
+ /**
292
+ * Introduction step.
293
+ */
294
+ public function welcome_step() {
295
+ ?>
296
+ <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
297
+ <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
298
+ <form method="post">
299
+ <div class="cartflows-setup-actions step">
300
+ <div class="button-prev-wrap">
301
+ </div>
302
+ <div class="button-next-wrap">
303
+ <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
304
+ </div>
305
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
306
+ </div>
307
+ </form>
308
+ <?php
309
+ }
310
+
311
+ /**
312
+ * Save Locale Settings.
313
+ */
314
+ public function welcome_step_save() {
315
+ check_admin_referer( 'cartflow-setup' );
316
+
317
+ // Update site title & tagline.
318
+ $redirect_url = $this->get_next_step_link();
319
+
320
+ wp_safe_redirect( esc_url_raw( $redirect_url ) );
321
+ exit;
322
+ }
323
+
324
+ /**
325
+ * Locale settings
326
+ */
327
+ public function page_builder_step() {
328
+ ?>
329
+
330
+ <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
331
+ <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
332
+ <form method="post">
333
+ <table class="cartflows-table widefat">
334
+ <tr class="cartflows-row">
335
+ <td class="cartflows-row-heading">
336
+ <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
337
+ </td>
338
+ <td class="cartflows-row-content">
339
+ <?php
340
+ $installed_plugins = get_plugins();
341
+ $plugins = array(
342
+ array(
343
+ 'title' => __( 'Elementor', 'cartflows' ),
344
+ 'value' => 'elementor',
345
+ 'data' => array(
346
+ 'slug' => 'elementor',
347
+ 'init' => 'elementor/elementor.php',
348
+ 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
349
+ 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
350
+ ),
351
+ ),
352
+ array(
353
+ 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
354
+ 'value' => 'beaver-builder',
355
+ 'data' => array(
356
+ 'slug' => 'beaver-builder-lite-version',
357
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
358
+ 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
359
+ 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
360
+ ),
361
+ ),
362
+ array(
363
+ 'title' => __( 'Divi', 'cartflows' ),
364
+ 'value' => 'divi',
365
+ 'data' => array(
366
+ 'slug' => 'divi',
367
+ 'init' => 'divi',
368
+ 'active' => 'yes',
369
+ 'install' => 'NA',
370
+ ),
371
+ ),
372
+ array(
373
+ 'title' => __( 'Gutenberg', 'cartflows' ),
374
+ 'value' => 'gutenberg',
375
+ 'data' => array(
376
+ 'slug' => 'ultimate-addons-for-gutenberg',
377
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
378
+ 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
379
+ 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
380
+ ),
381
+ ),
382
+ array(
383
+ 'title' => __( 'Other', 'cartflows' ),
384
+ 'value' => 'other',
385
+ 'data' => array(
386
+ 'slug' => 'other',
387
+ 'init' => false,
388
+ 'active' => 'yes',
389
+ 'install' => 'NA',
390
+ ),
391
+ ),
392
+ );
393
+ ?>
394
+ <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
395
+ <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
396
+ <?php
397
+ foreach ( $plugins as $key => $plugin ) {
398
+ echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
399
+ }
400
+ ?>
401
+ </select>
402
+ </td>
403
+ </tr>
404
+ </table>
405
+ <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
406
+ <div class="cartflows-setup-actions step">
407
+ <div class="button-prev-wrap">
408
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
409
+ </div>
410
+ <div class="button-next-wrap">
411
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
412
+ <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
413
+ </div>
414
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
415
+ </div>
416
+ </form>
417
+ <?php
418
+ }
419
+
420
+ /**
421
+ * Render checkout step.
422
+ */
423
+ public function checkout_step() {
424
+
425
+ $installed_plugins = get_plugins();
426
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
427
+ $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
428
+ $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
429
+ $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
430
+ ?>
431
+ <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
432
+ <div class="cartflows-setup-message">
433
+ <p>
434
+ <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
435
+ </p>
436
+ <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
437
+ <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
438
+ </div>
439
+
440
+ <div class="cartflows-setup-extra-notice">
441
+
442
+ <span>
443
+ <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
444
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
445
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
446
+
447
+ </span>
448
+
449
+ </div>
450
+
451
+ <div class="cartflows-setup-actions step">
452
+ <div class="button-prev-wrap">
453
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
454
+ </div>
455
+ <div class="button-next-wrap">
456
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
457
+ <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
458
+ </div>
459
+ </div>
460
+
461
+ <?php
462
+ }
463
+
464
+ /**
465
+ * Save Locale Settings.
466
+ */
467
+ public function activate_wc_plugins() {
468
+
469
+ check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
470
+
471
+ $plugin_slug_arr = array(
472
+ 'woocommerce/woocommerce.php' => true,
473
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
474
+ );
475
+
476
+ $activate = array(
477
+ 'woocommerce/woocommerce.php' => false,
478
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
479
+ );
480
+
481
+ foreach ( $plugin_slug_arr as $slug => $do_silently ) {
482
+
483
+ $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
484
+ }
485
+
486
+ foreach ( $activate as $slug => $data ) {
487
+
488
+ if ( is_wp_error( $data ) ) {
489
+ wp_send_json_error(
490
+ array(
491
+ 'success' => false,
492
+ 'message' => $data->get_error_message(),
493
+ )
494
+ );
495
+ }
496
+ }
497
+
498
+ wp_send_json_success();
499
+ }
500
+
501
+ /**
502
+ * Save Locale Settings.
503
+ */
504
+ public function page_builder_step_save() {
505
+
506
+ if ( ! current_user_can( 'manage_options' ) ) {
507
+ return;
508
+ }
509
+
510
+ check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
511
+
512
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
513
+ $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
514
+ $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
515
+
516
+ $do_sliently = true;
517
+ if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
518
+ $do_sliently = false;
519
+ }
520
+
521
+ $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
522
+
523
+ if ( $save_option ) {
524
+ $this->save_page_builder_option();
525
+ }
526
+
527
+ if ( is_wp_error( $activate ) ) {
528
+ wp_send_json_error(
529
+ array(
530
+ 'success' => false,
531
+ 'message' => $activate->get_error_message(),
532
+ )
533
+ );
534
+ }
535
+
536
+ wp_send_json_success(
537
+ array( 'plugin' => $plugin_slug )
538
+ );
539
+ }
540
+
541
+ /**
542
+ * Save selected page builder in options database.
543
+ */
544
+ public function save_page_builder_option() {
545
+
546
+ if ( ! current_user_can( 'manage_options' ) ) {
547
+ return;
548
+ }
549
+
550
+ $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
551
+
552
+ $wcf_settings = get_option( '_cartflows_common', array() );
553
+
554
+ if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
555
+ $page_builder = 'beaver-builder';
556
+ }
557
+
558
+ $wcf_settings['default_page_builder'] = $page_builder;
559
+
560
+ update_option( '_cartflows_common', $wcf_settings );
561
+
562
+ wp_send_json_success(
563
+ array( 'plugin' => $page_builder )
564
+ );
565
+
566
+ }
567
+
568
+ /**
569
+ * Final step.
570
+ */
571
+ public function ready_step() {
572
+
573
+ // Set setup wizard status to complete.
574
+ update_option( 'wcf_setup_complete', true );
575
+ ?>
576
+ <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
577
+
578
+ <div class="cartflows-setup-next-steps">
579
+ <div class="cartflows-setup-next-steps-last">
580
+
581
+ <p class="success">
582
+ <?php
583
+ esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
584
+ ?>
585
+ </p>
586
+
587
+
588
+ <ul class="wcf-wizard-next-steps">
589
+ <li class="wcf-wizard-next-step-item">
590
+ <div class="wcf-wizard-next-step-description">
591
+ <p class="next-step-heading">Next step</p>
592
+ <h3 class="next-step-description">Create First Flow</h3>
593
+ <p class="next-step-extra-info">You're ready to add flows to your website.</p>
594
+ </div>
595
+ <div class="wcf-wizard-next-step-action">
596
+ <p class="wc-setup-actions step">
597
+ <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
598
+ </p>
599
+ </div>
600
+ </li>
601
+ </ul>
602
+
603
+ </div>
604
+ </div>
605
+ <?php
606
+ }
607
+
608
+ /**
609
+ * Training course step.
610
+ */
611
+ public function training_step() {
612
+ $current_user = wp_get_current_user();
613
+ ?>
614
+ <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
615
+
616
+ <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
617
+ <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
618
+ <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
619
+ <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
620
+ <div class="mauticform-innerform">
621
+ <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
622
+ <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
623
+ <div class="cartflows-setup-message">
624
+ <p>
625
+ <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
626
+ <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
627
+ </p>
628
+ <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
629
+ </div>
630
+ <span class="mauticform-errormsg" style="display: none;"></span>
631
+ </div>
632
+ </div>
633
+ </div>
634
+
635
+ <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
636
+ <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
637
+ <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
638
+ <div class="cartflows-setup-actions step">
639
+ <div class="button-prev-wrap">
640
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
641
+ </div>
642
+ <div class="button-next-wrap">
643
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
644
+ <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
645
+ </div>
646
+ </div>
647
+ </form>
648
+ </div>
649
+ <?php
650
+ }
651
+
652
+ /**
653
+ * Localize variables in admin
654
+ */
655
+ public function localize_vars() {
656
+
657
+ $vars = array();
658
+
659
+ $ajax_actions = array(
660
+ 'wcf_page_builder_step_save',
661
+ 'wcf_wc_plugins_activate',
662
+ );
663
+
664
+ foreach ( $ajax_actions as $action ) {
665
+
666
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
667
+ }
668
+
669
+ return $vars;
670
+ }
671
+
672
+ /**
673
+ * Add JS script for mautic form
674
+ */
675
+ public function add_mautic_form_script() {
676
+
677
+ if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
678
+ return;
679
+ }
680
+ ?>
681
+
682
+ <script type="text/javascript">
683
+ /** This section is only needed once per page if manually copying **/
684
+ if (typeof MauticSDKLoaded == 'undefined') {
685
+ var MauticSDKLoaded = true;
686
+ var head = document.getElementsByTagName('head')[0];
687
+ var script = document.createElement('script');
688
+ script.type = 'text/javascript';
689
+ script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
690
+ script.onload = function() {
691
+ MauticSDK.onLoad();
692
+ };
693
+ head.appendChild(script);
694
+ var MauticDomain = 'https://go.cartflows.com';
695
+ var MauticLang = {
696
+ 'submittingMessage': "Please wait..."
697
+ };
698
+ }
699
+ </script>
700
+ <?php
701
+ }
702
+ }
703
+
704
+ new CartFlows_Wizard();
705
+
706
+ endif;
classes/lib/notices/class-astra-notices.php CHANGED
@@ -1,365 +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;
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;
includes/admin/cartflows-general.php CHANGED
@@ -1,525 +1,525 @@
1
- <?php
2
- /**
3
- * General settings
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $settings = Cartflows_Helper::get_common_settings();
9
-
10
- $debug_data = Cartflows_Helper::get_debug_settings();
11
-
12
- $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
-
14
- $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
-
16
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
-
18
- $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
-
20
- $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
- ?>
22
-
23
-
24
- <?php if ( $error_log ) : ?>
25
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
- <?php Cartflows_Logger::status_logs_file(); ?>
27
- </div>
28
- <?php else : ?>
29
- <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
- <input type="hidden" name="action" value="wcf_save_common_settings">
31
- <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
-
33
- <div id="poststuff">
34
- <div id="post-body" class="columns-2">
35
- <div id="post-body-content">
36
-
37
- <!-- Getting Started -->
38
- <div class="postbox introduction">
39
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
- <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
- </h2>
42
- <div class="inside">
43
- <div class="iframe-wrap">
44
- <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
- </div>
46
- <p>
47
- <?php
48
- esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
- ?>
50
- </p>
51
- </div>
52
- </div>
53
- <!-- Getting Started -->
54
-
55
- <!-- General Settings -->
56
- <div class="general-settings-form postbox">
57
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
- <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
- </h2>
60
- <div class="inside">
61
- <form method="post" class="wrap wcf-clear" action="" >
62
- <div class="form-wrap">
63
- <?php
64
-
65
- do_action( 'cartflows_before_settings_fields', $settings );
66
-
67
- echo Cartflows_Admin_Fields::checkobox_field(
68
- array(
69
- 'id' => 'wcf_disallow_indexing',
70
- 'name' => '_cartflows_common[disallow_indexing]',
71
- 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
- 'value' => $settings['disallow_indexing'],
73
- )
74
- );
75
-
76
- if ( wcf()->is_woo_active ) {
77
- echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
- array(
79
- 'id' => 'wcf_global_checkout',
80
- 'name' => '_cartflows_common[global_checkout]',
81
- 'title' => __( 'Global Checkout', 'cartflows' ),
82
- 'value' => $settings['global_checkout'],
83
- )
84
- );
85
- }
86
- echo Cartflows_Admin_Fields::select_field(
87
- array(
88
- 'id' => 'wcf_default_page_builder',
89
- 'name' => '_cartflows_common[default_page_builder]',
90
- 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
- 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
- 'value' => $settings['default_page_builder'],
93
- 'options' => array(
94
- 'elementor' => __( 'Elementor', 'cartflows' ),
95
- 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
- 'divi' => __( 'Divi', 'cartflows' ),
97
- 'gutenberg' => __( 'Gutenberg', 'cartflows' ),
98
- 'other' => __( 'Other', 'cartflows' ),
99
- ),
100
- )
101
- );
102
-
103
- do_action( 'cartflows_after_settings_fields', $settings );
104
-
105
- ?>
106
- </div>
107
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
108
- <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
109
- </form>
110
- </div>
111
- </div>
112
- <!-- General Settings -->
113
-
114
- <?php do_action( 'cartflows_after_general_settings' ); ?>
115
-
116
- <!-- Permalink Settings -->
117
- <div class="general-settingss-form postbox">
118
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
119
- <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
120
- </h2>
121
- <div class="inside">
122
- <form method="post" class="wrap wcf-clear" action="" >
123
- <div class="form-wrap wcf_permalink_settings">
124
- <?php
125
-
126
- echo Cartflows_Admin_Fields::radio_field(
127
- array(
128
- 'id' => 'permalink_structure',
129
- 'name' => '_cartflows_permalink[permalink_structure]',
130
- 'value' => $permalink_settings['permalink_structure'],
131
- 'options' => array(
132
- '' =>
133
- array(
134
- 'label' => __( 'Default', 'cartflows' ),
135
- 'description' => 'Default WordPress Permalink',
136
- ),
137
-
138
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
139
- array(
140
- 'label' => __( 'Flow and Step Slug', 'cartflows' ),
141
- 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
142
- ),
143
-
144
- '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
145
- array(
146
- 'label' => __( 'Flow Slug', 'cartflows' ),
147
- 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
148
- ),
149
-
150
- '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
151
- array(
152
- 'label' => __( 'Step Slug', 'cartflows' ),
153
- 'description' => get_site_url() . '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
154
- ),
155
- ),
156
- )
157
- );
158
- ?>
159
- <hr/>
160
- <?php
161
-
162
- echo Cartflows_Admin_Fields::title_field(
163
- array(
164
- 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
165
- )
166
- );
167
-
168
- echo Cartflows_Admin_Fields::text_field(
169
- array(
170
- 'id' => 'wcf_permalink_step_base',
171
- 'name' => '_cartflows_permalink[permalink]',
172
- 'title' => __( 'Step Base', 'cartflows' ),
173
- 'value' => $permalink_settings['permalink'],
174
- 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
175
- )
176
- );
177
-
178
- echo Cartflows_Admin_Fields::text_field(
179
- array(
180
- 'id' => 'wcf_permalink_flow_base',
181
- 'name' => '_cartflows_permalink[permalink_flow_base]',
182
- 'title' => __( 'Flow Base', 'cartflows' ),
183
- 'value' => $permalink_settings['permalink_flow_base'],
184
- 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
185
- )
186
- );
187
-
188
- ?>
189
-
190
-
191
- </div>
192
- <p>
193
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
194
- <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
195
- <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
196
- </p>
197
-
198
-
199
- </form>
200
- </div>
201
- </div>
202
- <!-- Permalink Settings -->
203
-
204
- <!-- Facebook Pixel Tracking -->
205
- <div class="general-settingss-form postbox">
206
- <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
207
-
208
- <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
209
- </h2>
210
-
211
- <form method="post" class="wrap wcf-clear" action="">
212
- <div class="form-wrap">
213
- <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
214
- <div id="post-body">
215
-
216
- <div class="inside">
217
- <div class="form-wrap">
218
- <?php
219
- echo Cartflows_Admin_Fields::checkobox_field(
220
- array(
221
- 'id' => 'wcf_facebook_pixel_tracking',
222
- 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
223
- 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
224
- 'value' => $facebook_settings['facebook_pixel_tracking'],
225
- )
226
- );
227
-
228
- echo "<div class='wcf-fb-pixel-wrapper'>";
229
- ?>
230
- <hr/>
231
- <?php
232
- echo Cartflows_Admin_Fields::checkobox_field(
233
- array(
234
- 'id' => 'wcf_facebook_pixel_tracking_for_site',
235
- 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
236
- 'title' => __( 'Enable for the whole site', 'cartflows' ),
237
- 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
238
- )
239
- );
240
-
241
- echo Cartflows_Admin_Fields::title_field(
242
- array(
243
- 'title' => '',
244
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
245
- )
246
- );
247
- ?>
248
- <hr/>
249
- <?php
250
- echo Cartflows_Admin_Fields::text_field(
251
- array(
252
- 'id' => 'wcf_facebook_pixel_id',
253
- 'name' => '_cartflows_facebook[facebook_pixel_id]',
254
- 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
255
- 'value' => $facebook_settings['facebook_pixel_id'],
256
- )
257
- );
258
-
259
-
260
- echo Cartflows_Admin_Fields::title_field(
261
- array(
262
- 'title' => __( 'Enable Events:', 'cartflows' ),
263
- )
264
- );
265
-
266
-
267
- echo Cartflows_Admin_Fields::checkobox_field(
268
- array(
269
- 'id' => 'wcf_facebook_pixel_initiate_checkout',
270
- 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
271
- 'title' => __( 'Initiate Checkout', 'cartflows' ),
272
- 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
273
- )
274
- );
275
-
276
- echo Cartflows_Admin_Fields::checkobox_field(
277
- array(
278
- 'id' => 'wcf_facebook_pixel_add_payment_info',
279
- 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
280
- 'title' => __( 'Add Payment Info', 'cartflows' ),
281
- 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
282
- )
283
- );
284
-
285
- echo Cartflows_Admin_Fields::checkobox_field(
286
- array(
287
- 'id' => 'wcf_facebook_pixel_purchase_complete',
288
- 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
289
- 'title' => __( 'Purchase Complete', 'cartflows' ),
290
- 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
291
- )
292
- );
293
-
294
- echo '</div>';
295
-
296
- ?>
297
- </div>
298
-
299
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
300
- <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
301
- </div>
302
- </div>
303
- </div>
304
- </form>
305
- </div>
306
- <!-- Facebook Pixel Tracking -->
307
-
308
- <!-- Google Analytics Tracking -->
309
- <div class="general-settingss-form postbox">
310
- <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
311
- <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
312
- </h2>
313
- <div class="inside">
314
- <form method="post" class="wrap wcf-clear" action="" >
315
- <div class="form-wrap">
316
- <?php
317
-
318
- echo Cartflows_Admin_Fields::checkobox_field(
319
- array(
320
- 'id' => 'enable_google-analytics-id',
321
- 'name' => '_cartflows_google_analytics[enable_google_analytics]',
322
- 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
323
- 'value' => $google_analytics_settings['enable_google_analytics'],
324
- )
325
- );
326
-
327
- echo "<div class='wcf-google-analytics-wrapper'>";
328
- ?>
329
- <hr/>
330
- <?php
331
- echo Cartflows_Admin_Fields::checkobox_field(
332
- array(
333
- 'id' => 'enable_google_analytics_for_site',
334
- 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
335
- 'title' => __( 'Enable for the whole website', 'cartflows' ),
336
- 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
337
- )
338
- );
339
-
340
- echo Cartflows_Admin_Fields::title_field(
341
- array(
342
- 'title' => '',
343
- 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
344
- )
345
- );
346
- ?>
347
- <hr/>
348
- <?php
349
- echo Cartflows_Admin_Fields::text_field(
350
- array(
351
- 'id' => 'google-analytics-id',
352
- 'name' => '_cartflows_google_analytics[google_analytics_id]',
353
- 'title' => __( 'Google Analytics ID', 'cartflows' ),
354
- 'value' => $google_analytics_settings['google_analytics_id'],
355
- 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
356
- )
357
- );
358
-
359
- echo Cartflows_Admin_Fields::title_field(
360
- array(
361
- 'title' => __( 'Enable Events:', 'cartflows' ),
362
- )
363
- );
364
-
365
- echo Cartflows_Admin_Fields::checkobox_field(
366
- array(
367
- 'id' => 'enable_begin_checkout',
368
- 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
369
- 'title' => __( 'Begin Checkout', 'cartflows' ),
370
- 'value' => $google_analytics_settings['enable_begin_checkout'],
371
- )
372
- );
373
-
374
- echo Cartflows_Admin_Fields::checkobox_field(
375
- array(
376
- 'id' => 'enable_add_to_cart',
377
- 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
378
- 'title' => __( 'Add To Cart', 'cartflows' ),
379
- 'value' => $google_analytics_settings['enable_add_to_cart'],
380
- )
381
- );
382
-
383
- echo Cartflows_Admin_Fields::checkobox_field(
384
- array(
385
- 'id' => 'enable_add_payment_info',
386
- 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
387
- 'title' => __( 'Add Payment Info', 'cartflows' ),
388
- 'value' => $google_analytics_settings['enable_add_payment_info'],
389
- )
390
- );
391
-
392
- echo Cartflows_Admin_Fields::checkobox_field(
393
- array(
394
- 'id' => 'enable_purchase_event',
395
- 'name' => '_cartflows_google_analytics[enable_purchase_event]',
396
- 'title' => __( 'Purchase', 'cartflows' ),
397
- 'value' => $google_analytics_settings['enable_purchase_event'],
398
- )
399
- );
400
-
401
- echo Cartflows_Admin_Fields::title_field(
402
- array(
403
- 'title' => '',
404
- 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
405
- )
406
- );
407
-
408
- do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
409
-
410
- echo '</div>';
411
- ?>
412
-
413
-
414
- </div>
415
- <p>
416
- <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
417
- <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
418
- </p>
419
-
420
-
421
- </form>
422
- </div>
423
- </div>
424
- <!-- Google Analytics Tracking -->
425
-
426
- <?php do_action( 'cartflows_register_general_settings' ); ?>
427
-
428
- </div>
429
-
430
- <!-- Right Sidebar -->
431
- <div class="postbox-container" id="postbox-container-1">
432
- <div id="side-sortables">
433
-
434
- <div class="postbox">
435
- <h2 class="hndle">
436
- <span class="dashicons dashicons-book"></span>
437
- <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
438
- </h2>
439
- <div class="inside">
440
- <p>
441
- <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
442
- </p>
443
- <p>
444
- <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
445
- </p>
446
- </div>
447
- </div>
448
-
449
- <div class="postbox">
450
- <h2 class="hndle">
451
- <span class="dashicons dashicons-groups"></span>
452
- <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
453
- </h2>
454
- <div class="inside">
455
- <p>
456
- <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
457
- </p>
458
- <p>
459
- <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
460
- </p>
461
- </div>
462
- </div>
463
-
464
- <div class="postbox">
465
- <h2 class="hndle">
466
- <span class="dashicons dashicons-sos"></span>
467
- <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
468
- </h2>
469
- <div class="inside">
470
- <p>
471
- <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
472
- </p>
473
- <p>
474
- <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
475
- </p>
476
- </div>
477
- </div>
478
- <?php
479
- if ( 'true' == $debug_on ) {
480
- ?>
481
- <div class="postbox">
482
- <h2 class="hndle">
483
- <span class="dashicons dashicons-editor-code"></span>
484
- <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
485
- </h2>
486
- <div class="inside">
487
- <form method="post" class="wrap wcf-clear" action="">
488
- <p>
489
- <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
490
- </p>
491
- <?php
492
- echo Cartflows_Admin_Fields::checkobox_field(
493
- array(
494
- 'id' => 'allow_minified_files',
495
- 'name' => '_cartflows_debug_data[allow_minified_files]',
496
- 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
497
- 'value' => $debug_data['allow_minified_files'],
498
- )
499
- );
500
- ?>
501
- <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
502
- <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
503
- </form>
504
- </div>
505
- </div>
506
- <?php
507
- }
508
- ?>
509
- </div>
510
- </div>
511
- <!-- Right Sidebar -->
512
-
513
- </div>
514
- <!-- /post-body -->
515
- <br class="clear">
516
- </div>
517
- </div>
518
- <?php endif; ?>
519
-
520
- <?php
521
- /**
522
- * Loads Zapier settings admin view.
523
- */
524
- do_action( 'cartflows_after_settings' );
525
- ?>
1
+ <?php
2
+ /**
3
+ * General settings
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $settings = Cartflows_Helper::get_common_settings();
9
+
10
+ $debug_data = Cartflows_Helper::get_debug_settings();
11
+
12
+ $permalink_settings = Cartflows_Helper::get_permalink_settings();
13
+
14
+ $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
15
+
16
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
17
+
18
+ $debug_on = ( isset( $_GET['debug'] ) ) ? sanitize_text_field( wp_unslash( $_GET['debug'] ) ) : 'false'; //phpcs:ignore
19
+
20
+ $error_log = filter_input( INPUT_GET, 'cartflows-error-log', FILTER_VALIDATE_BOOLEAN );
21
+ ?>
22
+
23
+
24
+ <?php if ( $error_log ) : ?>
25
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
26
+ <?php Cartflows_Logger::status_logs_file(); ?>
27
+ </div>
28
+ <?php else : ?>
29
+ <div class="wrap wcf-addon-wrap wcf-clear wcf-container">
30
+ <input type="hidden" name="action" value="wcf_save_common_settings">
31
+ <h1 class="screen-reader-text"><?php esc_html_e( 'General Settings', 'cartflows' ); ?></h1>
32
+
33
+ <div id="poststuff">
34
+ <div id="post-body" class="columns-2">
35
+ <div id="post-body-content">
36
+
37
+ <!-- Getting Started -->
38
+ <div class="postbox introduction">
39
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
40
+ <span><?php esc_html_e( 'Getting Started', 'cartflows' ); ?></span>
41
+ </h2>
42
+ <div class="inside">
43
+ <div class="iframe-wrap">
44
+ <iframe width="560" height="315" src="https://www.youtube.com/embed/SlE0moPKjMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
45
+ </div>
46
+ <p>
47
+ <?php
48
+ esc_attr_e( 'Modernizing WordPress eCommerce!', 'cartflows' );
49
+ ?>
50
+ </p>
51
+ </div>
52
+ </div>
53
+ <!-- Getting Started -->
54
+
55
+ <!-- General Settings -->
56
+ <div class="general-settings-form postbox">
57
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
58
+ <span><?php esc_html_e( 'General Settings', 'cartflows' ); ?></span>
59
+ </h2>
60
+ <div class="inside">
61
+ <form method="post" class="wrap wcf-clear" action="" >
62
+ <div class="form-wrap">
63
+ <?php
64
+
65
+ do_action( 'cartflows_before_settings_fields', $settings );
66
+
67
+ echo Cartflows_Admin_Fields::checkobox_field(
68
+ array(
69
+ 'id' => 'wcf_disallow_indexing',
70
+ 'name' => '_cartflows_common[disallow_indexing]',
71
+ 'title' => __( 'Disallow search engines from indexing flows', 'cartflows' ),
72
+ 'value' => $settings['disallow_indexing'],
73
+ )
74
+ );
75
+
76
+ if ( wcf()->is_woo_active ) {
77
+ echo Cartflows_Admin_Fields::flow_checkout_selection_field(
78
+ array(
79
+ 'id' => 'wcf_global_checkout',
80
+ 'name' => '_cartflows_common[global_checkout]',
81
+ 'title' => __( 'Global Checkout', 'cartflows' ),
82
+ 'value' => $settings['global_checkout'],
83
+ )
84
+ );
85
+ }
86
+ echo Cartflows_Admin_Fields::select_field(
87
+ array(
88
+ 'id' => 'wcf_default_page_builder',
89
+ 'name' => '_cartflows_common[default_page_builder]',
90
+ 'title' => __( 'Show Templates designed with', 'cartflows' ),
91
+ 'description' => __( 'CartFlows offers flow templates that can be imported in one click. These templates are available in few different page builders. Please choose your preferred page builder from the list so you will only see templates that are made using that page builder..', 'cartflows' ),
92
+ 'value' => $settings['default_page_builder'],
93
+ 'options' => array(
94
+ 'elementor' => __( 'Elementor', 'cartflows' ),
95
+ 'beaver-builder' => __( 'Beaver Builder', 'cartflows' ),
96
+ 'divi' => __( 'Divi', 'cartflows' ),
97
+ 'gutenberg' => __( 'Gutenberg', 'cartflows' ),
98
+ 'other' => __( 'Other', 'cartflows' ),
99
+ ),
100
+ )
101
+ );
102
+
103
+ do_action( 'cartflows_after_settings_fields', $settings );
104
+
105
+ ?>
106
+ </div>
107
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
108
+ <?php wp_nonce_field( 'cartflows-common-settings', 'cartflows-common-settings-nonce' ); ?>
109
+ </form>
110
+ </div>
111
+ </div>
112
+ <!-- General Settings -->
113
+
114
+ <?php do_action( 'cartflows_after_general_settings' ); ?>
115
+
116
+ <!-- Permalink Settings -->
117
+ <div class="general-settingss-form postbox">
118
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
119
+ <span><?php esc_html_e( 'Permalink Settings', 'cartflows' ); ?></span>
120
+ </h2>
121
+ <div class="inside">
122
+ <form method="post" class="wrap wcf-clear" action="" >
123
+ <div class="form-wrap wcf_permalink_settings">
124
+ <?php
125
+
126
+ echo Cartflows_Admin_Fields::radio_field(
127
+ array(
128
+ 'id' => 'permalink_structure',
129
+ 'name' => '_cartflows_permalink[permalink_structure]',
130
+ 'value' => $permalink_settings['permalink_structure'],
131
+ 'options' => array(
132
+ '' =>
133
+ array(
134
+ 'label' => __( 'Default', 'cartflows' ),
135
+ 'description' => 'Default WordPress Permalink',
136
+ ),
137
+
138
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
139
+ array(
140
+ 'label' => __( 'Flow and Step Slug', 'cartflows' ),
141
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
142
+ ),
143
+
144
+ '/' . CARTFLOWS_FLOW_POST_TYPE . '/%flowname%' =>
145
+ array(
146
+ 'label' => __( 'Flow Slug', 'cartflows' ),
147
+ 'description' => get_site_url() . '/<code>' . CARTFLOWS_FLOW_POST_TYPE . '</code>/%flowname%/%stepname%/',
148
+ ),
149
+
150
+ '/%flowname%/' . CARTFLOWS_STEP_POST_TYPE =>
151
+ array(
152
+ 'label' => __( 'Step Slug', 'cartflows' ),
153
+ 'description' => get_site_url() . '/%flowname%/<code>' . CARTFLOWS_STEP_POST_TYPE . '</code>/%stepname%/',
154
+ ),
155
+ ),
156
+ )
157
+ );
158
+ ?>
159
+ <hr/>
160
+ <?php
161
+
162
+ echo Cartflows_Admin_Fields::title_field(
163
+ array(
164
+ 'title' => __( 'Post Type Permalink Base', 'cartflows' ),
165
+ )
166
+ );
167
+
168
+ echo Cartflows_Admin_Fields::text_field(
169
+ array(
170
+ 'id' => 'wcf_permalink_step_base',
171
+ 'name' => '_cartflows_permalink[permalink]',
172
+ 'title' => __( 'Step Base', 'cartflows' ),
173
+ 'value' => $permalink_settings['permalink'],
174
+ 'placeholder' => CARTFLOWS_STEP_POST_TYPE,
175
+ )
176
+ );
177
+
178
+ echo Cartflows_Admin_Fields::text_field(
179
+ array(
180
+ 'id' => 'wcf_permalink_flow_base',
181
+ 'name' => '_cartflows_permalink[permalink_flow_base]',
182
+ 'title' => __( 'Flow Base', 'cartflows' ),
183
+ 'value' => $permalink_settings['permalink_flow_base'],
184
+ 'placeholder' => CARTFLOWS_FLOW_POST_TYPE,
185
+ )
186
+ );
187
+
188
+ ?>
189
+
190
+
191
+ </div>
192
+ <p>
193
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
194
+ <?php submit_button( __( 'Set Default', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'reset', false ); ?>
195
+ <?php wp_nonce_field( 'cartflows-permalink-settings', 'cartflows-permalink-settings-nonce' ); ?>
196
+ </p>
197
+
198
+
199
+ </form>
200
+ </div>
201
+ </div>
202
+ <!-- Permalink Settings -->
203
+
204
+ <!-- Facebook Pixel Tracking -->
205
+ <div class="general-settingss-form postbox">
206
+ <h2 class="wcf-facebook-hndle wcf-normal-cusror ui-sortable-handle hndle">
207
+
208
+ <span><?php esc_html_e( 'Facebook Pixel Settings', 'cartflows' ); ?></span>
209
+ </h2>
210
+
211
+ <form method="post" class="wrap wcf-clear" action="">
212
+ <div class="form-wrap">
213
+ <input type="hidden" name="action" value="wcf_save_facebook_pixel_settings">
214
+ <div id="post-body">
215
+
216
+ <div class="inside">
217
+ <div class="form-wrap">
218
+ <?php
219
+ echo Cartflows_Admin_Fields::checkobox_field(
220
+ array(
221
+ 'id' => 'wcf_facebook_pixel_tracking',
222
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking]',
223
+ 'title' => __( 'Enable Facebook Pixel Tracking', 'cartflows' ),
224
+ 'value' => $facebook_settings['facebook_pixel_tracking'],
225
+ )
226
+ );
227
+
228
+ echo "<div class='wcf-fb-pixel-wrapper'>";
229
+ ?>
230
+ <hr/>
231
+ <?php
232
+ echo Cartflows_Admin_Fields::checkobox_field(
233
+ array(
234
+ 'id' => 'wcf_facebook_pixel_tracking_for_site',
235
+ 'name' => '_cartflows_facebook[facebook_pixel_tracking_for_site]',
236
+ 'title' => __( 'Enable for the whole site', 'cartflows' ),
237
+ 'value' => $facebook_settings['facebook_pixel_tracking_for_site'],
238
+ )
239
+ );
240
+
241
+ echo Cartflows_Admin_Fields::title_field(
242
+ array(
243
+ 'title' => '',
244
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
245
+ )
246
+ );
247
+ ?>
248
+ <hr/>
249
+ <?php
250
+ echo Cartflows_Admin_Fields::text_field(
251
+ array(
252
+ 'id' => 'wcf_facebook_pixel_id',
253
+ 'name' => '_cartflows_facebook[facebook_pixel_id]',
254
+ 'title' => __( 'Enter Facebook pixel ID', 'cartflows' ),
255
+ 'value' => $facebook_settings['facebook_pixel_id'],
256
+ )
257
+ );
258
+
259
+
260
+ echo Cartflows_Admin_Fields::title_field(
261
+ array(
262
+ 'title' => __( 'Enable Events:', 'cartflows' ),
263
+ )
264
+ );
265
+
266
+
267
+ echo Cartflows_Admin_Fields::checkobox_field(
268
+ array(
269
+ 'id' => 'wcf_facebook_pixel_initiate_checkout',
270
+ 'name' => '_cartflows_facebook[facebook_pixel_initiate_checkout]',
271
+ 'title' => __( 'Initiate Checkout', 'cartflows' ),
272
+ 'value' => $facebook_settings['facebook_pixel_initiate_checkout'],
273
+ )
274
+ );
275
+
276
+ echo Cartflows_Admin_Fields::checkobox_field(
277
+ array(
278
+ 'id' => 'wcf_facebook_pixel_add_payment_info',
279
+ 'name' => '_cartflows_facebook[facebook_pixel_add_payment_info]',
280
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
281
+ 'value' => $facebook_settings['facebook_pixel_add_payment_info'],
282
+ )
283
+ );
284
+
285
+ echo Cartflows_Admin_Fields::checkobox_field(
286
+ array(
287
+ 'id' => 'wcf_facebook_pixel_purchase_complete',
288
+ 'name' => '_cartflows_facebook[facebook_pixel_purchase_complete]',
289
+ 'title' => __( 'Purchase Complete', 'cartflows' ),
290
+ 'value' => $facebook_settings['facebook_pixel_purchase_complete'],
291
+ )
292
+ );
293
+
294
+ echo '</div>';
295
+
296
+ ?>
297
+ </div>
298
+
299
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-facebook-setting-save-btn button-primary button', 'submit', false ); ?>
300
+ <?php wp_nonce_field( 'cartflows-facebook-settings', 'cartflows-facebook-settings-nonce' ); ?>
301
+ </div>
302
+ </div>
303
+ </div>
304
+ </form>
305
+ </div>
306
+ <!-- Facebook Pixel Tracking -->
307
+
308
+ <!-- Google Analytics Tracking -->
309
+ <div class="general-settingss-form postbox">
310
+ <h2 class="hndle wcf-normal-cusror ui-sortable-handle">
311
+ <span><?php esc_html_e( 'Google Analytics Settings', 'cartflows' ); ?></span>
312
+ </h2>
313
+ <div class="inside">
314
+ <form method="post" class="wrap wcf-clear" action="" >
315
+ <div class="form-wrap">
316
+ <?php
317
+
318
+ echo Cartflows_Admin_Fields::checkobox_field(
319
+ array(
320
+ 'id' => 'enable_google-analytics-id',
321
+ 'name' => '_cartflows_google_analytics[enable_google_analytics]',
322
+ 'title' => __( 'Enable Google Analytics Tracking', 'cartflows' ),
323
+ 'value' => $google_analytics_settings['enable_google_analytics'],
324
+ )
325
+ );
326
+
327
+ echo "<div class='wcf-google-analytics-wrapper'>";
328
+ ?>
329
+ <hr/>
330
+ <?php
331
+ echo Cartflows_Admin_Fields::checkobox_field(
332
+ array(
333
+ 'id' => 'enable_google_analytics_for_site',
334
+ 'name' => '_cartflows_google_analytics[enable_google_analytics_for_site]',
335
+ 'title' => __( 'Enable for the whole website', 'cartflows' ),
336
+ 'value' => $google_analytics_settings['enable_google_analytics_for_site'],
337
+ )
338
+ );
339
+
340
+ echo Cartflows_Admin_Fields::title_field(
341
+ array(
342
+ 'title' => '',
343
+ 'description' => __( 'If this option is unchecked, it will only apply to CartFlows steps.', 'cartflows' ),
344
+ )
345
+ );
346
+ ?>
347
+ <hr/>
348
+ <?php
349
+ echo Cartflows_Admin_Fields::text_field(
350
+ array(
351
+ 'id' => 'google-analytics-id',
352
+ 'name' => '_cartflows_google_analytics[google_analytics_id]',
353
+ 'title' => __( 'Google Analytics ID', 'cartflows' ),
354
+ 'value' => $google_analytics_settings['google_analytics_id'],
355
+ 'description' => __( 'Log into your <a href="https://analytics.google.com/" target="_blank">google analytics account</a> to find your ID. eg: UA-XXXXXX-X&period;', 'cartflows' ),
356
+ )
357
+ );
358
+
359
+ echo Cartflows_Admin_Fields::title_field(
360
+ array(
361
+ 'title' => __( 'Enable Events:', 'cartflows' ),
362
+ )
363
+ );
364
+
365
+ echo Cartflows_Admin_Fields::checkobox_field(
366
+ array(
367
+ 'id' => 'enable_begin_checkout',
368
+ 'name' => '_cartflows_google_analytics[enable_begin_checkout]',
369
+ 'title' => __( 'Begin Checkout', 'cartflows' ),
370
+ 'value' => $google_analytics_settings['enable_begin_checkout'],
371
+ )
372
+ );
373
+
374
+ echo Cartflows_Admin_Fields::checkobox_field(
375
+ array(
376
+ 'id' => 'enable_add_to_cart',
377
+ 'name' => '_cartflows_google_analytics[enable_add_to_cart]',
378
+ 'title' => __( 'Add To Cart', 'cartflows' ),
379
+ 'value' => $google_analytics_settings['enable_add_to_cart'],
380
+ )
381
+ );
382
+
383
+ echo Cartflows_Admin_Fields::checkobox_field(
384
+ array(
385
+ 'id' => 'enable_add_payment_info',
386
+ 'name' => '_cartflows_google_analytics[enable_add_payment_info]',
387
+ 'title' => __( 'Add Payment Info', 'cartflows' ),
388
+ 'value' => $google_analytics_settings['enable_add_payment_info'],
389
+ )
390
+ );
391
+
392
+ echo Cartflows_Admin_Fields::checkobox_field(
393
+ array(
394
+ 'id' => 'enable_purchase_event',
395
+ 'name' => '_cartflows_google_analytics[enable_purchase_event]',
396
+ 'title' => __( 'Purchase', 'cartflows' ),
397
+ 'value' => $google_analytics_settings['enable_purchase_event'],
398
+ )
399
+ );
400
+
401
+ echo Cartflows_Admin_Fields::title_field(
402
+ array(
403
+ 'title' => '',
404
+ 'description' => __( 'Google Analytics not working correctly? <a href="https://cartflows.com/docs/troubleshooting-google-analytics-tracking-issues/" > Click here </a> to know more. ', 'cartflows' ),
405
+ )
406
+ );
407
+
408
+ do_action( 'cartflows_google_analytics_admin_fields', $google_analytics_settings );
409
+
410
+ echo '</div>';
411
+ ?>
412
+
413
+
414
+ </div>
415
+ <p>
416
+ <?php submit_button( __( 'Save Changes', 'cartflows' ), 'cartflows-common-setting-save-btn button-primary button', 'submit', false ); ?>
417
+ <?php wp_nonce_field( 'cartflows-google-analytics-settings', 'cartflows-google-analytics-settings-nonce' ); ?>
418
+ </p>
419
+
420
+
421
+ </form>
422
+ </div>
423
+ </div>
424
+ <!-- Google Analytics Tracking -->
425
+
426
+ <?php do_action( 'cartflows_register_general_settings' ); ?>
427
+
428
+ </div>
429
+
430
+ <!-- Right Sidebar -->
431
+ <div class="postbox-container" id="postbox-container-1">
432
+ <div id="side-sortables">
433
+
434
+ <div class="postbox">
435
+ <h2 class="hndle">
436
+ <span class="dashicons dashicons-book"></span>
437
+ <span><?php esc_html_e( 'Knowledge Base', 'cartflows' ); ?></span>
438
+ </h2>
439
+ <div class="inside">
440
+ <p>
441
+ <?php esc_html_e( 'Not sure how something works? Take a peek at the knowledge base and learn.', 'cartflows' ); ?>
442
+ </p>
443
+ <p>
444
+ <a href="<?php echo esc_url( 'https://cartflows.com/docs' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Visit Knowledge Base »', 'cartflows' ); ?></a>
445
+ </p>
446
+ </div>
447
+ </div>
448
+
449
+ <div class="postbox">
450
+ <h2 class="hndle">
451
+ <span class="dashicons dashicons-groups"></span>
452
+ <span><?php esc_html_e( 'Community', 'cartflows' ); ?></span>
453
+ </h2>
454
+ <div class="inside">
455
+ <p>
456
+ <?php esc_html_e( 'Join the community of super helpful CartFlows users. Say hello, ask questions, give feedback and help each other!', 'cartflows' ); ?>
457
+ </p>
458
+ <p>
459
+ <a href="<?php echo esc_url( 'https://www.facebook.com/groups/cartflows/' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Join Our Facebook Group »', 'cartflows' ); ?></a>
460
+ </p>
461
+ </div>
462
+ </div>
463
+
464
+ <div class="postbox">
465
+ <h2 class="hndle">
466
+ <span class="dashicons dashicons-sos"></span>
467
+ <span><?php esc_html_e( 'Five Star Support', 'cartflows' ); ?></span>
468
+ </h2>
469
+ <div class="inside">
470
+ <p>
471
+ <?php esc_html_e( 'Got a question? Get in touch with CartFlows developers. We\'re happy to help!', 'cartflows' ); ?>
472
+ </p>
473
+ <p>
474
+ <a href="<?php echo esc_url( 'https://cartflows.com/contact' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Submit a Ticket »', 'cartflows' ); ?></a>
475
+ </p>
476
+ </div>
477
+ </div>
478
+ <?php
479
+ if ( 'true' == $debug_on ) {
480
+ ?>
481
+ <div class="postbox">
482
+ <h2 class="hndle">
483
+ <span class="dashicons dashicons-editor-code"></span>
484
+ <span><?php esc_html_e( 'Load Minified CSS', 'cartflows' ); ?></span>
485
+ </h2>
486
+ <div class="inside">
487
+ <form method="post" class="wrap wcf-clear" action="">
488
+ <p>
489
+ <?php esc_html_e( 'Load the Minified CSS from here. Just Enable it by checking the below given checkbox.', 'cartflows' ); ?>
490
+ </p>
491
+ <?php
492
+ echo Cartflows_Admin_Fields::checkobox_field(
493
+ array(
494
+ 'id' => 'allow_minified_files',
495
+ 'name' => '_cartflows_debug_data[allow_minified_files]',
496
+ 'title' => __( 'Load minified CSS & JS Files', 'cartflows' ),
497
+ 'value' => $debug_data['allow_minified_files'],
498
+ )
499
+ );
500
+ ?>
501
+ <?php submit_button( __( 'Save', 'cartflows' ), 'button-primary button', 'submit', false ); ?>
502
+ <?php wp_nonce_field( 'cartflows-debug-settings', 'cartflows-debug-settings-nonce' ); ?>
503
+ </form>
504
+ </div>
505
+ </div>
506
+ <?php
507
+ }
508
+ ?>
509
+ </div>
510
+ </div>
511
+ <!-- Right Sidebar -->
512
+
513
+ </div>
514
+ <!-- /post-body -->
515
+ <br class="clear">
516
+ </div>
517
+ </div>
518
+ <?php endif; ?>
519
+
520
+ <?php
521
+ /**
522
+ * Loads Zapier settings admin view.
523
+ */
524
+ do_action( 'cartflows_after_settings' );
525
+ ?>
languages/cartflows.pot CHANGED
@@ -1,2099 +1,2099 @@
1
- # Copyright (C) 2020 CartFlows Inc
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"
11
- "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
- "Language-Team: LANGUAGE <LL@li.org>\n"
14
- "Language: en\n"
15
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "X-Poedit-Country: United States\n"
17
- "X-Poedit-SourceCharset: UTF-8\n"
18
- "X-Poedit-KeywordsList: "
19
- "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
- "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
- "X-Poedit-Basepath: ../\n"
22
- "X-Poedit-SearchPath-0: .\n"
23
- "X-Poedit-Bookmarks: \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 ""
74
-
75
- #: classes/batch-process/class-cartflows-importer-elementor.php:56
76
- msgid "Invalid content. Expected an array."
77
- msgstr ""
78
-
79
- #: classes/batch-process/helpers/class-wp-background-process.php:435
80
- msgid "Every %d Minutes"
81
- msgstr ""
82
-
83
- #: classes/class-cartflows-admin-fields.php:235
84
- msgid "Select"
85
- msgstr ""
86
-
87
- #: classes/class-cartflows-admin-fields.php:238
88
- msgid "No Checkout Steps"
89
- msgstr ""
90
-
91
- #: classes/class-cartflows-admin-fields.php:264
92
- #. translators: %s: link
93
- msgid ""
94
- "Be sure not to add any product in above selected Global Checkout step. "
95
- "Please read information about how to set up Global Checkout %1$shere%2$s."
96
- msgstr ""
97
-
98
- #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
99
- #: includes/admin/cartflows-general-bck.php:34
100
- #: modules/optin/classes/class-cartflows-optin-meta.php:150
101
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
102
- msgid "Settings"
103
- msgstr ""
104
-
105
- #: classes/class-cartflows-admin.php:440
106
- msgid "Installing and activating.."
107
- msgstr ""
108
-
109
- #: classes/class-cartflows-admin.php:441
110
- msgid "There was an error with the installation of plugin."
111
- msgstr ""
112
-
113
- #: classes/class-cartflows-admin.php:495
114
- msgid "Flows Library"
115
- msgstr ""
116
-
117
- #: classes/class-cartflows-admin.php:502
118
- #: modules/flow/view/meta-flow-steps.php:156
119
- msgid "Ready Templates"
120
- msgstr ""
121
-
122
- #: classes/class-cartflows-admin.php:505
123
- #: modules/flow/view/meta-flow-steps.php:159
124
- msgid "Create Your Own"
125
- msgstr ""
126
-
127
- #: classes/class-cartflows-admin.php:516
128
- #: modules/flow/view/meta-flow-steps.php:171
129
- msgid "Search Sites"
130
- msgstr ""
131
-
132
- #: classes/class-cartflows-admin.php:517
133
- #: modules/flow/view/meta-flow-steps.php:172
134
- msgid "Search Flow..."
135
- msgstr ""
136
-
137
- #: classes/class-cartflows-admin.php:534
138
- msgid "Design Your Flow"
139
- msgstr ""
140
-
141
- #: classes/class-cartflows-admin.php:535
142
- #: classes/class-cartflows-importer.php:665
143
- #: classes/class-cartflows-importer.php:764
144
- #: modules/flow/view/meta-flow-steps.php:202
145
- msgid "Learn How"
146
- msgstr ""
147
-
148
- #: classes/class-cartflows-api.php:369
149
- msgid "Request successfully processed!"
150
- msgstr ""
151
-
152
- #: classes/class-cartflows-cloning.php:423
153
- msgid "Clone this flow"
154
- msgstr ""
155
-
156
- #: classes/class-cartflows-cloning.php:423
157
- #: modules/flow/view/meta-flow-steps.php:115
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
-
166
- #: classes/class-cartflows-flow-frontend.php:53
167
- msgid ""
168
- "Test mode is active — which displays random products for previewing. It can "
169
- "be deactivated from the flow settings in the admin dashboard."
170
- msgstr ""
171
-
172
- #: classes/class-cartflows-flow-frontend.php:58
173
- msgid "Click here to disable it"
174
- msgstr ""
175
-
176
- #: classes/class-cartflows-importer.php:81
177
- msgid "Export this flow"
178
- msgstr ""
179
-
180
- #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
181
- msgid "Export"
182
- msgstr ""
183
-
184
- #: classes/class-cartflows-importer.php:92
185
- msgid "Flow Export"
186
- msgstr ""
187
-
188
- #: classes/class-cartflows-importer.php:93
189
- msgid "Flow Import"
190
- msgstr ""
191
-
192
- #: classes/class-cartflows-importer.php:104
193
- msgid "No post to export has been supplied!"
194
- msgstr ""
195
-
196
- #: classes/class-cartflows-importer.php:278
197
- msgid "Please upload a valid .json file"
198
- msgstr ""
199
-
200
- #: classes/class-cartflows-importer.php:284
201
- msgid "Please upload a file to import"
202
- msgstr ""
203
-
204
- #: classes/class-cartflows-importer.php:506
205
- msgid "Successfully imported flows."
206
- msgstr ""
207
-
208
- #: classes/class-cartflows-importer.php:538
209
- msgid "Loading Steps"
210
- msgstr ""
211
-
212
- #: classes/class-cartflows-importer.php:540
213
- msgid "Getting steps from the cloud. Please wait for the moment."
214
- msgstr ""
215
-
216
- #: classes/class-cartflows-importer.php:551
217
- msgid "Searching Template.."
218
- msgstr ""
219
-
220
- #: classes/class-cartflows-importer.php:553
221
- msgid "Getting templates from the cloud. Please wait for the moment."
222
- msgstr ""
223
-
224
- #: classes/class-cartflows-importer.php:562
225
- msgid "Importing.."
226
- msgstr ""
227
-
228
- #: classes/class-cartflows-importer.php:571
229
- #: classes/class-cartflows-importer.php:611
230
- msgid "Imported"
231
- msgstr ""
232
-
233
- #: classes/class-cartflows-importer.php:572
234
- #: classes/class-cartflows-importer.php:612
235
- msgid "Thanks for patience"
236
- msgstr ""
237
-
238
- #: classes/class-cartflows-importer.php:581
239
- #: classes/class-cartflows-importer.php:593
240
- msgid "Coming Soon!"
241
- msgstr ""
242
-
243
- #: classes/class-cartflows-importer.php:612
244
- msgid "Redirecting to the Elementor edit window."
245
- msgstr ""
246
-
247
- #: classes/class-cartflows-importer.php:658
248
- #: classes/class-cartflows-importer.php:774
249
- msgid "Pro"
250
- msgstr ""
251
-
252
- #: classes/class-cartflows-importer.php:699
253
- #: classes/class-cartflows-importer.php:806
254
- msgid "Activate License"
255
- msgstr ""
256
-
257
- #: classes/class-cartflows-importer.php:701
258
- #: classes/class-cartflows-importer.php:808
259
- #: modules/flow/classes/class-cartflows-flow-meta.php:474
260
- msgid "Get Pro"
261
- msgstr ""
262
-
263
- #: classes/class-cartflows-importer.php:726
264
- msgid "Create"
265
- msgstr ""
266
-
267
- #: classes/class-cartflows-importer.php:825
268
- msgid "Under Maintenance.."
269
- msgstr ""
270
-
271
- #: classes/class-cartflows-importer.php:826
272
- msgid ""
273
- "If you are seeing this message, most likely our servers are under routine "
274
- "maintenance and we will be back shortly."
275
- msgstr ""
276
-
277
- #: classes/class-cartflows-importer.php:827
278
- msgid ""
279
- "In rare case, it is possible your website is having trouble connecting with "
280
- "ours. If you need help, please feel free to get in touch with us from our "
281
- "website.."
282
- msgstr ""
283
-
284
- #: classes/class-cartflows-importer.php:857
285
- #. translators: %s: Plugin string
286
- msgid ""
287
- "%1$s to see CartFlows templates. If you prefer another page builder tool, "
288
- "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
289
- msgstr ""
290
-
291
- #: classes/class-cartflows-importer.php:872
292
- msgid "All"
293
- msgstr ""
294
-
295
- #: classes/class-cartflows-importer.php:875
296
- msgid "Select Step Type"
297
- msgstr ""
298
-
299
- #: classes/class-cartflows-importer.php:959
300
- msgid "Import from Cloud"
301
- msgstr ""
302
-
303
- #: classes/class-cartflows-importer.php:1264
304
- msgid "Sales Landing"
305
- msgstr ""
306
-
307
- #: classes/class-cartflows-importer.php:1268
308
- #: modules/flow/classes/class-cartflows-step-post-type.php:253
309
- #: modules/flow/view/meta-flow-steps.php:12
310
- msgid "Checkout (Woo)"
311
- msgstr ""
312
-
313
- #: classes/class-cartflows-importer.php:1272
314
- #: modules/flow/classes/class-cartflows-step-post-type.php:260
315
- #: modules/flow/view/meta-flow-steps.php:13
316
- msgid "Thank You (Woo)"
317
- msgstr ""
318
-
319
- #: classes/class-cartflows-importer.php:1280
320
- #: modules/flow/classes/class-cartflows-step-post-type.php:239
321
- #: modules/flow/view/meta-flow-steps.php:11
322
- msgid "Landing"
323
- msgstr ""
324
-
325
- #: classes/class-cartflows-importer.php:1284
326
- msgid "Thank You"
327
- msgstr ""
328
-
329
- #: classes/class-cartflows-importer.php:1394
330
- #. translators: %s: template ID
331
- msgid "Invalid template id %1$s or post id %2$s."
332
- msgstr ""
333
-
334
- #: classes/class-cartflows-importer.php:1469
335
- #. translators: %s: flow ID
336
- msgid "Invalid flow id %1$s OR step type %2$s."
337
- msgstr ""
338
-
339
- #: classes/class-cartflows-importer.php:1594
340
- msgid ""
341
- "Elementor is not activated. Please activate plugin Elementor Page Builder "
342
- "to import the step."
343
- msgstr ""
344
-
345
- #: classes/class-cartflows-importer.php:1697
346
- msgid "Action failed. Invalid Security Nonce."
347
- msgstr ""
348
-
349
- #: classes/class-cartflows-importer.php:1704
350
- msgid "User have not plugin install permissions."
351
- msgstr ""
352
-
353
- #: classes/class-cartflows-importer.php:1726
354
- msgid "Plugin Successfully Activated"
355
- msgstr ""
356
-
357
- #: classes/class-cartflows-learndash-compatibility.php:86
358
- msgid "None"
359
- msgstr ""
360
-
361
- #: classes/class-cartflows-learndash-compatibility.php:113
362
- #. translators: 1: anchor start, 2: anchor close
363
- msgid ""
364
- "Non-enrolled students will redirect to the selected CartFlows template. If "
365
- "you have not created any Flow already, add new Flow from %1$shere%2$s."
366
- msgstr ""
367
-
368
- #: classes/class-cartflows-learndash-compatibility.php:119
369
- msgid "Select CartFlows Template for this Course"
370
- msgstr ""
371
-
372
- #: classes/class-cartflows-loader.php:222
373
- #. translators: %s: html tags
374
- msgid ""
375
- "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
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
-
394
- #: classes/class-cartflows-logger.php:161
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
-
443
- #: classes/class-cartflows-meta.php:34
444
- msgid "Update"
445
- msgstr ""
446
-
447
- #: classes/class-cartflows-meta.php:42
448
- #: modules/flow/classes/class-cartflows-flow-meta.php:95
449
- #: modules/flow/classes/class-cartflows-flow-meta.php:733
450
- msgid "Back to edit Flow"
451
- msgstr ""
452
-
453
- #: classes/class-cartflows-meta.php:63
454
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
455
- #: modules/landing/classes/class-cartflows-landing-meta.php:136
456
- #: modules/optin/classes/class-cartflows-optin-meta.php:156
457
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
458
- msgid "Custom Script"
459
- msgstr ""
460
-
461
- #: classes/class-cartflows-meta.php:66
462
- msgid ""
463
- "Custom script lets you add your own custom script on front end of this flow "
464
- "page."
465
- msgstr ""
466
-
467
- #: classes/class-cartflows-metabox.php:59
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."
670
- msgstr ""
671
-
672
- #: classes/logger/class-cartflows-wc-logger.php:58
673
- #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
674
- msgid "The provided handler %1$s does not implement %2$s."
675
- msgstr ""
676
-
677
- #: classes/logger/class-cartflows-wc-logger.php:136
678
- #. translators: 1: Cartflows_WC_Logger::log 2: level
679
- msgid "%1$s was called with an invalid level \"%2$s\"."
680
- msgstr ""
681
-
682
- #: includes/admin/cartflows-admin.php:19
683
- #: includes/admin/cartflows-general.php:48
684
- msgid "Modernizing WordPress eCommerce!"
685
- msgstr ""
686
-
687
- #: includes/admin/cartflows-admin.php:29
688
- msgid "Settings saved successfully."
689
- msgstr ""
690
-
691
- #: includes/admin/cartflows-error-log.php:36
692
- msgid "%1$s at %2$s"
693
- msgstr ""
694
-
695
- #: includes/admin/cartflows-error-log.php:41
696
- #: modules/flow/classes/class-cartflows-flow-post-type.php:225
697
- #: modules/flow/view/meta-flow-steps.php:104
698
- msgid "View"
699
- msgstr ""
700
-
701
- #: includes/admin/cartflows-error-log.php:65
702
- msgid "Delete log"
703
- msgstr ""
704
-
705
- #: includes/admin/cartflows-error-log.php:70
706
- msgid "There are currently no logs to view."
707
- msgstr ""
708
-
709
- #: includes/admin/cartflows-general-bck.php:10
710
- msgid "Selec"
711
- msgstr ""
712
-
713
- #: includes/admin/cartflows-general-bck.php:22
714
- msgid "General"
715
- msgstr ""
716
-
717
- #: includes/admin/cartflows-general.php:31
718
- #: includes/admin/cartflows-general.php:58
719
- msgid "General Settings"
720
- msgstr ""
721
-
722
- #: includes/admin/cartflows-general.php:40
723
- msgid "Getting Started"
724
- msgstr ""
725
-
726
- #: includes/admin/cartflows-general.php:71
727
- msgid "Disallow search engines from indexing flows"
728
- msgstr ""
729
-
730
- #: includes/admin/cartflows-general.php:81
731
- #: modules/flow/view/meta-flow-steps.php:93
732
- msgid "Global Checkout"
733
- msgstr ""
734
-
735
- #: includes/admin/cartflows-general.php:90
736
- msgid "Show Templates designed with"
737
- msgstr ""
738
-
739
- #: includes/admin/cartflows-general.php:91
740
- msgid ""
741
- "CartFlows offers flow templates that can be imported in one click. These "
742
- "templates are available in few different page builders. Please choose your "
743
- "preferred page builder from the list so you will only see templates that "
744
- "are made using that page builder.."
745
- msgstr ""
746
-
747
- #: includes/admin/cartflows-general.php:95
748
- msgid "Beaver Builder"
749
- msgstr ""
750
-
751
- #: includes/admin/cartflows-general.php:107
752
- #: includes/admin/cartflows-general.php:193
753
- #: includes/admin/cartflows-general.php:299
754
- #: includes/admin/cartflows-general.php:416
755
- msgid "Save Changes"
756
- msgstr ""
757
-
758
- #: includes/admin/cartflows-general.php:119
759
- msgid "Permalink Settings"
760
- msgstr ""
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
-
768
- #: includes/admin/cartflows-general.php:140
769
- msgid "Flow and Step Slug"
770
- msgstr ""
771
-
772
- #: includes/admin/cartflows-general.php:146
773
- msgid "Flow Slug"
774
- msgstr ""
775
-
776
- #: includes/admin/cartflows-general.php:152
777
- msgid "Step Slug"
778
- msgstr ""
779
-
780
- #: includes/admin/cartflows-general.php:164
781
- msgid "Post Type Permalink Base"
782
- msgstr ""
783
-
784
- #: includes/admin/cartflows-general.php:172
785
- msgid "Step Base"
786
- msgstr ""
787
-
788
- #: includes/admin/cartflows-general.php:182
789
- msgid "Flow Base"
790
- msgstr ""
791
-
792
- #: includes/admin/cartflows-general.php:194
793
- msgid "Set Default"
794
- msgstr ""
795
-
796
- #: includes/admin/cartflows-general.php:208
797
- msgid "Facebook Pixel Settings"
798
- msgstr ""
799
-
800
- #: includes/admin/cartflows-general.php:223
801
- msgid "Enable Facebook Pixel Tracking"
802
- msgstr ""
803
-
804
- #: includes/admin/cartflows-general.php:236
805
- msgid "Enable for the whole site"
806
- msgstr ""
807
-
808
- #: includes/admin/cartflows-general.php:244
809
- #: includes/admin/cartflows-general.php:343
810
- msgid "If this option is unchecked, it will only apply to CartFlows steps."
811
- msgstr ""
812
-
813
- #: includes/admin/cartflows-general.php:254
814
- msgid "Enter Facebook pixel ID"
815
- msgstr ""
816
-
817
- #: includes/admin/cartflows-general.php:262
818
- #: includes/admin/cartflows-general.php:361
819
- msgid "Enable Events:"
820
- msgstr ""
821
-
822
- #: includes/admin/cartflows-general.php:271
823
- msgid "Initiate Checkout"
824
- msgstr ""
825
-
826
- #: includes/admin/cartflows-general.php:280
827
- #: includes/admin/cartflows-general.php:387
828
- msgid "Add Payment Info"
829
- msgstr ""
830
-
831
- #: includes/admin/cartflows-general.php:289
832
- msgid "Purchase Complete"
833
- msgstr ""
834
-
835
- #: includes/admin/cartflows-general.php:311
836
- msgid "Google Analytics Settings"
837
- msgstr ""
838
-
839
- #: includes/admin/cartflows-general.php:322
840
- msgid "Enable Google Analytics Tracking"
841
- msgstr ""
842
-
843
- #: includes/admin/cartflows-general.php:335
844
- msgid "Enable for the whole website"
845
- msgstr ""
846
-
847
- #: includes/admin/cartflows-general.php:353
848
- msgid "Google Analytics ID"
849
- msgstr ""
850
-
851
- #: includes/admin/cartflows-general.php:355
852
- msgid ""
853
- "Log into your <a href=\"https://analytics.google.com/\" "
854
- "target=\"_blank\">google analytics account</a> to find your ID. eg: "
855
- "UA-XXXXXX-X&period;"
856
- msgstr ""
857
-
858
- #: includes/admin/cartflows-general.php:369
859
- msgid "Begin Checkout"
860
- msgstr ""
861
-
862
- #: includes/admin/cartflows-general.php:378
863
- msgid "Add To Cart"
864
- msgstr ""
865
-
866
- #: includes/admin/cartflows-general.php:396
867
- msgid "Purchase"
868
- msgstr ""
869
-
870
- #: includes/admin/cartflows-general.php:404
871
- msgid ""
872
- "Google Analytics not working correctly? <a "
873
- "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
874
- "issues/\" > Click here </a> to know more. "
875
- msgstr ""
876
-
877
- #: includes/admin/cartflows-general.php:437
878
- msgid "Knowledge Base"
879
- msgstr ""
880
-
881
- #: includes/admin/cartflows-general.php:441
882
- msgid "Not sure how something works? Take a peek at the knowledge base and learn."
883
- msgstr ""
884
-
885
- #: includes/admin/cartflows-general.php:444
886
- msgid "Visit Knowledge Base »"
887
- msgstr ""
888
-
889
- #: includes/admin/cartflows-general.php:452
890
- msgid "Community"
891
- msgstr ""
892
-
893
- #: includes/admin/cartflows-general.php:456
894
- msgid ""
895
- "Join the community of super helpful CartFlows users. Say hello, ask "
896
- "questions, give feedback and help each other!"
897
- msgstr ""
898
-
899
- #: includes/admin/cartflows-general.php:459
900
- msgid "Join Our Facebook Group »"
901
- msgstr ""
902
-
903
- #: includes/admin/cartflows-general.php:467
904
- msgid "Five Star Support"
905
- msgstr ""
906
-
907
- #: includes/admin/cartflows-general.php:471
908
- msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
909
- msgstr ""
910
-
911
- #: includes/admin/cartflows-general.php:474
912
- msgid "Submit a Ticket »"
913
- msgstr ""
914
-
915
- #: includes/admin/cartflows-general.php:484
916
- msgid "Load Minified CSS"
917
- msgstr ""
918
-
919
- #: includes/admin/cartflows-general.php:489
920
- msgid ""
921
- "Load the Minified CSS from here. Just Enable it by checking the below given "
922
- "checkbox."
923
- msgstr ""
924
-
925
- #: includes/admin/cartflows-general.php:496
926
- msgid "Load minified CSS & JS Files"
927
- msgstr ""
928
-
929
- #: includes/admin/cartflows-general.php:501
930
- msgid "Save"
931
- msgstr ""
932
-
933
- #: includes/exporter.php:12
934
- msgid "Export Flows to a JSON file"
935
- msgstr ""
936
-
937
- #: includes/exporter.php:13
938
- msgid ""
939
- "This tool allows you to generate and download a JSON file containing a list "
940
- "of all flows."
941
- msgstr ""
942
-
943
- #: includes/importer.php:12
944
- msgid "Import Flows to a JSON file"
945
- msgstr ""
946
-
947
- #: includes/importer.php:13
948
- msgid "This tool allows you to import the flows from the JSON file."
949
- msgstr ""
950
-
951
- #: includes/importer.php:21
952
- msgid "Import"
953
- msgstr ""
954
-
955
- #: includes/meta-fields/generate-product-repeater.php:36
956
- msgid "Remove"
957
- msgstr ""
958
-
959
- #: includes/meta-fields/generate-product-repeater.php:51
960
- msgid "Product Quantity"
961
- msgstr ""
962
-
963
- #: includes/meta-fields/generate-product-repeater.php:65
964
- msgid "Discount Type"
965
- msgstr ""
966
-
967
- #: includes/meta-fields/generate-product-repeater.php:69
968
- msgid "Select Discount Type"
969
- msgstr ""
970
-
971
- #: includes/meta-fields/generate-product-repeater.php:70
972
- msgid "Original"
973
- msgstr ""
974
-
975
- #: includes/meta-fields/generate-product-repeater.php:71
976
- msgid "Percentage"
977
- msgstr ""
978
-
979
- #: includes/meta-fields/generate-product-repeater.php:72
980
- msgid "Price"
981
- msgstr ""
982
-
983
- #: includes/meta-fields/generate-product-repeater.php:83
984
- msgid "Discount Value"
985
- msgstr ""
986
-
987
- #: includes/meta-fields/generate-product-repeater.php:85
988
- msgid "Discount value will apply for each quantity of product."
989
- msgstr ""
990
-
991
- #: includes/meta-fields/get-product-selection-repeater.php:112
992
- msgid "Add New Product"
993
- msgstr ""
994
-
995
- #: includes/meta-fields/get-product-selection-repeater.php:113
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 ""
1003
- "WooCommerce functions do not exist. If you are in an IFrame, please reload "
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
-
1064
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1065
- msgid "Checkout Layout"
1066
- msgstr ""
1067
-
1068
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1069
- #: modules/landing/classes/class-cartflows-landing-meta.php:130
1070
- #: modules/optin/classes/class-cartflows-optin-meta.php:126
1071
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1072
- msgid "Shortcodes"
1073
- msgstr ""
1074
-
1075
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1076
- #: modules/optin/classes/class-cartflows-optin-meta.php:132
1077
- msgid "Select Product"
1078
- msgstr ""
1079
-
1080
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1081
- msgid "Product Options"
1082
- msgstr ""
1083
-
1084
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1085
- msgid "Order Bump"
1086
- msgstr ""
1087
-
1088
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1089
- msgid "Checkout Offer"
1090
- msgstr ""
1091
-
1092
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1093
- msgid "Checkout Design"
1094
- msgstr ""
1095
-
1096
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1097
- msgid "Checkout Fields"
1098
- msgstr ""
1099
-
1100
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1101
- msgid "Checkout Settings"
1102
- msgstr ""
1103
-
1104
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1105
- msgid "Logo (Optional)"
1106
- msgstr ""
1107
-
1108
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1109
- #. translators: %s: link
1110
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1111
- msgstr ""
1112
-
1113
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1114
- #. translators: %s: link.
1115
- msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1116
- msgstr ""
1117
-
1118
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1119
- msgid "Add this shortcode to your checkout page"
1120
- msgstr ""
1121
-
1122
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1123
- #. translators: %s: link
1124
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1125
- msgstr ""
1126
-
1127
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1128
- #. translators: %s: link
1129
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1130
- msgstr ""
1131
-
1132
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1133
- #. translators: %s: link
1134
- msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1135
- msgstr ""
1136
-
1137
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1138
- #. translators: %s: link
1139
- msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1140
- msgstr ""
1141
-
1142
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1143
- #. translators: %s: link
1144
- msgid ""
1145
- "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1146
- "feature"
1147
- msgstr ""
1148
-
1149
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1150
- #. translators: %s: link
1151
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
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 ""
1159
-
1160
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1161
- msgid "Place Order Button Text"
1162
- msgstr ""
1163
-
1164
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1165
- msgid "Place order"
1166
- msgstr ""
1167
-
1168
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1169
- msgid "It will change the Place Order Button text on checkout page."
1170
- msgstr ""
1171
-
1172
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1173
- msgid "Enable cart editing on checkout"
1174
- msgstr ""
1175
-
1176
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1177
- #. translators: %s: link
1178
- msgid "Users will able to remove products from the checkout page."
1179
- msgstr ""
1180
-
1181
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1182
- msgid "One Column (Available in CartFlows Pro) "
1183
- msgstr ""
1184
-
1185
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1186
- msgid "Two Step (Available in CartFlows Pro) "
1187
- msgstr ""
1188
-
1189
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1190
- msgid "Checkout Skin"
1191
- msgstr ""
1192
-
1193
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1194
- msgid "One Column"
1195
- msgstr ""
1196
-
1197
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1198
- msgid "Two Column"
1199
- msgstr ""
1200
-
1201
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1202
- msgid "Two Step"
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
-
1210
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
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"
1220
- msgstr ""
1221
-
1222
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1223
- msgid "Advance Options"
1224
- msgstr ""
1225
-
1226
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1227
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1228
- msgid "Heading"
1229
- msgstr ""
1230
-
1231
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1232
- msgid "Heading Color"
1233
- msgstr ""
1234
-
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
-
1351
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1352
- msgid "Buttons"
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
-
1375
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1376
- msgid "Sections"
1377
- msgstr ""
1378
-
1379
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1380
- msgid "Highlight Area Background Color"
1381
- msgstr ""
1382
-
1383
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1384
- msgid "Header Logo"
1385
- msgstr ""
1386
-
1387
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1388
- msgid "Logo Width (In px)"
1389
- msgstr ""
1390
-
1391
- #: modules/checkout/templates/wcf-template.php:46
1392
- msgid "Copyright &copy;"
1393
- msgstr ""
1394
-
1395
- #: modules/checkout/templates/wcf-template.php:50
1396
- msgid "All Rights Reserved"
1397
- msgstr ""
1398
-
1399
- #: modules/flow/classes/class-cartflows-flow-meta.php:263
1400
- #. translators: %s flow id
1401
- msgid "Step not deleted for flow - %s"
1402
- msgstr ""
1403
-
1404
- #: modules/flow/classes/class-cartflows-flow-meta.php:294
1405
- #. translators: %s flow id
1406
- msgid "Step deleted for flow - %s"
1407
- msgstr ""
1408
-
1409
- #: modules/flow/classes/class-cartflows-flow-meta.php:322
1410
- #. translators: %s flow id
1411
- msgid "Steps not sorted for flow - %s"
1412
- msgstr ""
1413
-
1414
- #: modules/flow/classes/class-cartflows-flow-meta.php:345
1415
- #. translators: %s flow id
1416
- msgid "Steps sorted for flow - %s"
1417
- msgstr ""
1418
-
1419
- #: modules/flow/classes/class-cartflows-flow-meta.php:456
1420
- msgid "Analytics"
1421
- msgstr ""
1422
-
1423
- #: modules/flow/classes/class-cartflows-flow-meta.php:473
1424
- #. translators: %s: link
1425
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1426
- msgstr ""
1427
-
1428
- #: modules/flow/classes/class-cartflows-flow-meta.php:491
1429
- msgid "Flow Settings"
1430
- msgstr ""
1431
-
1432
- #: modules/flow/classes/class-cartflows-flow-meta.php:576
1433
- msgid "Enable Test Mode"
1434
- msgstr ""
1435
-
1436
- #: modules/flow/classes/class-cartflows-flow-meta.php:583
1437
- msgid ""
1438
- "If you are using WooCommerce plugin then test mode will add random products "
1439
- "in your flow, so you can preview it easily while testing."
1440
- msgstr ""
1441
-
1442
- #: modules/flow/classes/class-cartflows-flow-meta.php:702
1443
- #: modules/flow/view/meta-flow-steps.php:133
1444
- msgid "Add New Step"
1445
- msgstr ""
1446
-
1447
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1448
- msgid "Flow: "
1449
- msgstr ""
1450
-
1451
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1452
- msgid "Name: "
1453
- msgstr ""
1454
-
1455
- #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1456
- msgid "Search Flows"
1457
- msgstr ""
1458
-
1459
- #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1460
- msgid "All Flows"
1461
- msgstr ""
1462
-
1463
- #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1464
- msgid "Edit Flow"
1465
- msgstr ""
1466
-
1467
- #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1468
- msgid "View Flow"
1469
- msgstr ""
1470
-
1471
- #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1472
- #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1473
- #: modules/flow/classes/class-cartflows-step-post-type.php:167
1474
- #: modules/flow/classes/class-cartflows-step-post-type.php:169
1475
- msgid "Add New"
1476
- msgstr ""
1477
-
1478
- #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1479
- msgid "Update Flow"
1480
- msgstr ""
1481
-
1482
- #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1483
- msgid "New Flow Name"
1484
- msgstr ""
1485
-
1486
- #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1487
- msgid "Upgrade to CartFlows Pro"
1488
- msgstr ""
1489
-
1490
- #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1491
- msgid "Slug"
1492
- msgstr ""
1493
-
1494
- #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1495
- msgid "Flows"
1496
- msgstr ""
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 ""
1554
-
1555
- #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1556
- #: modules/widgets/class-cartflows-next-step.php:78
1557
- msgid "Next Step"
1558
- msgstr ""
1559
-
1560
- #: modules/flow/classes/class-cartflows-step-post-type.php:163
1561
- msgid "Search Steps"
1562
- msgstr ""
1563
-
1564
- #: modules/flow/classes/class-cartflows-step-post-type.php:164
1565
- msgid "All Steps"
1566
- msgstr ""
1567
-
1568
- #: modules/flow/classes/class-cartflows-step-post-type.php:165
1569
- #: modules/flow/view/meta-flow-steps.php:106
1570
- msgid "Edit Step"
1571
- msgstr ""
1572
-
1573
- #: modules/flow/classes/class-cartflows-step-post-type.php:166
1574
- #: modules/flow/view/meta-flow-steps.php:102
1575
- msgid "View Step"
1576
- msgstr ""
1577
-
1578
- #: modules/flow/classes/class-cartflows-step-post-type.php:168
1579
- msgid "Update Step"
1580
- msgstr ""
1581
-
1582
- #: modules/flow/classes/class-cartflows-step-post-type.php:170
1583
- msgid "New Step Name"
1584
- msgstr ""
1585
-
1586
- #: modules/flow/classes/class-cartflows-step-post-type.php:211
1587
- msgid "Step Type"
1588
- msgstr ""
1589
-
1590
- #: modules/flow/classes/class-cartflows-step-post-type.php:221
1591
- msgid "Step Flow"
1592
- msgstr ""
1593
-
1594
- #: modules/flow/classes/class-cartflows-step-post-type.php:246
1595
- #: modules/flow/view/meta-flow-steps.php:16
1596
- msgid "Optin (Woo)"
1597
- msgstr ""
1598
-
1599
- #: modules/flow/classes/class-cartflows-step-post-type.php:267
1600
- #: modules/flow/view/meta-flow-steps.php:14
1601
- msgid "Upsell (Woo)"
1602
- msgstr ""
1603
-
1604
- #: modules/flow/classes/class-cartflows-step-post-type.php:274
1605
- #: modules/flow/view/meta-flow-steps.php:15
1606
- msgid "Downsell (Woo)"
1607
- msgstr ""
1608
-
1609
- #: modules/flow/view/meta-flow-steps.php:85
1610
- msgid "No Product Assigned"
1611
- msgstr ""
1612
-
1613
- #: modules/flow/view/meta-flow-steps.php:89
1614
- msgid "Global Checkout - Remove selected checkout product"
1615
- msgstr ""
1616
-
1617
- #: modules/flow/view/meta-flow-steps.php:108
1618
- msgid "Edit"
1619
- msgstr ""
1620
-
1621
- #: modules/flow/view/meta-flow-steps.php:113
1622
- msgid "Clone Step"
1623
- msgstr ""
1624
-
1625
- #: modules/flow/view/meta-flow-steps.php:118
1626
- msgid "Delete Step"
1627
- msgstr ""
1628
-
1629
- #: modules/flow/view/meta-flow-steps.php:120
1630
- msgid "Delete"
1631
- msgstr ""
1632
-
1633
- #: modules/flow/view/meta-flow-steps.php:149
1634
- msgid "Steps Library"
1635
- msgstr ""
1636
-
1637
- #: modules/flow/view/meta-flow-steps.php:198
1638
- msgid "Create Step"
1639
- msgstr ""
1640
-
1641
- #: modules/flow/view/meta-flow-steps.php:200
1642
- msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1643
- msgstr ""
1644
-
1645
- #: modules/landing/classes/class-cartflows-landing-meta.php:66
1646
- msgid "Landing Page Settings"
1647
- msgstr ""
1648
-
1649
- #: modules/landing/classes/class-cartflows-landing-meta.php:169
1650
- msgid "Next Step Link"
1651
- msgstr ""
1652
-
1653
- #: modules/optin/classes/class-cartflows-optin-markup.php:165
1654
- msgid "Please place shortcode on Optin step-type only."
1655
- msgstr ""
1656
-
1657
- #: modules/optin/classes/class-cartflows-optin-markup.php:225
1658
- msgid ""
1659
- "No product is selected. Please select a Simple, Virtual and Free product "
1660
- "from the meta settings."
1661
- msgstr ""
1662
-
1663
- #: modules/optin/classes/class-cartflows-optin-markup.php:242
1664
- msgid "Please update the selected product's price to zero (0)."
1665
- msgstr ""
1666
-
1667
- #: modules/optin/classes/class-cartflows-optin-markup.php:251
1668
- #: modules/optin/classes/class-cartflows-optin-markup.php:255
1669
- msgid "Please select a Simple, Virtual and Free product."
1670
- msgstr ""
1671
-
1672
- #: modules/optin/classes/class-cartflows-optin-meta.php:65
1673
- msgid "Optin Settings"
1674
- msgstr ""
1675
-
1676
- #: modules/optin/classes/class-cartflows-optin-meta.php:138
1677
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1678
- msgid "Design"
1679
- msgstr ""
1680
-
1681
- #: modules/optin/classes/class-cartflows-optin-meta.php:144
1682
- msgid "Form Fields"
1683
- msgstr ""
1684
-
1685
- #: modules/optin/classes/class-cartflows-optin-meta.php:213
1686
- msgid "Add this shortcode to your optin page"
1687
- msgstr ""
1688
-
1689
- #: modules/optin/classes/class-cartflows-optin-meta.php:238
1690
- msgid "Select Free Product"
1691
- msgstr ""
1692
-
1693
- #: modules/optin/classes/class-cartflows-optin-meta.php:239
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
-
1760
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1761
- msgid "Thank You Page Settings"
1762
- msgstr ""
1763
-
1764
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1765
- msgid "Edit Fields"
1766
- msgstr ""
1767
-
1768
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1769
- msgid "Order Details"
1770
- msgstr ""
1771
-
1772
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1773
- msgid "Text"
1774
- msgstr ""
1775
-
1776
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1777
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1778
- msgid "Color"
1779
- msgstr ""
1780
-
1781
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1782
- msgid "Advanced Options"
1783
- msgstr ""
1784
-
1785
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1786
- msgid "Container Width (In px)"
1787
- msgstr ""
1788
-
1789
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1790
- msgid "Section Background Color"
1791
- msgstr ""
1792
-
1793
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1794
- msgid "Enable Order Overview "
1795
- msgstr ""
1796
-
1797
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1798
- msgid "Enable Order Details "
1799
- msgstr ""
1800
-
1801
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1802
- msgid "Enable Billing Details "
1803
- msgstr ""
1804
-
1805
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1806
- msgid "Enable Shipping Details "
1807
- msgstr ""
1808
-
1809
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1810
- msgid "Thank You Page Text"
1811
- msgstr ""
1812
-
1813
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1814
- #: woocommerce/template/checkout/thankyou.php:41
1815
- #: woocommerce/template/checkout/thankyou.php:83
1816
- msgid "Thank you. Your order has been received."
1817
- msgstr ""
1818
-
1819
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1820
- msgid "It will change the default text on thank you page."
1821
- msgstr ""
1822
-
1823
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1824
- msgid "Redirect After Purchase"
1825
- msgstr ""
1826
-
1827
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1828
- msgid "Redirect Link"
1829
- msgstr ""
1830
-
1831
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1832
- msgid "https://"
1833
- msgstr ""
1834
-
1835
- #: modules/widgets/class-cartflows-next-step.php:24
1836
- msgid "CartFlows Next Step"
1837
- msgstr ""
1838
-
1839
- #: modules/widgets/class-cartflows-next-step.php:26
1840
- msgid "Next Step Widgets"
1841
- msgstr ""
1842
-
1843
- #: modules/widgets/class-cartflows-next-step.php:106
1844
- msgid "New title"
1845
- msgstr ""
1846
-
1847
- #: modules/widgets/class-cartflows-next-step.php:123
1848
- msgid "Title:"
1849
- msgstr ""
1850
-
1851
- #: modules/widgets/class-cartflows-next-step.php:127
1852
- msgid "Flow ID:"
1853
- msgstr ""
1854
-
1855
- #: modules/widgets/class-cartflows-next-step.php:131
1856
- msgid "Step ID:"
1857
- msgstr ""
1858
-
1859
- #: woocommerce/template/cart/cart-shipping.php:51
1860
- #. Translators: $s shipping destination.
1861
- msgid "Estimate for %s."
1862
- msgstr ""
1863
-
1864
- #: woocommerce/template/cart/cart-shipping.php:52
1865
- msgid "Change address"
1866
- msgstr ""
1867
-
1868
- #: woocommerce/template/cart/cart-shipping.php:54
1869
- msgid "This is only an estimate. Prices will be updated during checkout."
1870
- msgstr ""
1871
-
1872
- #: woocommerce/template/cart/cart-shipping.php:61
1873
- msgid "Enter your address to view shipping options."
1874
- msgstr ""
1875
-
1876
- #: woocommerce/template/cart/cart-shipping.php:63
1877
- msgid ""
1878
- "There are no shipping methods available. Please ensure that your address "
1879
- "has been entered correctly, or contact us if you need any help."
1880
- msgstr ""
1881
-
1882
- #: woocommerce/template/cart/cart-shipping.php:66
1883
- #. Translators: $s shipping destination.
1884
- msgid "No shipping options were found for %s."
1885
- msgstr ""
1886
-
1887
- #: woocommerce/template/cart/cart-shipping.php:67
1888
- msgid "Enter a different address"
1889
- msgstr ""
1890
-
1891
- #: woocommerce/template/checkout/form-billing.php:27
1892
- msgid "Billing &amp; Shipping"
1893
- msgstr ""
1894
-
1895
- #: woocommerce/template/checkout/form-billing.php:31
1896
- msgid "Billing details"
1897
- msgstr ""
1898
-
1899
- #: woocommerce/template/checkout/form-billing.php:59
1900
- msgid "Create an account?"
1901
- msgstr ""
1902
-
1903
- #: woocommerce/template/checkout/form-checkout.php:26
1904
- msgid "You must be logged in to checkout."
1905
- msgstr ""
1906
-
1907
- #: woocommerce/template/checkout/form-checkout.php:52
1908
- msgid "Your order"
1909
- msgstr ""
1910
-
1911
- #: woocommerce/template/checkout/form-coupon.php:26
1912
- msgid "Have a coupon?"
1913
- msgstr ""
1914
-
1915
- #: woocommerce/template/checkout/form-coupon.php:26
1916
- msgid "Click here to enter your code"
1917
- msgstr ""
1918
-
1919
- #: woocommerce/template/checkout/form-coupon.php:31
1920
- msgid "If you have a coupon code, please apply it below."
1921
- msgstr ""
1922
-
1923
- #: woocommerce/template/checkout/form-coupon.php:34
1924
- msgid "Coupon code"
1925
- msgstr ""
1926
-
1927
- #: woocommerce/template/checkout/form-coupon.php:38
1928
- msgid "Apply coupon"
1929
- msgstr ""
1930
-
1931
- #: woocommerce/template/checkout/form-login.php:26
1932
- msgid "Returning customer?"
1933
- msgstr ""
1934
-
1935
- #: woocommerce/template/checkout/form-login.php:26
1936
- msgid "Click here to login"
1937
- msgstr ""
1938
-
1939
- #: woocommerce/template/checkout/form-login.php:32
1940
- msgid ""
1941
- "If you have shopped with us before, please enter your details below. If you "
1942
- "are a new customer, please proceed to the Billing &amp; Shipping section."
1943
- msgstr ""
1944
-
1945
- #: woocommerce/template/checkout/form-shipping.php:26
1946
- msgid "Ship to a different address?"
1947
- msgstr ""
1948
-
1949
- #: woocommerce/template/checkout/form-shipping.php:57
1950
- msgid "Additional information"
1951
- msgstr ""
1952
-
1953
- #: woocommerce/template/checkout/payment.php:33
1954
- msgid ""
1955
- "Sorry, it seems that there are no available payment methods for your state. "
1956
- "Please contact us if you require assistance or wish to make alternate "
1957
- "arrangements."
1958
- msgstr ""
1959
-
1960
- #: woocommerce/template/checkout/payment.php:33
1961
- msgid "Please fill in your details above to see available payment methods."
1962
- msgstr ""
1963
-
1964
- #: woocommerce/template/checkout/payment.php:42
1965
- #. translators: $1 and $2 opening and closing emphasis tags respectively
1966
- msgid ""
1967
- "Since your browser does not support JavaScript, or it is disabled, please "
1968
- "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1969
- "order. You may be charged more than the amount stated above if you fail to "
1970
- "do so."
1971
- msgstr ""
1972
-
1973
- #: woocommerce/template/checkout/payment.php:44
1974
- msgid "Update totals"
1975
- msgstr ""
1976
-
1977
- #: woocommerce/template/checkout/review-order.php:26
1978
- #: woocommerce/template/order/order-details.php:51
1979
- msgid "Product"
1980
- msgstr ""
1981
-
1982
- #: woocommerce/template/checkout/review-order.php:27
1983
- #: woocommerce/template/checkout/review-order.php:107
1984
- #: woocommerce/template/order/order-details.php:52
1985
- msgid "Total"
1986
- msgstr ""
1987
-
1988
- #: woocommerce/template/checkout/review-order.php:60
1989
- msgid "Subtotal"
1990
- msgstr ""
1991
-
1992
- #: woocommerce/template/checkout/thankyou.php:30
1993
- msgid ""
1994
- "Unfortunately your order cannot be processed as the originating "
1995
- "bank/merchant has declined your transaction. Please attempt your purchase "
1996
- "again."
1997
- msgstr ""
1998
-
1999
- #: woocommerce/template/checkout/thankyou.php:33
2000
- msgid "Pay"
2001
- msgstr ""
2002
-
2003
- #: woocommerce/template/checkout/thankyou.php:35
2004
- msgid "My account"
2005
- msgstr ""
2006
-
2007
- #: woocommerce/template/checkout/thankyou.php:46
2008
- msgid "Order number:"
2009
- msgstr ""
2010
-
2011
- #: woocommerce/template/checkout/thankyou.php:51
2012
- msgid "Date:"
2013
- msgstr ""
2014
-
2015
- #: woocommerce/template/checkout/thankyou.php:57
2016
- msgid "Email:"
2017
- msgstr ""
2018
-
2019
- #: woocommerce/template/checkout/thankyou.php:63
2020
- msgid "Total:"
2021
- msgstr ""
2022
-
2023
- #: woocommerce/template/checkout/thankyou.php:69
2024
- msgid "Payment method:"
2025
- msgstr ""
2026
-
2027
- #: woocommerce/template/global/form-login.php:34
2028
- msgid "Username or email"
2029
- msgstr ""
2030
-
2031
- #: woocommerce/template/global/form-login.php:38
2032
- msgid "Password"
2033
- msgstr ""
2034
-
2035
- #: woocommerce/template/global/form-login.php:48
2036
- msgid "Login"
2037
- msgstr ""
2038
-
2039
- #: woocommerce/template/global/form-login.php:53
2040
- msgid "Remember me"
2041
- msgstr ""
2042
-
2043
- #: woocommerce/template/global/form-login.php:57
2044
- msgid "Lost your password?"
2045
- msgstr ""
2046
-
2047
- #: woocommerce/template/order/order-details.php:45
2048
- msgid "Order details"
2049
- msgstr ""
2050
-
2051
- #: woocommerce/template/order/order-details.php:93
2052
- msgid "Note:"
2053
- msgstr ""
2054
-
2055
- #. Plugin Name of the plugin/theme
2056
- msgid "CartFlows"
2057
- msgstr ""
2058
-
2059
- #. Author URI of the plugin/theme
2060
- msgid "https://cartflows.com/"
2061
- msgstr ""
2062
-
2063
- #. Description of the plugin/theme
2064
- msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2065
- msgstr ""
2066
-
2067
- #. Author of the plugin/theme
2068
- msgid "CartFlows Inc"
2069
- msgstr ""
2070
-
2071
- #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2072
- msgctxt "flow general name"
2073
- msgid "Flows"
2074
- msgstr ""
2075
-
2076
- #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2077
- msgctxt "flow singular name"
2078
- msgid "Flow"
2079
- msgstr ""
2080
-
2081
- #: modules/flow/classes/class-cartflows-step-post-type.php:161
2082
- msgctxt "flow step general name"
2083
- msgid "Steps"
2084
- msgstr ""
2085
-
2086
- #: modules/flow/classes/class-cartflows-step-post-type.php:162
2087
- msgctxt "flow step singular name"
2088
- msgid "Step"
2089
- msgstr ""
2090
-
2091
- #: modules/flow/classes/class-cartflows-step-post-type.php:315
2092
- msgctxt "cartflows"
2093
- msgid "CartFlows — Boxed"
2094
- msgstr ""
2095
-
2096
- #: modules/flow/classes/class-cartflows-step-post-type.php:316
2097
- msgctxt "cartflows"
2098
- msgid "Template for Page Builders"
2099
  msgstr ""
1
+ # Copyright (C) 2020 CartFlows Inc
2
+ # This file is distributed under the same license as the CartFlows package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: CartFlows 1.5.12\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-07-01 06:22:56+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=utf-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "Language: en\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-Country: United States\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-KeywordsList: "
19
+ "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
+ "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
+ "X-Poedit-Basepath: ../\n"
22
+ "X-Poedit-SearchPath-0: .\n"
23
+ "X-Poedit-Bookmarks: \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 ""
74
+
75
+ #: classes/batch-process/class-cartflows-importer-elementor.php:56
76
+ msgid "Invalid content. Expected an array."
77
+ msgstr ""
78
+
79
+ #: classes/batch-process/helpers/class-wp-background-process.php:435
80
+ msgid "Every %d Minutes"
81
+ msgstr ""
82
+
83
+ #: classes/class-cartflows-admin-fields.php:235
84
+ msgid "Select"
85
+ msgstr ""
86
+
87
+ #: classes/class-cartflows-admin-fields.php:238
88
+ msgid "No Checkout Steps"
89
+ msgstr ""
90
+
91
+ #: classes/class-cartflows-admin-fields.php:264
92
+ #. translators: %s: link
93
+ msgid ""
94
+ "Be sure not to add any product in above selected Global Checkout step. "
95
+ "Please read information about how to set up Global Checkout %1$shere%2$s."
96
+ msgstr ""
97
+
98
+ #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
99
+ #: includes/admin/cartflows-general-bck.php:34
100
+ #: modules/optin/classes/class-cartflows-optin-meta.php:150
101
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
102
+ msgid "Settings"
103
+ msgstr ""
104
+
105
+ #: classes/class-cartflows-admin.php:440
106
+ msgid "Installing and activating.."
107
+ msgstr ""
108
+
109
+ #: classes/class-cartflows-admin.php:441
110
+ msgid "There was an error with the installation of plugin."
111
+ msgstr ""
112
+
113
+ #: classes/class-cartflows-admin.php:495
114
+ msgid "Flows Library"
115
+ msgstr ""
116
+
117
+ #: classes/class-cartflows-admin.php:502
118
+ #: modules/flow/view/meta-flow-steps.php:156
119
+ msgid "Ready Templates"
120
+ msgstr ""
121
+
122
+ #: classes/class-cartflows-admin.php:505
123
+ #: modules/flow/view/meta-flow-steps.php:159
124
+ msgid "Create Your Own"
125
+ msgstr ""
126
+
127
+ #: classes/class-cartflows-admin.php:516
128
+ #: modules/flow/view/meta-flow-steps.php:171
129
+ msgid "Search Sites"
130
+ msgstr ""
131
+
132
+ #: classes/class-cartflows-admin.php:517
133
+ #: modules/flow/view/meta-flow-steps.php:172
134
+ msgid "Search Flow..."
135
+ msgstr ""
136
+
137
+ #: classes/class-cartflows-admin.php:534
138
+ msgid "Design Your Flow"
139
+ msgstr ""
140
+
141
+ #: classes/class-cartflows-admin.php:535
142
+ #: classes/class-cartflows-importer.php:665
143
+ #: classes/class-cartflows-importer.php:764
144
+ #: modules/flow/view/meta-flow-steps.php:202
145
+ msgid "Learn How"
146
+ msgstr ""
147
+
148
+ #: classes/class-cartflows-api.php:369
149
+ msgid "Request successfully processed!"
150
+ msgstr ""
151
+
152
+ #: classes/class-cartflows-cloning.php:423
153
+ msgid "Clone this flow"
154
+ msgstr ""
155
+
156
+ #: classes/class-cartflows-cloning.php:423
157
+ #: modules/flow/view/meta-flow-steps.php:115
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
+
166
+ #: classes/class-cartflows-flow-frontend.php:53
167
+ msgid ""
168
+ "Test mode is active — which displays random products for previewing. It can "
169
+ "be deactivated from the flow settings in the admin dashboard."
170
+ msgstr ""
171
+
172
+ #: classes/class-cartflows-flow-frontend.php:58
173
+ msgid "Click here to disable it"
174
+ msgstr ""
175
+
176
+ #: classes/class-cartflows-importer.php:81
177
+ msgid "Export this flow"
178
+ msgstr ""
179
+
180
+ #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
181
+ msgid "Export"
182
+ msgstr ""
183
+
184
+ #: classes/class-cartflows-importer.php:92
185
+ msgid "Flow Export"
186
+ msgstr ""
187
+
188
+ #: classes/class-cartflows-importer.php:93
189
+ msgid "Flow Import"
190
+ msgstr ""
191
+
192
+ #: classes/class-cartflows-importer.php:104
193
+ msgid "No post to export has been supplied!"
194
+ msgstr ""
195
+
196
+ #: classes/class-cartflows-importer.php:278
197
+ msgid "Please upload a valid .json file"
198
+ msgstr ""
199
+
200
+ #: classes/class-cartflows-importer.php:284
201
+ msgid "Please upload a file to import"
202
+ msgstr ""
203
+
204
+ #: classes/class-cartflows-importer.php:506
205
+ msgid "Successfully imported flows."
206
+ msgstr ""
207
+
208
+ #: classes/class-cartflows-importer.php:538
209
+ msgid "Loading Steps"
210
+ msgstr ""
211
+
212
+ #: classes/class-cartflows-importer.php:540
213
+ msgid "Getting steps from the cloud. Please wait for the moment."
214
+ msgstr ""
215
+
216
+ #: classes/class-cartflows-importer.php:551
217
+ msgid "Searching Template.."
218
+ msgstr ""
219
+
220
+ #: classes/class-cartflows-importer.php:553
221
+ msgid "Getting templates from the cloud. Please wait for the moment."
222
+ msgstr ""
223
+
224
+ #: classes/class-cartflows-importer.php:562
225
+ msgid "Importing.."
226
+ msgstr ""
227
+
228
+ #: classes/class-cartflows-importer.php:571
229
+ #: classes/class-cartflows-importer.php:611
230
+ msgid "Imported"
231
+ msgstr ""
232
+
233
+ #: classes/class-cartflows-importer.php:572
234
+ #: classes/class-cartflows-importer.php:612
235
+ msgid "Thanks for patience"
236
+ msgstr ""
237
+
238
+ #: classes/class-cartflows-importer.php:581
239
+ #: classes/class-cartflows-importer.php:593
240
+ msgid "Coming Soon!"
241
+ msgstr ""
242
+
243
+ #: classes/class-cartflows-importer.php:612
244
+ msgid "Redirecting to the Elementor edit window."
245
+ msgstr ""
246
+
247
+ #: classes/class-cartflows-importer.php:658
248
+ #: classes/class-cartflows-importer.php:774
249
+ msgid "Pro"
250
+ msgstr ""
251
+
252
+ #: classes/class-cartflows-importer.php:699
253
+ #: classes/class-cartflows-importer.php:806
254
+ msgid "Activate License"
255
+ msgstr ""
256
+
257
+ #: classes/class-cartflows-importer.php:701
258
+ #: classes/class-cartflows-importer.php:808
259
+ #: modules/flow/classes/class-cartflows-flow-meta.php:474
260
+ msgid "Get Pro"
261
+ msgstr ""
262
+
263
+ #: classes/class-cartflows-importer.php:726
264
+ msgid "Create"
265
+ msgstr ""
266
+
267
+ #: classes/class-cartflows-importer.php:825
268
+ msgid "Under Maintenance.."
269
+ msgstr ""
270
+
271
+ #: classes/class-cartflows-importer.php:826
272
+ msgid ""
273
+ "If you are seeing this message, most likely our servers are under routine "
274
+ "maintenance and we will be back shortly."
275
+ msgstr ""
276
+
277
+ #: classes/class-cartflows-importer.php:827
278
+ msgid ""
279
+ "In rare case, it is possible your website is having trouble connecting with "
280
+ "ours. If you need help, please feel free to get in touch with us from our "
281
+ "website.."
282
+ msgstr ""
283
+
284
+ #: classes/class-cartflows-importer.php:857
285
+ #. translators: %s: Plugin string
286
+ msgid ""
287
+ "%1$s to see CartFlows templates. If you prefer another page builder tool, "
288
+ "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
289
+ msgstr ""
290
+
291
+ #: classes/class-cartflows-importer.php:872
292
+ msgid "All"
293
+ msgstr ""
294
+
295
+ #: classes/class-cartflows-importer.php:875
296
+ msgid "Select Step Type"
297
+ msgstr ""
298
+
299
+ #: classes/class-cartflows-importer.php:959
300
+ msgid "Import from Cloud"
301
+ msgstr ""
302
+
303
+ #: classes/class-cartflows-importer.php:1267
304
+ msgid "Sales Landing"
305
+ msgstr ""
306
+
307
+ #: classes/class-cartflows-importer.php:1271
308
+ #: modules/flow/classes/class-cartflows-step-post-type.php:253
309
+ #: modules/flow/view/meta-flow-steps.php:12
310
+ msgid "Checkout (Woo)"
311
+ msgstr ""
312
+
313
+ #: classes/class-cartflows-importer.php:1275
314
+ #: modules/flow/classes/class-cartflows-step-post-type.php:260
315
+ #: modules/flow/view/meta-flow-steps.php:13
316
+ msgid "Thank You (Woo)"
317
+ msgstr ""
318
+
319
+ #: classes/class-cartflows-importer.php:1283
320
+ #: modules/flow/classes/class-cartflows-step-post-type.php:239
321
+ #: modules/flow/view/meta-flow-steps.php:11
322
+ msgid "Landing"
323
+ msgstr ""
324
+
325
+ #: classes/class-cartflows-importer.php:1287
326
+ msgid "Thank You"
327
+ msgstr ""
328
+
329
+ #: classes/class-cartflows-importer.php:1397
330
+ #. translators: %s: template ID
331
+ msgid "Invalid template id %1$s or post id %2$s."
332
+ msgstr ""
333
+
334
+ #: classes/class-cartflows-importer.php:1472
335
+ #. translators: %s: flow ID
336
+ msgid "Invalid flow id %1$s OR step type %2$s."
337
+ msgstr ""
338
+
339
+ #: classes/class-cartflows-importer.php:1597
340
+ msgid ""
341
+ "Elementor is not activated. Please activate plugin Elementor Page Builder "
342
+ "to import the step."
343
+ msgstr ""
344
+
345
+ #: classes/class-cartflows-importer.php:1700
346
+ msgid "Action failed. Invalid Security Nonce."
347
+ msgstr ""
348
+
349
+ #: classes/class-cartflows-importer.php:1707
350
+ msgid "User have not plugin install permissions."
351
+ msgstr ""
352
+
353
+ #: classes/class-cartflows-importer.php:1729
354
+ msgid "Plugin Successfully Activated"
355
+ msgstr ""
356
+
357
+ #: classes/class-cartflows-learndash-compatibility.php:86
358
+ msgid "None"
359
+ msgstr ""
360
+
361
+ #: classes/class-cartflows-learndash-compatibility.php:113
362
+ #. translators: 1: anchor start, 2: anchor close
363
+ msgid ""
364
+ "Non-enrolled students will redirect to the selected CartFlows template. If "
365
+ "you have not created any Flow already, add new Flow from %1$shere%2$s."
366
+ msgstr ""
367
+
368
+ #: classes/class-cartflows-learndash-compatibility.php:119
369
+ msgid "Select CartFlows Template for this Course"
370
+ msgstr ""
371
+
372
+ #: classes/class-cartflows-loader.php:222
373
+ #. translators: %s: html tags
374
+ msgid ""
375
+ "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
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
+
394
+ #: classes/class-cartflows-logger.php:161
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
+
443
+ #: classes/class-cartflows-meta.php:34
444
+ msgid "Update"
445
+ msgstr ""
446
+
447
+ #: classes/class-cartflows-meta.php:42
448
+ #: modules/flow/classes/class-cartflows-flow-meta.php:95
449
+ #: modules/flow/classes/class-cartflows-flow-meta.php:733
450
+ msgid "Back to edit Flow"
451
+ msgstr ""
452
+
453
+ #: classes/class-cartflows-meta.php:63
454
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
455
+ #: modules/landing/classes/class-cartflows-landing-meta.php:136
456
+ #: modules/optin/classes/class-cartflows-optin-meta.php:156
457
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
458
+ msgid "Custom Script"
459
+ msgstr ""
460
+
461
+ #: classes/class-cartflows-meta.php:66
462
+ msgid ""
463
+ "Custom script lets you add your own custom script on front end of this flow "
464
+ "page."
465
+ msgstr ""
466
+
467
+ #: classes/class-cartflows-metabox.php:59
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."
670
+ msgstr ""
671
+
672
+ #: classes/logger/class-cartflows-wc-logger.php:58
673
+ #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
674
+ msgid "The provided handler %1$s does not implement %2$s."
675
+ msgstr ""
676
+
677
+ #: classes/logger/class-cartflows-wc-logger.php:136
678
+ #. translators: 1: Cartflows_WC_Logger::log 2: level
679
+ msgid "%1$s was called with an invalid level \"%2$s\"."
680
+ msgstr ""
681
+
682
+ #: includes/admin/cartflows-admin.php:19
683
+ #: includes/admin/cartflows-general.php:48
684
+ msgid "Modernizing WordPress eCommerce!"
685
+ msgstr ""
686
+
687
+ #: includes/admin/cartflows-admin.php:29
688
+ msgid "Settings saved successfully."
689
+ msgstr ""
690
+
691
+ #: includes/admin/cartflows-error-log.php:36
692
+ msgid "%1$s at %2$s"
693
+ msgstr ""
694
+
695
+ #: includes/admin/cartflows-error-log.php:41
696
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:225
697
+ #: modules/flow/view/meta-flow-steps.php:104
698
+ msgid "View"
699
+ msgstr ""
700
+
701
+ #: includes/admin/cartflows-error-log.php:65
702
+ msgid "Delete log"
703
+ msgstr ""
704
+
705
+ #: includes/admin/cartflows-error-log.php:70
706
+ msgid "There are currently no logs to view."
707
+ msgstr ""
708
+
709
+ #: includes/admin/cartflows-general-bck.php:10
710
+ msgid "Selec"
711
+ msgstr ""
712
+
713
+ #: includes/admin/cartflows-general-bck.php:22
714
+ msgid "General"
715
+ msgstr ""
716
+
717
+ #: includes/admin/cartflows-general.php:31
718
+ #: includes/admin/cartflows-general.php:58
719
+ msgid "General Settings"
720
+ msgstr ""
721
+
722
+ #: includes/admin/cartflows-general.php:40
723
+ msgid "Getting Started"
724
+ msgstr ""
725
+
726
+ #: includes/admin/cartflows-general.php:71
727
+ msgid "Disallow search engines from indexing flows"
728
+ msgstr ""
729
+
730
+ #: includes/admin/cartflows-general.php:81
731
+ #: modules/flow/view/meta-flow-steps.php:93
732
+ msgid "Global Checkout"
733
+ msgstr ""
734
+
735
+ #: includes/admin/cartflows-general.php:90
736
+ msgid "Show Templates designed with"
737
+ msgstr ""
738
+
739
+ #: includes/admin/cartflows-general.php:91
740
+ msgid ""
741
+ "CartFlows offers flow templates that can be imported in one click. These "
742
+ "templates are available in few different page builders. Please choose your "
743
+ "preferred page builder from the list so you will only see templates that "
744
+ "are made using that page builder.."
745
+ msgstr ""
746
+
747
+ #: includes/admin/cartflows-general.php:95
748
+ msgid "Beaver Builder"
749
+ msgstr ""
750
+
751
+ #: includes/admin/cartflows-general.php:107
752
+ #: includes/admin/cartflows-general.php:193
753
+ #: includes/admin/cartflows-general.php:299
754
+ #: includes/admin/cartflows-general.php:416
755
+ msgid "Save Changes"
756
+ msgstr ""
757
+
758
+ #: includes/admin/cartflows-general.php:119
759
+ msgid "Permalink Settings"
760
+ msgstr ""
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
+
768
+ #: includes/admin/cartflows-general.php:140
769
+ msgid "Flow and Step Slug"
770
+ msgstr ""
771
+
772
+ #: includes/admin/cartflows-general.php:146
773
+ msgid "Flow Slug"
774
+ msgstr ""
775
+
776
+ #: includes/admin/cartflows-general.php:152
777
+ msgid "Step Slug"
778
+ msgstr ""
779
+
780
+ #: includes/admin/cartflows-general.php:164
781
+ msgid "Post Type Permalink Base"
782
+ msgstr ""
783
+
784
+ #: includes/admin/cartflows-general.php:172
785
+ msgid "Step Base"
786
+ msgstr ""
787
+
788
+ #: includes/admin/cartflows-general.php:182
789
+ msgid "Flow Base"
790
+ msgstr ""
791
+
792
+ #: includes/admin/cartflows-general.php:194
793
+ msgid "Set Default"
794
+ msgstr ""
795
+
796
+ #: includes/admin/cartflows-general.php:208
797
+ msgid "Facebook Pixel Settings"
798
+ msgstr ""
799
+
800
+ #: includes/admin/cartflows-general.php:223
801
+ msgid "Enable Facebook Pixel Tracking"
802
+ msgstr ""
803
+
804
+ #: includes/admin/cartflows-general.php:236
805
+ msgid "Enable for the whole site"
806
+ msgstr ""
807
+
808
+ #: includes/admin/cartflows-general.php:244
809
+ #: includes/admin/cartflows-general.php:343
810
+ msgid "If this option is unchecked, it will only apply to CartFlows steps."
811
+ msgstr ""
812
+
813
+ #: includes/admin/cartflows-general.php:254
814
+ msgid "Enter Facebook pixel ID"
815
+ msgstr ""
816
+
817
+ #: includes/admin/cartflows-general.php:262
818
+ #: includes/admin/cartflows-general.php:361
819
+ msgid "Enable Events:"
820
+ msgstr ""
821
+
822
+ #: includes/admin/cartflows-general.php:271
823
+ msgid "Initiate Checkout"
824
+ msgstr ""
825
+
826
+ #: includes/admin/cartflows-general.php:280
827
+ #: includes/admin/cartflows-general.php:387
828
+ msgid "Add Payment Info"
829
+ msgstr ""
830
+
831
+ #: includes/admin/cartflows-general.php:289
832
+ msgid "Purchase Complete"
833
+ msgstr ""
834
+
835
+ #: includes/admin/cartflows-general.php:311
836
+ msgid "Google Analytics Settings"
837
+ msgstr ""
838
+
839
+ #: includes/admin/cartflows-general.php:322
840
+ msgid "Enable Google Analytics Tracking"
841
+ msgstr ""
842
+
843
+ #: includes/admin/cartflows-general.php:335
844
+ msgid "Enable for the whole website"
845
+ msgstr ""
846
+
847
+ #: includes/admin/cartflows-general.php:353
848
+ msgid "Google Analytics ID"
849
+ msgstr ""
850
+
851
+ #: includes/admin/cartflows-general.php:355
852
+ msgid ""
853
+ "Log into your <a href=\"https://analytics.google.com/\" "
854
+ "target=\"_blank\">google analytics account</a> to find your ID. eg: "
855
+ "UA-XXXXXX-X&period;"
856
+ msgstr ""
857
+
858
+ #: includes/admin/cartflows-general.php:369
859
+ msgid "Begin Checkout"
860
+ msgstr ""
861
+
862
+ #: includes/admin/cartflows-general.php:378
863
+ msgid "Add To Cart"
864
+ msgstr ""
865
+
866
+ #: includes/admin/cartflows-general.php:396
867
+ msgid "Purchase"
868
+ msgstr ""
869
+
870
+ #: includes/admin/cartflows-general.php:404
871
+ msgid ""
872
+ "Google Analytics not working correctly? <a "
873
+ "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
874
+ "issues/\" > Click here </a> to know more. "
875
+ msgstr ""
876
+
877
+ #: includes/admin/cartflows-general.php:437
878
+ msgid "Knowledge Base"
879
+ msgstr ""
880
+
881
+ #: includes/admin/cartflows-general.php:441
882
+ msgid "Not sure how something works? Take a peek at the knowledge base and learn."
883
+ msgstr ""
884
+
885
+ #: includes/admin/cartflows-general.php:444
886
+ msgid "Visit Knowledge Base »"
887
+ msgstr ""
888
+
889
+ #: includes/admin/cartflows-general.php:452
890
+ msgid "Community"
891
+ msgstr ""
892
+
893
+ #: includes/admin/cartflows-general.php:456
894
+ msgid ""
895
+ "Join the community of super helpful CartFlows users. Say hello, ask "
896
+ "questions, give feedback and help each other!"
897
+ msgstr ""
898
+
899
+ #: includes/admin/cartflows-general.php:459
900
+ msgid "Join Our Facebook Group »"
901
+ msgstr ""
902
+
903
+ #: includes/admin/cartflows-general.php:467
904
+ msgid "Five Star Support"
905
+ msgstr ""
906
+
907
+ #: includes/admin/cartflows-general.php:471
908
+ msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
909
+ msgstr ""
910
+
911
+ #: includes/admin/cartflows-general.php:474
912
+ msgid "Submit a Ticket »"
913
+ msgstr ""
914
+
915
+ #: includes/admin/cartflows-general.php:484
916
+ msgid "Load Minified CSS"
917
+ msgstr ""
918
+
919
+ #: includes/admin/cartflows-general.php:489
920
+ msgid ""
921
+ "Load the Minified CSS from here. Just Enable it by checking the below given "
922
+ "checkbox."
923
+ msgstr ""
924
+
925
+ #: includes/admin/cartflows-general.php:496
926
+ msgid "Load minified CSS & JS Files"
927
+ msgstr ""
928
+
929
+ #: includes/admin/cartflows-general.php:501
930
+ msgid "Save"
931
+ msgstr ""
932
+
933
+ #: includes/exporter.php:12
934
+ msgid "Export Flows to a JSON file"
935
+ msgstr ""
936
+
937
+ #: includes/exporter.php:13
938
+ msgid ""
939
+ "This tool allows you to generate and download a JSON file containing a list "
940
+ "of all flows."
941
+ msgstr ""
942
+
943
+ #: includes/importer.php:12
944
+ msgid "Import Flows to a JSON file"
945
+ msgstr ""
946
+
947
+ #: includes/importer.php:13
948
+ msgid "This tool allows you to import the flows from the JSON file."
949
+ msgstr ""
950
+
951
+ #: includes/importer.php:21
952
+ msgid "Import"
953
+ msgstr ""
954
+
955
+ #: includes/meta-fields/generate-product-repeater.php:36
956
+ msgid "Remove"
957
+ msgstr ""
958
+
959
+ #: includes/meta-fields/generate-product-repeater.php:51
960
+ msgid "Product Quantity"
961
+ msgstr ""
962
+
963
+ #: includes/meta-fields/generate-product-repeater.php:65
964
+ msgid "Discount Type"
965
+ msgstr ""
966
+
967
+ #: includes/meta-fields/generate-product-repeater.php:69
968
+ msgid "Select Discount Type"
969
+ msgstr ""
970
+
971
+ #: includes/meta-fields/generate-product-repeater.php:70
972
+ msgid "Original"
973
+ msgstr ""
974
+
975
+ #: includes/meta-fields/generate-product-repeater.php:71
976
+ msgid "Percentage"
977
+ msgstr ""
978
+
979
+ #: includes/meta-fields/generate-product-repeater.php:72
980
+ msgid "Price"
981
+ msgstr ""
982
+
983
+ #: includes/meta-fields/generate-product-repeater.php:83
984
+ msgid "Discount Value"
985
+ msgstr ""
986
+
987
+ #: includes/meta-fields/generate-product-repeater.php:85
988
+ msgid "Discount value will apply for each quantity of product."
989
+ msgstr ""
990
+
991
+ #: includes/meta-fields/get-product-selection-repeater.php:112
992
+ msgid "Add New Product"
993
+ msgstr ""
994
+
995
+ #: includes/meta-fields/get-product-selection-repeater.php:113
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 ""
1003
+ "WooCommerce functions do not exist. If you are in an IFrame, please reload "
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
+
1064
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1065
+ msgid "Checkout Layout"
1066
+ msgstr ""
1067
+
1068
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1069
+ #: modules/landing/classes/class-cartflows-landing-meta.php:130
1070
+ #: modules/optin/classes/class-cartflows-optin-meta.php:126
1071
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1072
+ msgid "Shortcodes"
1073
+ msgstr ""
1074
+
1075
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1076
+ #: modules/optin/classes/class-cartflows-optin-meta.php:132
1077
+ msgid "Select Product"
1078
+ msgstr ""
1079
+
1080
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1081
+ msgid "Product Options"
1082
+ msgstr ""
1083
+
1084
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1085
+ msgid "Order Bump"
1086
+ msgstr ""
1087
+
1088
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1089
+ msgid "Checkout Offer"
1090
+ msgstr ""
1091
+
1092
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1093
+ msgid "Checkout Design"
1094
+ msgstr ""
1095
+
1096
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1097
+ msgid "Checkout Fields"
1098
+ msgstr ""
1099
+
1100
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1101
+ msgid "Checkout Settings"
1102
+ msgstr ""
1103
+
1104
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1105
+ msgid "Logo (Optional)"
1106
+ msgstr ""
1107
+
1108
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1109
+ #. translators: %s: link
1110
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1111
+ msgstr ""
1112
+
1113
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1114
+ #. translators: %s: link.
1115
+ msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1116
+ msgstr ""
1117
+
1118
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1119
+ msgid "Add this shortcode to your checkout page"
1120
+ msgstr ""
1121
+
1122
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1123
+ #. translators: %s: link
1124
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1125
+ msgstr ""
1126
+
1127
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1128
+ #. translators: %s: link
1129
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1130
+ msgstr ""
1131
+
1132
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1133
+ #. translators: %s: link
1134
+ msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1135
+ msgstr ""
1136
+
1137
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1138
+ #. translators: %s: link
1139
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1140
+ msgstr ""
1141
+
1142
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1143
+ #. translators: %s: link
1144
+ msgid ""
1145
+ "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1146
+ "feature"
1147
+ msgstr ""
1148
+
1149
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1150
+ #. translators: %s: link
1151
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
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 ""
1159
+
1160
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1161
+ msgid "Place Order Button Text"
1162
+ msgstr ""
1163
+
1164
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1165
+ msgid "Place order"
1166
+ msgstr ""
1167
+
1168
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1169
+ msgid "It will change the Place Order Button text on checkout page."
1170
+ msgstr ""
1171
+
1172
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1173
+ msgid "Enable cart editing on checkout"
1174
+ msgstr ""
1175
+
1176
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1177
+ #. translators: %s: link
1178
+ msgid "Users will able to remove products from the checkout page."
1179
+ msgstr ""
1180
+
1181
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1182
+ msgid "One Column (Available in CartFlows Pro) "
1183
+ msgstr ""
1184
+
1185
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1186
+ msgid "Two Step (Available in CartFlows Pro) "
1187
+ msgstr ""
1188
+
1189
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1190
+ msgid "Checkout Skin"
1191
+ msgstr ""
1192
+
1193
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1194
+ msgid "One Column"
1195
+ msgstr ""
1196
+
1197
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1198
+ msgid "Two Column"
1199
+ msgstr ""
1200
+
1201
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1202
+ msgid "Two Step"
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
+
1210
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
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"
1220
+ msgstr ""
1221
+
1222
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1223
+ msgid "Advance Options"
1224
+ msgstr ""
1225
+
1226
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1227
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1228
+ msgid "Heading"
1229
+ msgstr ""
1230
+
1231
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1232
+ msgid "Heading Color"
1233
+ msgstr ""
1234
+
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
+
1351
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1352
+ msgid "Buttons"
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
+
1375
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1376
+ msgid "Sections"
1377
+ msgstr ""
1378
+
1379
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1380
+ msgid "Highlight Area Background Color"
1381
+ msgstr ""
1382
+
1383
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1384
+ msgid "Header Logo"
1385
+ msgstr ""
1386
+
1387
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1388
+ msgid "Logo Width (In px)"
1389
+ msgstr ""
1390
+
1391
+ #: modules/checkout/templates/wcf-template.php:46
1392
+ msgid "Copyright &copy;"
1393
+ msgstr ""
1394
+
1395
+ #: modules/checkout/templates/wcf-template.php:50
1396
+ msgid "All Rights Reserved"
1397
+ msgstr ""
1398
+
1399
+ #: modules/flow/classes/class-cartflows-flow-meta.php:263
1400
+ #. translators: %s flow id
1401
+ msgid "Step not deleted for flow - %s"
1402
+ msgstr ""
1403
+
1404
+ #: modules/flow/classes/class-cartflows-flow-meta.php:294
1405
+ #. translators: %s flow id
1406
+ msgid "Step deleted for flow - %s"
1407
+ msgstr ""
1408
+
1409
+ #: modules/flow/classes/class-cartflows-flow-meta.php:322
1410
+ #. translators: %s flow id
1411
+ msgid "Steps not sorted for flow - %s"
1412
+ msgstr ""
1413
+
1414
+ #: modules/flow/classes/class-cartflows-flow-meta.php:345
1415
+ #. translators: %s flow id
1416
+ msgid "Steps sorted for flow - %s"
1417
+ msgstr ""
1418
+
1419
+ #: modules/flow/classes/class-cartflows-flow-meta.php:456
1420
+ msgid "Analytics"
1421
+ msgstr ""
1422
+
1423
+ #: modules/flow/classes/class-cartflows-flow-meta.php:473
1424
+ #. translators: %s: link
1425
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1426
+ msgstr ""
1427
+
1428
+ #: modules/flow/classes/class-cartflows-flow-meta.php:491
1429
+ msgid "Flow Settings"
1430
+ msgstr ""
1431
+
1432
+ #: modules/flow/classes/class-cartflows-flow-meta.php:576
1433
+ msgid "Enable Test Mode"
1434
+ msgstr ""
1435
+
1436
+ #: modules/flow/classes/class-cartflows-flow-meta.php:583
1437
+ msgid ""
1438
+ "If you are using WooCommerce plugin then test mode will add random products "
1439
+ "in your flow, so you can preview it easily while testing."
1440
+ msgstr ""
1441
+
1442
+ #: modules/flow/classes/class-cartflows-flow-meta.php:702
1443
+ #: modules/flow/view/meta-flow-steps.php:133
1444
+ msgid "Add New Step"
1445
+ msgstr ""
1446
+
1447
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1448
+ msgid "Flow: "
1449
+ msgstr ""
1450
+
1451
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1452
+ msgid "Name: "
1453
+ msgstr ""
1454
+
1455
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1456
+ msgid "Search Flows"
1457
+ msgstr ""
1458
+
1459
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1460
+ msgid "All Flows"
1461
+ msgstr ""
1462
+
1463
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1464
+ msgid "Edit Flow"
1465
+ msgstr ""
1466
+
1467
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1468
+ msgid "View Flow"
1469
+ msgstr ""
1470
+
1471
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1472
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1473
+ #: modules/flow/classes/class-cartflows-step-post-type.php:167
1474
+ #: modules/flow/classes/class-cartflows-step-post-type.php:169
1475
+ msgid "Add New"
1476
+ msgstr ""
1477
+
1478
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1479
+ msgid "Update Flow"
1480
+ msgstr ""
1481
+
1482
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1483
+ msgid "New Flow Name"
1484
+ msgstr ""
1485
+
1486
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1487
+ msgid "Upgrade to CartFlows Pro"
1488
+ msgstr ""
1489
+
1490
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1491
+ msgid "Slug"
1492
+ msgstr ""
1493
+
1494
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1495
+ msgid "Flows"
1496
+ msgstr ""
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 ""
1554
+
1555
+ #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1556
+ #: modules/widgets/class-cartflows-next-step.php:78
1557
+ msgid "Next Step"
1558
+ msgstr ""
1559
+
1560
+ #: modules/flow/classes/class-cartflows-step-post-type.php:163
1561
+ msgid "Search Steps"
1562
+ msgstr ""
1563
+
1564
+ #: modules/flow/classes/class-cartflows-step-post-type.php:164
1565
+ msgid "All Steps"
1566
+ msgstr ""
1567
+
1568
+ #: modules/flow/classes/class-cartflows-step-post-type.php:165
1569
+ #: modules/flow/view/meta-flow-steps.php:106
1570
+ msgid "Edit Step"
1571
+ msgstr ""
1572
+
1573
+ #: modules/flow/classes/class-cartflows-step-post-type.php:166
1574
+ #: modules/flow/view/meta-flow-steps.php:102
1575
+ msgid "View Step"
1576
+ msgstr ""
1577
+
1578
+ #: modules/flow/classes/class-cartflows-step-post-type.php:168
1579
+ msgid "Update Step"
1580
+ msgstr ""
1581
+
1582
+ #: modules/flow/classes/class-cartflows-step-post-type.php:170
1583
+ msgid "New Step Name"
1584
+ msgstr ""
1585
+
1586
+ #: modules/flow/classes/class-cartflows-step-post-type.php:211
1587
+ msgid "Step Type"
1588
+ msgstr ""
1589
+
1590
+ #: modules/flow/classes/class-cartflows-step-post-type.php:221
1591
+ msgid "Step Flow"
1592
+ msgstr ""
1593
+
1594
+ #: modules/flow/classes/class-cartflows-step-post-type.php:246
1595
+ #: modules/flow/view/meta-flow-steps.php:16
1596
+ msgid "Optin (Woo)"
1597
+ msgstr ""
1598
+
1599
+ #: modules/flow/classes/class-cartflows-step-post-type.php:267
1600
+ #: modules/flow/view/meta-flow-steps.php:14
1601
+ msgid "Upsell (Woo)"
1602
+ msgstr ""
1603
+
1604
+ #: modules/flow/classes/class-cartflows-step-post-type.php:274
1605
+ #: modules/flow/view/meta-flow-steps.php:15
1606
+ msgid "Downsell (Woo)"
1607
+ msgstr ""
1608
+
1609
+ #: modules/flow/view/meta-flow-steps.php:85
1610
+ msgid "No Product Assigned"
1611
+ msgstr ""
1612
+
1613
+ #: modules/flow/view/meta-flow-steps.php:89
1614
+ msgid "Global Checkout - Remove selected checkout product"
1615
+ msgstr ""
1616
+
1617
+ #: modules/flow/view/meta-flow-steps.php:108
1618
+ msgid "Edit"
1619
+ msgstr ""
1620
+
1621
+ #: modules/flow/view/meta-flow-steps.php:113
1622
+ msgid "Clone Step"
1623
+ msgstr ""
1624
+
1625
+ #: modules/flow/view/meta-flow-steps.php:118
1626
+ msgid "Delete Step"
1627
+ msgstr ""
1628
+
1629
+ #: modules/flow/view/meta-flow-steps.php:120
1630
+ msgid "Delete"
1631
+ msgstr ""
1632
+
1633
+ #: modules/flow/view/meta-flow-steps.php:149
1634
+ msgid "Steps Library"
1635
+ msgstr ""
1636
+
1637
+ #: modules/flow/view/meta-flow-steps.php:198
1638
+ msgid "Create Step"
1639
+ msgstr ""
1640
+
1641
+ #: modules/flow/view/meta-flow-steps.php:200
1642
+ msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1643
+ msgstr ""
1644
+
1645
+ #: modules/landing/classes/class-cartflows-landing-meta.php:66
1646
+ msgid "Landing Page Settings"
1647
+ msgstr ""
1648
+
1649
+ #: modules/landing/classes/class-cartflows-landing-meta.php:169
1650
+ msgid "Next Step Link"
1651
+ msgstr ""
1652
+
1653
+ #: modules/optin/classes/class-cartflows-optin-markup.php:165
1654
+ msgid "Please place shortcode on Optin step-type only."
1655
+ msgstr ""
1656
+
1657
+ #: modules/optin/classes/class-cartflows-optin-markup.php:225
1658
+ msgid ""
1659
+ "No product is selected. Please select a Simple, Virtual and Free product "
1660
+ "from the meta settings."
1661
+ msgstr ""
1662
+
1663
+ #: modules/optin/classes/class-cartflows-optin-markup.php:242
1664
+ msgid "Please update the selected product's price to zero (0)."
1665
+ msgstr ""
1666
+
1667
+ #: modules/optin/classes/class-cartflows-optin-markup.php:251
1668
+ #: modules/optin/classes/class-cartflows-optin-markup.php:255
1669
+ msgid "Please select a Simple, Virtual and Free product."
1670
+ msgstr ""
1671
+
1672
+ #: modules/optin/classes/class-cartflows-optin-meta.php:65
1673
+ msgid "Optin Settings"
1674
+ msgstr ""
1675
+
1676
+ #: modules/optin/classes/class-cartflows-optin-meta.php:138
1677
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1678
+ msgid "Design"
1679
+ msgstr ""
1680
+
1681
+ #: modules/optin/classes/class-cartflows-optin-meta.php:144
1682
+ msgid "Form Fields"
1683
+ msgstr ""
1684
+
1685
+ #: modules/optin/classes/class-cartflows-optin-meta.php:213
1686
+ msgid "Add this shortcode to your optin page"
1687
+ msgstr ""
1688
+
1689
+ #: modules/optin/classes/class-cartflows-optin-meta.php:238
1690
+ msgid "Select Free Product"
1691
+ msgstr ""
1692
+
1693
+ #: modules/optin/classes/class-cartflows-optin-meta.php:239
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
+
1760
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1761
+ msgid "Thank You Page Settings"
1762
+ msgstr ""
1763
+
1764
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1765
+ msgid "Edit Fields"
1766
+ msgstr ""
1767
+
1768
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1769
+ msgid "Order Details"
1770
+ msgstr ""
1771
+
1772
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1773
+ msgid "Text"
1774
+ msgstr ""
1775
+
1776
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1777
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1778
+ msgid "Color"
1779
+ msgstr ""
1780
+
1781
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1782
+ msgid "Advanced Options"
1783
+ msgstr ""
1784
+
1785
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1786
+ msgid "Container Width (In px)"
1787
+ msgstr ""
1788
+
1789
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1790
+ msgid "Section Background Color"
1791
+ msgstr ""
1792
+
1793
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1794
+ msgid "Enable Order Overview "
1795
+ msgstr ""
1796
+
1797
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1798
+ msgid "Enable Order Details "
1799
+ msgstr ""
1800
+
1801
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1802
+ msgid "Enable Billing Details "
1803
+ msgstr ""
1804
+
1805
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1806
+ msgid "Enable Shipping Details "
1807
+ msgstr ""
1808
+
1809
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1810
+ msgid "Thank You Page Text"
1811
+ msgstr ""
1812
+
1813
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1814
+ #: woocommerce/template/checkout/thankyou.php:41
1815
+ #: woocommerce/template/checkout/thankyou.php:83
1816
+ msgid "Thank you. Your order has been received."
1817
+ msgstr ""
1818
+
1819
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1820
+ msgid "It will change the default text on thank you page."
1821
+ msgstr ""
1822
+
1823
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1824
+ msgid "Redirect After Purchase"
1825
+ msgstr ""
1826
+
1827
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1828
+ msgid "Redirect Link"
1829
+ msgstr ""
1830
+
1831
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1832
+ msgid "https://"
1833
+ msgstr ""
1834
+
1835
+ #: modules/widgets/class-cartflows-next-step.php:24
1836
+ msgid "CartFlows Next Step"
1837
+ msgstr ""
1838
+
1839
+ #: modules/widgets/class-cartflows-next-step.php:26
1840
+ msgid "Next Step Widgets"
1841
+ msgstr ""
1842
+
1843
+ #: modules/widgets/class-cartflows-next-step.php:106
1844
+ msgid "New title"
1845
+ msgstr ""
1846
+
1847
+ #: modules/widgets/class-cartflows-next-step.php:123
1848
+ msgid "Title:"
1849
+ msgstr ""
1850
+
1851
+ #: modules/widgets/class-cartflows-next-step.php:127
1852
+ msgid "Flow ID:"
1853
+ msgstr ""
1854
+
1855
+ #: modules/widgets/class-cartflows-next-step.php:131
1856
+ msgid "Step ID:"
1857
+ msgstr ""
1858
+
1859
+ #: woocommerce/template/cart/cart-shipping.php:51
1860
+ #. Translators: $s shipping destination.
1861
+ msgid "Estimate for %s."
1862
+ msgstr ""
1863
+
1864
+ #: woocommerce/template/cart/cart-shipping.php:52
1865
+ msgid "Change address"
1866
+ msgstr ""
1867
+
1868
+ #: woocommerce/template/cart/cart-shipping.php:54
1869
+ msgid "This is only an estimate. Prices will be updated during checkout."
1870
+ msgstr ""
1871
+
1872
+ #: woocommerce/template/cart/cart-shipping.php:61
1873
+ msgid "Enter your address to view shipping options."
1874
+ msgstr ""
1875
+
1876
+ #: woocommerce/template/cart/cart-shipping.php:63
1877
+ msgid ""
1878
+ "There are no shipping methods available. Please ensure that your address "
1879
+ "has been entered correctly, or contact us if you need any help."
1880
+ msgstr ""
1881
+
1882
+ #: woocommerce/template/cart/cart-shipping.php:66
1883
+ #. Translators: $s shipping destination.
1884
+ msgid "No shipping options were found for %s."
1885
+ msgstr ""
1886
+
1887
+ #: woocommerce/template/cart/cart-shipping.php:67
1888
+ msgid "Enter a different address"
1889
+ msgstr ""
1890
+
1891
+ #: woocommerce/template/checkout/form-billing.php:27
1892
+ msgid "Billing &amp; Shipping"
1893
+ msgstr ""
1894
+
1895
+ #: woocommerce/template/checkout/form-billing.php:31
1896
+ msgid "Billing details"
1897
+ msgstr ""
1898
+
1899
+ #: woocommerce/template/checkout/form-billing.php:59
1900
+ msgid "Create an account?"
1901
+ msgstr ""
1902
+
1903
+ #: woocommerce/template/checkout/form-checkout.php:26
1904
+ msgid "You must be logged in to checkout."
1905
+ msgstr ""
1906
+
1907
+ #: woocommerce/template/checkout/form-checkout.php:52
1908
+ msgid "Your order"
1909
+ msgstr ""
1910
+
1911
+ #: woocommerce/template/checkout/form-coupon.php:26
1912
+ msgid "Have a coupon?"
1913
+ msgstr ""
1914
+
1915
+ #: woocommerce/template/checkout/form-coupon.php:26
1916
+ msgid "Click here to enter your code"
1917
+ msgstr ""
1918
+
1919
+ #: woocommerce/template/checkout/form-coupon.php:31
1920
+ msgid "If you have a coupon code, please apply it below."
1921
+ msgstr ""
1922
+
1923
+ #: woocommerce/template/checkout/form-coupon.php:34
1924
+ msgid "Coupon code"
1925
+ msgstr ""
1926
+
1927
+ #: woocommerce/template/checkout/form-coupon.php:38
1928
+ msgid "Apply coupon"
1929
+ msgstr ""
1930
+
1931
+ #: woocommerce/template/checkout/form-login.php:26
1932
+ msgid "Returning customer?"
1933
+ msgstr ""
1934
+
1935
+ #: woocommerce/template/checkout/form-login.php:26
1936
+ msgid "Click here to login"
1937
+ msgstr ""
1938
+
1939
+ #: woocommerce/template/checkout/form-login.php:32
1940
+ msgid ""
1941
+ "If you have shopped with us before, please enter your details below. If you "
1942
+ "are a new customer, please proceed to the Billing &amp; Shipping section."
1943
+ msgstr ""
1944
+
1945
+ #: woocommerce/template/checkout/form-shipping.php:26
1946
+ msgid "Ship to a different address?"
1947
+ msgstr ""
1948
+
1949
+ #: woocommerce/template/checkout/form-shipping.php:57
1950
+ msgid "Additional information"
1951
+ msgstr ""
1952
+
1953
+ #: woocommerce/template/checkout/payment.php:33
1954
+ msgid ""
1955
+ "Sorry, it seems that there are no available payment methods for your state. "
1956
+ "Please contact us if you require assistance or wish to make alternate "
1957
+ "arrangements."
1958
+ msgstr ""
1959
+
1960
+ #: woocommerce/template/checkout/payment.php:33
1961
+ msgid "Please fill in your details above to see available payment methods."
1962
+ msgstr ""
1963
+
1964
+ #: woocommerce/template/checkout/payment.php:42
1965
+ #. translators: $1 and $2 opening and closing emphasis tags respectively
1966
+ msgid ""
1967
+ "Since your browser does not support JavaScript, or it is disabled, please "
1968
+ "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1969
+ "order. You may be charged more than the amount stated above if you fail to "
1970
+ "do so."
1971
+ msgstr ""
1972
+
1973
+ #: woocommerce/template/checkout/payment.php:44
1974
+ msgid "Update totals"
1975
+ msgstr ""
1976
+
1977
+ #: woocommerce/template/checkout/review-order.php:26
1978
+ #: woocommerce/template/order/order-details.php:51
1979
+ msgid "Product"
1980
+ msgstr ""
1981
+
1982
+ #: woocommerce/template/checkout/review-order.php:27
1983
+ #: woocommerce/template/checkout/review-order.php:107
1984
+ #: woocommerce/template/order/order-details.php:52
1985
+ msgid "Total"
1986
+ msgstr ""
1987
+
1988
+ #: woocommerce/template/checkout/review-order.php:60
1989
+ msgid "Subtotal"
1990
+ msgstr ""
1991
+
1992
+ #: woocommerce/template/checkout/thankyou.php:30
1993
+ msgid ""
1994
+ "Unfortunately your order cannot be processed as the originating "
1995
+ "bank/merchant has declined your transaction. Please attempt your purchase "
1996
+ "again."
1997
+ msgstr ""
1998
+
1999
+ #: woocommerce/template/checkout/thankyou.php:33
2000
+ msgid "Pay"
2001
+ msgstr ""
2002
+
2003
+ #: woocommerce/template/checkout/thankyou.php:35
2004
+ msgid "My account"
2005
+ msgstr ""
2006
+
2007
+ #: woocommerce/template/checkout/thankyou.php:46
2008
+ msgid "Order number:"
2009
+ msgstr ""
2010
+
2011
+ #: woocommerce/template/checkout/thankyou.php:51
2012
+ msgid "Date:"
2013
+ msgstr ""
2014
+
2015
+ #: woocommerce/template/checkout/thankyou.php:57
2016
+ msgid "Email:"
2017
+ msgstr ""
2018
+
2019
+ #: woocommerce/template/checkout/thankyou.php:63
2020
+ msgid "Total:"
2021
+ msgstr ""
2022
+
2023
+ #: woocommerce/template/checkout/thankyou.php:69
2024
+ msgid "Payment method:"
2025
+ msgstr ""
2026
+
2027
+ #: woocommerce/template/global/form-login.php:34
2028
+ msgid "Username or email"
2029
+ msgstr ""
2030
+
2031
+ #: woocommerce/template/global/form-login.php:38
2032
+ msgid "Password"
2033
+ msgstr ""
2034
+
2035
+ #: woocommerce/template/global/form-login.php:48
2036
+ msgid "Login"
2037
+ msgstr ""
2038
+
2039
+ #: woocommerce/template/global/form-login.php:53
2040
+ msgid "Remember me"
2041
+ msgstr ""
2042
+
2043
+ #: woocommerce/template/global/form-login.php:57
2044
+ msgid "Lost your password?"
2045
+ msgstr ""
2046
+
2047
+ #: woocommerce/template/order/order-details.php:45
2048
+ msgid "Order details"
2049
+ msgstr ""
2050
+
2051
+ #: woocommerce/template/order/order-details.php:93
2052
+ msgid "Note:"
2053
+ msgstr ""
2054
+
2055
+ #. Plugin Name of the plugin/theme
2056
+ msgid "CartFlows"
2057
+ msgstr ""
2058
+
2059
+ #. Author URI of the plugin/theme
2060
+ msgid "https://cartflows.com/"
2061
+ msgstr ""
2062
+
2063
+ #. Description of the plugin/theme
2064
+ msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2065
+ msgstr ""
2066
+
2067
+ #. Author of the plugin/theme
2068
+ msgid "CartFlows Inc"
2069
+ msgstr ""
2070
+
2071
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2072
+ msgctxt "flow general name"
2073
+ msgid "Flows"
2074
+ msgstr ""
2075
+
2076
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2077
+ msgctxt "flow singular name"
2078
+ msgid "Flow"
2079
+ msgstr ""
2080
+
2081
+ #: modules/flow/classes/class-cartflows-step-post-type.php:161
2082
+ msgctxt "flow step general name"
2083
+ msgid "Steps"
2084
+ msgstr ""
2085
+
2086
+ #: modules/flow/classes/class-cartflows-step-post-type.php:162
2087
+ msgctxt "flow step singular name"
2088
+ msgid "Step"
2089
+ msgstr ""
2090
+
2091
+ #: modules/flow/classes/class-cartflows-step-post-type.php:315
2092
+ msgctxt "cartflows"
2093
+ msgid "CartFlows — Boxed"
2094
+ msgstr ""
2095
+
2096
+ #: modules/flow/classes/class-cartflows-step-post-type.php:316
2097
+ msgctxt "cartflows"
2098
+ msgid "Template for Page Builders"
2099
  msgstr ""
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1288 +1,1288 @@
1
- <?php
2
- /**
3
- * Checkout markup.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Checkout_Markup {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var object instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- */
25
- public static function get_instance() {
26
- if ( ! isset( self::$instance ) ) {
27
- self::$instance = new self();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Set is checkout flag */
38
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
-
40
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
-
42
- /* Show notice if cart is empty */
43
- add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
-
45
- /* Checkout Shortcode */
46
- add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
-
48
- /* Preconfigured cart data */
49
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
-
51
- /* Embed Checkout */
52
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
-
54
- /* Ajax Endpoint */
55
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
-
57
- add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
-
59
- add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
-
61
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
-
63
- add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
- add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
-
66
- add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
-
68
- /* Global Checkout */
69
- add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
-
71
- add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
-
74
- add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
-
77
- add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
-
79
- add_filter( 'woocommerce_paypal_express_checkout_payment_button_data', array( $this, 'change_return_cancel_url' ), 10, 2 );
80
-
81
- add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
82
-
83
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
84
- }
85
-
86
- /**
87
- * Modify WooCommerce paypal arguments.
88
- *
89
- * @param array $args argumenets for payment.
90
- * @param WC_Order $order order data.
91
- * @return array
92
- */
93
- public function modify_paypal_args( $args, $order ) {
94
-
95
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
96
-
97
- if ( ! $checkout_id ) {
98
- return $args;
99
- }
100
-
101
- // Set cancel return URL.
102
- $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
103
-
104
- return $args;
105
- }
106
-
107
- /**
108
- * Change PayPal Express cancel URL.
109
- *
110
- * @param array $data button data.
111
- * @param string $page current page.
112
- * @return array $data modified button data with new cancel url.
113
- */
114
- public function change_return_cancel_url( $data, $page ) {
115
-
116
- global $post;
117
-
118
- if ( _is_wcf_checkout_type() ) {
119
-
120
- $checkout_id = $post->ID;
121
-
122
- if ( $checkout_id ) {
123
-
124
- // Change the default Cart URL with the CartFlows Checkout page.
125
- $data['cancel_url'] = esc_url_raw( get_permalink( $checkout_id ) );
126
- }
127
- }
128
-
129
- // Returing the modified data.
130
- return $data;
131
- }
132
-
133
- /**
134
- * Modify WooCommerce paypal arguments.
135
- *
136
- * @param string $product_name product name.
137
- * @param object $cart_item cart item.
138
- * @param string $cart_item_key cart item key.
139
- * @return string
140
- */
141
- public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
142
-
143
- $checkout_id = get_the_ID();
144
- if ( ! $checkout_id ) {
145
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
146
- }
147
-
148
- if ( ! empty( $checkout_id ) ) {
149
- $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
150
- if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
151
- $remove_label = apply_filters(
152
- 'woocommerce_cart_item_remove_link',
153
- sprintf(
154
- '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
155
- esc_attr( $cart_item['product_id'] ),
156
- $cart_item_key
157
- ),
158
- $cart_item_key
159
- );
160
-
161
- $product_name = $remove_label . $product_name;
162
- }
163
- }
164
-
165
- return $product_name;
166
-
167
- }
168
-
169
- /**
170
- * Change order button text .
171
- *
172
- * @param string $woo_button_text place order.
173
- * @return string
174
- */
175
- public function place_order_button_text( $woo_button_text ) {
176
-
177
- $checkout_id = get_the_ID();
178
- if ( ! $checkout_id ) {
179
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
180
- }
181
-
182
- $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
183
-
184
- if ( ! empty( $wcf_order_button_text ) ) {
185
- $woo_button_text = $wcf_order_button_text;
186
- }
187
-
188
- return $woo_button_text;
189
- }
190
-
191
- /**
192
- * Display all WooCommerce notices.
193
- *
194
- * @since 1.1.5
195
- */
196
- public function display_woo_notices() {
197
-
198
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
199
- woocommerce_output_all_notices();
200
- }
201
- }
202
-
203
-
204
- /**
205
- * Redirect from default to the global checkout page
206
- *
207
- * @since 1.0.0
208
- */
209
- public function global_checkout_template_redirect() {
210
-
211
- if ( ! is_checkout() ) {
212
- return;
213
- }
214
-
215
- if ( wcf()->utils->is_step_post_type() ) {
216
- return;
217
- }
218
-
219
- // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
220
- if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
221
- return;
222
- }
223
-
224
- // redirect only for cartflows checkout pages.
225
- $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
226
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
227
-
228
- $common = Cartflows_Helper::get_common_settings();
229
-
230
- $global_checkout = $common['global_checkout'];
231
-
232
- if (
233
- isset( $_SERVER['REQUEST_URI'] ) &&
234
- // ignore on order-pay.
235
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
236
- // ignore on TY page.
237
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
238
- // ignore if order-pay in query param.
239
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
240
- ) {
241
-
242
- if ( '' !== $global_checkout ) {
243
-
244
- $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
245
-
246
- if ( ! empty( $link ) ) {
247
-
248
- wp_safe_redirect( $link );
249
- die();
250
- }
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * Check for checkout flag
257
- *
258
- * @param bool $is_checkout is checkout.
259
- *
260
- * @return bool
261
- */
262
- public function woo_checkout_flag( $is_checkout ) {
263
-
264
- if ( ! is_admin() ) {
265
-
266
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
267
-
268
- $is_checkout = true;
269
- }
270
- }
271
-
272
- return $is_checkout;
273
- }
274
-
275
- /**
276
- * Render checkout shortcode markup.
277
- *
278
- * @param array $atts attributes.
279
- * @return string
280
- */
281
- public function checkout_shortcode_markup( $atts ) {
282
-
283
- if ( ! function_exists( 'wc_print_notices' ) ) {
284
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
285
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
286
-
287
- return $notice_out;
288
- }
289
-
290
- $atts = shortcode_atts(
291
- array(
292
- 'id' => 0,
293
- ),
294
- $atts
295
- );
296
-
297
- $checkout_id = intval( $atts['id'] );
298
-
299
- if ( empty( $checkout_id ) ) {
300
-
301
- if ( ! _is_wcf_checkout_type() ) {
302
-
303
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
304
- }
305
-
306
- global $post;
307
-
308
- $checkout_id = intval( $post->ID );
309
- }
310
-
311
- $output = '';
312
-
313
- ob_start();
314
-
315
- do_action( 'cartflows_checkout_form_before', $checkout_id );
316
-
317
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
318
-
319
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
320
-
321
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
322
-
323
- if ( file_exists( $template_layout ) ) {
324
- include $template_layout;
325
- } else {
326
- include $template_default;
327
- }
328
-
329
- $output .= ob_get_clean();
330
-
331
- return $output;
332
- }
333
-
334
- /**
335
- * Configure Cart Data.
336
- *
337
- * @since 1.0.0
338
- *
339
- * @return void
340
- */
341
- public function preconfigured_cart_data() {
342
-
343
- if ( is_admin() ) {
344
- return;
345
- }
346
-
347
- global $post;
348
-
349
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
350
-
351
- if ( wp_doing_ajax() ) {
352
- return;
353
- } else {
354
-
355
- if ( _is_wcf_checkout_type() ) {
356
- $checkout_id = $post->ID;
357
- } else {
358
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
359
- }
360
-
361
- $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
362
-
363
- if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
364
-
365
- if ( WC()->cart->is_empty() ) {
366
- wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
367
- }
368
-
369
- return;
370
- }
371
-
372
- if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
373
- return;
374
- }
375
-
376
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
377
-
378
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
379
-
380
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
381
- $products = 'dummy';
382
- } else {
383
- $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
384
- }
385
-
386
- if ( ! is_array( $products ) ) {
387
-
388
- if ( 'dummy' === $products ) {
389
-
390
- $args = array(
391
- 'posts_per_page' => 1,
392
- 'orderby' => 'rand',
393
- 'post_type' => 'product',
394
- 'meta_query' => array( //phpcs:ignore
395
- // Exclude out of stock products.
396
- array(
397
- 'key' => '_stock_status',
398
- 'value' => 'outofstock',
399
- 'compare' => 'NOT IN',
400
- ),
401
- ),
402
- 'tax_query' => array( //phpcs:ignore
403
- array(
404
- 'taxonomy' => 'product_type',
405
- 'field' => 'slug',
406
- 'terms' => 'simple',
407
- ),
408
- ),
409
- );
410
-
411
- $random_product = get_posts( $args );
412
-
413
- if ( isset( $random_product[0]->ID ) ) {
414
- $products = array(
415
- array(
416
- 'product' => $random_product[0]->ID,
417
- 'add_to_cart' => true,
418
- ),
419
- );
420
- } else {
421
- return;
422
- }
423
- } else {
424
- return;
425
- }
426
- }
427
-
428
- /* Empty the current cart */
429
- WC()->cart->empty_cart();
430
-
431
- if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
432
- wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
433
- return;
434
- }
435
-
436
- /* Set customer session if not set */
437
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
438
- WC()->session->set_customer_session_cookie( true );
439
- }
440
-
441
- $cart_product_count = 0;
442
- $cart_key = '';
443
- $products_new = array();
444
-
445
- $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
446
-
447
- foreach ( $products as $index => $data ) {
448
-
449
- if ( ! isset( $data['product'] ) ) {
450
- continue;
451
- }
452
-
453
- if ( empty( $data['add_to_cart'] ) ) {
454
- continue;
455
- }
456
-
457
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
458
- break;
459
- }
460
-
461
- $product_id = $data['product'];
462
- $_product = wc_get_product( $product_id );
463
-
464
- if ( ! empty( $_product ) ) {
465
-
466
- $quantity = 1;
467
-
468
- if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
469
- $quantity = $data['quantity'];
470
- }
471
-
472
- $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
473
- $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
474
- $_product_price = $_product->get_price( $data['product'] );
475
-
476
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
477
-
478
- $cart_item_data = array();
479
-
480
- if ( ! empty( $custom_price ) ) {
481
-
482
- $cart_item_data = array(
483
- 'custom_price' => $custom_price,
484
- );
485
- }
486
-
487
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
488
-
489
- if ( $_product->is_type( 'variable' ) ) {
490
-
491
- $default_attributes = $_product->get_default_attributes();
492
-
493
- if ( ! empty( $default_attributes ) ) {
494
-
495
- foreach ( $_product->get_children() as $variation_id ) {
496
-
497
- $single_variation = new WC_Product_Variation( $variation_id );
498
-
499
- if ( $default_attributes == $single_variation->get_attributes() ) {
500
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
501
- $cart_product_count++;
502
- }
503
- }
504
- } else {
505
-
506
- $product_childrens = $_product->get_children();
507
-
508
- if ( isset( $product_childrens[0] ) ) {
509
- $variation = wc_get_product( $product_childrens[0] );
510
- $_product_price = $variation->get_price();
511
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
512
- if ( ! empty( $custom_price ) ) {
513
- $cart_item_data = array(
514
- 'custom_price' => $custom_price,
515
- 'data' => $data,
516
- );
517
- }
518
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
519
- $cart_product_count++;
520
- } else {
521
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
522
- }
523
- }
524
- } else {
525
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
526
- $cart_product_count++;
527
- }
528
- } else {
529
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
530
- wc_add_notice( $wrong_product_notice );
531
- /**
532
- WC()->cart->add_to_cart( $product_id, $quantity );.
533
- */
534
- }
535
- }
536
- $products_new[ $index ] = array(
537
- 'cart_item_key' => $cart_key,
538
- );
539
- }
540
-
541
- /* Set checkout products data */
542
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
543
-
544
- /* Since 1.2.2 */
545
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
546
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
547
- }
548
- }
549
- }
550
-
551
- /**
552
- * Load shortcode data.
553
- *
554
- * @return void
555
- */
556
- public function shortcode_load_data() {
557
-
558
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
559
-
560
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
561
-
562
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
563
-
564
- /* Show notices if cart has errors */
565
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
566
-
567
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
568
-
569
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
570
-
571
- // Outputting the hidden field in checkout page.
572
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
573
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
-
575
- remove_all_actions( 'woocommerce_checkout_billing' );
576
- remove_all_actions( 'woocommerce_checkout_shipping' );
577
-
578
- // Hook in actions once.
579
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
580
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
581
-
582
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
583
-
584
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
585
-
586
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
587
-
588
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
589
-
590
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
591
-
592
- global $post;
593
-
594
- if ( _is_wcf_checkout_type() ) {
595
- $checkout_id = $post->ID;
596
- } else {
597
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
598
- }
599
-
600
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
601
- }
602
- }
603
-
604
- /**
605
- * Render checkout ID hidden field.
606
- *
607
- * @param array $checkout checkout session data.
608
- * @return void
609
- */
610
- public function checkout_shortcode_post_id( $checkout ) {
611
-
612
- global $post;
613
-
614
- if ( _is_wcf_checkout_type() ) {
615
- $checkout_id = $post->ID;
616
- } else {
617
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
618
- }
619
-
620
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
621
-
622
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
623
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
624
- }
625
-
626
- /**
627
- * Load shortcode scripts.
628
- *
629
- * @return void
630
- */
631
- public function shortcode_scripts() {
632
-
633
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
634
-
635
- wp_enqueue_script(
636
- 'wcf-checkout-template',
637
- wcf()->utils->get_js_url( 'checkout-template' ),
638
- array( 'jquery' ),
639
- CARTFLOWS_VER,
640
- true
641
- );
642
-
643
- do_action( 'cartflows_checkout_scripts' );
644
-
645
- $style = $this->generate_style();
646
-
647
- wp_add_inline_style( 'wcf-checkout-template', $style );
648
-
649
- }
650
-
651
- /**
652
- * Load compatibility scripts.
653
- *
654
- * @return void
655
- */
656
- public function compatibility_scripts() {
657
-
658
- global $post;
659
-
660
- if ( _is_wcf_checkout_type() ) {
661
- $checkout_id = $post->ID;
662
- } else {
663
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
664
- }
665
-
666
- // Add DIVI Compatibility css if DIVI theme is enabled.
667
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
668
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
669
- ) {
670
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
671
- }
672
-
673
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
674
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
675
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
676
- }
677
-
678
- // Add The7 Compatibility css if The7 theme is enabled.
679
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
680
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
681
- }
682
- }
683
-
684
- /**
685
- * Generate styles.
686
- *
687
- * @return string
688
- */
689
- public function generate_style() {
690
-
691
- global $post;
692
-
693
- if ( _is_wcf_checkout_type() ) {
694
- $checkout_id = $post->ID;
695
- } else {
696
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
697
- }
698
-
699
- /*Output css variable */
700
- $output = '';
701
-
702
- CartFlows_Font_Families::render_fonts( $checkout_id );
703
-
704
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
705
-
706
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
707
-
708
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
709
-
710
- /**
711
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
712
- $r = '';
713
- $g = '';
714
- $b = '';
715
-
716
- $field_tb_padding = '';
717
- $field_lr_padding = '';
718
-
719
- $field_heading_color = '';
720
- $field_color = '';
721
- $field_bg_color = '';
722
- $field_border_color = '';
723
- $field_label_color = '';
724
- $submit_tb_padding = '';
725
- $submit_lr_padding = '';
726
- $hl_bg_color = '';
727
- $field_input_size = '';
728
- $box_border_color = '';
729
- $section_bg_color = '';
730
- $submit_button_height = '';
731
- $submit_color = '';
732
- $submit_bg_color = $primary_color;
733
- $submit_border_color = $primary_color;
734
-
735
- $submit_hover_color = '';
736
- $submit_bg_hover_color = $primary_color;
737
- $submit_border_hover_color = $primary_color;
738
-
739
- $section_heading_color = '';
740
-
741
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
742
-
743
- $button_font_family = '';
744
- $button_font_weight = '';
745
- $input_font_family = '';
746
- $input_font_weight = '';
747
- $heading_font_family = '';
748
- $heading_font_weight = '';
749
- $base_font_family = $base_font_family;
750
- /**
751
- $base_font_weight = $base_font_weight;*/
752
-
753
- if ( 'yes' == $is_advance_option ) {
754
-
755
- /**
756
- * Get Font Family and Font Weight weight values
757
- */
758
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
759
-
760
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
761
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
762
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
763
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
764
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
765
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
766
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
767
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
768
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
769
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
770
-
771
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
772
-
773
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
774
-
775
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
776
-
777
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
778
-
779
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
780
-
781
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
782
-
783
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
784
-
785
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
786
-
787
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
788
-
789
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
790
-
791
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
792
-
793
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
794
-
795
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
796
-
797
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
798
-
799
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
800
-
801
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
802
-
803
- /**
804
- * Get font values
805
- */
806
-
807
- if ( 'custom' == $submit_button_height ) {
808
- $submit_button_height = '38px';
809
- }
810
-
811
- if ( 'custom' == $field_input_size ) {
812
- $field_input_size = '38px';
813
- }
814
- }
815
- if ( isset( $primary_color ) ) {
816
-
817
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
818
- }
819
-
820
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
821
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
822
-
823
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
824
-
825
- } else {
826
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
827
- }
828
-
829
- return $output;
830
- }
831
-
832
- /**
833
- * Get ajax end points.
834
- *
835
- * @param string $endpoint_url end point URL.
836
- * @param string $request end point request.
837
- * @return string
838
- */
839
- public function get_ajax_endpoint( $endpoint_url, $request ) {
840
-
841
- global $post;
842
-
843
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
844
-
845
- if ( _is_wcf_checkout_type() ) {
846
-
847
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
848
-
849
- if ( '' === $request ) {
850
- $query_args = array(
851
- 'wc-ajax' => '%%endpoint%%',
852
- );
853
- } else {
854
- $query_args = array(
855
- 'wc-ajax' => $request,
856
- );
857
- }
858
-
859
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
860
- $uri = $uri[0];
861
-
862
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
863
- }
864
- }
865
- }
866
-
867
- return $endpoint_url;
868
- }
869
-
870
-
871
- /**
872
- * Save checkout fields.
873
- *
874
- * @param int $order_id order id.
875
- * @param array $posted posted data.
876
- * @return void
877
- */
878
- public function save_checkout_fields( $order_id, $posted ) {
879
-
880
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
881
-
882
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
883
-
884
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
885
-
886
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
887
-
888
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
889
-
890
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
891
- }
892
- }
893
-
894
- }
895
-
896
- /**
897
- * Enable Logo In Header Of Checkout Page
898
- *
899
- * @return void
900
- */
901
- public function enable_logo_in_header() {
902
- global $post;
903
-
904
- if ( _is_wcf_checkout_type() ) {
905
- $checkout_id = $post->ID;
906
- } else {
907
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
908
- }
909
-
910
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
911
- $add_image_markup = '';
912
-
913
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
914
- $add_image_markup = '<div class="wcf-checkout-header-image">';
915
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
916
- $add_image_markup .= '</div>';
917
- }
918
-
919
- echo $add_image_markup;
920
- }
921
-
922
- /**
923
- * Add text to the bootom of the checkout page.
924
- *
925
- * @return void
926
- */
927
- public function show_cartflows_copyright_message() {
928
- $output_string = '';
929
-
930
- $output_string .= '<div class="wcf-footer-primary">';
931
- $output_string .= '<div class="wcf-footer-content">';
932
- $output_string .= '<p class="wcf-footer-message">';
933
- $output_string .= 'Checkout powered by CartFlows';
934
- $output_string .= '</p>';
935
- $output_string .= '</div>';
936
- $output_string .= '</div>';
937
-
938
- echo $output_string;
939
- }
940
-
941
- /**
942
- * Redirect users to our checkout if hidden param
943
- *
944
- * @param string $redirect redirect url.
945
- * @param object $user user.
946
- * @return string
947
- */
948
- public function after_login_redirect( $redirect, $user ) {
949
-
950
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
951
-
952
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
953
-
954
- $redirect = get_permalink( $checkout_id );
955
- }
956
-
957
- return $redirect;
958
- }
959
-
960
- /**
961
- * Display coupon code field after review order fields.
962
- */
963
- public function display_custom_coupon_field() {
964
-
965
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
966
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
967
-
968
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
969
- return;
970
-
971
- }
972
-
973
- $coupon_field = array(
974
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
975
- 'button_text' => __( 'Apply', 'cartflows' ),
976
- 'class' => '',
977
- );
978
-
979
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
980
-
981
- ob_start();
982
- ?>
983
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
984
- <div class="wcf-coupon-col-1">
985
- <span>
986
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
987
- </span>
988
- </div>
989
- <div class="wcf-coupon-col-2">
990
- <span>
991
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
992
- </span>
993
- </div>
994
- </div>
995
- <?php
996
- echo ob_get_clean();
997
- }
998
-
999
- /**
1000
- * Apply filter to change class of remove coupon field.
1001
- *
1002
- * @param string $coupon coupon.
1003
- * @return string
1004
- */
1005
- public function remove_coupon_text( $coupon ) {
1006
-
1007
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1008
- return $coupon;
1009
-
1010
- }
1011
- /**
1012
- * Apply filter to change the placeholder text of coupon field.
1013
- *
1014
- * @return string
1015
- */
1016
- public function coupon_field_placeholder() {
1017
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1018
- }
1019
-
1020
- /**
1021
- * Apply filter to change the button text of coupon field.
1022
- *
1023
- * @return string
1024
- */
1025
- public function coupon_button_text() {
1026
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1027
- }
1028
-
1029
- /**
1030
- * Apply coupon on submit of custom coupon form.
1031
- */
1032
- public function apply_coupon() {
1033
-
1034
- $response = '';
1035
-
1036
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1037
- if ( ! empty( $_POST['coupon_code'] ) ) {
1038
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1039
- } else {
1040
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1041
- }
1042
-
1043
- $response = array(
1044
- 'status' => $result,
1045
- 'msg' => wc_print_notices( true ),
1046
- );
1047
-
1048
- echo wp_json_encode( $response );
1049
-
1050
- die();
1051
- }
1052
-
1053
-
1054
- /**
1055
- * Added ajax nonce to localize variable.
1056
- *
1057
- * @param array $vars localize variables.
1058
- */
1059
- public function add_localize_vars( $vars ) {
1060
-
1061
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1062
-
1063
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1064
-
1065
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1066
-
1067
- $vars['allow_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();
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-meta.php CHANGED
@@ -1,760 +1,760 @@
1
- <?php
2
- /**
3
- * Flow meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Flow_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option;
27
-
28
- /**
29
- * For Gutenberg
30
- *
31
- * @var $is_gutenberg_editor_active
32
- */
33
- private $is_gutenberg_editor_active = false;
34
-
35
- /**
36
- * Initiator
37
- */
38
- public static function get_instance() {
39
- if ( ! isset( self::$instance ) ) {
40
- self::$instance = new self();
41
- }
42
-
43
- return self::$instance;
44
- }
45
-
46
- /**
47
- * Constructor
48
- */
49
- public function __construct() {
50
-
51
- add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
-
53
- add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
-
55
- /* Init Metabox */
56
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
-
59
- /* Add Scripts */
60
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
-
62
- add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
- add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
-
65
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
-
67
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
-
69
- /* To check the status of gutenberg */
70
- add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
-
72
- /* Add back to edit flow button for gutenberg */
73
- add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
- }
75
-
76
- /**
77
- * Display admin notices.
78
- *
79
- * @since 1.0.0
80
- *
81
- * @return void
82
- */
83
- public function admin_notices() {
84
-
85
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
- return;
87
- }
88
-
89
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
- if ( $flow_id ) { ?>
91
- <div class="wcf-notice-back-edit-flow">
92
- <p>
93
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
- <i class="dashicons dashicons-arrow-left-alt"></i>
95
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
- </a>
97
- </p>
98
- </div>
99
- <?php
100
- }
101
- }
102
-
103
- /**
104
- * Initialize admin actions.
105
- *
106
- * @since 1.0.0
107
- *
108
- * @return void
109
- */
110
- public function admin_init_actions() {
111
- add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
- add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
- add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
- }
115
-
116
- /**
117
- * Delete term data and steps data after deleting flow.
118
- *
119
- * @since 1.0.0
120
- * @param int $pid post id.
121
- *
122
- * @return void
123
- */
124
- public function step_post_sync( $pid ) {
125
-
126
- global $post_type;
127
-
128
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
-
130
- $steps = get_post_meta( $pid, 'wcf-steps', true );
131
-
132
- if ( $steps && is_array( $steps ) ) {
133
- foreach ( $steps as $i => $step ) {
134
- wp_delete_post( $step['id'], true );
135
- }
136
- }
137
-
138
- $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
-
140
- if ( is_array( $term_data ) ) {
141
- wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
- }
143
- }
144
- }
145
-
146
- /**
147
- * Trash steps data after trashing flow.
148
- *
149
- * @since 1.0.0
150
- * @param int $pid post id.
151
- *
152
- * @return void
153
- */
154
- public function step_post_trash_sync( $pid ) {
155
-
156
- global $post_type;
157
-
158
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
-
160
- $steps = get_post_meta( $pid, 'wcf-steps', true );
161
-
162
- if ( $steps && is_array( $steps ) ) {
163
- foreach ( $steps as $i => $step ) {
164
- wp_trash_post( $step['id'] );
165
- }
166
- }
167
- }
168
- }
169
-
170
- /**
171
- * Untrash steps data after restoring flow.
172
- *
173
- * @since 1.0.0
174
- * @param int $pid post id.
175
- *
176
- * @return void
177
- */
178
- public function step_post_untrash_sync( $pid ) {
179
-
180
- global $post_type;
181
-
182
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
-
184
- $steps = get_post_meta( $pid, 'wcf-steps', true );
185
-
186
- if ( $steps && is_array( $steps ) ) {
187
- foreach ( $steps as $i => $step ) {
188
- wp_untrash_post( $step['id'] );
189
- }
190
- }
191
- }
192
- }
193
-
194
- /**
195
- * Create step for given flow.
196
- *
197
- * @param int $flow_id flow ID.
198
- * @param int $step_type step type.
199
- * @param int $step_title step title.
200
- * @since 1.0.0
201
- *
202
- * @return int
203
- */
204
- public function create_step( $flow_id, $step_type, $step_title ) {
205
-
206
- $new_step_id = wp_insert_post(
207
- array(
208
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
- 'post_title' => $step_title,
210
- 'post_status' => 'publish',
211
- )
212
- );
213
-
214
- if ( $new_step_id ) {
215
-
216
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
-
218
- if ( ! is_array( $flow_steps ) ) {
219
- $flow_steps = array();
220
- }
221
-
222
- $flow_steps[] = array(
223
- 'id' => $new_step_id,
224
- 'title' => $step_title,
225
- 'type' => $step_type,
226
- );
227
-
228
- // insert post meta.
229
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
-
232
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
- }
235
-
236
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
-
238
- return $new_step_id;
239
- }
240
-
241
- /**
242
- * Delete step for flow
243
- *
244
- * @since 1.0.0
245
- *
246
- * @return void
247
- */
248
- public function cartflows_delete_flow_step() {
249
-
250
- if ( ! current_user_can( 'manage_options' ) ) {
251
- return;
252
- }
253
-
254
- check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
-
256
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
- $flow_id = intval( $_POST['post_id'] );
258
- $step_id = intval( $_POST['step_id'] );
259
- }
260
- $result = array(
261
- 'status' => false,
262
- /* translators: %s flow id */
263
- 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
- );
265
-
266
- if ( ! $flow_id || ! $step_id ) {
267
- wp_send_json( $result );
268
- }
269
-
270
- wp_delete_post( $step_id, true );
271
-
272
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
-
274
- if ( ! is_array( $flow_steps ) ) {
275
- wp_send_json( $result );
276
- }
277
-
278
- foreach ( $flow_steps as $index => $data ) {
279
-
280
- if ( intval( $data['id'] ) === $step_id ) {
281
- unset( $flow_steps[ $index ] );
282
- break;
283
- }
284
- }
285
-
286
- /* Set index order properly */
287
- $flow_steps = array_merge( $flow_steps );
288
-
289
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
-
291
- $result = array(
292
- 'status' => true,
293
- /* translators: %s flow id */
294
- 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
- );
296
-
297
- wp_send_json( $result );
298
- }
299
-
300
- /**
301
- * Reorder step flow
302
- *
303
- * @since 1.0.0
304
- *
305
- * @return void
306
- */
307
- public function cartflows_reorder_flow_steps() {
308
-
309
- if ( ! current_user_can( 'manage_options' ) ) {
310
- return;
311
- }
312
-
313
- check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
-
315
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
- $flow_id = intval( $_POST['post_id'] );
317
- $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
- }
319
- $result = array(
320
- 'status' => false,
321
- /* translators: %s flow id */
322
- 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
- );
324
-
325
- if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
- wp_send_json( $result );
327
- }
328
-
329
- $new_flow_steps = array();
330
-
331
- foreach ( $step_ids as $index => $step_id ) {
332
-
333
- $new_flow_steps[] = array(
334
- 'id' => intval( $step_id ),
335
- 'title' => get_the_title( $step_id ),
336
- 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
- );
338
- }
339
-
340
- update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
-
342
- $result = array(
343
- 'status' => true,
344
- /* translators: %s flow id */
345
- 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
- );
347
-
348
- wp_send_json( $result );
349
- }
350
-
351
-
352
- /**
353
- * Load admin scripts
354
- *
355
- * @since 1.0.0
356
- *
357
- * @return void
358
- */
359
- public function admin_scripts() {
360
-
361
- global $pagenow;
362
- global $post;
363
-
364
- $screen = get_current_screen();
365
-
366
- if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
-
368
- wp_enqueue_script(
369
- 'wcf-flow-meta',
370
- CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
- array( 'jquery', 'jquery-ui-sortable' ),
372
- CARTFLOWS_VER,
373
- true
374
- );
375
-
376
- wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
- wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
-
379
- $localize = array(
380
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
- );
382
-
383
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
- }
385
- }
386
-
387
- /**
388
- * Initialize meta box
389
- *
390
- * @since 1.0.0
391
- *
392
- * @return void
393
- */
394
- public function init_metabox() {
395
-
396
- /**
397
- * Fires after the title field.
398
- *
399
- * @param WP_Post $post Post object.
400
- */
401
- add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
- add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
- }
405
-
406
- /**
407
- * Is first time import?
408
- *
409
- * @param integer $post_id post ID.
410
- * @return bool
411
- */
412
- public function is_flow_imported( $post_id = 0 ) {
413
-
414
- if ( 0 === $post_id ) {
415
- $post_id = get_the_ID();
416
- }
417
-
418
- $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
- $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
-
421
- if ( empty( $steps ) && 'import' === $choice ) {
422
- return true;
423
- }
424
-
425
- return false;
426
- }
427
-
428
- /**
429
- * Setup meta box.
430
- *
431
- * @return void
432
- */
433
- public function setup_meta_box() {
434
- if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
- return;
436
- }
437
-
438
- /**
439
- * Adding Add new step button to the top*/
440
- echo $this->add_add_new_step_button();
441
-
442
- $this->markup_meta_box();
443
-
444
- $this->add_upgrade_to_pro_metabox();
445
- }
446
-
447
-
448
- /**
449
- * Add metabox when cartflows pro is not enabled.
450
- */
451
- public function add_upgrade_to_pro_metabox() {
452
-
453
- if ( ! _is_cartflows_pro() ) {
454
- add_meta_box(
455
- 'wcf-upgrade-pro',
456
- __( 'Analytics', 'cartflows' ),
457
- array( $this, 'upgrade_to_pro' ),
458
- CARTFLOWS_FLOW_POST_TYPE,
459
- 'side',
460
- 'high'
461
- );
462
- }
463
-
464
- }
465
-
466
- /**
467
- * Show Upgrade To Pro markup.
468
- */
469
- public function upgrade_to_pro() {
470
-
471
- echo '<div>';
472
- /* translators: %s: link */
473
- echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
- echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
- echo '</div>';
476
-
477
- }
478
-
479
- /**
480
- * Settings meta box.
481
- *
482
- * @return void
483
- */
484
- public function settings_meta_box() {
485
-
486
- if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
-
488
- /* No need of sandbox will delete it later */
489
- add_meta_box(
490
- 'wcf-sandbox-settings', // Id.
491
- __( 'Flow Settings', 'cartflows' ), // Title.
492
- array( $this, 'sandbox_meta_box' ), // Callback.
493
- CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
- 'side', // Context.
495
- 'high' // Priority.
496
- );
497
-
498
- do_action( 'cartflows_add_flow_metabox' );
499
- }
500
- }
501
-
502
- /**
503
- * Metabox Markup
504
- *
505
- * @return void
506
- */
507
- public function markup_meta_box() {
508
- global $post;
509
-
510
- wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
-
512
- // Get defaults.
513
- $meta = self::get_current_post_meta( $post->ID );
514
-
515
- /**
516
- * Get options
517
- */
518
- $updated_data = array(
519
- 'steps' => $meta['wcf-steps']['default'],
520
- );
521
-
522
- do_action( 'wcf_flow_settings_markup_before', $meta );
523
- $this->page_header_tab( $updated_data );
524
- do_action( 'wcf_flow_settings_markup_after', $meta );
525
- }
526
-
527
- /**
528
- * Metabox Markup
529
- *
530
- * @param object $post Post object.
531
- * @return void
532
- */
533
- public function sandbox_meta_box( $post ) {
534
-
535
- // Get defaults.
536
- $meta = self::get_current_post_meta( $post->ID );
537
-
538
- /**
539
- * Get options
540
- */
541
- foreach ( $meta as $key => $value ) {
542
- $updated_data[ $key ] = $meta[ $key ]['default'];
543
- }
544
-
545
- do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
- $this->sandbox_markup( $updated_data );
547
- do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
- }
549
-
550
- /**
551
- * Page Header Tabs
552
- *
553
- * @param array $options Post meta.
554
- * @return void
555
- */
556
- public function page_header_tab( $options ) {
557
-
558
- include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
- }
560
-
561
- /**
562
- * Sandbox Markup
563
- *
564
- * @param array $options Post meta.
565
- * @return void
566
- */
567
- public function sandbox_markup( $options ) {
568
- ?>
569
- <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
- <div class="wcf-flow-sandbox-table-container">
571
- <?php
572
- echo wcf()->meta->get_checkbox_field(
573
- array(
574
- 'name' => 'wcf-testing',
575
- 'value' => $options['wcf-testing'],
576
- 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
- )
578
- );
579
-
580
- echo wcf()->meta->get_description_field(
581
- array(
582
- 'name' => 'wcf-testing-note',
583
- 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
- )
585
- );
586
-
587
- ?>
588
- </div>
589
- </div>
590
- <?php
591
- }
592
-
593
- /**
594
- * Keep the menu open when editing the flows.
595
- * Highlights the wanted admin (sub-) menu items for the CPT.
596
- *
597
- * @since 1.0.0
598
- */
599
- public function menu_highlight() {
600
- global $parent_file, $submenu_file, $post_type;
601
- if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
- $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
- $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
- endif;
605
- }
606
-
607
- /**
608
- * Get metabox options
609
- *
610
- * @param int $post_id post id.
611
- * @return array
612
- */
613
- public static function get_meta_option( $post_id ) {
614
-
615
- if ( null === self::$meta_option ) {
616
- /**
617
- * Set metabox options
618
- */
619
- self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
- }
621
-
622
- return self::$meta_option;
623
- }
624
-
625
- /**
626
- * Get metabox options
627
- *
628
- * @param int $post_id post ID.
629
- * @return array
630
- */
631
- public static function get_current_post_meta( $post_id ) {
632
-
633
- $stored = get_post_meta( $post_id );
634
-
635
- $default_meta = self::get_meta_option( $post_id );
636
-
637
- // Set stored and override defaults.
638
- foreach ( $stored as $key => $value ) {
639
- if ( array_key_exists( $key, $default_meta ) ) {
640
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
- } else {
642
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
- }
644
- }
645
-
646
- return self::get_meta_option( $post_id );
647
- }
648
-
649
- /**
650
- * Metabox Save
651
- *
652
- * @param number $post_id Post ID.
653
- * @return void
654
- */
655
- public function save_meta_box( $post_id ) {
656
-
657
- // Checks save status.
658
- $is_autosave = wp_is_post_autosave( $post_id );
659
- $is_revision = wp_is_post_revision( $post_id );
660
-
661
- $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
-
663
- // Exits script depending on save status.
664
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
- return;
666
- }
667
-
668
- wcf()->options->save_flow_fields( $post_id );
669
- }
670
-
671
- /**
672
- * Localize variables in admin
673
- *
674
- * @param array $vars variables.
675
- */
676
- public function localize_vars( $vars ) {
677
-
678
- $ajax_actions = array(
679
- 'wcf_setup_default_steps',
680
- 'wcf_add_flow_step',
681
- 'wcf_delete_flow_step',
682
- 'wcf_reorder_flow_steps',
683
- );
684
-
685
- foreach ( $ajax_actions as $action ) {
686
-
687
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
- }
689
-
690
- return $vars;
691
- }
692
-
693
- /**
694
- * Add New Step Button
695
- *
696
- * @return string
697
- */
698
- public function add_add_new_step_button() {
699
- $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
- $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
- $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
- $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
- $add_new_btn_markup .= '</button>';
704
- $add_new_btn_markup .= '</div>';
705
-
706
- return $add_new_btn_markup;
707
- }
708
-
709
- /**
710
- * Back to flow button gutenberg template
711
- *
712
- * @return void
713
- */
714
- public function gutenberg_module_templates() {
715
-
716
- // Exit if block editor is not enabled.
717
- if ( ! $this->is_gutenberg_editor_active ) {
718
- return;
719
- }
720
-
721
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
- return;
723
- }
724
-
725
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
-
727
- if ( $flow_id ) {
728
- ?>
729
- <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
- <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
- <i class="dashicons dashicons-arrow-left-alt"></i>
733
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
- </a>
735
- </div>
736
- </script>
737
- <?php
738
- }
739
- }
740
-
741
- /**
742
- * Set status true for gutenberg.
743
- *
744
- * @return void
745
- */
746
- public function set_block_editor_status() {
747
-
748
- if ( ! current_user_can( 'manage_options' ) ) {
749
- return;
750
- }
751
-
752
- // Set gutenberg status here.
753
- $this->is_gutenberg_editor_active = true;
754
- }
755
- }
756
-
757
- /**
758
- * Kicking this off by calling 'get_instance()' method
759
- */
760
- Cartflows_Flow_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Flow_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option;
27
+
28
+ /**
29
+ * For Gutenberg
30
+ *
31
+ * @var $is_gutenberg_editor_active
32
+ */
33
+ private $is_gutenberg_editor_active = false;
34
+
35
+ /**
36
+ * Initiator
37
+ */
38
+ public static function get_instance() {
39
+ if ( ! isset( self::$instance ) ) {
40
+ self::$instance = new self();
41
+ }
42
+
43
+ return self::$instance;
44
+ }
45
+
46
+ /**
47
+ * Constructor
48
+ */
49
+ public function __construct() {
50
+
51
+ add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
+
53
+ add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
+
55
+ /* Init Metabox */
56
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
+
59
+ /* Add Scripts */
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
+
62
+ add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
+ add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
+
65
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
+
67
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
+
69
+ /* To check the status of gutenberg */
70
+ add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
+
72
+ /* Add back to edit flow button for gutenberg */
73
+ add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
+ }
75
+
76
+ /**
77
+ * Display admin notices.
78
+ *
79
+ * @since 1.0.0
80
+ *
81
+ * @return void
82
+ */
83
+ public function admin_notices() {
84
+
85
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
+ return;
87
+ }
88
+
89
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
+ if ( $flow_id ) { ?>
91
+ <div class="wcf-notice-back-edit-flow">
92
+ <p>
93
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
+ <i class="dashicons dashicons-arrow-left-alt"></i>
95
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
+ </a>
97
+ </p>
98
+ </div>
99
+ <?php
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Initialize admin actions.
105
+ *
106
+ * @since 1.0.0
107
+ *
108
+ * @return void
109
+ */
110
+ public function admin_init_actions() {
111
+ add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
+ add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
+ add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
+ }
115
+
116
+ /**
117
+ * Delete term data and steps data after deleting flow.
118
+ *
119
+ * @since 1.0.0
120
+ * @param int $pid post id.
121
+ *
122
+ * @return void
123
+ */
124
+ public function step_post_sync( $pid ) {
125
+
126
+ global $post_type;
127
+
128
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
+
130
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
131
+
132
+ if ( $steps && is_array( $steps ) ) {
133
+ foreach ( $steps as $i => $step ) {
134
+ wp_delete_post( $step['id'], true );
135
+ }
136
+ }
137
+
138
+ $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
+
140
+ if ( is_array( $term_data ) ) {
141
+ wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
+ }
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Trash steps data after trashing flow.
148
+ *
149
+ * @since 1.0.0
150
+ * @param int $pid post id.
151
+ *
152
+ * @return void
153
+ */
154
+ public function step_post_trash_sync( $pid ) {
155
+
156
+ global $post_type;
157
+
158
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
+
160
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
161
+
162
+ if ( $steps && is_array( $steps ) ) {
163
+ foreach ( $steps as $i => $step ) {
164
+ wp_trash_post( $step['id'] );
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Untrash steps data after restoring flow.
172
+ *
173
+ * @since 1.0.0
174
+ * @param int $pid post id.
175
+ *
176
+ * @return void
177
+ */
178
+ public function step_post_untrash_sync( $pid ) {
179
+
180
+ global $post_type;
181
+
182
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
+
184
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
185
+
186
+ if ( $steps && is_array( $steps ) ) {
187
+ foreach ( $steps as $i => $step ) {
188
+ wp_untrash_post( $step['id'] );
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Create step for given flow.
196
+ *
197
+ * @param int $flow_id flow ID.
198
+ * @param int $step_type step type.
199
+ * @param int $step_title step title.
200
+ * @since 1.0.0
201
+ *
202
+ * @return int
203
+ */
204
+ public function create_step( $flow_id, $step_type, $step_title ) {
205
+
206
+ $new_step_id = wp_insert_post(
207
+ array(
208
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
+ 'post_title' => $step_title,
210
+ 'post_status' => 'publish',
211
+ )
212
+ );
213
+
214
+ if ( $new_step_id ) {
215
+
216
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
+
218
+ if ( ! is_array( $flow_steps ) ) {
219
+ $flow_steps = array();
220
+ }
221
+
222
+ $flow_steps[] = array(
223
+ 'id' => $new_step_id,
224
+ 'title' => $step_title,
225
+ 'type' => $step_type,
226
+ );
227
+
228
+ // insert post meta.
229
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
+
232
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
+ }
235
+
236
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
+
238
+ return $new_step_id;
239
+ }
240
+
241
+ /**
242
+ * Delete step for flow
243
+ *
244
+ * @since 1.0.0
245
+ *
246
+ * @return void
247
+ */
248
+ public function cartflows_delete_flow_step() {
249
+
250
+ if ( ! current_user_can( 'manage_options' ) ) {
251
+ return;
252
+ }
253
+
254
+ check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
+
256
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
+ $flow_id = intval( $_POST['post_id'] );
258
+ $step_id = intval( $_POST['step_id'] );
259
+ }
260
+ $result = array(
261
+ 'status' => false,
262
+ /* translators: %s flow id */
263
+ 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
+ );
265
+
266
+ if ( ! $flow_id || ! $step_id ) {
267
+ wp_send_json( $result );
268
+ }
269
+
270
+ wp_delete_post( $step_id, true );
271
+
272
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
+
274
+ if ( ! is_array( $flow_steps ) ) {
275
+ wp_send_json( $result );
276
+ }
277
+
278
+ foreach ( $flow_steps as $index => $data ) {
279
+
280
+ if ( intval( $data['id'] ) === $step_id ) {
281
+ unset( $flow_steps[ $index ] );
282
+ break;
283
+ }
284
+ }
285
+
286
+ /* Set index order properly */
287
+ $flow_steps = array_merge( $flow_steps );
288
+
289
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
+
291
+ $result = array(
292
+ 'status' => true,
293
+ /* translators: %s flow id */
294
+ 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
+ );
296
+
297
+ wp_send_json( $result );
298
+ }
299
+
300
+ /**
301
+ * Reorder step flow
302
+ *
303
+ * @since 1.0.0
304
+ *
305
+ * @return void
306
+ */
307
+ public function cartflows_reorder_flow_steps() {
308
+
309
+ if ( ! current_user_can( 'manage_options' ) ) {
310
+ return;
311
+ }
312
+
313
+ check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
+
315
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
+ $flow_id = intval( $_POST['post_id'] );
317
+ $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
+ }
319
+ $result = array(
320
+ 'status' => false,
321
+ /* translators: %s flow id */
322
+ 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
+ );
324
+
325
+ if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
+ wp_send_json( $result );
327
+ }
328
+
329
+ $new_flow_steps = array();
330
+
331
+ foreach ( $step_ids as $index => $step_id ) {
332
+
333
+ $new_flow_steps[] = array(
334
+ 'id' => intval( $step_id ),
335
+ 'title' => get_the_title( $step_id ),
336
+ 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
+ );
338
+ }
339
+
340
+ update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
+
342
+ $result = array(
343
+ 'status' => true,
344
+ /* translators: %s flow id */
345
+ 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
+ );
347
+
348
+ wp_send_json( $result );
349
+ }
350
+
351
+
352
+ /**
353
+ * Load admin scripts
354
+ *
355
+ * @since 1.0.0
356
+ *
357
+ * @return void
358
+ */
359
+ public function admin_scripts() {
360
+
361
+ global $pagenow;
362
+ global $post;
363
+
364
+ $screen = get_current_screen();
365
+
366
+ if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
+
368
+ wp_enqueue_script(
369
+ 'wcf-flow-meta',
370
+ CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
+ array( 'jquery', 'jquery-ui-sortable' ),
372
+ CARTFLOWS_VER,
373
+ true
374
+ );
375
+
376
+ wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
+ wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
+
379
+ $localize = array(
380
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
+ );
382
+
383
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Initialize meta box
389
+ *
390
+ * @since 1.0.0
391
+ *
392
+ * @return void
393
+ */
394
+ public function init_metabox() {
395
+
396
+ /**
397
+ * Fires after the title field.
398
+ *
399
+ * @param WP_Post $post Post object.
400
+ */
401
+ add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
+ add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
+ }
405
+
406
+ /**
407
+ * Is first time import?
408
+ *
409
+ * @param integer $post_id post ID.
410
+ * @return bool
411
+ */
412
+ public function is_flow_imported( $post_id = 0 ) {
413
+
414
+ if ( 0 === $post_id ) {
415
+ $post_id = get_the_ID();
416
+ }
417
+
418
+ $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
+ $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
+
421
+ if ( empty( $steps ) && 'import' === $choice ) {
422
+ return true;
423
+ }
424
+
425
+ return false;
426
+ }
427
+
428
+ /**
429
+ * Setup meta box.
430
+ *
431
+ * @return void
432
+ */
433
+ public function setup_meta_box() {
434
+ if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
+ return;
436
+ }
437
+
438
+ /**
439
+ * Adding Add new step button to the top*/
440
+ echo $this->add_add_new_step_button();
441
+
442
+ $this->markup_meta_box();
443
+
444
+ $this->add_upgrade_to_pro_metabox();
445
+ }
446
+
447
+
448
+ /**
449
+ * Add metabox when cartflows pro is not enabled.
450
+ */
451
+ public function add_upgrade_to_pro_metabox() {
452
+
453
+ if ( ! _is_cartflows_pro() ) {
454
+ add_meta_box(
455
+ 'wcf-upgrade-pro',
456
+ __( 'Analytics', 'cartflows' ),
457
+ array( $this, 'upgrade_to_pro' ),
458
+ CARTFLOWS_FLOW_POST_TYPE,
459
+ 'side',
460
+ 'high'
461
+ );
462
+ }
463
+
464
+ }
465
+
466
+ /**
467
+ * Show Upgrade To Pro markup.
468
+ */
469
+ public function upgrade_to_pro() {
470
+
471
+ echo '<div>';
472
+ /* translators: %s: link */
473
+ echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
+ echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
+ echo '</div>';
476
+
477
+ }
478
+
479
+ /**
480
+ * Settings meta box.
481
+ *
482
+ * @return void
483
+ */
484
+ public function settings_meta_box() {
485
+
486
+ if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
+
488
+ /* No need of sandbox will delete it later */
489
+ add_meta_box(
490
+ 'wcf-sandbox-settings', // Id.
491
+ __( 'Flow Settings', 'cartflows' ), // Title.
492
+ array( $this, 'sandbox_meta_box' ), // Callback.
493
+ CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
+ 'side', // Context.
495
+ 'high' // Priority.
496
+ );
497
+
498
+ do_action( 'cartflows_add_flow_metabox' );
499
+ }
500
+ }
501
+
502
+ /**
503
+ * Metabox Markup
504
+ *
505
+ * @return void
506
+ */
507
+ public function markup_meta_box() {
508
+ global $post;
509
+
510
+ wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
+
512
+ // Get defaults.
513
+ $meta = self::get_current_post_meta( $post->ID );
514
+
515
+ /**
516
+ * Get options
517
+ */
518
+ $updated_data = array(
519
+ 'steps' => $meta['wcf-steps']['default'],
520
+ );
521
+
522
+ do_action( 'wcf_flow_settings_markup_before', $meta );
523
+ $this->page_header_tab( $updated_data );
524
+ do_action( 'wcf_flow_settings_markup_after', $meta );
525
+ }
526
+
527
+ /**
528
+ * Metabox Markup
529
+ *
530
+ * @param object $post Post object.
531
+ * @return void
532
+ */
533
+ public function sandbox_meta_box( $post ) {
534
+
535
+ // Get defaults.
536
+ $meta = self::get_current_post_meta( $post->ID );
537
+
538
+ /**
539
+ * Get options
540
+ */
541
+ foreach ( $meta as $key => $value ) {
542
+ $updated_data[ $key ] = $meta[ $key ]['default'];
543
+ }
544
+
545
+ do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
+ $this->sandbox_markup( $updated_data );
547
+ do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
+ }
549
+
550
+ /**
551
+ * Page Header Tabs
552
+ *
553
+ * @param array $options Post meta.
554
+ * @return void
555
+ */
556
+ public function page_header_tab( $options ) {
557
+
558
+ include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
+ }
560
+
561
+ /**
562
+ * Sandbox Markup
563
+ *
564
+ * @param array $options Post meta.
565
+ * @return void
566
+ */
567
+ public function sandbox_markup( $options ) {
568
+ ?>
569
+ <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
+ <div class="wcf-flow-sandbox-table-container">
571
+ <?php
572
+ echo wcf()->meta->get_checkbox_field(
573
+ array(
574
+ 'name' => 'wcf-testing',
575
+ 'value' => $options['wcf-testing'],
576
+ 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
+ )
578
+ );
579
+
580
+ echo wcf()->meta->get_description_field(
581
+ array(
582
+ 'name' => 'wcf-testing-note',
583
+ 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
+ )
585
+ );
586
+
587
+ ?>
588
+ </div>
589
+ </div>
590
+ <?php
591
+ }
592
+
593
+ /**
594
+ * Keep the menu open when editing the flows.
595
+ * Highlights the wanted admin (sub-) menu items for the CPT.
596
+ *
597
+ * @since 1.0.0
598
+ */
599
+ public function menu_highlight() {
600
+ global $parent_file, $submenu_file, $post_type;
601
+ if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
+ $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
+ $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
+ endif;
605
+ }
606
+
607
+ /**
608
+ * Get metabox options
609
+ *
610
+ * @param int $post_id post id.
611
+ * @return array
612
+ */
613
+ public static function get_meta_option( $post_id ) {
614
+
615
+ if ( null === self::$meta_option ) {
616
+ /**
617
+ * Set metabox options
618
+ */
619
+ self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
+ }
621
+
622
+ return self::$meta_option;
623
+ }
624
+
625
+ /**
626
+ * Get metabox options
627
+ *
628
+ * @param int $post_id post ID.
629
+ * @return array
630
+ */
631
+ public static function get_current_post_meta( $post_id ) {
632
+
633
+ $stored = get_post_meta( $post_id );
634
+
635
+ $default_meta = self::get_meta_option( $post_id );
636
+
637
+ // Set stored and override defaults.
638
+ foreach ( $stored as $key => $value ) {
639
+ if ( array_key_exists( $key, $default_meta ) ) {
640
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
+ } else {
642
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
+ }
644
+ }
645
+
646
+ return self::get_meta_option( $post_id );
647
+ }
648
+
649
+ /**
650
+ * Metabox Save
651
+ *
652
+ * @param number $post_id Post ID.
653
+ * @return void
654
+ */
655
+ public function save_meta_box( $post_id ) {
656
+
657
+ // Checks save status.
658
+ $is_autosave = wp_is_post_autosave( $post_id );
659
+ $is_revision = wp_is_post_revision( $post_id );
660
+
661
+ $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
+
663
+ // Exits script depending on save status.
664
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
+ return;
666
+ }
667
+
668
+ wcf()->options->save_flow_fields( $post_id );
669
+ }
670
+
671
+ /**
672
+ * Localize variables in admin
673
+ *
674
+ * @param array $vars variables.
675
+ */
676
+ public function localize_vars( $vars ) {
677
+
678
+ $ajax_actions = array(
679
+ 'wcf_setup_default_steps',
680
+ 'wcf_add_flow_step',
681
+ 'wcf_delete_flow_step',
682
+ 'wcf_reorder_flow_steps',
683
+ );
684
+
685
+ foreach ( $ajax_actions as $action ) {
686
+
687
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
+ }
689
+
690
+ return $vars;
691
+ }
692
+
693
+ /**
694
+ * Add New Step Button
695
+ *
696
+ * @return string
697
+ */
698
+ public function add_add_new_step_button() {
699
+ $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
+ $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
+ $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
+ $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
+ $add_new_btn_markup .= '</button>';
704
+ $add_new_btn_markup .= '</div>';
705
+
706
+ return $add_new_btn_markup;
707
+ }
708
+
709
+ /**
710
+ * Back to flow button gutenberg template
711
+ *
712
+ * @return void
713
+ */
714
+ public function gutenberg_module_templates() {
715
+
716
+ // Exit if block editor is not enabled.
717
+ if ( ! $this->is_gutenberg_editor_active ) {
718
+ return;
719
+ }
720
+
721
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
+ return;
723
+ }
724
+
725
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
+
727
+ if ( $flow_id ) {
728
+ ?>
729
+ <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
+ <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
+ <i class="dashicons dashicons-arrow-left-alt"></i>
733
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
+ </a>
735
+ </div>
736
+ </script>
737
+ <?php
738
+ }
739
+ }
740
+
741
+ /**
742
+ * Set status true for gutenberg.
743
+ *
744
+ * @return void
745
+ */
746
+ public function set_block_editor_status() {
747
+
748
+ if ( ! current_user_can( 'manage_options' ) ) {
749
+ return;
750
+ }
751
+
752
+ // Set gutenberg status here.
753
+ $this->is_gutenberg_editor_active = true;
754
+ }
755
+ }
756
+
757
+ /**
758
+ * Kicking this off by calling 'get_instance()' method
759
+ */
760
+ Cartflows_Flow_Meta::get_instance();
modules/flow/classes/class-cartflows-step-post-type.php CHANGED
@@ -1,500 +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
- $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();
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/flow/view/meta-flow-steps.php CHANGED
@@ -1,210 +1,210 @@
1
- <?php
2
- /**
3
- * View Flow steps
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
-
10
- $steps = array(
11
- 'landing' => __( 'Landing', 'cartflows' ),
12
- 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
- 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
- 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
- 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
- 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
- );
18
-
19
- ?>
20
- <div class="wcf-flow-steps-meta-box">
21
- <div class="wcf-flow-settings">
22
- <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
- <div class="wcf-flow-steps-wrap">
24
- <div class="wcf-flow-steps-container">
25
- <?php if ( is_array( $options['steps'] ) ) { ?>
26
- <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
- <?php
28
- $term_slug = '';
29
- $term_name = '';
30
- $step_wrap_class = '';
31
- $has_product_assigned = true;
32
- $is_global_checkout = '';
33
- $common = '';
34
- $data_step_id = intval( $data['id'] );
35
-
36
- if ( isset( $data['type'] ) ) {
37
- $term_slug = $data['type'];
38
- $term_name = $steps[ $data['type'] ];
39
- }
40
-
41
- if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
- $step_wrap_class .= ' invalid-step';
43
- }
44
-
45
- if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
-
47
- $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
-
49
- if ( $highlight_step_id === $data_step_id ) {
50
- $step_wrap_class .= ' wcf-new-step-highlight';
51
- }
52
- }
53
-
54
- if ( 'checkout' === $term_slug ) {
55
-
56
- $common = Cartflows_Helper::get_common_settings();
57
-
58
- $is_global_checkout = (int) $common['global_checkout'];
59
-
60
- if ( $data['id'] === $is_global_checkout ) {
61
- $step_wrap_class .= ' wcf-global-checkout';
62
- }
63
- }
64
-
65
- if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
-
67
- $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
-
69
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
- $step_wrap_class .= ' wcf-no-product-step';
71
- }
72
- }
73
-
74
- ?>
75
- <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
- <div class="wcf-step">
77
- <div class="wcf-step-left-content">
78
- <span class="dashicons dashicons-menu"></span>
79
- <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
- <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
-
82
- <?php
83
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
- ?>
85
- <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
- <?php
87
- } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
- ?>
89
- <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
- <?php
91
- } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
- ?>
93
- <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
- <?php
95
- }
96
- ?>
97
-
98
- <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
- <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
- </div>
101
- <div class="wcf-steps-action-buttons">
102
- <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
- <span class="dashicons dashicons-visibility"></span>
104
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
- </a>
106
- <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
- <span class="dashicons dashicons-edit"></span>
108
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
- </a>
110
- <?php
111
- if ( _is_cartflows_pro() ) {
112
- ?>
113
- <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
- <span class="dashicons dashicons-admin-page"></span>
115
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
- </a>
117
- <?php } ?>
118
- <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
- <span class="dashicons dashicons-trash"></span>
120
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
- </a>
122
- </div>
123
- </div>
124
- </div><!-- .wcf-step-wrap -->
125
- <?php } ?>
126
- <?php } ?>
127
- </div><!-- .wcf-flow-steps-container -->
128
- </div> <!-- .wcf-flow-steps-wrap -->
129
- <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
- <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
- <div class='wcf-add-new-step-btn-wrap'>
132
- <button class='wcf-trigger-popup button button-primary'>
133
- <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
- </button>
135
- </div>
136
- </div><!-- .wcf-flow-buttons-wrap -->
137
- </div><!-- .wcf-flow-settings -->
138
-
139
- <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
- <div class="wcf-templates-popup-content">
141
- <div class="spinner"></div>
142
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
-
144
- <div id="wcf-remote-step-actions" class="wcf-template-header">
145
- <div class="wcf-template-logo-wrap">
146
- <span class="wcf-cartflows-logo-img">
147
- <span class="cartflows-logo-icon"></span>
148
- </span>
149
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
- </div>
151
- <div class="wcf-tab-wrapper">
152
- <?php if ( 'other' !== $default_page_builder ) { ?>
153
- <div id="wcf-get-started-steps">
154
- <ul class="filter-links ">
155
- <li>
156
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
157
- </li>
158
- <li>
159
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
- </li>
161
- </ul>
162
- </div>
163
- <?php } ?>
164
- </div>
165
- <div class="wcf-popup-close-wrap">
166
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
- </div>
168
- </div>
169
-
170
- <!--<div class="wcf-search-form">
171
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
- </div>-->
174
-
175
- <div id="wcf-remote-content">
176
- <?php if ( 'other' !== $default_page_builder ) { ?>
177
- <div id="wcf-ready-templates">
178
- <div id="wcf-remote-filters">
179
- <div id="wcf-page-builders"></div>
180
- <div id="wcf-categories"></div>
181
- </div>
182
- <div class="wcf-page-builder-notice"></div>
183
- <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
- </div>
186
- <?php } ?>
187
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
- <div class="inner">
189
- <div id="wcf-scratch-steps-categories">
190
- <select class="step-type-filter-links filter-links">
191
- <option value="" class="current"> Select Step Type </option>
192
-
193
- <?php foreach ( $steps as $key => $value ) { ?>
194
- <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
- <?php } ?>
196
- </select>
197
- </div>
198
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
- <?php if ( ! _is_cartflows_pro() ) { ?>
200
- <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
- <?php } ?>
202
- <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
- </div><!-- .wcf-templates-popup-overlay -->
209
- </div>
210
- <?php
1
+ <?php
2
+ /**
3
+ * View Flow steps
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
+
10
+ $steps = array(
11
+ 'landing' => __( 'Landing', 'cartflows' ),
12
+ 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
+ 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
+ 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
+ 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
+ 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
+ );
18
+
19
+ ?>
20
+ <div class="wcf-flow-steps-meta-box">
21
+ <div class="wcf-flow-settings">
22
+ <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
+ <div class="wcf-flow-steps-wrap">
24
+ <div class="wcf-flow-steps-container">
25
+ <?php if ( is_array( $options['steps'] ) ) { ?>
26
+ <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
+ <?php
28
+ $term_slug = '';
29
+ $term_name = '';
30
+ $step_wrap_class = '';
31
+ $has_product_assigned = true;
32
+ $is_global_checkout = '';
33
+ $common = '';
34
+ $data_step_id = intval( $data['id'] );
35
+
36
+ if ( isset( $data['type'] ) ) {
37
+ $term_slug = $data['type'];
38
+ $term_name = $steps[ $data['type'] ];
39
+ }
40
+
41
+ if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
+ $step_wrap_class .= ' invalid-step';
43
+ }
44
+
45
+ if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
+
47
+ $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
+
49
+ if ( $highlight_step_id === $data_step_id ) {
50
+ $step_wrap_class .= ' wcf-new-step-highlight';
51
+ }
52
+ }
53
+
54
+ if ( 'checkout' === $term_slug ) {
55
+
56
+ $common = Cartflows_Helper::get_common_settings();
57
+
58
+ $is_global_checkout = (int) $common['global_checkout'];
59
+
60
+ if ( $data['id'] === $is_global_checkout ) {
61
+ $step_wrap_class .= ' wcf-global-checkout';
62
+ }
63
+ }
64
+
65
+ if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
+
67
+ $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
+
69
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
+ $step_wrap_class .= ' wcf-no-product-step';
71
+ }
72
+ }
73
+
74
+ ?>
75
+ <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
+ <div class="wcf-step">
77
+ <div class="wcf-step-left-content">
78
+ <span class="dashicons dashicons-menu"></span>
79
+ <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
+ <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
+
82
+ <?php
83
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
+ ?>
85
+ <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
+ <?php
87
+ } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
+ ?>
89
+ <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
+ <?php
91
+ } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
+ ?>
93
+ <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
+ <?php
95
+ }
96
+ ?>
97
+
98
+ <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
+ <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
+ </div>
101
+ <div class="wcf-steps-action-buttons">
102
+ <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
+ <span class="dashicons dashicons-visibility"></span>
104
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
+ </a>
106
+ <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
+ <span class="dashicons dashicons-edit"></span>
108
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
+ </a>
110
+ <?php
111
+ if ( _is_cartflows_pro() ) {
112
+ ?>
113
+ <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
+ <span class="dashicons dashicons-admin-page"></span>
115
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
+ </a>
117
+ <?php } ?>
118
+ <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
+ <span class="dashicons dashicons-trash"></span>
120
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
+ </a>
122
+ </div>
123
+ </div>
124
+ </div><!-- .wcf-step-wrap -->
125
+ <?php } ?>
126
+ <?php } ?>
127
+ </div><!-- .wcf-flow-steps-container -->
128
+ </div> <!-- .wcf-flow-steps-wrap -->
129
+ <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
+ <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
+ <div class='wcf-add-new-step-btn-wrap'>
132
+ <button class='wcf-trigger-popup button button-primary'>
133
+ <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
+ </button>
135
+ </div>
136
+ </div><!-- .wcf-flow-buttons-wrap -->
137
+ </div><!-- .wcf-flow-settings -->
138
+
139
+ <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
+ <div class="wcf-templates-popup-content">
141
+ <div class="spinner"></div>
142
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
+
144
+ <div id="wcf-remote-step-actions" class="wcf-template-header">
145
+ <div class="wcf-template-logo-wrap">
146
+ <span class="wcf-cartflows-logo-img">
147
+ <span class="cartflows-logo-icon"></span>
148
+ </span>
149
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
+ </div>
151
+ <div class="wcf-tab-wrapper">
152
+ <?php if ( 'other' !== $default_page_builder ) { ?>
153
+ <div id="wcf-get-started-steps">
154
+ <ul class="filter-links ">
155
+ <li>
156
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
157
+ </li>
158
+ <li>
159
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
+ </li>
161
+ </ul>
162
+ </div>
163
+ <?php } ?>
164
+ </div>
165
+ <div class="wcf-popup-close-wrap">
166
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
+ </div>
168
+ </div>
169
+
170
+ <!--<div class="wcf-search-form">
171
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
+ </div>-->
174
+
175
+ <div id="wcf-remote-content">
176
+ <?php if ( 'other' !== $default_page_builder ) { ?>
177
+ <div id="wcf-ready-templates">
178
+ <div id="wcf-remote-filters">
179
+ <div id="wcf-page-builders"></div>
180
+ <div id="wcf-categories"></div>
181
+ </div>
182
+ <div class="wcf-page-builder-notice"></div>
183
+ <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
+ </div>
186
+ <?php } ?>
187
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
+ <div class="inner">
189
+ <div id="wcf-scratch-steps-categories">
190
+ <select class="step-type-filter-links filter-links">
191
+ <option value="" class="current"> Select Step Type </option>
192
+
193
+ <?php foreach ( $steps as $key => $value ) { ?>
194
+ <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
+ <?php } ?>
196
+ </select>
197
+ </div>
198
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
+ <?php if ( ! _is_cartflows_pro() ) { ?>
200
+ <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
+ <?php } ?>
202
+ <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ </div><!-- .wcf-templates-popup-overlay -->
209
+ </div>
210
+ <?php
modules/thankyou/classes/class-cartflows-thankyou-markup.php CHANGED
@@ -1,374 +1,314 @@
1
- <?php
2
- /**
3
- * Front end and markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Thankyou_Markup {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- /* Downsell Shortcode */
39
- add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
40
-
41
- add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
42
-
43
- add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
44
-
45
- /* Set is checkout flag */
46
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
47
-
48
- /* Custom redirection of thank you page */
49
- add_action( 'template_redirect', array( $this, 'redirect_tq_page_to_custom_url' ) );
50
-
51
- add_action( 'cartflows_thank_you_scripts', array( $this, 'add_divi_compatibility_css' ) );
52
- }
53
-
54
- /**
55
- * Redirect to custom url instead of thank you page.
56
- */
57
- public function redirect_tq_page_to_custom_url() {
58
- global $post;
59
-
60
- if ( _is_wcf_thankyou_type() ) {
61
-
62
- $thank_you_id = $post->ID;
63
- $enable_redirection = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-tq-redirect-section' );
64
- $redirect_link = wp_http_validate_url( wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-redirect-link' ) );
65
-
66
- if ( 'yes' === $enable_redirection && ! empty( $redirect_link ) ) {
67
- exit( wp_redirect( $redirect_link ) ); //phpcs:ignore
68
- }
69
- }
70
- }
71
- /**
72
- * Order shortcode markup
73
- *
74
- * @param array $atts attributes.
75
- * @since 1.0.0
76
- */
77
- public function cartflows_order_details_shortcode_markup( $atts ) {
78
-
79
- $output = '';
80
-
81
- if ( _is_wcf_thankyou_type() ) {
82
- /* Remove order item link */
83
- add_filter( 'woocommerce_order_item_permalink', '__return_false' );
84
-
85
- /* Change order text */
86
- add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'custom_tq_text' ), 10, 2 );
87
-
88
- if ( ! function_exists( 'wc_print_notices' ) ) {
89
-
90
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
91
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
92
-
93
- return $notice_out;
94
- }
95
-
96
- $order = false;
97
-
98
- $id_param = 'wcf-order';
99
- $key_param = 'wcf-key';
100
-
101
- if ( isset( $_GET['wcf-opt-order'] ) ) { //phpcs:ignore
102
- $id_param = 'wcf-opt-order';
103
- $key_param = 'wcf-opt-key';
104
- }
105
-
106
- if ( ! isset( $_GET[ $id_param ] ) && wcf()->flow->is_flow_testmode() ) { //phpcs:ignore
107
- $args = array(
108
- 'limit' => 1,
109
- 'order' => 'DESC',
110
- 'post_type' => 'shop_order',
111
- 'status' => array( 'completed', 'processing' ),
112
- );
113
-
114
- $latest_order = wc_get_orders( $args );
115
-
116
- $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
117
-
118
- if ( $order_id > 0 ) {
119
- $order = wc_get_order( $order_id );
120
-
121
- if ( ! $order ) {
122
- $order = false;
123
- }
124
- }
125
- } else {
126
- if ( ! isset( $_GET[ $id_param ] ) ) { //phpcs:ignore
127
- return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
128
- }
129
-
130
- // Get the order.
131
- $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET[ $id_param ] ) ? 0 : intval( $_GET[ $id_param ] ) ); //phpcs:ignore
132
- $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET[ $key_param ] ) ? '' : wc_clean( wp_unslash( $_GET[ $key_param ] ) ) ); //phpcs:ignore
133
-
134
- if ( $order_id > 0 ) {
135
- $order = wc_get_order( $order_id );
136
-
137
- if ( ! $order || $order->get_order_key() !== $order_key ) {
138
- $order = false;
139
- }
140
- }
141
- }
142
-
143
- // Empty awaiting payment session.
144
- unset( WC()->session->order_awaiting_payment );
145
-
146
- if ( null !== WC()->session ) {
147
- if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
148
- WC()->cart = new WC_Cart();
149
- }
150
-
151
- if ( ! WC()->cart->is_empty() ) {
152
- // wc_empty_cart();
153
- // Empty current cart.
154
- WC()->cart->empty_cart( true );
155
-
156
- wc_clear_notices();
157
- }
158
-
159
- wc_print_notices();
160
- }
161
-
162
- do_action( 'cartflows_thankyou_details_before', $order );
163
-
164
- ob_start();
165
- echo "<div class='wcf-thankyou-wrap' id='wcf-thankyou-wrap'>";
166
- wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
167
- echo '</div>';
168
- $output = ob_get_clean();
169
- }
170
-
171
- return $output;
172
- }
173
-
174
- /**
175
- * Load Thank You scripts.
176
- *
177
- * @return void
178
- */
179
- public function thank_you_scripts() {
180
-
181
- if ( _is_wcf_thankyou_type() ) {
182
-
183
- do_action( 'cartflows_thank_you_scripts' );
184
-
185
- $style = $this->generate_thank_you_style();
186
-
187
- wp_add_inline_style( 'wcf-frontend-global', $style );
188
- }
189
- }
190
-
191
- /**
192
- * Load DIVI compatibility Thank You style.
193
- *
194
- * @return void
195
- */
196
- public function add_divi_compatibility_css() {
197
-
198
- global $post;
199
-
200
- $thank_you_id = $post->ID;
201
-
202
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
203
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id )
204
- ) {
205
- wp_enqueue_style( 'wcf-frontend-global-divi', wcf()->utils->get_css_url( 'frontend-divi' ), array(), CARTFLOWS_VER );
206
- }
207
- }
208
-
209
- /**
210
- * Set thank you as a order received page.
211
- *
212
- * @param boolean $is_order_page order page.
213
- * @return boolean
214
- */
215
- public function set_order_received_page( $is_order_page ) {
216
-
217
- if ( _is_wcf_thankyou_type() ) {
218
- $is_order_page = true;
219
- }
220
-
221
- return $is_order_page;
222
- }
223
-
224
- /**
225
- * Generate Thank You Styles.
226
- *
227
- * @return string
228
- */
229
- public function generate_thank_you_style() {
230
-
231
- global $post;
232
-
233
- if ( _is_wcf_thankyou_type() ) {
234
- $thank_you_id = $post->ID;
235
- } else {
236
- $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
237
- }
238
-
239
- CartFlows_Font_Families::render_fonts( $thank_you_id );
240
-
241
- $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
242
- $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
243
- $text_font_size = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-size' );
244
- $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
245
- $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
246
- $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
247
- $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
248
- $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
249
-
250
- $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
251
-
252
- $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
253
-
254
- $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
255
-
256
- $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
257
-
258
- $output = "
259
- .wcf-thankyou-wrap{
260
- color: {$text_color};
261
- font-family: {$text_font_family};
262
- max-width:{$container_width}px;
263
- font-size: {$text_font_size}px;
264
- }
265
-
266
- .woocommerce-order h2.woocommerce-column__title,
267
- .woocommerce-order h2.woocommerce-order-details__title,
268
- .woocommerce-order .woocommerce-thankyou-order-received,
269
- .woocommerce-order-details h2,
270
- .woocommerce-order h2.wc-bacs-bank-details-heading,
271
- .woocommerce-order h2.woocommerce-order-downloads__title {
272
- color: {$heading_text_color};
273
- font-family: {$heading_font_family};
274
- font-weight: {$heading_font_weight};
275
- }
276
-
277
- .woocommerce-order ul.order_details,
278
- .woocommerce-order .woocommerce-order-details,
279
- .woocommerce-order .woocommerce-customer-details,
280
- .woocommerce-order .woocommerce-bacs-bank-details,
281
- .woocommerce-order .woocommerce-order-downloads{
282
- background-color: {$section_bg_color}
283
- }
284
- img.emoji, img.wp-smiley {}
285
- ";
286
-
287
- if ( 'no' == $show_order_review ) {
288
- $output .= '
289
- .woocommerce-order ul.order_details{
290
- display: none;
291
- }
292
- ';
293
- }
294
-
295
- if ( 'no' == $show_order_details ) {
296
- $output .= '
297
- .woocommerce-order .woocommerce-order-details{
298
- display: none;
299
- }
300
- ';
301
- }
302
-
303
- if ( 'no' == $show_billing_details ) {
304
- $output .= '
305
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
306
- display: none;
307
- }
308
- ';
309
- }
310
-
311
- if ( 'no' == $show_shipping_details ) {
312
- $output .= '
313
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
314
- display: none;
315
- }
316
- ';
317
- }
318
-
319
- if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
320
- $output .= '
321
- .woocommerce-order .woocommerce-customer-details{
322
- display: none;
323
- }
324
- ';
325
- }
326
-
327
- return $output;
328
- }
329
-
330
- /**
331
- * Set as a checkout page if it is thank you page.
332
- * Thank you page need to be set as a checkout page.
333
- * Becauye ayment gateways will not load if it is not checkout.
334
- *
335
- * @param bool $is_checkout is checkout.
336
- *
337
- * @return bool
338
- */
339
- public function woo_checkout_flag( $is_checkout ) {
340
-
341
- if ( ! is_admin() ) {
342
- if ( _is_wcf_thankyou_type() ) {
343
- $is_checkout = true;
344
- }
345
- }
346
-
347
- return $is_checkout;
348
- }
349
-
350
- /**
351
- * Add custom text on thank you page.
352
- *
353
- * @param string $woo_text Default text.
354
- * @param int $order order.
355
- */
356
- public function custom_tq_text( $woo_text, $order ) {
357
-
358
- global $post;
359
-
360
- $thank_you_id = $post->ID;
361
- $new_text = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text' );
362
-
363
- if ( ! empty( $new_text ) ) {
364
- $woo_text = do_shortcode( $new_text );
365
- }
366
-
367
- return $woo_text;
368
- }
369
- }
370
-
371
- /**
372
- * Kicking this off by calling 'get_instance()' method
373
- */
374
- Cartflows_Thankyou_Markup::get_instance();
1
+ <?php
2
+ /**
3
+ * Front end and markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Thankyou_Markup {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ /* Downsell Shortcode */
39
+ add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
40
+
41
+ add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
42
+
43
+ add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
44
+
45
+ /* Set is checkout flag */
46
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
47
+
48
+ /* Custom redirection of thank you page */
49
+ add_action( 'template_redirect', array( $this, 'redirect_tq_page_to_custom_url' ) );
50
+
51
+ add_action( 'cartflows_thank_you_scripts', array( $this, 'add_divi_compatibility_css' ) );
52
+ }
53
+
54
+ /**
55
+ * Redirect to custom url instead of thank you page.
56
+ */
57
+ public function redirect_tq_page_to_custom_url() {
58
+ global $post;
59
+
60
+ if ( _is_wcf_thankyou_type() ) {
61
+
62
+ $thank_you_id = $post->ID;
63
+ $enable_redirection = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-tq-redirect-section' );
64
+ $redirect_link = wp_http_validate_url( wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-redirect-link' ) );
65
+
66
+ if ( 'yes' === $enable_redirection && ! empty( $redirect_link ) ) {
67
+ exit( wp_redirect( $redirect_link ) ); //phpcs:ignore
68
+ }
69
+ }
70
+ }
71
+ /**
72
+ * Order shortcode markup
73
+ *
74
+ * @param array $atts attributes.
75
+ * @since 1.0.0
76
+ */
77
+ public function cartflows_order_details_shortcode_markup( $atts ) {
78
+
79
+ $output = '';
80
+
81
+ if ( _is_wcf_thankyou_type() ) {
82
+ /* Remove order item link */
83
+ add_filter( 'woocommerce_order_item_permalink', '__return_false' );
84
+
85
+ /* Change order text */
86
+ add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'custom_tq_text' ), 10, 2 );
87
+
88
+ if ( ! function_exists( 'wc_print_notices' ) ) {
89
+
90
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
91
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
92
+
93
+ return $notice_out;
94
+ }
95
+
96
+ $order = false;
97
+
98
+ $id_param = 'wcf-order';
99
+ $key_param = 'wcf-key';
100
+
101
+ if ( isset( $_GET['wcf-opt-order'] ) ) { //phpcs:ignore
102
+ $id_param = 'wcf-opt-order';
103
+ $key_param = 'wcf-opt-key';
104
+ }
105
+
106
+ if ( ! isset( $_GET[ $id_param ] ) && wcf()->flow->is_flow_testmode() ) { //phpcs:ignore
107
+ $args = array(
108
+ 'limit' => 1,
109
+ 'order' => 'DESC',
110
+ 'post_type' => 'shop_order',
111
+ 'status' => array( 'completed', 'processing' ),
112
+ );
113
+
114
+ $latest_order = wc_get_orders( $args );
115
+
116
+ $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
117
+
118
+ if ( $order_id > 0 ) {
119
+ $order = wc_get_order( $order_id );
120
+
121
+ if ( ! $order ) {
122
+ $order = false;
123
+ }
124
+ }
125
+ } else {
126
+ if ( ! isset( $_GET[ $id_param ] ) ) { //phpcs:ignore
127
+ return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
128
+ }
129
+
130
+ // Get the order.
131
+ $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET[ $id_param ] ) ? 0 : intval( $_GET[ $id_param ] ) ); //phpcs:ignore
132
+ $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET[ $key_param ] ) ? '' : wc_clean( wp_unslash( $_GET[ $key_param ] ) ) ); //phpcs:ignore
133
+
134
+ if ( $order_id > 0 ) {
135
+ $order = wc_get_order( $order_id );
136
+
137
+ if ( ! $order || $order->get_order_key() !== $order_key ) {
138
+ $order = false;
139
+ }
140
+ }
141
+ }
142
+
143
+ // Empty awaiting payment session.
144
+ unset( WC()->session->order_awaiting_payment );
145
+
146
+ if ( null !== WC()->session ) {
147
+ if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
148
+ WC()->cart = new WC_Cart();
149
+ }
150
+
151
+ if ( ! WC()->cart->is_empty() ) {
152
+ // wc_empty_cart();
153
+ // Empty current cart.
154
+ WC()->cart->empty_cart( true );
155
+
156
+ wc_clear_notices();
157
+ }
158
+
159
+ wc_print_notices();
160
+ }
161
+
162
+ do_action( 'cartflows_thankyou_details_before', $order );
163
+
164
+ ob_start();
165
+ echo "<div class='wcf-thankyou-wrap' id='wcf-thankyou-wrap'>";
166
+ wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
167
+ echo '</div>';
168
+ $output = ob_get_clean();
169
+ }
170
+
171
+ return $output;
172
+ }
173
+
174
+ /**
175
+ * Load Thank You scripts.
176
+ *
177
+ * @return void
178
+ */
179
+ public function thank_you_scripts() {
180
+
181
+ if ( _is_wcf_thankyou_type() ) {
182
+
183
+ do_action( 'cartflows_thank_you_scripts' );
184
+
185
+ $style = $this->generate_thank_you_style();
186
+
187
+ wp_add_inline_style( 'wcf-frontend-global', $style );
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Load DIVI compatibility Thank You style.
193
+ *
194
+ * @return void
195
+ */
196
+ public function add_divi_compatibility_css() {
197
+
198
+ global $post;
199
+
200
+ $thank_you_id = $post->ID;
201
+
202
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
203
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id )
204
+ ) {
205
+ wp_enqueue_style( 'wcf-frontend-global-divi', wcf()->utils->get_css_url( 'frontend-divi' ), array(), CARTFLOWS_VER );
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Set thank you as a order received page.
211
+ *
212
+ * @param boolean $is_order_page order page.
213
+ * @return boolean
214
+ */
215
+ public function set_order_received_page( $is_order_page ) {
216
+
217
+ if ( _is_wcf_thankyou_type() ) {
218
+ $is_order_page = true;
219
+ }
220
+
221
+ return $is_order_page;
222
+ }
223
+
224
+ /**
225
+ * Generate Thank You Styles.
226
+ *
227
+ * @return string
228
+ */
229
+ public function generate_thank_you_style() {
230
+
231
+ global $post;
232
+
233
+ if ( _is_wcf_thankyou_type() ) {
234
+ $thank_you_id = $post->ID;
235
+ } else {
236
+ $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
237
+ }
238
+
239
+ CartFlows_Font_Families::render_fonts( $thank_you_id );
240
+
241
+ $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
242
+ $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
243
+ $text_font_size = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-size' );
244
+ $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
245
+ $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
246
+ $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
247
+ $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
248
+ $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
249
+
250
+ $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
251
+
252
+ $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
253
+
254
+ $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
255
+
256
+ $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
257
+
258
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
259
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id ) ) {
260
+
261
+ include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-divi-css.php';
262
+
263
+ } else {
264
+ include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-css.php';
265
+ }
266
+
267
+ return $output;
268
+ }
269
+
270
+ /**
271
+ * Set as a checkout page if it is thank you page.
272
+ * Thank you page need to be set as a checkout page.
273
+ * Becauye ayment gateways will not load if it is not checkout.
274
+ *
275
+ * @param bool $is_checkout is checkout.
276
+ *
277
+ * @return bool
278
+ */
279
+ public function woo_checkout_flag( $is_checkout ) {
280
+
281
+ if ( ! is_admin() ) {
282
+ if ( _is_wcf_thankyou_type() ) {
283
+ $is_checkout = true;
284
+ }
285
+ }
286
+
287
+ return $is_checkout;
288
+ }
289
+
290
+ /**
291
+ * Add custom text on thank you page.
292
+ *
293
+ * @param string $woo_text Default text.
294
+ * @param int $order order.
295
+ */
296
+ public function custom_tq_text( $woo_text, $order ) {
297
+
298
+ global $post;
299
+
300
+ $thank_you_id = $post->ID;
301
+ $new_text = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text' );
302
+
303
+ if ( ! empty( $new_text ) ) {
304
+ $woo_text = do_shortcode( $new_text );
305
+ }
306
+
307
+ return $woo_text;
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Kicking this off by calling 'get_instance()' method
313
+ */
314
+ Cartflows_Thankyou_Markup::get_instance();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
modules/thankyou/includes/thankyou-dynamic-css.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Dynamic Thank you css.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $output = "
9
+
10
+ .wcf-thankyou-wrap{
11
+ color: {$text_color};
12
+ font-family: {$text_font_family};
13
+ max-width:{$container_width}px;
14
+ font-size: {$text_font_size}px;
15
+ }
16
+
17
+ .woocommerce-order h2.woocommerce-column__title,
18
+ .woocommerce-order h2.woocommerce-order-details__title,
19
+ .woocommerce-order .woocommerce-thankyou-order-received,
20
+ .woocommerce-order-details h2,
21
+ .woocommerce-order h2.wc-bacs-bank-details-heading,
22
+ .woocommerce-order h2.woocommerce-order-downloads__title {
23
+ color: {$heading_text_color};
24
+ font-family: {$heading_font_family};
25
+ font-weight: {$heading_font_weight};
26
+ }
27
+
28
+ .woocommerce-order ul.order_details,
29
+ .woocommerce-order .woocommerce-order-details,
30
+ .woocommerce-order .woocommerce-customer-details,
31
+ .woocommerce-order .woocommerce-bacs-bank-details,
32
+ .woocommerce-order .woocommerce-order-downloads{
33
+ background-color: {$section_bg_color}
34
+ }
35
+ img.emoji, img.wp-smiley {}
36
+ ";
37
+
38
+ if ( 'no' == $show_order_review ) {
39
+ $output .= '
40
+ .woocommerce-order ul.order_details{
41
+ display: none;
42
+ }
43
+ ';
44
+ }
45
+
46
+ if ( 'no' == $show_order_details ) {
47
+ $output .= '
48
+ .woocommerce-order .woocommerce-order-details{
49
+ display: none;
50
+ }
51
+ ';
52
+ }
53
+
54
+ if ( 'no' == $show_billing_details ) {
55
+ $output .= '
56
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
+ display: none;
58
+ }
59
+ ';
60
+ }
61
+
62
+ if ( 'no' == $show_shipping_details ) {
63
+ $output .= '
64
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
65
+ display: none;
66
+ }
67
+ ';
68
+ }
69
+
70
+ if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
71
+ $output .= '
72
+ .woocommerce-order .woocommerce-customer-details{
73
+ display: none;
74
+ }
75
+ ';
76
+ }
modules/thankyou/includes/thankyou-dynamic-divi-css.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Dynamic DIVI Thank you css.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $output = "
9
+
10
+ .et_pb_module #wcf-thankyou-wrap{
11
+ color: {$text_color};
12
+ font-family: {$text_font_family};
13
+ max-width:{$container_width}px;
14
+ font-size: {$text_font_size}px;
15
+ }
16
+
17
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-column__title,
18
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-details__title,
19
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-thankyou-order-received,
20
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order-details h2,
21
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.wc-bacs-bank-details-heading,
22
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-downloads__title {
23
+ color: {$heading_text_color};
24
+ font-family: {$heading_font_family};
25
+ font-weight: {$heading_font_weight};
26
+ }
27
+
28
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details,
29
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details,
30
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details,
31
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-bacs-bank-details,
32
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-downloads{
33
+ background-color: {$section_bg_color}
34
+ }
35
+ img.emoji, img.wp-smiley {}
36
+ ";
37
+
38
+ if ( 'no' == $show_order_review ) {
39
+ $output .= '
40
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details{
41
+ display: none !important;
42
+ }
43
+ ';
44
+ }
45
+
46
+ if ( 'no' == $show_order_details ) {
47
+ $output .= '
48
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details{
49
+ display: none !important;
50
+ }
51
+ ';
52
+ }
53
+
54
+ if ( 'no' == $show_billing_details ) {
55
+ $output .= '
56
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
+ display: none;
58
+ }
59
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
+ float:left;
61
+ }
62
+ ';
63
+ }
64
+
65
+ if ( 'no' == $show_shipping_details ) {
66
+ $output .= '
67
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
68
+ display: none ;
69
+ }
70
+ ';
71
+ }
72
+
73
+ if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
74
+ $output .= '
75
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details{
76
+ display: none !important;
77
+ }
78
+ ';
79
+ }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: brainstormforce, wpcrafter
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
- Tested up to: 5.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,8 +126,13 @@ 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
  = 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.
3
  Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
+ Tested up to: 5.4.2
7
+ Stable tag: 1.5.12
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
+
130
+ = Version 1.5.12 - Wednesday, 1st July 2020 =
131
+ * Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
132
+ * Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.
133
+
134
  = Version 1.5.11 - Tuesday, 16th June 2020 =
135
+ * New: Users can now share [non-personal usage data](https://my.cartflows.com/usage-tracking/?utm_source=wp_repo&utm_medium=changelog&utm_campaign=usage_tracking) to help us test and develop better products.
136
  * Fix: CartFlows setup wizard.
137
  * Fix: Showing notice 'Remove selected product from checkout' even there is no product selected in Global checkout.
138
  * Fix: Redirected to the cart when the order canceled by a user for PayPal checkout gateway.