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

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

Code changes from version 1.5.4 to 1.5.5

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.4
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.5
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,3 +1,6 @@
 
 
 
1
  Version 1.5.4 - Tuesday, 7th April 2020
2
  - Improvement: Hardened the security of the plugin.
3
  - Fix: Older flows were not displaying in the library.
1
+ Version 1.5.5 - Tuesday, 14th April 2020
2
+ - Fix: CSS conflict with the latest release of Astra theme.
3
+
4
  Version 1.5.4 - Tuesday, 7th April 2020
5
  - Improvement: Hardened the security of the plugin.
6
  - Fix: Older flows were not displaying in the library.
classes/class-cartflows-api.php CHANGED
@@ -1,381 +1,381 @@
1
- <?php
2
- /**
3
- * CartFlows API
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_API' ) ) :
10
-
11
- /**
12
- * CartFlows API
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_API {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @access private
22
- * @var object Class object.
23
- * @since 1.0.0
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- *
43
- * @since 1.0.0
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get site URL.
50
- *
51
- * @since 1.0.0
52
- *
53
- * @return string Site URL.
54
- */
55
- public static function get_site_url() {
56
- return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
- }
58
-
59
- /**
60
- * Get Client Site Templates Rest API URL.
61
- *
62
- * @since 1.0.0
63
- *
64
- * @return string API site URL.
65
- */
66
- public static function get_step_endpoint_url() {
67
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
- }
69
-
70
- /**
71
- * Get Client Site Category Rest API URL.
72
- *
73
- * @since 1.0.0
74
- *
75
- * @return string API site URL.
76
- */
77
- public static function get_category_endpoint_url() {
78
- return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
- }
80
-
81
- /**
82
- * Get API request URL.
83
- *
84
- * @since 1.0.0
85
- *
86
- * @param string $api_base base of api request.
87
- * @return string API site URL.
88
- */
89
- public static function get_request_api_url( $api_base = '' ) {
90
- return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
- }
92
-
93
- /**
94
- * License Args.
95
- *
96
- * @return array License arguments.
97
- */
98
- public static function get_licence_args() {
99
- return apply_filters( 'cartflows_licence_args', array() );
100
- }
101
-
102
- /**
103
- * Get single demo.
104
- *
105
- * @since 1.0.0
106
- *
107
- * @param string $site_id Template ID of the site.
108
- * @return array Template data.
109
- */
110
- public static function get_template( $site_id ) {
111
- // @codingStandardsIgnoreStart
112
- $request_params = array(
113
- 'licence_args' => self::get_licence_args(),
114
- '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta',
115
- );
116
- // @codingStandardsIgnoreEnd
117
-
118
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
-
120
- $api_args = array(
121
- 'timeout' => 15,
122
- );
123
-
124
- $response = self::remote_get( $url, $api_args );
125
-
126
- if ( $response['success'] ) {
127
- $template = $response['data'];
128
- return array(
129
- 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
- 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
- 'data' => $template,
132
- 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
- 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
134
- 'success' => $response['success'],
135
- );
136
- }
137
-
138
- return array(
139
- 'title' => '',
140
- 'post_meta' => array(),
141
- 'message' => $response['message'],
142
- 'data' => $response['data'],
143
- 'divi_content' => '',
144
- 'success' => $response['success'],
145
- );
146
- }
147
-
148
- /**
149
- * Get Cloud Templates
150
- *
151
- * @since 1.0.0
152
- *
153
- * @param array $args For selecting the demos (Search terms, pagination etc).
154
- * @return array CartFlows list.
155
- */
156
- public static function get_templates( $args = array() ) {
157
-
158
- $request_params = wp_parse_args(
159
- $args,
160
- array(
161
- 'page' => '1',
162
- 'per_page' => '100',
163
- )
164
- );
165
-
166
- $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
167
-
168
- $api_args = array(
169
- 'timeout' => 15,
170
- );
171
-
172
- $response = self::remote_get( $url, $api_args );
173
-
174
- if ( $response['success'] ) {
175
- $templates_data = $response['data'];
176
- $templates = array();
177
- foreach ( $templates_data as $key => $template ) {
178
-
179
- if ( ! isset( $template->id ) ) {
180
- continue;
181
- }
182
-
183
- $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
184
- $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
185
- $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
186
- $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
187
- $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
188
- $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
189
- $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
190
- $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
191
- $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
192
- }
193
-
194
- return array(
195
- 'templates' => $templates,
196
- 'templates_count' => $response['count'],
197
- 'data' => $response,
198
- );
199
- }
200
-
201
- return array(
202
- 'templates' => array(),
203
- 'templates_count' => 0,
204
- 'data' => $response,
205
- );
206
-
207
- }
208
-
209
- /**
210
- * Get categories.
211
- *
212
- * @since 1.0.0
213
- * @param array $args Arguments.
214
- * @return array Category data.
215
- */
216
- public static function get_categories( $args = array() ) {
217
-
218
- $request_params = apply_filters(
219
- 'cartflows_categories_api_params',
220
- wp_parse_args(
221
- $args,
222
- array(
223
- 'page' => '1',
224
- 'per_page' => '100',
225
- )
226
- )
227
- );
228
-
229
- $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
230
-
231
- $api_args = apply_filters(
232
- 'cartflows_api_args',
233
- array(
234
- 'timeout' => 15,
235
- )
236
- );
237
-
238
- $response = self::remote_get( $url, $api_args );
239
-
240
- if ( $response['success'] ) {
241
- $categories_data = $response['data'];
242
- $categories = array();
243
-
244
- foreach ( $categories_data as $key => $category ) {
245
- if ( isset( $category->count ) && ! empty( $category->count ) ) {
246
- $categories[] = array(
247
- 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
248
- 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
249
- 'description' => isset( $category->description ) ? $category->description : '',
250
- 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
251
- 'name' => isset( $category->name ) ? $category->name : '',
252
- 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
253
- 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
254
- 'parent' => isset( $category->parent ) ? $category->parent : '',
255
- );
256
- }
257
- }
258
-
259
- return array(
260
- 'categories' => $categories,
261
- 'categories_count' => $response['count'],
262
- 'data' => $response,
263
- );
264
- }
265
-
266
- return array(
267
- 'categories' => array(),
268
- 'categories_count' => 0,
269
- 'data' => $response,
270
- );
271
- }
272
-
273
- /**
274
- * Remote GET API Request
275
- *
276
- * @since 1.0.0
277
- *
278
- * @param string $url Target server API URL.
279
- * @param array $args Array of arguments for the API request.
280
- * @return mixed Return the API request result.
281
- */
282
- public static function remote_get( $url = '', $args = array() ) {
283
- $request = wp_remote_get( $url, $args );
284
- return self::request( $request );
285
- }
286
-
287
- /**
288
- * Remote POST API Request
289
- *
290
- * @since 1.0.0
291
- *
292
- * @param string $url Target server API URL.
293
- * @param array $args Array of arguments for the API request.
294
- * @return mixed Return the API request result.
295
- */
296
- public static function remote_post( $url = '', $args = array() ) {
297
- $request = wp_remote_post( $url, $args );
298
-
299
- return self::request( $request );
300
- }
301
-
302
- /**
303
- * Site API Request
304
- *
305
- * @since 1.0.0
306
- *
307
- * @param boolean $api_base Target server API URL.
308
- * @param array $args Array of arguments for the API request.
309
- * @return mixed Return the API request result.
310
- */
311
- public static function site_request( $api_base = '', $args = array() ) {
312
-
313
- $api_url = self::get_request_api_url( $api_base );
314
-
315
- return self::remote_post( $api_url, $args );
316
- }
317
-
318
- /**
319
- * API Request
320
- *
321
- * Handle the API request and return the result.
322
- *
323
- * @since 1.0.0
324
- *
325
- * @param array $request Array of arguments for the API request.
326
- * @return mixed Return the API request result.
327
- */
328
- public static function request( $request ) {
329
-
330
- // Is WP Error?
331
- if ( is_wp_error( $request ) ) {
332
- return array(
333
- 'success' => false,
334
- 'message' => $request->get_error_message(),
335
- 'data' => $request,
336
- 'count' => 0,
337
- );
338
- }
339
-
340
- // Invalid response code.
341
- if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
342
- return array(
343
- 'success' => false,
344
- 'message' => $request['response'],
345
- 'data' => $request,
346
- 'count' => 0,
347
- );
348
- }
349
-
350
- // Get body data.
351
- $body = wp_remote_retrieve_body( $request );
352
-
353
- // Is WP Error?
354
- if ( is_wp_error( $body ) ) {
355
- return array(
356
- 'success' => false,
357
- 'message' => $body->get_error_message(),
358
- 'data' => $request,
359
- 'count' => 0,
360
- );
361
- }
362
-
363
- // Decode body content.
364
- $body_decoded = json_decode( $body );
365
-
366
- return array(
367
- 'success' => true,
368
- 'message' => __( 'Request successfully processed!', 'cartflows' ),
369
- 'data' => (array) $body_decoded,
370
- 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
371
- );
372
- }
373
-
374
- }
375
-
376
- /**
377
- * Initialize class object with 'get_instance()' method
378
- */
379
- CartFlows_API::get_instance();
380
-
381
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows API
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_API' ) ) :
10
+
11
+ /**
12
+ * CartFlows API
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_API {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @access private
22
+ * @var object Class object.
23
+ * @since 1.0.0
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ *
43
+ * @since 1.0.0
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get site URL.
50
+ *
51
+ * @since 1.0.0
52
+ *
53
+ * @return string Site URL.
54
+ */
55
+ public static function get_site_url() {
56
+ return apply_filters( 'cartflows_templates_url', CARTFLOWS_TEMPLATES_URL );
57
+ }
58
+
59
+ /**
60
+ * Get Client Site Templates Rest API URL.
61
+ *
62
+ * @since 1.0.0
63
+ *
64
+ * @return string API site URL.
65
+ */
66
+ public static function get_step_endpoint_url() {
67
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_STEP_POST_TYPE . '/';
68
+ }
69
+
70
+ /**
71
+ * Get Client Site Category Rest API URL.
72
+ *
73
+ * @since 1.0.0
74
+ *
75
+ * @return string API site URL.
76
+ */
77
+ public static function get_category_endpoint_url() {
78
+ return self::get_site_url() . 'wp-json/wp/v2/' . CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER . '/';
79
+ }
80
+
81
+ /**
82
+ * Get API request URL.
83
+ *
84
+ * @since 1.0.0
85
+ *
86
+ * @param string $api_base base of api request.
87
+ * @return string API site URL.
88
+ */
89
+ public static function get_request_api_url( $api_base = '' ) {
90
+ return self::get_site_url() . 'wp-json/' . CARTFLOWS_STEP_POST_TYPE . '/v1/' . $api_base;
91
+ }
92
+
93
+ /**
94
+ * License Args.
95
+ *
96
+ * @return array License arguments.
97
+ */
98
+ public static function get_licence_args() {
99
+ return apply_filters( 'cartflows_licence_args', array() );
100
+ }
101
+
102
+ /**
103
+ * Get single demo.
104
+ *
105
+ * @since 1.0.0
106
+ *
107
+ * @param string $site_id Template ID of the site.
108
+ * @return array Template data.
109
+ */
110
+ public static function get_template( $site_id ) {
111
+ // @codingStandardsIgnoreStart
112
+ $request_params = array(
113
+ 'licence_args' => self::get_licence_args(),
114
+ '_fields' => 'id,slug,status,type,link,title,featured_media,template,cartflows_step_page_builder,cartflows_step_type,cartflows_step_flow,featured_image_url,licence_status,flow_type,step_type,page_builder,divi_content,post_meta',
115
+ );
116
+ // @codingStandardsIgnoreEnd
117
+
118
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() . $site_id );
119
+
120
+ $api_args = array(
121
+ 'timeout' => 15,
122
+ );
123
+
124
+ $response = self::remote_get( $url, $api_args );
125
+
126
+ if ( $response['success'] ) {
127
+ $template = $response['data'];
128
+ return array(
129
+ 'title' => ( isset( $template['title']->rendered ) ) ? $template['title']->rendered : '',
130
+ 'post_meta' => ( isset( $template['post_meta'] ) ) ? $template['post_meta'] : '',
131
+ 'data' => $template,
132
+ 'divi_content' => isset( $response['data']['divi_content'] ) ? $response['data']['divi_content'] : '',
133
+ 'message' => $response['message'], // Your API Key is not valid. Please add valid API Key.
134
+ 'success' => $response['success'],
135
+ );
136
+ }
137
+
138
+ return array(
139
+ 'title' => '',
140
+ 'post_meta' => array(),
141
+ 'message' => $response['message'],
142
+ 'data' => $response['data'],
143
+ 'divi_content' => '',
144
+ 'success' => $response['success'],
145
+ );
146
+ }
147
+
148
+ /**
149
+ * Get Cloud Templates
150
+ *
151
+ * @since 1.0.0
152
+ *
153
+ * @param array $args For selecting the demos (Search terms, pagination etc).
154
+ * @return array CartFlows list.
155
+ */
156
+ public static function get_templates( $args = array() ) {
157
+
158
+ $request_params = wp_parse_args(
159
+ $args,
160
+ array(
161
+ 'page' => '1',
162
+ 'per_page' => '100',
163
+ )
164
+ );
165
+
166
+ $url = add_query_arg( $request_params, self::get_step_endpoint_url() );
167
+
168
+ $api_args = array(
169
+ 'timeout' => 15,
170
+ );
171
+
172
+ $response = self::remote_get( $url, $api_args );
173
+
174
+ if ( $response['success'] ) {
175
+ $templates_data = $response['data'];
176
+ $templates = array();
177
+ foreach ( $templates_data as $key => $template ) {
178
+
179
+ if ( ! isset( $template->id ) ) {
180
+ continue;
181
+ }
182
+
183
+ $templates[ $key ]['id'] = isset( $template->id ) ? esc_attr( $template->id ) : '';
184
+ $templates[ $key ]['slug'] = isset( $template->slug ) ? esc_attr( $template->slug ) : '';
185
+ $templates[ $key ]['link'] = isset( $template->link ) ? esc_url( $template->link ) : '';
186
+ $templates[ $key ]['date'] = isset( $template->date ) ? esc_attr( $template->date ) : '';
187
+ $templates[ $key ]['title'] = isset( $template->title->rendered ) ? esc_attr( $template->title->rendered ) : '';
188
+ $templates[ $key ]['featured_image_url'] = isset( $template->featured_image_url ) ? esc_url( $template->featured_image_url ) : '';
189
+ $templates[ $key ]['content'] = isset( $template->content->rendered ) ? $template->content->rendered : '';
190
+ $templates[ $key ]['divi_content'] = isset( $template->divi_content ) ? $template->divi_content : '';
191
+ $templates[ $key ]['post_meta'] = isset( $template->post_meta ) ? $template->post_meta : '';
192
+ }
193
+
194
+ return array(
195
+ 'templates' => $templates,
196
+ 'templates_count' => $response['count'],
197
+ 'data' => $response,
198
+ );
199
+ }
200
+
201
+ return array(
202
+ 'templates' => array(),
203
+ 'templates_count' => 0,
204
+ 'data' => $response,
205
+ );
206
+
207
+ }
208
+
209
+ /**
210
+ * Get categories.
211
+ *
212
+ * @since 1.0.0
213
+ * @param array $args Arguments.
214
+ * @return array Category data.
215
+ */
216
+ public static function get_categories( $args = array() ) {
217
+
218
+ $request_params = apply_filters(
219
+ 'cartflows_categories_api_params',
220
+ wp_parse_args(
221
+ $args,
222
+ array(
223
+ 'page' => '1',
224
+ 'per_page' => '100',
225
+ )
226
+ )
227
+ );
228
+
229
+ $url = add_query_arg( $request_params, self::get_category_endpoint_url() );
230
+
231
+ $api_args = apply_filters(
232
+ 'cartflows_api_args',
233
+ array(
234
+ 'timeout' => 15,
235
+ )
236
+ );
237
+
238
+ $response = self::remote_get( $url, $api_args );
239
+
240
+ if ( $response['success'] ) {
241
+ $categories_data = $response['data'];
242
+ $categories = array();
243
+
244
+ foreach ( $categories_data as $key => $category ) {
245
+ if ( isset( $category->count ) && ! empty( $category->count ) ) {
246
+ $categories[] = array(
247
+ 'id' => isset( $category->id ) ? absint( $category->id ) : 0,
248
+ 'count' => isset( $category->count ) ? absint( $category->count ) : 0,
249
+ 'description' => isset( $category->description ) ? $category->description : '',
250
+ 'link' => isset( $category->link ) ? esc_url( $category->link ) : '',
251
+ 'name' => isset( $category->name ) ? $category->name : '',
252
+ 'slug' => isset( $category->slug ) ? sanitize_text_field( $category->slug ) : '',
253
+ 'taxonomy' => isset( $category->taxonomy ) ? $category->taxonomy : '',
254
+ 'parent' => isset( $category->parent ) ? $category->parent : '',
255
+ );
256
+ }
257
+ }
258
+
259
+ return array(
260
+ 'categories' => $categories,
261
+ 'categories_count' => $response['count'],
262
+ 'data' => $response,
263
+ );
264
+ }
265
+
266
+ return array(
267
+ 'categories' => array(),
268
+ 'categories_count' => 0,
269
+ 'data' => $response,
270
+ );
271
+ }
272
+
273
+ /**
274
+ * Remote GET API Request
275
+ *
276
+ * @since 1.0.0
277
+ *
278
+ * @param string $url Target server API URL.
279
+ * @param array $args Array of arguments for the API request.
280
+ * @return mixed Return the API request result.
281
+ */
282
+ public static function remote_get( $url = '', $args = array() ) {
283
+ $request = wp_remote_get( $url, $args );
284
+ return self::request( $request );
285
+ }
286
+
287
+ /**
288
+ * Remote POST API Request
289
+ *
290
+ * @since 1.0.0
291
+ *
292
+ * @param string $url Target server API URL.
293
+ * @param array $args Array of arguments for the API request.
294
+ * @return mixed Return the API request result.
295
+ */
296
+ public static function remote_post( $url = '', $args = array() ) {
297
+ $request = wp_remote_post( $url, $args );
298
+
299
+ return self::request( $request );
300
+ }
301
+
302
+ /**
303
+ * Site API Request
304
+ *
305
+ * @since 1.0.0
306
+ *
307
+ * @param boolean $api_base Target server API URL.
308
+ * @param array $args Array of arguments for the API request.
309
+ * @return mixed Return the API request result.
310
+ */
311
+ public static function site_request( $api_base = '', $args = array() ) {
312
+
313
+ $api_url = self::get_request_api_url( $api_base );
314
+
315
+ return self::remote_post( $api_url, $args );
316
+ }
317
+
318
+ /**
319
+ * API Request
320
+ *
321
+ * Handle the API request and return the result.
322
+ *
323
+ * @since 1.0.0
324
+ *
325
+ * @param array $request Array of arguments for the API request.
326
+ * @return mixed Return the API request result.
327
+ */
328
+ public static function request( $request ) {
329
+
330
+ // Is WP Error?
331
+ if ( is_wp_error( $request ) ) {
332
+ return array(
333
+ 'success' => false,
334
+ 'message' => $request->get_error_message(),
335
+ 'data' => $request,
336
+ 'count' => 0,
337
+ );
338
+ }
339
+
340
+ // Invalid response code.
341
+ if ( wp_remote_retrieve_response_code( $request ) != 200 ) {
342
+ return array(
343
+ 'success' => false,
344
+ 'message' => $request['response'],
345
+ 'data' => $request,
346
+ 'count' => 0,
347
+ );
348
+ }
349
+
350
+ // Get body data.
351
+ $body = wp_remote_retrieve_body( $request );
352
+
353
+ // Is WP Error?
354
+ if ( is_wp_error( $body ) ) {
355
+ return array(
356
+ 'success' => false,
357
+ 'message' => $body->get_error_message(),
358
+ 'data' => $request,
359
+ 'count' => 0,
360
+ );
361
+ }
362
+
363
+ // Decode body content.
364
+ $body_decoded = json_decode( $body );
365
+
366
+ return array(
367
+ 'success' => true,
368
+ 'message' => __( 'Request successfully processed!', 'cartflows' ),
369
+ 'data' => (array) $body_decoded,
370
+ 'count' => wp_remote_retrieve_header( $request, 'x-wp-total' ),
371
+ );
372
+ }
373
+
374
+ }
375
+
376
+ /**
377
+ * Initialize class object with 'get_instance()' method
378
+ */
379
+ CartFlows_API::get_instance();
380
+
381
+ endif;
classes/class-cartflows-importer.php CHANGED
@@ -1,1692 +1,1692 @@
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', false );
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
- if ( is_array( $all_meta ) ) {
202
-
203
- if ( $export_all ) {
204
- foreach ( $all_meta as $meta_key => $value ) {
205
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
206
- }
207
- } else {
208
-
209
- foreach ( $all_meta as $meta_key => $value ) {
210
- if ( substr( $meta_key, 0, strlen( 'wcf' ) ) === 'wcf' ) {
211
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
212
- } elseif ( in_array( $meta_key, $valid_step_meta_keys, true ) ) {
213
- $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
214
- }
215
- }
216
- }
217
- }
218
-
219
- // Add single step.
220
- $step_data_arr = array(
221
- 'title' => get_the_title( $step['id'] ),
222
- 'type' => $step['type'],
223
- 'meta' => $new_all_meta,
224
- 'post_content' => '',
225
- );
226
-
227
- if ( $export_all ) {
228
-
229
- $step_post_obj = get_post( $step['id'] );
230
-
231
- $step_data_arr['post_content'] = $step_post_obj->post_content;
232
- }
233
-
234
- $new_steps[] = $step_data_arr;
235
- }
236
- }
237
-
238
- // Add single flow.
239
- return array(
240
- 'title' => get_the_title( $flow_id ),
241
- 'steps' => $new_steps,
242
- );
243
- }
244
-
245
- /**
246
- * Get all flow export data
247
- *
248
- * @since 1.1.4
249
- */
250
- public function get_all_flow_export_data() {
251
-
252
- $query_args = array(
253
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
254
-
255
- // Query performance optimization.
256
- 'fields' => 'ids',
257
- 'no_found_rows' => true,
258
- 'posts_per_page' => -1,
259
- );
260
-
261
- $query = new WP_Query( $query_args );
262
- $flows = array();
263
- if ( $query->posts ) {
264
- foreach ( $query->posts as $key => $post_id ) {
265
- $flows[] = $this->get_flow_export_data( $post_id );
266
- }
267
- }
268
-
269
- return $flows;
270
- }
271
-
272
- /**
273
- * Import our exported file
274
- *
275
- * @since 1.1.4
276
- */
277
- public function import_json() {
278
- if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
279
- return;
280
- }
281
-
282
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
283
- return;
284
- }
285
-
286
- if ( ! current_user_can( 'manage_options' ) ) {
287
- return;
288
- }
289
-
290
- $filename = $_FILES['file']['name']; //phpcs:ignore
291
- $file_info = explode( '.', $filename );
292
- $extension = end( $file_info );
293
-
294
- if ( 'json' != $extension ) {
295
- wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
296
- }
297
-
298
- $file = $_FILES['file']['tmp_name']; //phpcs:ignore
299
-
300
- if ( empty( $file ) ) {
301
- wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
302
- }
303
-
304
- // Retrieve the settings from the file and convert the JSON object to an array.
305
- $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
306
-
307
- $this->import_from_json_data( $flows );
308
-
309
- add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
310
- }
311
-
312
- /**
313
- * Import flow from the JSON data
314
- *
315
- * @since x.x.x
316
- * @param array $flows JSON array.
317
- * @return void
318
- */
319
- public function import_from_json_data( $flows ) {
320
- if ( $flows ) {
321
-
322
- foreach ( $flows as $key => $flow ) {
323
-
324
- $flow_title = $flow['title'];
325
- if ( post_exists( $flow['title'] ) ) {
326
- $flow_title = $flow['title'] . ' Copy';
327
- }
328
-
329
- // Create post object.
330
- $new_flow_args = apply_filters(
331
- 'cartflows_flow_importer_args',
332
- array(
333
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
334
- 'post_title' => $flow_title,
335
- 'post_status' => 'draft',
336
- )
337
- );
338
-
339
- // Insert the post into the database.
340
- $flow_id = wp_insert_post( $new_flow_args );
341
-
342
- /**
343
- * Fire after flow import
344
- *
345
- * @since x.x.x
346
- * @param int $flow_id Flow ID.
347
- * @param array $new_flow_args Flow post args.
348
- * @param array $flows Flow JSON data.
349
- */
350
- do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
351
-
352
- if ( $flow['steps'] ) {
353
- foreach ( $flow['steps'] as $key => $step ) {
354
-
355
- $new_step_args = apply_filters(
356
- 'cartflows_step_importer_args',
357
- array(
358
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
359
- 'post_title' => $step['title'],
360
- 'post_status' => 'publish',
361
- 'meta_input' => $step['meta'],
362
- 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
363
- )
364
- );
365
-
366
- $new_step_id = wp_insert_post( $new_step_args );
367
-
368
- /**
369
- * Fire after step import
370
- *
371
- * @since x.x.x
372
- * @param int $new_step_id step ID.
373
- * @param int $flow_id flow ID.
374
- * @param array $new_step_args Step post args.
375
- * @param array $flow_steps Flow steps.
376
- * @param array $flows All flows JSON data.
377
- */
378
- do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
379
-
380
- // Insert post meta.
381
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
382
-
383
- $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
384
- $current_term = term_exists( $step['type'], $step_taxonomy );
385
-
386
- // // Set type object.
387
- $data = get_term( $current_term['term_id'], $step_taxonomy );
388
- $step_slug = $data->slug;
389
- wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
390
-
391
- // Set type.
392
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
393
-
394
- // Set flow.
395
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
396
-
397
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
398
-
399
- if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
400
-
401
- // Download and replace images.
402
- $content = $this->get_content( $step['post_content'] );
403
-
404
- // Update post content.
405
- wp_update_post(
406
- array(
407
- 'ID' => $new_step_id,
408
- 'post_content' => $content,
409
- )
410
- );
411
- }
412
- }
413
- }
414
- }
415
- }
416
- }
417
-
418
- /**
419
- * Download and Replace hotlink images
420
- *
421
- * @since x.x.x
422
- *
423
- * @param string $content Mixed post content.
424
- * @return array Hotlink image array.
425
- */
426
- public function get_content( $content = '' ) {
427
-
428
- $all_links = wp_extract_urls( $content );
429
- $image_links = array();
430
- $image_map = array();
431
-
432
- // Not have any link.
433
- if ( empty( $all_links ) ) {
434
- return $content;
435
- }
436
-
437
- foreach ( $all_links as $key => $link ) {
438
- if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $link ) ) {
439
- $image_links[] = $link;
440
- }
441
- }
442
-
443
- // Not have any image link.
444
- if ( empty( $image_links ) ) {
445
- return $content;
446
- }
447
-
448
- foreach ( $image_links as $key => $image_url ) {
449
-
450
- // Download remote image.
451
- $image = array(
452
- 'url' => $image_url,
453
- 'id' => wp_rand( 000, 999 ),
454
- );
455
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
456
-
457
- // Old and New image mapping links.
458
- $image_map[ $image_url ] = $downloaded_image['url'];
459
- }
460
-
461
- // Replace old image links with new image links.
462
- foreach ( $image_map as $old_url => $new_url ) {
463
- $content = str_replace( $old_url, $new_url, $content );
464
- }
465
-
466
- return $content;
467
-
468
- }
469
-
470
- /**
471
- * Imported notice
472
- *
473
- * @since 1.1.4
474
- */
475
- public function imported_successfully() {
476
- ?>
477
- <div class="notice notice-success">
478
- <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
479
- </div>
480
- <?php
481
- }
482
-
483
- /**
484
- * Clear Cache.
485
- *
486
- * @since 1.0.0
487
- */
488
- public function clear_cache() {
489
- // Clear 'Elementor' file cache.
490
- if ( class_exists( '\Elementor\Plugin' ) ) {
491
- Elementor\Plugin::$instance->files_manager->clear_cache();
492
- }
493
- }
494
-
495
- /**
496
- * JS Templates
497
- *
498
- * @since 1.0.0
499
- *
500
- * @return void
501
- */
502
- public function js_templates() {
503
-
504
- // Loading Templates.
505
- ?>
506
- <script type="text/template" id="tmpl-cartflows-step-loading">
507
- <div class="template-message-block cartflows-step-loading">
508
- <h2>
509
- <span class="spinner"></span>
510
- <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
511
- </h2>
512
- <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
513
- </div>
514
- </script>
515
-
516
- <?php
517
- // Search Templates.
518
- ?>
519
- <script type="text/template" id="tmpl-cartflows-searching-templates">
520
- <div class="template-message-block cartflows-searching-templates">
521
- <h2>
522
- <span class="spinner"></span>
523
- <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
524
- </h2>
525
- <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
526
- </div>
527
- </script>
528
-
529
- <?php
530
- // CartFlows Importing Template.
531
- ?>
532
- <script type="text/template" id="tmpl-cartflows-step-importing">
533
- <div class="template-message-block cartflows-step-importing">
534
- <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
535
- </div>
536
- </script>
537
-
538
- <?php
539
- // CartFlows Imported.
540
- ?>
541
- <script type="text/template" id="tmpl-cartflows-step-imported">
542
- <div class="template-message-block cartflows-step-imported">
543
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
544
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
545
- </script>
546
-
547
- <?php
548
- // No templates.
549
- ?>
550
- <script type="text/template" id="tmpl-cartflows-no-steps">
551
- <div class="cartflows-no-steps">
552
- <div class="template-message-block">
553
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
554
- <p class="description"></p>
555
- </div>
556
- </div>
557
- </script>
558
-
559
- <?php
560
- // No templates.
561
- ?>
562
- <script type="text/template" id="tmpl-cartflows-no-flows">
563
- <div class="cartflows-no-flows">
564
- <div class="template-message-block">
565
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
566
- <p class="description"></p>
567
- </div>
568
- </div>
569
- </script>
570
-
571
- <?php
572
- // Error handling.
573
- ?>
574
- <script type="text/template" id="tmpl-templator-error">
575
- <div class="notice notice-error"><p>{{ data }}</p></div>
576
- </script>
577
-
578
- <?php
579
- // Redirect to Elementor.
580
- ?>
581
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
582
- <div class="template-message-block templator-redirect-to-elementor">
583
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
584
- <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>
585
- </script>
586
-
587
- <?php
588
- /**
589
- * Responsive Buttons
590
- */
591
- ?>
592
- <script type="text/template" id="tmpl-cartflows-responsive-view">
593
- <span class="responsive-view">
594
- <span class="actions">
595
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
596
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
597
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
598
- </span>
599
- </span>
600
- </script>
601
-
602
- <?php
603
- // Templates data.
604
- ?>
605
- <script type="text/template" id="tmpl-cartflows-flows-list">
606
-
607
- <# console.log( data.items.length ) #>
608
- <# console.log( data.items ) #>
609
- <# if ( data.items.length ) { #>
610
- <# for ( key in data.items ) { #>
611
- <#
612
- var flow_steps = [];
613
- if( data.items[ key ].flow_steps ) {
614
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
615
- return value['id'];
616
- });
617
- }
618
- #>
619
- <div class="inner">
620
- <div class="template">
621
- <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 }}">
622
- <div class="template-screenshot">
623
- <# if( data.items[ key ].featured_image_url ) { #>
624
- <img src="{{ data.items[ key ].featured_image_url }}" />
625
- <# } else { #>
626
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
627
- <# } #>
628
- </div>
629
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
630
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
631
- <# } #>
632
- <# if( data.items[ key ].woo_required ) { #>
633
- <div class="notice notice-info" style="width: auto;">
634
- <p class="wcf-learn-how">
635
- Install/Activate WooCommerce to use this template.
636
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
637
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
638
- <i class="dashicons dashicons-external"></i>
639
- </a>
640
- </p>
641
- </div>
642
- <# } else { #>
643
- <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>
644
- <# } #>
645
-
646
- </span>
647
- <div class="template-id-container">
648
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
649
- <div class="template-actions">
650
-
651
- <#
652
- if( data.items[ key ].page_builder.slug ) {
653
- required_plugin_group = data.items[ key ].page_builder.slug;
654
- } else {
655
- required_plugin_group = '';
656
- }
657
-
658
- 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 ) {
659
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
660
- } else {
661
- import_btn_title = 'Import';
662
- } #>
663
-
664
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
665
- <# if( ! data.items[ key ].woo_required ) { #>
666
- <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>
667
- <# } else { #>
668
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
669
- <# } #>
670
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
671
- <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>
672
- <# } else { #>
673
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
674
- <# } #>
675
- </div>
676
- </div>
677
- </div>
678
- </div>
679
- <# } #>
680
- <# } #>
681
- </script>
682
-
683
- <?php
684
- // Empty Step.
685
- ?>
686
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
687
- <div class="inner">
688
- <div class="template">
689
- <span class="thumbnail site-preview cartflows-flow-preview">
690
- <div class="template-screenshot">
691
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
692
- </div>
693
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
694
- </span>
695
- <div class="template-id-container">
696
- <h3 class="template-name"> Blank </h3>
697
- <div class="template-actions">
698
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
699
- </div>
700
- </div>
701
- </div>
702
- </div>
703
- </script>
704
-
705
- <?php
706
- // Templates data.
707
- ?>
708
- <script type="text/template" id="tmpl-cartflows-steps-list">
709
- <# if ( data.items.length ) { #>
710
- <# for ( key in data.items ) { #>
711
- <#
712
- var flow_steps = [];
713
- if( data.items[ key ].flow_steps ) {
714
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
715
- return value['id'];
716
- });
717
- }
718
- #>
719
- <div class="inner">
720
- <div class="template">
721
- <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 }}">
722
- <div class="template-screenshot">
723
- <# if( data.items[ key ].featured_image_url ) { #>
724
- <img src="{{ data.items[ key ].featured_image_url }}" />
725
- <# } else { #>
726
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
727
- <# } #>
728
- </div>
729
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
730
-
731
- <# if( data.items[ key ].woo_required ) { #>
732
- <div class="notice notice-info" style="width: auto;">
733
- <p class="wcf-learn-how">
734
- Install/Activate WooCommerce to use this template.
735
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
736
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
737
- <i class="dashicons dashicons-external"></i>
738
- </a>
739
- </p>
740
- </div>
741
- <# } else { #>
742
- <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>
743
- <# } #>
744
-
745
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
746
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
747
- <# } #>
748
- </span>
749
- <div class="template-id-container">
750
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
751
- <div class="template-actions">
752
-
753
- <#
754
-
755
- var step_slug = data.items[ key ].step_type.slug || '';
756
- var step_title = data.items[ key ].step_type.name || '';
757
- var import_btn_title = 'Import';
758
-
759
- var required_plugin_group = '';
760
- if( data.items[ key ].page_builder ) {
761
- required_plugin_group = data.items[ key ].page_builder.slug;
762
-
763
- 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 ) {
764
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
765
- }
766
- }
767
- #>
768
-
769
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
770
-
771
- <# if( ! data.items[ key ].woo_required ) { #>
772
- <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>
773
- <# } else { #>
774
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
775
- <# } #>
776
-
777
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
778
- <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>
779
- <# } else { #>
780
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
781
- <# } #>
782
- </div>
783
- </div>
784
- </div>
785
- </div>
786
- <# } #>
787
- <# } #>
788
- </script>
789
-
790
- <?php
791
- /**
792
- * TMPL - Website Unreachable
793
- */
794
- ?>
795
- <script type="text/template" id="tmpl-cartflows-website-unreachable">
796
- <div class="postbox cartflows-website-unreachable">
797
- <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
798
- <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>
799
- <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>
800
- </div>
801
- </script>
802
-
803
- <?php
804
- /**
805
- * TMPL - Filters
806
- */
807
- ?>
808
- <script type="text/template" id="tmpl-cartflows-page-builder-notice">
809
- <?php
810
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
811
- $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
812
- $title = $page_builder['title'];
813
-
814
- $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
815
- $theme_status = '';
816
- if ( 'divi' === $default_page_builder ) {
817
-
818
- $theme_status = $page_builder['theme-status'];
819
- $plugin_status = $page_builder['plugin-status'];
820
-
821
- if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
822
- $plugin_string = 'Please activate ' . esc_html( $title );
823
- } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
824
- $plugin_string = 'Please install and activate ' . esc_html( $title );
825
- }
826
- }
827
- ?>
828
- <div class="wcf-page-builder-message">
829
- <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>
830
- <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>
831
- <p>We plan to add design templates made with more page builder shortly!</p>
832
- </div>
833
- </script>
834
-
835
- <?php
836
- /**
837
- * TMPL - Filters
838
- */
839
- ?>
840
- <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
841
- <# if ( data ) { #>
842
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
843
- <# if ( data.args.show_all ) { #>
844
- <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
845
- <# } #>
846
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
847
- <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
848
- <# } #>
849
- <# var step_slug_data = []; #>
850
- <# for ( key in data.items ) { #>
851
- <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>
852
-
853
- <# step_slug_data.push( data.items[ key ].slug ); #>
854
-
855
- <# } #>
856
- <# if( step_slug_data.indexOf("optin") === -1){ #>
857
- <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
858
- <# } #>
859
- </select>
860
- <# } #>
861
- </script>
862
-
863
- <script type="text/template" id="tmpl-cartflows-term-filters">
864
-
865
- <# if ( data ) { #>
866
-
867
- <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
868
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
869
-
870
- <# if ( data.args.show_all ) { #>
871
- <li>
872
- <a href="#" data-group="all"> All </a>
873
- </li>
874
- <# } #>
875
-
876
- <# for ( key in data.items ) { #>
877
- <li>
878
- <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>
879
- </li>
880
- <# } #>
881
-
882
- </ul>
883
-
884
- <?php
885
-
886
- /**
887
- <# } else { #>
888
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
889
-
890
- <# if ( data.args.show_all ) { #>
891
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
892
- <# } #>
893
-
894
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
895
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
896
- <# } #>
897
-
898
- <# for ( key in data.items ) { #>
899
- <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>
900
- <# } #>
901
-
902
- </select>
903
- */
904
- ?>
905
-
906
- <?php /* <# } #> */ ?>
907
-
908
- <# } #>
909
- </script>
910
-
911
- <?php
912
- // Step Type.
913
- ?>
914
- <script type="text/template" id="tmpl-cartflows-step-types">
915
- <ul class="wcf-tab nav-tabs">
916
- <# if( data.items_count ) { #>
917
- <# for( key in data.items ) { #>
918
- <# console.log( data.items[ key ].id ) #>
919
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
920
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
921
- </li>
922
- <# } #>
923
- <# } #>
924
- </ul>
925
- </script>
926
-
927
- <?php
928
- // Add to library button.
929
- ?>
930
- <script type="text/template" id="tmpl-templator-add-to-library">
931
- <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>
932
- </script>
933
- <?php
934
- }
935
-
936
- /**
937
- * Enqueue scripts
938
- *
939
- * @since 1.0.0
940
- *
941
- * @hook admin_enqueue_scripts
942
- * @param string $hook Current page hook.
943
- */
944
- public function scripts( $hook = '' ) {
945
-
946
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
947
- return;
948
- }
949
-
950
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
951
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
952
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
953
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
954
-
955
- $installed_plugins = get_plugins();
956
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
957
- $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
958
-
959
- $localize_vars = array(
960
- '_is_pro_active' => _is_cartflows_pro(),
961
- 'is_wc_installed' => $is_wc_installed,
962
- 'is_wc_activated' => $is_wc_activated,
963
-
964
- // Flow and its rest fields.
965
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
966
- 'flow_fields' => array(
967
- 'id',
968
- 'title',
969
- 'flow_type',
970
- 'page_builder',
971
- 'flow_steps',
972
- 'licence_status',
973
- 'featured_image_url',
974
- 'featured_media', // @required for field `featured_image_url`.
975
- ),
976
-
977
- // Flow type and rest fields.
978
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
979
- 'flow_type_fields' => array(
980
- 'id',
981
- 'name',
982
- 'slug',
983
- ),
984
-
985
- // Flow page builder and rest fields.
986
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
987
- 'flow_page_builder_fields' => array(
988
- 'id',
989
- 'name',
990
- 'slug',
991
- ),
992
-
993
- // Step page builder and rest fields.
994
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
995
- 'step_page_builder_fields' => array(
996
- 'id',
997
- 'name',
998
- 'slug',
999
- ),
1000
-
1001
- // Step and its rest fields.
1002
- 'step' => CARTFLOWS_STEP_POST_TYPE,
1003
- 'step_fields' => array(
1004
- 'title',
1005
- 'featured_image_url',
1006
- 'featured_media', // @required for field `featured_image_url`.
1007
- 'id',
1008
- 'flow_type',
1009
- 'step_type',
1010
- 'page_builder',
1011
- 'licence_status',
1012
- ),
1013
-
1014
- // Step type and its rest fields.
1015
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1016
- 'step_type_fields' => array(
1017
- 'id',
1018
- 'name',
1019
- 'slug',
1020
- ),
1021
-
1022
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
1023
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
1024
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1025
- 'site_url' => site_url(),
1026
- 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1027
- 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1028
- 'admin_url' => admin_url(),
1029
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1030
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1031
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1032
-
1033
- 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1034
-
1035
- 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1036
- );
1037
-
1038
- $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1039
-
1040
- // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1041
- // wp_die( );
1042
- // Add thickbox.
1043
- add_thickbox();
1044
-
1045
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1046
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1047
- }
1048
-
1049
- /**
1050
- * Import.
1051
- *
1052
- * @since 1.0.0
1053
- *
1054
- * @hook wp_ajax_cartflows_import_flow_step
1055
- * @return void
1056
- */
1057
- public function import_flow() {
1058
-
1059
- if ( ! current_user_can( 'manage_options' ) ) {
1060
- return;
1061
- }
1062
-
1063
- check_ajax_referer( 'cf-import-flow-step', 'security' );
1064
-
1065
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1066
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1067
-
1068
- wcf()->logger->import_log( '------------------------------------' );
1069
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1070
- wcf()->logger->import_log( '------------------------------------' );
1071
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1072
-
1073
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1074
-
1075
- $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1076
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1077
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1078
- $post_content = $response['data']['divi_content'];
1079
- }
1080
- }
1081
-
1082
- if ( false === $response['success'] ) {
1083
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1084
- wp_send_json_error( $response );
1085
- }
1086
-
1087
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1088
-
1089
- $new_step_id = wp_insert_post(
1090
- array(
1091
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1092
- 'post_title' => $response['title'],
1093
- 'post_content' => $post_content,
1094
- 'post_status' => 'publish',
1095
- )
1096
- );
1097
-
1098
- if ( is_wp_error( $new_step_id ) ) {
1099
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1100
- wp_send_json_error( $new_step_id );
1101
- }
1102
-
1103
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1104
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1105
- update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1106
- }
1107
- }
1108
-
1109
- /* Imported Step */
1110
- update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1111
-
1112
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1113
- // insert post meta.
1114
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1115
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1116
-
1117
- /**
1118
- * Import & Set type.
1119
- */
1120
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1121
-
1122
- $term_slug = '';
1123
- if ( $term ) {
1124
-
1125
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1126
- $term_exist = term_exists( $term->slug, $taxonomy );
1127
-
1128
- if ( empty( $term_exist ) ) {
1129
- $terms = array(
1130
- array(
1131
- 'name' => $term->name,
1132
- 'slug' => $term->slug,
1133
- ),
1134
- );
1135
-
1136
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1137
- wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1138
- }
1139
-
1140
- $current_term = term_exists( $term->slug, $taxonomy );
1141
-
1142
- // Set type object.
1143
- $data = get_term( $current_term['term_id'], $taxonomy );
1144
- $term_slug = $data->slug;
1145
- $term_name = $data->name;
1146
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1147
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1148
-
1149
- // Set type.
1150
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1151
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1152
- }
1153
-
1154
- // Set flow.
1155
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1156
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1157
-
1158
- /**
1159
- * Update steps for the current flow.
1160
- */
1161
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1162
-
1163
- if ( ! is_array( $flow_steps ) ) {
1164
- $flow_steps = array();
1165
- }
1166
-
1167
- $flow_steps[] = array(
1168
- 'id' => $new_step_id,
1169
- 'title' => $response['title'],
1170
- 'type' => $term_slug,
1171
- );
1172
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1173
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1174
-
1175
- // Import Post Meta.
1176
- self::import_post_meta( $new_step_id, $response );
1177
-
1178
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1179
- wcf()->logger->import_log( '------------------------------------' );
1180
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1181
- wcf()->logger->import_log( '------------------------------------' );
1182
-
1183
- do_action( 'cartflows_import_complete' );
1184
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1185
-
1186
- // Batch Process.
1187
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
1188
-
1189
- /**
1190
- * End
1191
- */
1192
- wp_send_json_success( $new_step_id );
1193
- }
1194
-
1195
- /**
1196
- * Import Step.
1197
- *
1198
- * @since 1.0.0
1199
- * @hook wp_ajax_cartflows_step_import
1200
- *
1201
- * @return void
1202
- */
1203
- public function create_default_flow() {
1204
-
1205
- if ( ! current_user_can( 'manage_options' ) ) {
1206
- return;
1207
- }
1208
-
1209
- check_ajax_referer( 'cf-default-flow', 'security' );
1210
-
1211
- // Create post object.
1212
- $new_flow_post = array(
1213
- 'post_content' => '',
1214
- 'post_status' => 'publish',
1215
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1216
- );
1217
-
1218
- // Insert the post into the database.
1219
- $flow_id = wp_insert_post( $new_flow_post );
1220
-
1221
- if ( is_wp_error( $flow_id ) ) {
1222
- wp_send_json_error( $flow_id->get_error_message() );
1223
- }
1224
-
1225
- $flow_steps = array();
1226
-
1227
- if ( wcf()->is_woo_active ) {
1228
- $steps_data = array(
1229
- 'sales' => array(
1230
- 'title' => __( 'Sales Landing', 'cartflows' ),
1231
- 'type' => 'landing',
1232
- ),
1233
- 'order-form' => array(
1234
- 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1235
- 'type' => 'checkout',
1236
- ),
1237
- 'order-confirmation' => array(
1238
- 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1239
- 'type' => 'thankyou',
1240
- ),
1241
- );
1242
-
1243
- } else {
1244
- $steps_data = array(
1245
- 'landing' => array(
1246
- 'title' => __( 'Landing', 'cartflows' ),
1247
- 'type' => 'landing',
1248
- ),
1249
- 'thankyou' => array(
1250
- 'title' => __( 'Thank You', 'cartflows' ),
1251
- 'type' => 'landing',
1252
- ),
1253
- );
1254
- }
1255
-
1256
- foreach ( $steps_data as $slug => $data ) {
1257
-
1258
- $post_content = '';
1259
- $step_type = trim( $data['type'] );
1260
-
1261
- $step_id = wp_insert_post(
1262
- array(
1263
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1264
- 'post_title' => $data['title'],
1265
- 'post_content' => $post_content,
1266
- 'post_status' => 'publish',
1267
- )
1268
- );
1269
-
1270
- if ( is_wp_error( $step_id ) ) {
1271
- wp_send_json_error( $step_id->get_error_message() );
1272
- }
1273
-
1274
- if ( $step_id ) {
1275
-
1276
- $flow_steps[] = array(
1277
- 'id' => $step_id,
1278
- 'title' => $data['title'],
1279
- 'type' => $step_type,
1280
- );
1281
-
1282
- // insert post meta.
1283
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1284
- update_post_meta( $step_id, 'wcf-step-type', $step_type );
1285
-
1286
- wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1287
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1288
-
1289
- update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1290
- }
1291
- }
1292
-
1293
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1294
-
1295
- wp_send_json_success( $flow_id );
1296
- }
1297
-
1298
- /**
1299
- * Create Flow
1300
- *
1301
- * @return void
1302
- */
1303
- public function create_flow() {
1304
-
1305
- if ( ! current_user_can( 'manage_options' ) ) {
1306
- return;
1307
- }
1308
-
1309
- check_ajax_referer( 'cf-create-flow', 'security' );
1310
-
1311
- // Create post object.
1312
- $new_flow_post = array(
1313
- 'post_content' => '',
1314
- 'post_status' => 'publish',
1315
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1316
- );
1317
-
1318
- // Insert the post into the database.
1319
- $flow_id = wp_insert_post( $new_flow_post );
1320
-
1321
- if ( is_wp_error( $flow_id ) ) {
1322
- wp_send_json_error( $flow_id->get_error_message() );
1323
- }
1324
-
1325
- /* Imported Flow */
1326
- update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1327
-
1328
- wp_send_json_success( $flow_id );
1329
- }
1330
-
1331
- /**
1332
- * Create Step
1333
- *
1334
- * @return void
1335
- */
1336
- public function import_step() {
1337
-
1338
- if ( ! current_user_can( 'manage_options' ) ) {
1339
- return;
1340
- }
1341
-
1342
- check_ajax_referer( 'cf-step-import', 'security' );
1343
-
1344
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1345
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1346
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1347
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1348
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1349
-
1350
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1351
-
1352
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1353
-
1354
- wcf()->logger->import_log( '------------------------------------' );
1355
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
1356
- wcf()->logger->import_log( '------------------------------------' );
1357
-
1358
- if ( empty( $template_id ) || empty( $post_id ) ) {
1359
- /* translators: %s: template ID */
1360
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1361
- wcf()->logger->import_log( $data );
1362
- wp_send_json_error( $data );
1363
- }
1364
-
1365
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1366
-
1367
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1368
-
1369
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1370
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1371
- update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1372
-
1373
- wp_update_post(
1374
- array(
1375
- 'ID' => $post_id,
1376
- 'post_content' => $response['data']['divi_content'],
1377
- )
1378
- );
1379
- }
1380
- }
1381
-
1382
- /* Imported Step */
1383
- update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1384
-
1385
- // Import Post Meta.
1386
- self::import_post_meta( $post_id, $response );
1387
-
1388
- do_action( 'cartflows_import_complete' );
1389
-
1390
- // Batch Process.
1391
- do_action( 'cartflows_after_template_import', $post_id, $response );
1392
-
1393
- wcf()->logger->import_log( '------------------------------------' );
1394
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1395
- wcf()->logger->import_log( '------------------------------------' );
1396
-
1397
- wp_send_json_success( $post_id );
1398
- }
1399
-
1400
- /**
1401
- * Import Step.
1402
- *
1403
- * @since 1.0.0
1404
- * @hook wp_ajax_cartflows_step_create_blank
1405
- *
1406
- * @return void
1407
- */
1408
- public function step_create_blank() {
1409
-
1410
- if ( ! current_user_can( 'manage_options' ) ) {
1411
- return;
1412
- }
1413
-
1414
- check_ajax_referer( 'cf-step-create-blank', 'security' );
1415
-
1416
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1417
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1418
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1419
-
1420
- if ( empty( $flow_id ) || empty( $step_type ) ) {
1421
- /* translators: %s: flow ID */
1422
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1423
- wcf()->logger->import_log( $data );
1424
- wp_send_json_error( $data );
1425
- }
1426
-
1427
- wcf()->logger->import_log( '------------------------------------' );
1428
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1429
-
1430
- $step_type_title = str_replace( '-', ' ', $step_type );
1431
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1432
-
1433
- $new_step_id = wp_insert_post(
1434
- array(
1435
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1436
- 'post_title' => $step_title,
1437
- 'post_content' => '',
1438
- 'post_status' => 'publish',
1439
- )
1440
- );
1441
-
1442
- // insert post meta.
1443
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1444
-
1445
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1446
- $term_exist = term_exists( $step_type_slug, $taxonomy );
1447
-
1448
- if ( empty( $term_exist ) ) {
1449
- $terms = array(
1450
- array(
1451
- 'name' => $step_type_title,
1452
- 'slug' => $step_type_slug,
1453
- ),
1454
- );
1455
-
1456
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1457
- wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1458
- }
1459
-
1460
- $current_term = term_exists( $step_type_slug, $taxonomy );
1461
-
1462
- // Set type object.
1463
- $data = get_term( $current_term['term_id'], $taxonomy );
1464
- $step_slug = $data->slug;
1465
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1466
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1467
-
1468
- // Set Default page Layout.
1469
- update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1470
-
1471
- // Set type.
1472
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1473
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1474
-
1475
- // Set flow.
1476
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1477
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1478
-
1479
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1480
-
1481
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1482
- wcf()->logger->import_log( '------------------------------------' );
1483
-
1484
- wp_send_json_success( $new_step_id );
1485
- }
1486
-
1487
- /**
1488
- * Import Post Meta
1489
- *
1490
- * @since 1.0.0
1491
- *
1492
- * @param integer $post_id Post ID.
1493
- * @param array $response Post meta.
1494
- * @return void
1495
- */
1496
- public static function import_post_meta( $post_id, $response ) {
1497
-
1498
- $metadata = (array) $response['post_meta'];
1499
-
1500
- foreach ( $metadata as $meta_key => $meta_value ) {
1501
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1502
-
1503
- if ( $meta_value ) {
1504
-
1505
- if ( is_serialized( $meta_value, true ) ) {
1506
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1507
- } elseif ( is_array( $meta_value ) ) {
1508
- $raw_data = json_decode( stripslashes( $meta_value ), true );
1509
- } else {
1510
- $raw_data = $meta_value;
1511
- }
1512
-
1513
- if ( '_elementor_data' === $meta_key ) {
1514
- if ( is_array( $raw_data ) ) {
1515
- $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1516
- } else {
1517
- $raw_data = wp_slash( $raw_data );
1518
- }
1519
- }
1520
- if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1521
- if ( is_array( $raw_data ) ) {
1522
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1523
- } else {
1524
- if ( ! is_object( $raw_data ) ) {
1525
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1526
- }
1527
- }
1528
- }
1529
-
1530
- update_post_meta( $post_id, $meta_key, $raw_data );
1531
- }
1532
- }
1533
- }
1534
-
1535
- /**
1536
- * Import Template for Elementor
1537
- *
1538
- * @since 1.0.0
1539
- *
1540
- * @param integer $post_id Post ID.
1541
- * @param array $response Post meta.
1542
- * @param array $page_build_data Page build data.
1543
- * @return void
1544
- */
1545
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1546
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1547
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1548
- wcf()->logger->import_log( $data );
1549
- wp_send_json_error( $data );
1550
- }
1551
-
1552
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1553
-
1554
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1555
-
1556
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1557
- $obj->import_single_template( $post_id );
1558
-
1559
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1560
- }
1561
-
1562
- /**
1563
- * Supported post types
1564
- *
1565
- * @since 1.0.0
1566
- *
1567
- * @return array Supported post types.
1568
- */
1569
- public static function supported_post_types() {
1570
- return apply_filters(
1571
- 'cartflows_supported_post_types',
1572
- array(
1573
- CARTFLOWS_FLOW_POST_TYPE,
1574
- )
1575
- );
1576
- }
1577
-
1578
- /**
1579
- * Check supported post type
1580
- *
1581
- * @since 1.0.0
1582
- *
1583
- * @param string $post_type Post type.
1584
- * @return boolean Supported post type status.
1585
- */
1586
- public static function is_supported_post( $post_type = '' ) {
1587
-
1588
- if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1589
- return true;
1590
- }
1591
-
1592
- return false;
1593
- }
1594
-
1595
- /**
1596
- * Set steps to the flow
1597
- *
1598
- * @param integer $flow_id Flow ID.
1599
- * @param integer $new_step_id New step ID.
1600
- * @param string $step_title Flow Type.
1601
- * @param string $step_slug Flow Type.
1602
- */
1603
- public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1604
- // Update steps for the current flow.
1605
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1606
-
1607
- if ( ! is_array( $flow_steps ) ) {
1608
- $flow_steps = array();
1609
- }
1610
-
1611
- $flow_steps[] = array(
1612
- 'id' => $new_step_id,
1613
- 'title' => $step_title,
1614
- 'type' => $step_slug,
1615
- );
1616
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1617
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1618
- }
1619
-
1620
- /**
1621
- * Localize variables in admin
1622
- *
1623
- * @param array $vars variables.
1624
- */
1625
- public function localize_vars( $vars ) {
1626
-
1627
- $ajax_actions = array(
1628
- 'cf_step_import',
1629
- 'cf_load_steps',
1630
- 'cf_create_flow',
1631
- 'cf_default_flow',
1632
- 'cf_step_create_blank',
1633
- 'cf_import_flow_step',
1634
- );
1635
-
1636
- foreach ( $ajax_actions as $action ) {
1637
-
1638
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1639
- }
1640
-
1641
- return $vars;
1642
- }
1643
-
1644
- /**
1645
- * Ajax action to activate plugin
1646
- */
1647
- public function activate_plugin() {
1648
-
1649
- if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1650
- wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1651
- }
1652
-
1653
- if ( ! current_user_can( 'activate_plugins' ) ) {
1654
- wp_send_json_error(
1655
- array(
1656
- 'success' => false,
1657
- 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1658
- )
1659
- );
1660
- }
1661
-
1662
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1663
-
1664
- $activate = activate_plugin( $plugin_init, '', false, true );
1665
-
1666
- if ( is_wp_error( $activate ) ) {
1667
- wp_send_json_error(
1668
- array(
1669
- 'success' => false,
1670
- 'message' => $activate->get_error_message(),
1671
- 'init' => $plugin_init,
1672
- )
1673
- );
1674
- }
1675
-
1676
- wp_send_json_success(
1677
- array(
1678
- 'success' => true,
1679
- 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1680
- 'init' => $plugin_init,
1681
- )
1682
- );
1683
- }
1684
-
1685
- }
1686
-
1687
- /**
1688
- * Initialize class object with 'get_instance()' method
1689
- */
1690
- CartFlows_Importer::get_instance();
1691
-
1692
- 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', false );
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
+ if ( is_array( $all_meta ) ) {
202
+
203
+ if ( $export_all ) {
204
+ foreach ( $all_meta as $meta_key => $value ) {
205
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
206
+ }
207
+ } else {
208
+
209
+ foreach ( $all_meta as $meta_key => $value ) {
210
+ if ( substr( $meta_key, 0, strlen( 'wcf' ) ) === 'wcf' ) {
211
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
212
+ } elseif ( in_array( $meta_key, $valid_step_meta_keys, true ) ) {
213
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ // Add single step.
220
+ $step_data_arr = array(
221
+ 'title' => get_the_title( $step['id'] ),
222
+ 'type' => $step['type'],
223
+ 'meta' => $new_all_meta,
224
+ 'post_content' => '',
225
+ );
226
+
227
+ if ( $export_all ) {
228
+
229
+ $step_post_obj = get_post( $step['id'] );
230
+
231
+ $step_data_arr['post_content'] = $step_post_obj->post_content;
232
+ }
233
+
234
+ $new_steps[] = $step_data_arr;
235
+ }
236
+ }
237
+
238
+ // Add single flow.
239
+ return array(
240
+ 'title' => get_the_title( $flow_id ),
241
+ 'steps' => $new_steps,
242
+ );
243
+ }
244
+
245
+ /**
246
+ * Get all flow export data
247
+ *
248
+ * @since 1.1.4
249
+ */
250
+ public function get_all_flow_export_data() {
251
+
252
+ $query_args = array(
253
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
254
+
255
+ // Query performance optimization.
256
+ 'fields' => 'ids',
257
+ 'no_found_rows' => true,
258
+ 'posts_per_page' => -1,
259
+ );
260
+
261
+ $query = new WP_Query( $query_args );
262
+ $flows = array();
263
+ if ( $query->posts ) {
264
+ foreach ( $query->posts as $key => $post_id ) {
265
+ $flows[] = $this->get_flow_export_data( $post_id );
266
+ }
267
+ }
268
+
269
+ return $flows;
270
+ }
271
+
272
+ /**
273
+ * Import our exported file
274
+ *
275
+ * @since 1.1.4
276
+ */
277
+ public function import_json() {
278
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
279
+ return;
280
+ }
281
+
282
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
283
+ return;
284
+ }
285
+
286
+ if ( ! current_user_can( 'manage_options' ) ) {
287
+ return;
288
+ }
289
+
290
+ $filename = $_FILES['file']['name']; //phpcs:ignore
291
+ $file_info = explode( '.', $filename );
292
+ $extension = end( $file_info );
293
+
294
+ if ( 'json' != $extension ) {
295
+ wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
296
+ }
297
+
298
+ $file = $_FILES['file']['tmp_name']; //phpcs:ignore
299
+
300
+ if ( empty( $file ) ) {
301
+ wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
302
+ }
303
+
304
+ // Retrieve the settings from the file and convert the JSON object to an array.
305
+ $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
306
+
307
+ $this->import_from_json_data( $flows );
308
+
309
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
310
+ }
311
+
312
+ /**
313
+ * Import flow from the JSON data
314
+ *
315
+ * @since x.x.x
316
+ * @param array $flows JSON array.
317
+ * @return void
318
+ */
319
+ public function import_from_json_data( $flows ) {
320
+ if ( $flows ) {
321
+
322
+ foreach ( $flows as $key => $flow ) {
323
+
324
+ $flow_title = $flow['title'];
325
+ if ( post_exists( $flow['title'] ) ) {
326
+ $flow_title = $flow['title'] . ' Copy';
327
+ }
328
+
329
+ // Create post object.
330
+ $new_flow_args = apply_filters(
331
+ 'cartflows_flow_importer_args',
332
+ array(
333
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
334
+ 'post_title' => $flow_title,
335
+ 'post_status' => 'draft',
336
+ )
337
+ );
338
+
339
+ // Insert the post into the database.
340
+ $flow_id = wp_insert_post( $new_flow_args );
341
+
342
+ /**
343
+ * Fire after flow import
344
+ *
345
+ * @since x.x.x
346
+ * @param int $flow_id Flow ID.
347
+ * @param array $new_flow_args Flow post args.
348
+ * @param array $flows Flow JSON data.
349
+ */
350
+ do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
351
+
352
+ if ( $flow['steps'] ) {
353
+ foreach ( $flow['steps'] as $key => $step ) {
354
+
355
+ $new_step_args = apply_filters(
356
+ 'cartflows_step_importer_args',
357
+ array(
358
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
359
+ 'post_title' => $step['title'],
360
+ 'post_status' => 'publish',
361
+ 'meta_input' => $step['meta'],
362
+ 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
363
+ )
364
+ );
365
+
366
+ $new_step_id = wp_insert_post( $new_step_args );
367
+
368
+ /**
369
+ * Fire after step import
370
+ *
371
+ * @since x.x.x
372
+ * @param int $new_step_id step ID.
373
+ * @param int $flow_id flow ID.
374
+ * @param array $new_step_args Step post args.
375
+ * @param array $flow_steps Flow steps.
376
+ * @param array $flows All flows JSON data.
377
+ */
378
+ do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
379
+
380
+ // Insert post meta.
381
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
382
+
383
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
384
+ $current_term = term_exists( $step['type'], $step_taxonomy );
385
+
386
+ // // Set type object.
387
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
388
+ $step_slug = $data->slug;
389
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
390
+
391
+ // Set type.
392
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
393
+
394
+ // Set flow.
395
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
396
+
397
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
398
+
399
+ if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
400
+
401
+ // Download and replace images.
402
+ $content = $this->get_content( $step['post_content'] );
403
+
404
+ // Update post content.
405
+ wp_update_post(
406
+ array(
407
+ 'ID' => $new_step_id,
408
+ 'post_content' => $content,
409
+ )
410
+ );
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Download and Replace hotlink images
420
+ *
421
+ * @since x.x.x
422
+ *
423
+ * @param string $content Mixed post content.
424
+ * @return array Hotlink image array.
425
+ */
426
+ public function get_content( $content = '' ) {
427
+
428
+ $all_links = wp_extract_urls( $content );
429
+ $image_links = array();
430
+ $image_map = array();
431
+
432
+ // Not have any link.
433
+ if ( empty( $all_links ) ) {
434
+ return $content;
435
+ }
436
+
437
+ foreach ( $all_links as $key => $link ) {
438
+ if ( preg_match( '/\.(jpg|jpeg|png|gif)/i', $link ) ) {
439
+ $image_links[] = $link;
440
+ }
441
+ }
442
+
443
+ // Not have any image link.
444
+ if ( empty( $image_links ) ) {
445
+ return $content;
446
+ }
447
+
448
+ foreach ( $image_links as $key => $image_url ) {
449
+
450
+ // Download remote image.
451
+ $image = array(
452
+ 'url' => $image_url,
453
+ 'id' => wp_rand( 000, 999 ),
454
+ );
455
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
456
+
457
+ // Old and New image mapping links.
458
+ $image_map[ $image_url ] = $downloaded_image['url'];
459
+ }
460
+
461
+ // Replace old image links with new image links.
462
+ foreach ( $image_map as $old_url => $new_url ) {
463
+ $content = str_replace( $old_url, $new_url, $content );
464
+ }
465
+
466
+ return $content;
467
+
468
+ }
469
+
470
+ /**
471
+ * Imported notice
472
+ *
473
+ * @since 1.1.4
474
+ */
475
+ public function imported_successfully() {
476
+ ?>
477
+ <div class="notice notice-success">
478
+ <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
479
+ </div>
480
+ <?php
481
+ }
482
+
483
+ /**
484
+ * Clear Cache.
485
+ *
486
+ * @since 1.0.0
487
+ */
488
+ public function clear_cache() {
489
+ // Clear 'Elementor' file cache.
490
+ if ( class_exists( '\Elementor\Plugin' ) ) {
491
+ Elementor\Plugin::$instance->files_manager->clear_cache();
492
+ }
493
+ }
494
+
495
+ /**
496
+ * JS Templates
497
+ *
498
+ * @since 1.0.0
499
+ *
500
+ * @return void
501
+ */
502
+ public function js_templates() {
503
+
504
+ // Loading Templates.
505
+ ?>
506
+ <script type="text/template" id="tmpl-cartflows-step-loading">
507
+ <div class="template-message-block cartflows-step-loading">
508
+ <h2>
509
+ <span class="spinner"></span>
510
+ <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
511
+ </h2>
512
+ <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
513
+ </div>
514
+ </script>
515
+
516
+ <?php
517
+ // Search Templates.
518
+ ?>
519
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
520
+ <div class="template-message-block cartflows-searching-templates">
521
+ <h2>
522
+ <span class="spinner"></span>
523
+ <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
524
+ </h2>
525
+ <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
526
+ </div>
527
+ </script>
528
+
529
+ <?php
530
+ // CartFlows Importing Template.
531
+ ?>
532
+ <script type="text/template" id="tmpl-cartflows-step-importing">
533
+ <div class="template-message-block cartflows-step-importing">
534
+ <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
535
+ </div>
536
+ </script>
537
+
538
+ <?php
539
+ // CartFlows Imported.
540
+ ?>
541
+ <script type="text/template" id="tmpl-cartflows-step-imported">
542
+ <div class="template-message-block cartflows-step-imported">
543
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
544
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
545
+ </script>
546
+
547
+ <?php
548
+ // No templates.
549
+ ?>
550
+ <script type="text/template" id="tmpl-cartflows-no-steps">
551
+ <div class="cartflows-no-steps">
552
+ <div class="template-message-block">
553
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
554
+ <p class="description"></p>
555
+ </div>
556
+ </div>
557
+ </script>
558
+
559
+ <?php
560
+ // No templates.
561
+ ?>
562
+ <script type="text/template" id="tmpl-cartflows-no-flows">
563
+ <div class="cartflows-no-flows">
564
+ <div class="template-message-block">
565
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
566
+ <p class="description"></p>
567
+ </div>
568
+ </div>
569
+ </script>
570
+
571
+ <?php
572
+ // Error handling.
573
+ ?>
574
+ <script type="text/template" id="tmpl-templator-error">
575
+ <div class="notice notice-error"><p>{{ data }}</p></div>
576
+ </script>
577
+
578
+ <?php
579
+ // Redirect to Elementor.
580
+ ?>
581
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
582
+ <div class="template-message-block templator-redirect-to-elementor">
583
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
584
+ <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>
585
+ </script>
586
+
587
+ <?php
588
+ /**
589
+ * Responsive Buttons
590
+ */
591
+ ?>
592
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
593
+ <span class="responsive-view">
594
+ <span class="actions">
595
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
596
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
597
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
598
+ </span>
599
+ </span>
600
+ </script>
601
+
602
+ <?php
603
+ // Templates data.
604
+ ?>
605
+ <script type="text/template" id="tmpl-cartflows-flows-list">
606
+
607
+ <# console.log( data.items.length ) #>
608
+ <# console.log( data.items ) #>
609
+ <# if ( data.items.length ) { #>
610
+ <# for ( key in data.items ) { #>
611
+ <#
612
+ var flow_steps = [];
613
+ if( data.items[ key ].flow_steps ) {
614
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
615
+ return value['id'];
616
+ });
617
+ }
618
+ #>
619
+ <div class="inner">
620
+ <div class="template">
621
+ <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 }}">
622
+ <div class="template-screenshot">
623
+ <# if( data.items[ key ].featured_image_url ) { #>
624
+ <img src="{{ data.items[ key ].featured_image_url }}" />
625
+ <# } else { #>
626
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
627
+ <# } #>
628
+ </div>
629
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
630
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
631
+ <# } #>
632
+ <# if( data.items[ key ].woo_required ) { #>
633
+ <div class="notice notice-info" style="width: auto;">
634
+ <p class="wcf-learn-how">
635
+ Install/Activate WooCommerce to use this template.
636
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
637
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
638
+ <i class="dashicons dashicons-external"></i>
639
+ </a>
640
+ </p>
641
+ </div>
642
+ <# } else { #>
643
+ <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>
644
+ <# } #>
645
+
646
+ </span>
647
+ <div class="template-id-container">
648
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
649
+ <div class="template-actions">
650
+
651
+ <#
652
+ if( data.items[ key ].page_builder.slug ) {
653
+ required_plugin_group = data.items[ key ].page_builder.slug;
654
+ } else {
655
+ required_plugin_group = '';
656
+ }
657
+
658
+ 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 ) {
659
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
660
+ } else {
661
+ import_btn_title = 'Import';
662
+ } #>
663
+
664
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
665
+ <# if( ! data.items[ key ].woo_required ) { #>
666
+ <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>
667
+ <# } else { #>
668
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
669
+ <# } #>
670
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
671
+ <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>
672
+ <# } else { #>
673
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
674
+ <# } #>
675
+ </div>
676
+ </div>
677
+ </div>
678
+ </div>
679
+ <# } #>
680
+ <# } #>
681
+ </script>
682
+
683
+ <?php
684
+ // Empty Step.
685
+ ?>
686
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
687
+ <div class="inner">
688
+ <div class="template">
689
+ <span class="thumbnail site-preview cartflows-flow-preview">
690
+ <div class="template-screenshot">
691
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
692
+ </div>
693
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
694
+ </span>
695
+ <div class="template-id-container">
696
+ <h3 class="template-name"> Blank </h3>
697
+ <div class="template-actions">
698
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
699
+ </div>
700
+ </div>
701
+ </div>
702
+ </div>
703
+ </script>
704
+
705
+ <?php
706
+ // Templates data.
707
+ ?>
708
+ <script type="text/template" id="tmpl-cartflows-steps-list">
709
+ <# if ( data.items.length ) { #>
710
+ <# for ( key in data.items ) { #>
711
+ <#
712
+ var flow_steps = [];
713
+ if( data.items[ key ].flow_steps ) {
714
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
715
+ return value['id'];
716
+ });
717
+ }
718
+ #>
719
+ <div class="inner">
720
+ <div class="template">
721
+ <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 }}">
722
+ <div class="template-screenshot">
723
+ <# if( data.items[ key ].featured_image_url ) { #>
724
+ <img src="{{ data.items[ key ].featured_image_url }}" />
725
+ <# } else { #>
726
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
727
+ <# } #>
728
+ </div>
729
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
730
+
731
+ <# if( data.items[ key ].woo_required ) { #>
732
+ <div class="notice notice-info" style="width: auto;">
733
+ <p class="wcf-learn-how">
734
+ Install/Activate WooCommerce to use this template.
735
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
736
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
737
+ <i class="dashicons dashicons-external"></i>
738
+ </a>
739
+ </p>
740
+ </div>
741
+ <# } else { #>
742
+ <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>
743
+ <# } #>
744
+
745
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
746
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
747
+ <# } #>
748
+ </span>
749
+ <div class="template-id-container">
750
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
751
+ <div class="template-actions">
752
+
753
+ <#
754
+
755
+ var step_slug = data.items[ key ].step_type.slug || '';
756
+ var step_title = data.items[ key ].step_type.name || '';
757
+ var import_btn_title = 'Import';
758
+
759
+ var required_plugin_group = '';
760
+ if( data.items[ key ].page_builder ) {
761
+ required_plugin_group = data.items[ key ].page_builder.slug;
762
+
763
+ 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 ) {
764
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
765
+ }
766
+ }
767
+ #>
768
+
769
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
770
+
771
+ <# if( ! data.items[ key ].woo_required ) { #>
772
+ <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>
773
+ <# } else { #>
774
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
775
+ <# } #>
776
+
777
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
778
+ <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>
779
+ <# } else { #>
780
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
781
+ <# } #>
782
+ </div>
783
+ </div>
784
+ </div>
785
+ </div>
786
+ <# } #>
787
+ <# } #>
788
+ </script>
789
+
790
+ <?php
791
+ /**
792
+ * TMPL - Website Unreachable
793
+ */
794
+ ?>
795
+ <script type="text/template" id="tmpl-cartflows-website-unreachable">
796
+ <div class="postbox cartflows-website-unreachable">
797
+ <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
798
+ <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>
799
+ <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>
800
+ </div>
801
+ </script>
802
+
803
+ <?php
804
+ /**
805
+ * TMPL - Filters
806
+ */
807
+ ?>
808
+ <script type="text/template" id="tmpl-cartflows-page-builder-notice">
809
+ <?php
810
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
811
+ $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
812
+ $title = $page_builder['title'];
813
+
814
+ $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
815
+ $theme_status = '';
816
+ if ( 'divi' === $default_page_builder ) {
817
+
818
+ $theme_status = $page_builder['theme-status'];
819
+ $plugin_status = $page_builder['plugin-status'];
820
+
821
+ if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
822
+ $plugin_string = 'Please activate ' . esc_html( $title );
823
+ } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
824
+ $plugin_string = 'Please install and activate ' . esc_html( $title );
825
+ }
826
+ }
827
+ ?>
828
+ <div class="wcf-page-builder-message">
829
+ <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>
830
+ <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>
831
+ <p>We plan to add design templates made with more page builder shortly!</p>
832
+ </div>
833
+ </script>
834
+
835
+ <?php
836
+ /**
837
+ * TMPL - Filters
838
+ */
839
+ ?>
840
+ <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
841
+ <# if ( data ) { #>
842
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
843
+ <# if ( data.args.show_all ) { #>
844
+ <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
845
+ <# } #>
846
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
847
+ <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
848
+ <# } #>
849
+ <# var step_slug_data = []; #>
850
+ <# for ( key in data.items ) { #>
851
+ <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>
852
+
853
+ <# step_slug_data.push( data.items[ key ].slug ); #>
854
+
855
+ <# } #>
856
+ <# if( step_slug_data.indexOf("optin") === -1){ #>
857
+ <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
858
+ <# } #>
859
+ </select>
860
+ <# } #>
861
+ </script>
862
+
863
+ <script type="text/template" id="tmpl-cartflows-term-filters">
864
+
865
+ <# if ( data ) { #>
866
+
867
+ <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
868
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
869
+
870
+ <# if ( data.args.show_all ) { #>
871
+ <li>
872
+ <a href="#" data-group="all"> All </a>
873
+ </li>
874
+ <# } #>
875
+
876
+ <# for ( key in data.items ) { #>
877
+ <li>
878
+ <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>
879
+ </li>
880
+ <# } #>
881
+
882
+ </ul>
883
+
884
+ <?php
885
+
886
+ /**
887
+ <# } else { #>
888
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
889
+
890
+ <# if ( data.args.show_all ) { #>
891
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
892
+ <# } #>
893
+
894
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
895
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
896
+ <# } #>
897
+
898
+ <# for ( key in data.items ) { #>
899
+ <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>
900
+ <# } #>
901
+
902
+ </select>
903
+ */
904
+ ?>
905
+
906
+ <?php /* <# } #> */ ?>
907
+
908
+ <# } #>
909
+ </script>
910
+
911
+ <?php
912
+ // Step Type.
913
+ ?>
914
+ <script type="text/template" id="tmpl-cartflows-step-types">
915
+ <ul class="wcf-tab nav-tabs">
916
+ <# if( data.items_count ) { #>
917
+ <# for( key in data.items ) { #>
918
+ <# console.log( data.items[ key ].id ) #>
919
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
920
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
921
+ </li>
922
+ <# } #>
923
+ <# } #>
924
+ </ul>
925
+ </script>
926
+
927
+ <?php
928
+ // Add to library button.
929
+ ?>
930
+ <script type="text/template" id="tmpl-templator-add-to-library">
931
+ <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>
932
+ </script>
933
+ <?php
934
+ }
935
+
936
+ /**
937
+ * Enqueue scripts
938
+ *
939
+ * @since 1.0.0
940
+ *
941
+ * @hook admin_enqueue_scripts
942
+ * @param string $hook Current page hook.
943
+ */
944
+ public function scripts( $hook = '' ) {
945
+
946
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
947
+ return;
948
+ }
949
+
950
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
951
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
952
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
953
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
954
+
955
+ $installed_plugins = get_plugins();
956
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
957
+ $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
958
+
959
+ $localize_vars = array(
960
+ '_is_pro_active' => _is_cartflows_pro(),
961
+ 'is_wc_installed' => $is_wc_installed,
962
+ 'is_wc_activated' => $is_wc_activated,
963
+
964
+ // Flow and its rest fields.
965
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
966
+ 'flow_fields' => array(
967
+ 'id',
968
+ 'title',
969
+ 'flow_type',
970
+ 'page_builder',
971
+ 'flow_steps',
972
+ 'licence_status',
973
+ 'featured_image_url',
974
+ 'featured_media', // @required for field `featured_image_url`.
975
+ ),
976
+
977
+ // Flow type and rest fields.
978
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
979
+ 'flow_type_fields' => array(
980
+ 'id',
981
+ 'name',
982
+ 'slug',
983
+ ),
984
+
985
+ // Flow page builder and rest fields.
986
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
987
+ 'flow_page_builder_fields' => array(
988
+ 'id',
989
+ 'name',
990
+ 'slug',
991
+ ),
992
+
993
+ // Step page builder and rest fields.
994
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
995
+ 'step_page_builder_fields' => array(
996
+ 'id',
997
+ 'name',
998
+ 'slug',
999
+ ),
1000
+
1001
+ // Step and its rest fields.
1002
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1003
+ 'step_fields' => array(
1004
+ 'title',
1005
+ 'featured_image_url',
1006
+ 'featured_media', // @required for field `featured_image_url`.
1007
+ 'id',
1008
+ 'flow_type',
1009
+ 'step_type',
1010
+ 'page_builder',
1011
+ 'licence_status',
1012
+ ),
1013
+
1014
+ // Step type and its rest fields.
1015
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1016
+ 'step_type_fields' => array(
1017
+ 'id',
1018
+ 'name',
1019
+ 'slug',
1020
+ ),
1021
+
1022
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1023
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1024
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1025
+ 'site_url' => site_url(),
1026
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1027
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1028
+ 'admin_url' => admin_url(),
1029
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1030
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1031
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1032
+
1033
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1034
+
1035
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1036
+ );
1037
+
1038
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1039
+
1040
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1041
+ // wp_die( );
1042
+ // Add thickbox.
1043
+ add_thickbox();
1044
+
1045
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1046
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1047
+ }
1048
+
1049
+ /**
1050
+ * Import.
1051
+ *
1052
+ * @since 1.0.0
1053
+ *
1054
+ * @hook wp_ajax_cartflows_import_flow_step
1055
+ * @return void
1056
+ */
1057
+ public function import_flow() {
1058
+
1059
+ if ( ! current_user_can( 'manage_options' ) ) {
1060
+ return;
1061
+ }
1062
+
1063
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1064
+
1065
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1066
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1067
+
1068
+ wcf()->logger->import_log( '------------------------------------' );
1069
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1070
+ wcf()->logger->import_log( '------------------------------------' );
1071
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1072
+
1073
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1074
+
1075
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1076
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1077
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1078
+ $post_content = $response['data']['divi_content'];
1079
+ }
1080
+ }
1081
+
1082
+ if ( false === $response['success'] ) {
1083
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1084
+ wp_send_json_error( $response );
1085
+ }
1086
+
1087
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1088
+
1089
+ $new_step_id = wp_insert_post(
1090
+ array(
1091
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1092
+ 'post_title' => $response['title'],
1093
+ 'post_content' => $post_content,
1094
+ 'post_status' => 'publish',
1095
+ )
1096
+ );
1097
+
1098
+ if ( is_wp_error( $new_step_id ) ) {
1099
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1100
+ wp_send_json_error( $new_step_id );
1101
+ }
1102
+
1103
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1104
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1105
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1106
+ }
1107
+ }
1108
+
1109
+ /* Imported Step */
1110
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1111
+
1112
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1113
+ // insert post meta.
1114
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1115
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1116
+
1117
+ /**
1118
+ * Import & Set type.
1119
+ */
1120
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1121
+
1122
+ $term_slug = '';
1123
+ if ( $term ) {
1124
+
1125
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1126
+ $term_exist = term_exists( $term->slug, $taxonomy );
1127
+
1128
+ if ( empty( $term_exist ) ) {
1129
+ $terms = array(
1130
+ array(
1131
+ 'name' => $term->name,
1132
+ 'slug' => $term->slug,
1133
+ ),
1134
+ );
1135
+
1136
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1137
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1138
+ }
1139
+
1140
+ $current_term = term_exists( $term->slug, $taxonomy );
1141
+
1142
+ // Set type object.
1143
+ $data = get_term( $current_term['term_id'], $taxonomy );
1144
+ $term_slug = $data->slug;
1145
+ $term_name = $data->name;
1146
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1147
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1148
+
1149
+ // Set type.
1150
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1151
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1152
+ }
1153
+
1154
+ // Set flow.
1155
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1156
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1157
+
1158
+ /**
1159
+ * Update steps for the current flow.
1160
+ */
1161
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1162
+
1163
+ if ( ! is_array( $flow_steps ) ) {
1164
+ $flow_steps = array();
1165
+ }
1166
+
1167
+ $flow_steps[] = array(
1168
+ 'id' => $new_step_id,
1169
+ 'title' => $response['title'],
1170
+ 'type' => $term_slug,
1171
+ );
1172
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1173
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1174
+
1175
+ // Import Post Meta.
1176
+ self::import_post_meta( $new_step_id, $response );
1177
+
1178
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1179
+ wcf()->logger->import_log( '------------------------------------' );
1180
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1181
+ wcf()->logger->import_log( '------------------------------------' );
1182
+
1183
+ do_action( 'cartflows_import_complete' );
1184
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1185
+
1186
+ // Batch Process.
1187
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1188
+
1189
+ /**
1190
+ * End
1191
+ */
1192
+ wp_send_json_success( $new_step_id );
1193
+ }
1194
+
1195
+ /**
1196
+ * Import Step.
1197
+ *
1198
+ * @since 1.0.0
1199
+ * @hook wp_ajax_cartflows_step_import
1200
+ *
1201
+ * @return void
1202
+ */
1203
+ public function create_default_flow() {
1204
+
1205
+ if ( ! current_user_can( 'manage_options' ) ) {
1206
+ return;
1207
+ }
1208
+
1209
+ check_ajax_referer( 'cf-default-flow', 'security' );
1210
+
1211
+ // Create post object.
1212
+ $new_flow_post = array(
1213
+ 'post_content' => '',
1214
+ 'post_status' => 'publish',
1215
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1216
+ );
1217
+
1218
+ // Insert the post into the database.
1219
+ $flow_id = wp_insert_post( $new_flow_post );
1220
+
1221
+ if ( is_wp_error( $flow_id ) ) {
1222
+ wp_send_json_error( $flow_id->get_error_message() );
1223
+ }
1224
+
1225
+ $flow_steps = array();
1226
+
1227
+ if ( wcf()->is_woo_active ) {
1228
+ $steps_data = array(
1229
+ 'sales' => array(
1230
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1231
+ 'type' => 'landing',
1232
+ ),
1233
+ 'order-form' => array(
1234
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1235
+ 'type' => 'checkout',
1236
+ ),
1237
+ 'order-confirmation' => array(
1238
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1239
+ 'type' => 'thankyou',
1240
+ ),
1241
+ );
1242
+
1243
+ } else {
1244
+ $steps_data = array(
1245
+ 'landing' => array(
1246
+ 'title' => __( 'Landing', 'cartflows' ),
1247
+ 'type' => 'landing',
1248
+ ),
1249
+ 'thankyou' => array(
1250
+ 'title' => __( 'Thank You', 'cartflows' ),
1251
+ 'type' => 'landing',
1252
+ ),
1253
+ );
1254
+ }
1255
+
1256
+ foreach ( $steps_data as $slug => $data ) {
1257
+
1258
+ $post_content = '';
1259
+ $step_type = trim( $data['type'] );
1260
+
1261
+ $step_id = wp_insert_post(
1262
+ array(
1263
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1264
+ 'post_title' => $data['title'],
1265
+ 'post_content' => $post_content,
1266
+ 'post_status' => 'publish',
1267
+ )
1268
+ );
1269
+
1270
+ if ( is_wp_error( $step_id ) ) {
1271
+ wp_send_json_error( $step_id->get_error_message() );
1272
+ }
1273
+
1274
+ if ( $step_id ) {
1275
+
1276
+ $flow_steps[] = array(
1277
+ 'id' => $step_id,
1278
+ 'title' => $data['title'],
1279
+ 'type' => $step_type,
1280
+ );
1281
+
1282
+ // insert post meta.
1283
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1284
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1285
+
1286
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1287
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1288
+
1289
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1290
+ }
1291
+ }
1292
+
1293
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1294
+
1295
+ wp_send_json_success( $flow_id );
1296
+ }
1297
+
1298
+ /**
1299
+ * Create Flow
1300
+ *
1301
+ * @return void
1302
+ */
1303
+ public function create_flow() {
1304
+
1305
+ if ( ! current_user_can( 'manage_options' ) ) {
1306
+ return;
1307
+ }
1308
+
1309
+ check_ajax_referer( 'cf-create-flow', 'security' );
1310
+
1311
+ // Create post object.
1312
+ $new_flow_post = array(
1313
+ 'post_content' => '',
1314
+ 'post_status' => 'publish',
1315
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1316
+ );
1317
+
1318
+ // Insert the post into the database.
1319
+ $flow_id = wp_insert_post( $new_flow_post );
1320
+
1321
+ if ( is_wp_error( $flow_id ) ) {
1322
+ wp_send_json_error( $flow_id->get_error_message() );
1323
+ }
1324
+
1325
+ /* Imported Flow */
1326
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1327
+
1328
+ wp_send_json_success( $flow_id );
1329
+ }
1330
+
1331
+ /**
1332
+ * Create Step
1333
+ *
1334
+ * @return void
1335
+ */
1336
+ public function import_step() {
1337
+
1338
+ if ( ! current_user_can( 'manage_options' ) ) {
1339
+ return;
1340
+ }
1341
+
1342
+ check_ajax_referer( 'cf-step-import', 'security' );
1343
+
1344
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1345
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1346
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1347
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1348
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1349
+
1350
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1351
+
1352
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1353
+
1354
+ wcf()->logger->import_log( '------------------------------------' );
1355
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1356
+ wcf()->logger->import_log( '------------------------------------' );
1357
+
1358
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1359
+ /* translators: %s: template ID */
1360
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1361
+ wcf()->logger->import_log( $data );
1362
+ wp_send_json_error( $data );
1363
+ }
1364
+
1365
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1366
+
1367
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1368
+
1369
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1370
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1371
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1372
+
1373
+ wp_update_post(
1374
+ array(
1375
+ 'ID' => $post_id,
1376
+ 'post_content' => $response['data']['divi_content'],
1377
+ )
1378
+ );
1379
+ }
1380
+ }
1381
+
1382
+ /* Imported Step */
1383
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1384
+
1385
+ // Import Post Meta.
1386
+ self::import_post_meta( $post_id, $response );
1387
+
1388
+ do_action( 'cartflows_import_complete' );
1389
+
1390
+ // Batch Process.
1391
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1392
+
1393
+ wcf()->logger->import_log( '------------------------------------' );
1394
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1395
+ wcf()->logger->import_log( '------------------------------------' );
1396
+
1397
+ wp_send_json_success( $post_id );
1398
+ }
1399
+
1400
+ /**
1401
+ * Import Step.
1402
+ *
1403
+ * @since 1.0.0
1404
+ * @hook wp_ajax_cartflows_step_create_blank
1405
+ *
1406
+ * @return void
1407
+ */
1408
+ public function step_create_blank() {
1409
+
1410
+ if ( ! current_user_can( 'manage_options' ) ) {
1411
+ return;
1412
+ }
1413
+
1414
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1415
+
1416
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1417
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1418
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1419
+
1420
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1421
+ /* translators: %s: flow ID */
1422
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1423
+ wcf()->logger->import_log( $data );
1424
+ wp_send_json_error( $data );
1425
+ }
1426
+
1427
+ wcf()->logger->import_log( '------------------------------------' );
1428
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1429
+
1430
+ $step_type_title = str_replace( '-', ' ', $step_type );
1431
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1432
+
1433
+ $new_step_id = wp_insert_post(
1434
+ array(
1435
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1436
+ 'post_title' => $step_title,
1437
+ 'post_content' => '',
1438
+ 'post_status' => 'publish',
1439
+ )
1440
+ );
1441
+
1442
+ // insert post meta.
1443
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1444
+
1445
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1446
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1447
+
1448
+ if ( empty( $term_exist ) ) {
1449
+ $terms = array(
1450
+ array(
1451
+ 'name' => $step_type_title,
1452
+ 'slug' => $step_type_slug,
1453
+ ),
1454
+ );
1455
+
1456
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1457
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1458
+ }
1459
+
1460
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1461
+
1462
+ // Set type object.
1463
+ $data = get_term( $current_term['term_id'], $taxonomy );
1464
+ $step_slug = $data->slug;
1465
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1466
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1467
+
1468
+ // Set Default page Layout.
1469
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1470
+
1471
+ // Set type.
1472
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1473
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1474
+
1475
+ // Set flow.
1476
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1477
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1478
+
1479
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1480
+
1481
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1482
+ wcf()->logger->import_log( '------------------------------------' );
1483
+
1484
+ wp_send_json_success( $new_step_id );
1485
+ }
1486
+
1487
+ /**
1488
+ * Import Post Meta
1489
+ *
1490
+ * @since 1.0.0
1491
+ *
1492
+ * @param integer $post_id Post ID.
1493
+ * @param array $response Post meta.
1494
+ * @return void
1495
+ */
1496
+ public static function import_post_meta( $post_id, $response ) {
1497
+
1498
+ $metadata = (array) $response['post_meta'];
1499
+
1500
+ foreach ( $metadata as $meta_key => $meta_value ) {
1501
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1502
+
1503
+ if ( $meta_value ) {
1504
+
1505
+ if ( is_serialized( $meta_value, true ) ) {
1506
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1507
+ } elseif ( is_array( $meta_value ) ) {
1508
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1509
+ } else {
1510
+ $raw_data = $meta_value;
1511
+ }
1512
+
1513
+ if ( '_elementor_data' === $meta_key ) {
1514
+ if ( is_array( $raw_data ) ) {
1515
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1516
+ } else {
1517
+ $raw_data = wp_slash( $raw_data );
1518
+ }
1519
+ }
1520
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1521
+ if ( is_array( $raw_data ) ) {
1522
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1523
+ } else {
1524
+ if ( ! is_object( $raw_data ) ) {
1525
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1526
+ }
1527
+ }
1528
+ }
1529
+
1530
+ update_post_meta( $post_id, $meta_key, $raw_data );
1531
+ }
1532
+ }
1533
+ }
1534
+
1535
+ /**
1536
+ * Import Template for Elementor
1537
+ *
1538
+ * @since 1.0.0
1539
+ *
1540
+ * @param integer $post_id Post ID.
1541
+ * @param array $response Post meta.
1542
+ * @param array $page_build_data Page build data.
1543
+ * @return void
1544
+ */
1545
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1546
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1547
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1548
+ wcf()->logger->import_log( $data );
1549
+ wp_send_json_error( $data );
1550
+ }
1551
+
1552
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1553
+
1554
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1555
+
1556
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1557
+ $obj->import_single_template( $post_id );
1558
+
1559
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1560
+ }
1561
+
1562
+ /**
1563
+ * Supported post types
1564
+ *
1565
+ * @since 1.0.0
1566
+ *
1567
+ * @return array Supported post types.
1568
+ */
1569
+ public static function supported_post_types() {
1570
+ return apply_filters(
1571
+ 'cartflows_supported_post_types',
1572
+ array(
1573
+ CARTFLOWS_FLOW_POST_TYPE,
1574
+ )
1575
+ );
1576
+ }
1577
+
1578
+ /**
1579
+ * Check supported post type
1580
+ *
1581
+ * @since 1.0.0
1582
+ *
1583
+ * @param string $post_type Post type.
1584
+ * @return boolean Supported post type status.
1585
+ */
1586
+ public static function is_supported_post( $post_type = '' ) {
1587
+
1588
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1589
+ return true;
1590
+ }
1591
+
1592
+ return false;
1593
+ }
1594
+
1595
+ /**
1596
+ * Set steps to the flow
1597
+ *
1598
+ * @param integer $flow_id Flow ID.
1599
+ * @param integer $new_step_id New step ID.
1600
+ * @param string $step_title Flow Type.
1601
+ * @param string $step_slug Flow Type.
1602
+ */
1603
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1604
+ // Update steps for the current flow.
1605
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1606
+
1607
+ if ( ! is_array( $flow_steps ) ) {
1608
+ $flow_steps = array();
1609
+ }
1610
+
1611
+ $flow_steps[] = array(
1612
+ 'id' => $new_step_id,
1613
+ 'title' => $step_title,
1614
+ 'type' => $step_slug,
1615
+ );
1616
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1617
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1618
+ }
1619
+
1620
+ /**
1621
+ * Localize variables in admin
1622
+ *
1623
+ * @param array $vars variables.
1624
+ */
1625
+ public function localize_vars( $vars ) {
1626
+
1627
+ $ajax_actions = array(
1628
+ 'cf_step_import',
1629
+ 'cf_load_steps',
1630
+ 'cf_create_flow',
1631
+ 'cf_default_flow',
1632
+ 'cf_step_create_blank',
1633
+ 'cf_import_flow_step',
1634
+ );
1635
+
1636
+ foreach ( $ajax_actions as $action ) {
1637
+
1638
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1639
+ }
1640
+
1641
+ return $vars;
1642
+ }
1643
+
1644
+ /**
1645
+ * Ajax action to activate plugin
1646
+ */
1647
+ public function activate_plugin() {
1648
+
1649
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1650
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1651
+ }
1652
+
1653
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1654
+ wp_send_json_error(
1655
+ array(
1656
+ 'success' => false,
1657
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1658
+ )
1659
+ );
1660
+ }
1661
+
1662
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1663
+
1664
+ $activate = activate_plugin( $plugin_init, '', false, true );
1665
+
1666
+ if ( is_wp_error( $activate ) ) {
1667
+ wp_send_json_error(
1668
+ array(
1669
+ 'success' => false,
1670
+ 'message' => $activate->get_error_message(),
1671
+ 'init' => $plugin_init,
1672
+ )
1673
+ );
1674
+ }
1675
+
1676
+ wp_send_json_success(
1677
+ array(
1678
+ 'success' => true,
1679
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1680
+ 'init' => $plugin_init,
1681
+ )
1682
+ );
1683
+ }
1684
+
1685
+ }
1686
+
1687
+ /**
1688
+ * Initialize class object with 'get_instance()' method
1689
+ */
1690
+ CartFlows_Importer::get_instance();
1691
+
1692
+ 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.4' );
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.5' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
classes/class-cartflows-meta-fields.php CHANGED
@@ -1,835 +1,835 @@
1
- <?php
2
- // @codingStandardsIgnoreStart
3
- /**
4
- * Meta Fields.
5
- *
6
- * @package CartFlows
7
- */
8
-
9
- /**
10
- * Class Cartflows_Meta_Fields.
11
- */
12
- class Cartflows_Meta_Fields {
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Initiator
23
- */
24
- public static function get_instance() {
25
- if ( ! isset( self::$instance ) ) {
26
- self::$instance = new self;
27
- }
28
-
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Add Scripts */
38
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_meta_scripts' ), 20 );
39
-
40
- add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
41
-
42
- add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
43
-
44
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
45
-
46
- }
47
- public function admin_meta_scripts() {
48
-
49
- global $pagenow;
50
- global $post;
51
-
52
- $screen = get_current_screen();
53
-
54
- if (
55
- ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) &&
56
- wcf()->utils->is_step_post_type( $screen->post_type )
57
- ) {
58
-
59
- wp_enqueue_style( 'woocommerce_admin_styles' );
60
-
61
- wp_enqueue_script( 'select2' );
62
- wp_enqueue_script( 'wc-enhanced-select' );
63
-
64
- wp_enqueue_script(
65
- 'wcf-admin-meta',
66
- CARTFLOWS_URL . 'admin/meta-assets/js/admin-edit.js',
67
- array( 'jquery', 'wp-color-picker' ),
68
- CARTFLOWS_VER,
69
- true
70
- );
71
-
72
- wp_enqueue_style( 'wcf-admin-meta', CARTFLOWS_URL . 'admin/meta-assets/css/admin-edit.css', array( 'wp-color-picker' ), CARTFLOWS_VER );
73
- wp_style_add_data( 'wcf-admin-meta', 'rtl', 'replace' );
74
-
75
- $localize = array(
76
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
77
- 'google_fonts' => CartFlows_Font_Families::get_google_fonts(),
78
- 'system_fonts' => CartFlows_Font_Families::get_system_fonts(),
79
- 'font_weights' => array(
80
- '100' => __( 'Thin 100', 'cartflows' ),
81
- '200' => __( 'Extra-Light 200', 'cartflows' ),
82
- '300' => __( 'Light 300', 'cartflows' ),
83
- '400' => __( 'Normal 400', 'cartflows' ),
84
- '500' => __( 'Medium 500', 'cartflows' ),
85
- '600' => __( 'Semi-Bold 600', 'cartflows' ),
86
- '700' => __( 'Bold 700', 'cartflows' ),
87
- '800' => __( 'Extra-Bold 800', 'cartflows' ),
88
- '900' => __( 'Ultra-Bold 900', 'cartflows' ),
89
- )
90
- );
91
-
92
- wp_localize_script( 'jquery', 'wcf', apply_filters( 'wcf_js_localize', $localize ) );
93
-
94
- do_action( 'cartflows_admin_meta_scripts' );
95
- }
96
- }
97
-
98
- /**
99
- * Function to search coupons
100
- */
101
- public function json_search_coupons() {
102
-
103
- check_admin_referer( 'wcf-json-search-coupons', 'security' );
104
-
105
- global $wpdb;
106
-
107
- $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
108
-
109
- if ( empty( $term ) ) {
110
- die();
111
- }
112
-
113
- $posts = wp_cache_get( 'wcf_search_coupons', 'wcf_funnel_Cart' );
114
-
115
- if ( false === $posts ) {
116
- $posts = $wpdb->get_results( // phpcs:ignore
117
- $wpdb->prepare(
118
- "SELECT *
119
- FROM {$wpdb->prefix}posts
120
- WHERE post_type = %s
121
- AND post_title LIKE %s
122
- AND post_status = %s",
123
- 'shop_coupon',
124
- $wpdb->esc_like( $term ) . '%',
125
- 'publish'
126
- )
127
- );
128
- wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
129
- }
130
-
131
- $coupons_found = array();
132
- $all_discount_types = wc_get_coupon_types();
133
-
134
- if ( $posts ) {
135
- foreach ( $posts as $post ) {
136
-
137
- $discount_type = get_post_meta( $post->ID, 'discount_type', true );
138
-
139
- if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
140
- $coupons_found[ get_the_title( $post->ID ) ] = get_the_title( $post->ID ) . ' (Type: ' . $all_discount_types[ $discount_type ] . ')';
141
- }
142
- }
143
- }
144
-
145
- wp_send_json( $coupons_found );
146
- }
147
-
148
- /**
149
- * Function to search coupons
150
- */
151
- public function json_search_pages() {
152
-
153
- check_ajax_referer( 'wcf-json-search-pages', 'security' );
154
-
155
- $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
156
-
157
- if ( empty( $term ) ) {
158
- die( 'not found' );
159
- }
160
-
161
- $search_string = $term;
162
- $data = array();
163
- $result = array();
164
-
165
- add_filter( 'posts_search', array( $this, 'search_only_titles' ), 10, 2 );
166
-
167
- $query = new WP_Query(
168
- array(
169
- 's' => $search_string,
170
- 'post_type' => 'page',
171
- 'posts_per_page' => -1,
172
- )
173
- );
174
-
175
- if ( $query->have_posts() ) {
176
- while ( $query->have_posts() ) {
177
- $query->the_post();
178
- $title = get_the_title();
179
- $title .= ( 0 != $query->post->post_parent ) ? ' (' . get_the_title( $query->post->post_parent ) . ')' : '';
180
- $id = get_the_id();
181
- $data[] = array(
182
- 'id' => $id,
183
- 'text' => $title,
184
- );
185
- }
186
- }
187
-
188
- if ( is_array( $data ) && ! empty( $data ) ) {
189
- $result[] = array(
190
- 'text' => '',
191
- 'children' => $data,
192
- );
193
- }
194
-
195
- wp_reset_postdata();
196
-
197
- // return the result in json.
198
- wp_send_json( $result );
199
- }
200
-
201
- public function search_only_titles( $search, $wp_query ) {
202
- if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
203
- global $wpdb;
204
-
205
- $q = $wp_query->query_vars;
206
- $n = ! empty( $q['exact'] ) ? '' : '%';
207
-
208
- $search = array();
209
-
210
- foreach ( (array) $q['search_terms'] as $term ) {
211
- $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $n . $wpdb->esc_like( $term ) . $n );
212
- }
213
-
214
- if ( ! is_user_logged_in() ) {
215
- $search[] = "$wpdb->posts.post_password = ''";
216
- }
217
-
218
- $search = ' AND ' . implode( ' AND ', $search );
219
- }
220
-
221
- return $search;
222
- }
223
-
224
- function get_field( $field_data, $field_content ) {
225
-
226
- $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
227
- $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
228
- $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
229
-
230
- $name_class = 'field-' . $field_data['name'];
231
-
232
- $field_html = '<div class="wcf-field-row ' . $name_class . '">';
233
-
234
- if( ! empty( $label ) || ! empty( $help ) ) {
235
- $field_html .= '<div class="wcf-field-row-heading">';
236
- if( ! empty( $label ) ) {
237
- $field_html .= '<label>' . esc_html( $label ) . '</label>';
238
- }
239
- if ( ! empty( $help ) ) {
240
- $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help">';
241
- // $field_html .= '<span class="wcf-tooltip" data-tooltip= "'. esc_attr( $help ) .'"></span>';
242
- $field_html .= '</i>';
243
- $field_html .= '<span class="wcf-tooltip-text">';
244
- $field_html .= $help;
245
- $field_html .= '</span>';
246
- }
247
- $field_html .= '</div>';
248
- }
249
-
250
- $field_html .= '<div class="wcf-field-row-content">';
251
- $field_html .= $field_content;
252
-
253
- if ( ! empty( $after_html ) ) {
254
- $field_html .= $after_html;
255
- }
256
-
257
- $field_html .= '</div>';
258
- $field_html .= '</div>';
259
-
260
- return $field_html;
261
- }
262
-
263
- function get_text_field( $field_data ) {
264
-
265
- $value = $field_data['value'];
266
-
267
- $attr = '';
268
-
269
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
270
-
271
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
272
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
273
- }
274
- }
275
-
276
- $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . esc_attr( $value ) . '" ' . $attr . '>';
277
-
278
- return $this->get_field( $field_data, $field_content );
279
- }
280
-
281
- function get_shortcode_field( $field_data ) {
282
-
283
- $attr = '';
284
-
285
- $attr_fields = array(
286
- 'readonly' => 'readonly',
287
- 'onfocus' => 'this.select()',
288
- 'onmouseup' => 'return false',
289
- );
290
-
291
- if ( $attr_fields && is_array( $attr_fields ) ) {
292
-
293
- foreach ( $attr_fields as $attr_key => $attr_value ) {
294
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
295
- }
296
- }
297
-
298
- $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $field_data['content'] . '" ' . $attr . '>';
299
-
300
- return $this->get_field( $field_data, $field_content );
301
- }
302
-
303
- function get_display_field( $field_data ) {
304
-
305
- $field_content = $field_data['content'];
306
-
307
- return $this->get_field( $field_data, $field_content );
308
- }
309
-
310
- function get_hr_line_field( $field_data ) {
311
-
312
- $field_data = array(
313
- 'name' => 'wcf-hr-line',
314
- 'content' => '<hr>'
315
- );
316
-
317
- $field_content = $field_data['content'];
318
-
319
- return $this->get_field( $field_data, $field_content );
320
- }
321
-
322
- function get_number_field( $field_data ) {
323
-
324
- $value = $field_data['value'];
325
-
326
- $attr = '';
327
-
328
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
329
-
330
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
331
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
332
- }
333
- }
334
-
335
- $field_content = '<input type="number" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
336
-
337
- return $this->get_field( $field_data, $field_content );
338
- }
339
-
340
- function get_hidden_field( $field_data ) {
341
-
342
- $value = $field_data['value'];
343
-
344
- $attr = '';
345
-
346
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
347
-
348
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
349
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
350
- }
351
- }
352
-
353
- $field_content = '<input type="hidden" id="' . $field_data['name'] . '" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
354
-
355
- return $this->get_field( $field_data, $field_content );
356
- }
357
-
358
- function get_area_field( $field_data ) {
359
-
360
- $value = $field_data['value'];
361
-
362
- $attr = '';
363
-
364
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
365
-
366
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
367
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
368
- }
369
- }
370
-
371
- $field_content = '<textarea name="' . $field_data['name'] . '" rows="10" cols="50" ' . $attr . '>';
372
- $field_content .= $value;
373
- $field_content .= '</textarea>';
374
-
375
- return $this->get_field( $field_data, $field_content );
376
- }
377
-
378
- function get_only_checkbox_field( $field_data ) {
379
-
380
- $value = $field_data['value'];
381
-
382
-
383
- $field_content = '';
384
- if ( isset( $field_data['before'] ) ) {
385
- $field_content .= '<span>' . $field_data['before'] . '</span>';
386
- }
387
- $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
388
- $field_content .= '<input type="checkbox" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . '>';
389
-
390
- if ( isset( $field_data['after'] ) ) {
391
- $field_content .= '<span>' . $field_data['after'] . '</span>';
392
- }
393
-
394
- if ( isset( $field_data['after_html'] ) ) {
395
- $field_content .= '<span>' . $field_data['after_html'] . '</span>';
396
- }
397
-
398
- return $field_content;
399
- }
400
-
401
- function get_checkbox_field( $field_data ) {
402
-
403
- $value = $field_data['value'];
404
-
405
- $field_content = '';
406
- if ( isset( $field_data['before'] ) ) {
407
- $field_content .= '<span>' . $field_data['before'] . '</span>';
408
- }
409
-
410
- $toggle_data = '';
411
- if ( isset( $field_data['toggle'] ) ) {
412
- $toggle_data .= 'toggle="' . htmlspecialchars( wp_json_encode( $field_data['toggle'] ) ) . '"';
413
- }
414
-
415
- $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
416
- $field_content .= '<input type="checkbox" id="'.$field_data['name'].'" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . ' ' . $toggle_data . '>';
417
-
418
- if ( isset( $field_data['after'] ) ) {
419
- $field_content .= '<span>' . $field_data['after'] . '</span>';
420
- }
421
-
422
- return $this->get_field( $field_data, $field_content );
423
- }
424
-
425
- function get_radio_field( $field_data ) {
426
-
427
- $value = $field_data['value'];
428
- $field_content = '';
429
-
430
- if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
431
-
432
- foreach ( $field_data['options'] as $data_key => $data_value ) {
433
-
434
- $field_content .= '<div class="wcf-radio-option">';
435
- $field_content .= '<input type="radio" name="' . $field_data['name'] . '" value="' . $data_key . '" ' . checked( $data_key, $value, false ) . '>';
436
- $field_content .= $data_value;
437
- $field_content .= '</div>';
438
- }
439
- }
440
-
441
- return $this->get_field( $field_data, $field_content );
442
- }
443
-
444
- function get_font_family_field( $field_data ) {
445
-
446
- $value = $field_data['value'];
447
-
448
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
449
-
450
- $field_content = '<select class="wcf-field-font-family" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
451
-
452
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
453
-
454
- $field_content .= '<optgroup label="Other System Fonts">';
455
- foreach ( CartFlows_Font_Families::get_system_fonts() as $name => $variants ) {
456
- $field_content .= '<option value="' . esc_attr( $name ) . '" ' . selected( $name, $value, false ) . '>' . esc_attr( $name ) . '</option>';
457
- }
458
- $field_content .= '</optgroup>';
459
- $field_content .= '<optgroup label="Google">';
460
- foreach ( CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) {
461
- $variants = wcf_get_prop( $single_font, '0' );
462
- $category = wcf_get_prop( $single_font, '1' );
463
- $font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category );
464
- $field_content .= '<option value="' . esc_attr( $font_value ) . '" ' . selected( $font_value, $value, false ) . '>' . esc_attr( $name ) . '</option>';
465
- }
466
- $field_content .= '</optgroup>';
467
-
468
- $field_content .= '</select>';
469
-
470
- return $this->get_field( $field_data, $field_content );
471
- }
472
-
473
- function get_font_weight_field( $field_data ) {
474
-
475
- $value = $field_data['value'];
476
-
477
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
478
-
479
- $field_content = '<select data-selected="'.esc_attr( $value ).'" class="wcf-field-font-weight" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
480
-
481
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
482
-
483
- $field_content .= '</select>';
484
-
485
- return $this->get_field( $field_data, $field_content );
486
- }
487
-
488
- function get_select_field( $field_data ) {
489
-
490
- $value = $field_data['value'];
491
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
492
-
493
- $field_content = '<select name="' . $field_data['name'] . '">';
494
-
495
-
496
- if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
497
-
498
- foreach ( $field_data['options'] as $data_key => $data_value ) {
499
-
500
- $disabled = '';
501
-
502
- if ( array_key_exists( $data_key, $pro_options ) ) {
503
- $disabled = 'disabled ';
504
- $data_value = $pro_options[ $data_key ];
505
- }
506
-
507
- $field_content .= '<option value="' . $data_key . '" ' . selected( $value, $data_key, false ) . ' ' . $disabled .'>' . $data_value . '</option>';
508
- }
509
- }
510
-
511
- $field_content .= '</select>';
512
-
513
- if ( isset( $field_data['after'] ) ) {
514
- $field_content .= '<span>' . $field_data['after'] . '</span>';
515
- }
516
-
517
- return $this->get_field( $field_data, $field_content );
518
- }
519
-
520
- function get_color_picker_field( $field_data ) {
521
-
522
- $value = $field_data['value'];
523
-
524
- $field_content = '<input class="wcf-color-picker" type="text" name="' . $field_data['name'] . '" value="' . $value . '">';
525
-
526
- return $this->get_field( $field_data, $field_content );
527
- }
528
-
529
- function get_product_selection_field( $field_data ) {
530
-
531
- $value = $field_data['value'];
532
-
533
- $multiple = '';
534
-
535
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
536
- $multiple = ' multiple="multiple"';
537
- }
538
-
539
- $allow_clear = '';
540
-
541
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
542
- $allow_clear = ' data-allow_clear="allow_clear"';
543
- }
544
-
545
- $field_content = '<select
546
- name="' . $field_data['name'] . '[]"
547
- class="wcf-product-search" ' . $multiple . $allow_clear . '
548
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
549
- data-action="woocommerce_json_search_products_and_variations">';
550
-
551
- if ( is_array( $value ) && ! empty( $value ) ) {
552
-
553
- foreach ( $value as $data_key => $product_id ) {
554
-
555
- $product = wc_get_product( $product_id );
556
-
557
- // posts.
558
- if ( ! empty( $product ) ) {
559
- $post_title = $product->get_name() . ' (#' . $product_id . ')';
560
-
561
- $field_content .= '<option value="' . $product_id . '" selected="selected" >' . $post_title . '</option>';
562
- }
563
- }
564
- }
565
- $field_content .= '</select>';
566
-
567
- return $this->get_field( $field_data, $field_content );
568
- }
569
-
570
- function get_coupon_selection_field( $field_data ) {
571
-
572
- $value = $field_data['value'];
573
-
574
- $multiple = '';
575
-
576
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
577
- $multiple = ' multiple="multiple"';
578
- }
579
-
580
- $allow_clear = '';
581
-
582
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
583
- $allow_clear = ' data-allow_clear="allow_clear"';
584
- }
585
-
586
- $field_content = '<select
587
- name="' . $field_data['name'] . '[]"
588
- class="wc-coupon-search wcf-coupon-search" ' . $multiple . $allow_clear . '
589
- data-placeholder="' . __( 'Search for a coupon&hellip;', 'cartflows' ) . '"
590
- data-action="wcf_json_search_coupons">';
591
-
592
- if ( is_array( $value ) && ! empty( $value ) ) {
593
-
594
- $all_discount_types = wc_get_coupon_types();
595
-
596
- foreach ( $value as $coupon_title ) {
597
-
598
- $coupon = new WC_Coupon( $coupon_title );
599
-
600
- $discount_type = $coupon->get_discount_type();
601
-
602
- if ( isset( $discount_type ) && $discount_type ) {
603
- $discount_type = ' ( Type: ' . $all_discount_types[ $discount_type ] . ' )';
604
- }
605
-
606
- $field_content .= '<option value="' . $coupon_title . '" selected="selected">' . $coupon_title . $discount_type . '</option>';
607
- }
608
- }
609
-
610
- $field_content .= '</select>';
611
-
612
- return $this->get_field( $field_data, $field_content );
613
- }
614
-
615
- function get_page_selection_field( $field_data ) {
616
-
617
- $value = $field_data['value'];
618
-
619
- $multiple = '';
620
-
621
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
622
- $multiple = 'multiple="multiple"';
623
- }
624
-
625
- $field_content = '<select
626
- name="' . $field_data['name'] . '[]"
627
- class="wcf-search-pages" ' . $multiple . '"
628
- data-action="wcf_json_search_pages">';
629
-
630
- if ( is_array( $value ) && ! empty( $value ) ) {
631
-
632
- foreach ( $value as $data_key => $data_value ) {
633
-
634
- $field_content .= '<option value="' . $data_value . '">' . get_the_title( $data_value ) . '</option>';
635
- }
636
- }
637
-
638
- $field_content .= '</select>';
639
-
640
- return $this->get_field( $field_data, $field_content );
641
- }
642
-
643
- function get_section( $field_data ) {
644
- $field_html = '<div class="wcf-field-row wcf-field-section">';
645
- $field_html .= '<div class="wcf-field-section-heading" colspan="2">';
646
- $field_html .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
647
-
648
- if ( isset( $field_data['help'] ) ) {
649
- $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help" title="' . esc_attr( $field_data['help'] ) . '"></i>';
650
- }
651
- $field_html .= '</div>';
652
- $field_html .= '</div>';
653
- return $field_html;
654
- }
655
-
656
- function get_description_field( $field_data ) {
657
-
658
- $field_html = '<div class="wcf-field-row wcf-field-desc ' . $field_data['name'] . '">';
659
- $field_html .= '<div class="wcf-field-desc-content">';
660
- $field_html .= $field_data['content'];
661
- $field_html .= '</div>';
662
- $field_html .= '</div>';
663
-
664
- return $field_html;
665
- }
666
-
667
- function get_product_selection_repeater( $field_data ) {
668
-
669
- $value = $field_data['value'];
670
-
671
- if ( ! is_array( $value ) ) {
672
-
673
- $value[0] = array(
674
- 'product' => '',
675
- );
676
- } else {
677
-
678
- if ( ! isset( $value[0] ) ) {
679
-
680
- $value[0] = array(
681
- 'product' => '',
682
- );
683
- }
684
- }
685
-
686
- $name_class = 'field-' . $field_data['name'];
687
-
688
- $field_html = '';
689
-
690
- $field_html .= '<script type="text/html" id="tmpl-wcf-product-repeater">';
691
- $field_html .= $this->generate_product_repeater_html( '{{id}}' );
692
- $field_html .= '</script>';
693
-
694
- $field_html .= '<div class="wcf-field-row wcf-product-repeater-field-row ' . $name_class . '">';
695
- $field_html .= '<div class="wcf-field-row-content">';
696
- $field_html .= '<div class="wcf-repeatables-wrap">';
697
-
698
- if ( is_array( $value ) ) {
699
-
700
- foreach ( $value as $p_key => $p_data ) {
701
-
702
- $selected_options = '';
703
-
704
- if ( isset( $p_data['product'] ) ) {
705
-
706
- $product = wc_get_product( $p_data['product'] );
707
-
708
- // posts.
709
- if ( ! empty( $product ) ) {
710
- $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
711
-
712
- $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
713
- }
714
- }
715
-
716
- $field_html .= $this->generate_product_repeater_html( $p_key, $selected_options );
717
- }
718
- }
719
-
720
- $field_html .= '<div class="wcf-add-repeatable-row">';
721
- $field_html .= '<div class="submit wcf-add-repeatable-wrap">';
722
- $field_html .= '<button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products">' . __( 'Add New Product', 'cartflows' ) . '</button>';
723
- $field_html .= '<a href="#!" class="button button-primary wcf-create-woo-product" data-name="wcf-create-woo-product">'. __( 'Create Product', 'cartflows' ) . '</a>';
724
- $field_html .= '</div>';
725
- $field_html .= '</div>';
726
-
727
- $field_html .= '</div>';
728
- $field_html .= '</div>';
729
- $field_html .= '</div>';
730
-
731
- return $field_html;
732
- }
733
-
734
- function generate_product_repeater_html( $id, $options = '' ) {
735
-
736
- $field_html = '<div class="wcf-repeatable-row" data-key="' . $id . '">';
737
-
738
- $field_html .= '<div class="wcf-repeatable-row-standard-fields">';
739
-
740
- /* Product Name */
741
- $field_html .= '<div class="wcf-repeatable-fields wcf-sel-product">';
742
- $field_html .= '<span class="wcf-repeatable-row-setting-field">';
743
- $field_html .= '<select
744
- name="wcf-checkout-products[' . $id . '][product]"
745
- class="wcf-product-search"
746
- data-allow_clear="allow_clear"
747
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
748
- data-action="woocommerce_json_search_products_and_variations">';
749
- $field_html .= $options;
750
- $field_html .= '</select>';
751
- $field_html .= '</span>';
752
- $field_html .= '<span class="wcf-repeatable-row-actions">';
753
- $field_html .= '<a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">';
754
- $field_html .= '<span class="dashicons dashicons-trash"></span>';
755
- $field_html .= '<span class="wcf-repeatable-remove-button">'. __( 'Remove', 'cartflows' ).'</span>';
756
- $field_html .= '</a>';
757
- $field_html .= '</span>';
758
- $field_html .= '</div>';
759
- $field_html .= '</div>';
760
- $field_html .= '</div>';
761
-
762
- return $field_html;
763
- }
764
-
765
- function get_image_field( $field_data ) {
766
-
767
- global $post;
768
- $value = $field_data['value'];
769
-
770
- $attr = '';
771
-
772
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
773
-
774
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
775
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
776
- }
777
- }
778
-
779
- $display_preview_box = ( isset( $value ) && '' != $value ) ? 'display:block;' : 'display:none';
780
-
781
- $field_content = '<div id="wcf-image-preview" style="'.$display_preview_box.'">';
782
-
783
- if( isset( $value ) ){
784
-
785
- $field_content .= '<img src="'. $field_data['value'] .'" class="saved-image" name="'. $field_data['name'] .'" width="150">';
786
- }
787
-
788
- $field_content .= '</div>';
789
-
790
- $image_data = htmlentities( serialize( get_post_meta( $post->ID, $field_data['name'].'-obj') ) );
791
-
792
- $field_content .= '<input type="hidden" id="'. $field_data['name'] .'" class="wcf-image" name="' . $field_data['name'] . '" value="'.$value.'">';
793
-
794
- $field_content .= '<input type="hidden" id="'. $field_data['name'].'-obj'.'" class="wcf-image-obj" name="' . $field_data['name'].'-obj'. '" value="'.$image_data.'">';
795
-
796
-
797
- $field_content .= '<button type="button" ' . $attr . ' class="wcf-select-image button-secondary">Select Image</button>';
798
-
799
- $display_remove_button = ( isset( $value ) && '' != $value ) ? 'display:inline-block; margin-left: 5px;' : 'display:none';
800
-
801
- $field_content .= '<button type="button" class="wcf-remove-image button-secondary" style="'.$display_remove_button.'">Remove Image</button>';
802
-
803
- return $this->get_field( $field_data, $field_content );
804
- }
805
-
806
- /**
807
- * Localize variables in admin
808
- *
809
- * @param array $vars variables.
810
- */
811
- function localize_vars( $vars ) {
812
-
813
- $ajax_actions = array(
814
- 'wcf_json_search_pages',
815
- 'wcf_json_search_coupons'
816
- );
817
-
818
- foreach ( $ajax_actions as $action ) {
819
-
820
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
821
- }
822
-
823
- /* Add product from iframe */
824
- $product_src = esc_url_raw( add_query_arg( array(
825
- 'post_type' => 'product',
826
- 'wcf-woo-iframe' => 'true',
827
- ), admin_url( 'post-new.php' ) ) );
828
-
829
- $vars['create_product_src'] = $product_src;
830
- /* Add product from iframe End */
831
-
832
- return $vars;
833
- }
834
- }
835
- // @codingStandardsIgnoreEnd
1
+ <?php
2
+ // @codingStandardsIgnoreStart
3
+ /**
4
+ * Meta Fields.
5
+ *
6
+ * @package CartFlows
7
+ */
8
+
9
+ /**
10
+ * Class Cartflows_Meta_Fields.
11
+ */
12
+ class Cartflows_Meta_Fields {
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Initiator
23
+ */
24
+ public static function get_instance() {
25
+ if ( ! isset( self::$instance ) ) {
26
+ self::$instance = new self;
27
+ }
28
+
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Add Scripts */
38
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_meta_scripts' ), 20 );
39
+
40
+ add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
41
+
42
+ add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
43
+
44
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
45
+
46
+ }
47
+ public function admin_meta_scripts() {
48
+
49
+ global $pagenow;
50
+ global $post;
51
+
52
+ $screen = get_current_screen();
53
+
54
+ if (
55
+ ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) &&
56
+ wcf()->utils->is_step_post_type( $screen->post_type )
57
+ ) {
58
+
59
+ wp_enqueue_style( 'woocommerce_admin_styles' );
60
+
61
+ wp_enqueue_script( 'select2' );
62
+ wp_enqueue_script( 'wc-enhanced-select' );
63
+
64
+ wp_enqueue_script(
65
+ 'wcf-admin-meta',
66
+ CARTFLOWS_URL . 'admin/meta-assets/js/admin-edit.js',
67
+ array( 'jquery', 'wp-color-picker' ),
68
+ CARTFLOWS_VER,
69
+ true
70
+ );
71
+
72
+ wp_enqueue_style( 'wcf-admin-meta', CARTFLOWS_URL . 'admin/meta-assets/css/admin-edit.css', array( 'wp-color-picker' ), CARTFLOWS_VER );
73
+ wp_style_add_data( 'wcf-admin-meta', 'rtl', 'replace' );
74
+
75
+ $localize = array(
76
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
77
+ 'google_fonts' => CartFlows_Font_Families::get_google_fonts(),
78
+ 'system_fonts' => CartFlows_Font_Families::get_system_fonts(),
79
+ 'font_weights' => array(
80
+ '100' => __( 'Thin 100', 'cartflows' ),
81
+ '200' => __( 'Extra-Light 200', 'cartflows' ),
82
+ '300' => __( 'Light 300', 'cartflows' ),
83
+ '400' => __( 'Normal 400', 'cartflows' ),
84
+ '500' => __( 'Medium 500', 'cartflows' ),
85
+ '600' => __( 'Semi-Bold 600', 'cartflows' ),
86
+ '700' => __( 'Bold 700', 'cartflows' ),
87
+ '800' => __( 'Extra-Bold 800', 'cartflows' ),
88
+ '900' => __( 'Ultra-Bold 900', 'cartflows' ),
89
+ )
90
+ );
91
+
92
+ wp_localize_script( 'jquery', 'wcf', apply_filters( 'wcf_js_localize', $localize ) );
93
+
94
+ do_action( 'cartflows_admin_meta_scripts' );
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Function to search coupons
100
+ */
101
+ public function json_search_coupons() {
102
+
103
+ check_admin_referer( 'wcf-json-search-coupons', 'security' );
104
+
105
+ global $wpdb;
106
+
107
+ $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
108
+
109
+ if ( empty( $term ) ) {
110
+ die();
111
+ }
112
+
113
+ $posts = wp_cache_get( 'wcf_search_coupons', 'wcf_funnel_Cart' );
114
+
115
+ if ( false === $posts ) {
116
+ $posts = $wpdb->get_results( // phpcs:ignore
117
+ $wpdb->prepare(
118
+ "SELECT *
119
+ FROM {$wpdb->prefix}posts
120
+ WHERE post_type = %s
121
+ AND post_title LIKE %s
122
+ AND post_status = %s",
123
+ 'shop_coupon',
124
+ $wpdb->esc_like( $term ) . '%',
125
+ 'publish'
126
+ )
127
+ );
128
+ wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
129
+ }
130
+
131
+ $coupons_found = array();
132
+ $all_discount_types = wc_get_coupon_types();
133
+
134
+ if ( $posts ) {
135
+ foreach ( $posts as $post ) {
136
+
137
+ $discount_type = get_post_meta( $post->ID, 'discount_type', true );
138
+
139
+ if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
140
+ $coupons_found[ get_the_title( $post->ID ) ] = get_the_title( $post->ID ) . ' (Type: ' . $all_discount_types[ $discount_type ] . ')';
141
+ }
142
+ }
143
+ }
144
+
145
+ wp_send_json( $coupons_found );
146
+ }
147
+
148
+ /**
149
+ * Function to search coupons
150
+ */
151
+ public function json_search_pages() {
152
+
153
+ check_ajax_referer( 'wcf-json-search-pages', 'security' );
154
+
155
+ $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
156
+
157
+ if ( empty( $term ) ) {
158
+ die( 'not found' );
159
+ }
160
+
161
+ $search_string = $term;
162
+ $data = array();
163
+ $result = array();
164
+
165
+ add_filter( 'posts_search', array( $this, 'search_only_titles' ), 10, 2 );
166
+
167
+ $query = new WP_Query(
168
+ array(
169
+ 's' => $search_string,
170
+ 'post_type' => 'page',
171
+ 'posts_per_page' => -1,
172
+ )
173
+ );
174
+
175
+ if ( $query->have_posts() ) {
176
+ while ( $query->have_posts() ) {
177
+ $query->the_post();
178
+ $title = get_the_title();
179
+ $title .= ( 0 != $query->post->post_parent ) ? ' (' . get_the_title( $query->post->post_parent ) . ')' : '';
180
+ $id = get_the_id();
181
+ $data[] = array(
182
+ 'id' => $id,
183
+ 'text' => $title,
184
+ );
185
+ }
186
+ }
187
+
188
+ if ( is_array( $data ) && ! empty( $data ) ) {
189
+ $result[] = array(
190
+ 'text' => '',
191
+ 'children' => $data,
192
+ );
193
+ }
194
+
195
+ wp_reset_postdata();
196
+
197
+ // return the result in json.
198
+ wp_send_json( $result );
199
+ }
200
+
201
+ public function search_only_titles( $search, $wp_query ) {
202
+ if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
203
+ global $wpdb;
204
+
205
+ $q = $wp_query->query_vars;
206
+ $n = ! empty( $q['exact'] ) ? '' : '%';
207
+
208
+ $search = array();
209
+
210
+ foreach ( (array) $q['search_terms'] as $term ) {
211
+ $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $n . $wpdb->esc_like( $term ) . $n );
212
+ }
213
+
214
+ if ( ! is_user_logged_in() ) {
215
+ $search[] = "$wpdb->posts.post_password = ''";
216
+ }
217
+
218
+ $search = ' AND ' . implode( ' AND ', $search );
219
+ }
220
+
221
+ return $search;
222
+ }
223
+
224
+ function get_field( $field_data, $field_content ) {
225
+
226
+ $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
227
+ $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
228
+ $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
229
+
230
+ $name_class = 'field-' . $field_data['name'];
231
+
232
+ $field_html = '<div class="wcf-field-row ' . $name_class . '">';
233
+
234
+ if( ! empty( $label ) || ! empty( $help ) ) {
235
+ $field_html .= '<div class="wcf-field-row-heading">';
236
+ if( ! empty( $label ) ) {
237
+ $field_html .= '<label>' . esc_html( $label ) . '</label>';
238
+ }
239
+ if ( ! empty( $help ) ) {
240
+ $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help">';
241
+ // $field_html .= '<span class="wcf-tooltip" data-tooltip= "'. esc_attr( $help ) .'"></span>';
242
+ $field_html .= '</i>';
243
+ $field_html .= '<span class="wcf-tooltip-text">';
244
+ $field_html .= $help;
245
+ $field_html .= '</span>';
246
+ }
247
+ $field_html .= '</div>';
248
+ }
249
+
250
+ $field_html .= '<div class="wcf-field-row-content">';
251
+ $field_html .= $field_content;
252
+
253
+ if ( ! empty( $after_html ) ) {
254
+ $field_html .= $after_html;
255
+ }
256
+
257
+ $field_html .= '</div>';
258
+ $field_html .= '</div>';
259
+
260
+ return $field_html;
261
+ }
262
+
263
+ function get_text_field( $field_data ) {
264
+
265
+ $value = $field_data['value'];
266
+
267
+ $attr = '';
268
+
269
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
270
+
271
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
272
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
273
+ }
274
+ }
275
+
276
+ $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . esc_attr( $value ) . '" ' . $attr . '>';
277
+
278
+ return $this->get_field( $field_data, $field_content );
279
+ }
280
+
281
+ function get_shortcode_field( $field_data ) {
282
+
283
+ $attr = '';
284
+
285
+ $attr_fields = array(
286
+ 'readonly' => 'readonly',
287
+ 'onfocus' => 'this.select()',
288
+ 'onmouseup' => 'return false',
289
+ );
290
+
291
+ if ( $attr_fields && is_array( $attr_fields ) ) {
292
+
293
+ foreach ( $attr_fields as $attr_key => $attr_value ) {
294
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
295
+ }
296
+ }
297
+
298
+ $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $field_data['content'] . '" ' . $attr . '>';
299
+
300
+ return $this->get_field( $field_data, $field_content );
301
+ }
302
+
303
+ function get_display_field( $field_data ) {
304
+
305
+ $field_content = $field_data['content'];
306
+
307
+ return $this->get_field( $field_data, $field_content );
308
+ }
309
+
310
+ function get_hr_line_field( $field_data ) {
311
+
312
+ $field_data = array(
313
+ 'name' => 'wcf-hr-line',
314
+ 'content' => '<hr>'
315
+ );
316
+
317
+ $field_content = $field_data['content'];
318
+
319
+ return $this->get_field( $field_data, $field_content );
320
+ }
321
+
322
+ function get_number_field( $field_data ) {
323
+
324
+ $value = $field_data['value'];
325
+
326
+ $attr = '';
327
+
328
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
329
+
330
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
331
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
332
+ }
333
+ }
334
+
335
+ $field_content = '<input type="number" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
336
+
337
+ return $this->get_field( $field_data, $field_content );
338
+ }
339
+
340
+ function get_hidden_field( $field_data ) {
341
+
342
+ $value = $field_data['value'];
343
+
344
+ $attr = '';
345
+
346
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
347
+
348
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
349
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
350
+ }
351
+ }
352
+
353
+ $field_content = '<input type="hidden" id="' . $field_data['name'] . '" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
354
+
355
+ return $this->get_field( $field_data, $field_content );
356
+ }
357
+
358
+ function get_area_field( $field_data ) {
359
+
360
+ $value = $field_data['value'];
361
+
362
+ $attr = '';
363
+
364
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
365
+
366
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
367
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
368
+ }
369
+ }
370
+
371
+ $field_content = '<textarea name="' . $field_data['name'] . '" rows="10" cols="50" ' . $attr . '>';
372
+ $field_content .= $value;
373
+ $field_content .= '</textarea>';
374
+
375
+ return $this->get_field( $field_data, $field_content );
376
+ }
377
+
378
+ function get_only_checkbox_field( $field_data ) {
379
+
380
+ $value = $field_data['value'];
381
+
382
+
383
+ $field_content = '';
384
+ if ( isset( $field_data['before'] ) ) {
385
+ $field_content .= '<span>' . $field_data['before'] . '</span>';
386
+ }
387
+ $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
388
+ $field_content .= '<input type="checkbox" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . '>';
389
+
390
+ if ( isset( $field_data['after'] ) ) {
391
+ $field_content .= '<span>' . $field_data['after'] . '</span>';
392
+ }
393
+
394
+ if ( isset( $field_data['after_html'] ) ) {
395
+ $field_content .= '<span>' . $field_data['after_html'] . '</span>';
396
+ }
397
+
398
+ return $field_content;
399
+ }
400
+
401
+ function get_checkbox_field( $field_data ) {
402
+
403
+ $value = $field_data['value'];
404
+
405
+ $field_content = '';
406
+ if ( isset( $field_data['before'] ) ) {
407
+ $field_content .= '<span>' . $field_data['before'] . '</span>';
408
+ }
409
+
410
+ $toggle_data = '';
411
+ if ( isset( $field_data['toggle'] ) ) {
412
+ $toggle_data .= 'toggle="' . htmlspecialchars( wp_json_encode( $field_data['toggle'] ) ) . '"';
413
+ }
414
+
415
+ $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
416
+ $field_content .= '<input type="checkbox" id="'.$field_data['name'].'" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . ' ' . $toggle_data . '>';
417
+
418
+ if ( isset( $field_data['after'] ) ) {
419
+ $field_content .= '<span>' . $field_data['after'] . '</span>';
420
+ }
421
+
422
+ return $this->get_field( $field_data, $field_content );
423
+ }
424
+
425
+ function get_radio_field( $field_data ) {
426
+
427
+ $value = $field_data['value'];
428
+ $field_content = '';
429
+
430
+ if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
431
+
432
+ foreach ( $field_data['options'] as $data_key => $data_value ) {
433
+
434
+ $field_content .= '<div class="wcf-radio-option">';
435
+ $field_content .= '<input type="radio" name="' . $field_data['name'] . '" value="' . $data_key . '" ' . checked( $data_key, $value, false ) . '>';
436
+ $field_content .= $data_value;
437
+ $field_content .= '</div>';
438
+ }
439
+ }
440
+
441
+ return $this->get_field( $field_data, $field_content );
442
+ }
443
+
444
+ function get_font_family_field( $field_data ) {
445
+
446
+ $value = $field_data['value'];
447
+
448
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
449
+
450
+ $field_content = '<select class="wcf-field-font-family" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
451
+
452
+ $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
453
+
454
+ $field_content .= '<optgroup label="Other System Fonts">';
455
+ foreach ( CartFlows_Font_Families::get_system_fonts() as $name => $variants ) {
456
+ $field_content .= '<option value="' . esc_attr( $name ) . '" ' . selected( $name, $value, false ) . '>' . esc_attr( $name ) . '</option>';
457
+ }
458
+ $field_content .= '</optgroup>';
459
+ $field_content .= '<optgroup label="Google">';
460
+ foreach ( CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) {
461
+ $variants = wcf_get_prop( $single_font, '0' );
462
+ $category = wcf_get_prop( $single_font, '1' );
463
+ $font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category );
464
+ $field_content .= '<option value="' . esc_attr( $font_value ) . '" ' . selected( $font_value, $value, false ) . '>' . esc_attr( $name ) . '</option>';
465
+ }
466
+ $field_content .= '</optgroup>';
467
+
468
+ $field_content .= '</select>';
469
+
470
+ return $this->get_field( $field_data, $field_content );
471
+ }
472
+
473
+ function get_font_weight_field( $field_data ) {
474
+
475
+ $value = $field_data['value'];
476
+
477
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
478
+
479
+ $field_content = '<select data-selected="'.esc_attr( $value ).'" class="wcf-field-font-weight" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
480
+
481
+ $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
482
+
483
+ $field_content .= '</select>';
484
+
485
+ return $this->get_field( $field_data, $field_content );
486
+ }
487
+
488
+ function get_select_field( $field_data ) {
489
+
490
+ $value = $field_data['value'];
491
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
492
+
493
+ $field_content = '<select name="' . $field_data['name'] . '">';
494
+
495
+
496
+ if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
497
+
498
+ foreach ( $field_data['options'] as $data_key => $data_value ) {
499
+
500
+ $disabled = '';
501
+
502
+ if ( array_key_exists( $data_key, $pro_options ) ) {
503
+ $disabled = 'disabled ';
504
+ $data_value = $pro_options[ $data_key ];
505
+ }
506
+
507
+ $field_content .= '<option value="' . $data_key . '" ' . selected( $value, $data_key, false ) . ' ' . $disabled .'>' . $data_value . '</option>';
508
+ }
509
+ }
510
+
511
+ $field_content .= '</select>';
512
+
513
+ if ( isset( $field_data['after'] ) ) {
514
+ $field_content .= '<span>' . $field_data['after'] . '</span>';
515
+ }
516
+
517
+ return $this->get_field( $field_data, $field_content );
518
+ }
519
+
520
+ function get_color_picker_field( $field_data ) {
521
+
522
+ $value = $field_data['value'];
523
+
524
+ $field_content = '<input class="wcf-color-picker" type="text" name="' . $field_data['name'] . '" value="' . $value . '">';
525
+
526
+ return $this->get_field( $field_data, $field_content );
527
+ }
528
+
529
+ function get_product_selection_field( $field_data ) {
530
+
531
+ $value = $field_data['value'];
532
+
533
+ $multiple = '';
534
+
535
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
536
+ $multiple = ' multiple="multiple"';
537
+ }
538
+
539
+ $allow_clear = '';
540
+
541
+ if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
542
+ $allow_clear = ' data-allow_clear="allow_clear"';
543
+ }
544
+
545
+ $field_content = '<select
546
+ name="' . $field_data['name'] . '[]"
547
+ class="wcf-product-search" ' . $multiple . $allow_clear . '
548
+ data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
549
+ data-action="woocommerce_json_search_products_and_variations">';
550
+
551
+ if ( is_array( $value ) && ! empty( $value ) ) {
552
+
553
+ foreach ( $value as $data_key => $product_id ) {
554
+
555
+ $product = wc_get_product( $product_id );
556
+
557
+ // posts.
558
+ if ( ! empty( $product ) ) {
559
+ $post_title = $product->get_name() . ' (#' . $product_id . ')';
560
+
561
+ $field_content .= '<option value="' . $product_id . '" selected="selected" >' . $post_title . '</option>';
562
+ }
563
+ }
564
+ }
565
+ $field_content .= '</select>';
566
+
567
+ return $this->get_field( $field_data, $field_content );
568
+ }
569
+
570
+ function get_coupon_selection_field( $field_data ) {
571
+
572
+ $value = $field_data['value'];
573
+
574
+ $multiple = '';
575
+
576
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
577
+ $multiple = ' multiple="multiple"';
578
+ }
579
+
580
+ $allow_clear = '';
581
+
582
+ if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
583
+ $allow_clear = ' data-allow_clear="allow_clear"';
584
+ }
585
+
586
+ $field_content = '<select
587
+ name="' . $field_data['name'] . '[]"
588
+ class="wc-coupon-search wcf-coupon-search" ' . $multiple . $allow_clear . '
589
+ data-placeholder="' . __( 'Search for a coupon&hellip;', 'cartflows' ) . '"
590
+ data-action="wcf_json_search_coupons">';
591
+
592
+ if ( is_array( $value ) && ! empty( $value ) ) {
593
+
594
+ $all_discount_types = wc_get_coupon_types();
595
+
596
+ foreach ( $value as $coupon_title ) {
597
+
598
+ $coupon = new WC_Coupon( $coupon_title );
599
+
600
+ $discount_type = $coupon->get_discount_type();
601
+
602
+ if ( isset( $discount_type ) && $discount_type ) {
603
+ $discount_type = ' ( Type: ' . $all_discount_types[ $discount_type ] . ' )';
604
+ }
605
+
606
+ $field_content .= '<option value="' . $coupon_title . '" selected="selected">' . $coupon_title . $discount_type . '</option>';
607
+ }
608
+ }
609
+
610
+ $field_content .= '</select>';
611
+
612
+ return $this->get_field( $field_data, $field_content );
613
+ }
614
+
615
+ function get_page_selection_field( $field_data ) {
616
+
617
+ $value = $field_data['value'];
618
+
619
+ $multiple = '';
620
+
621
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
622
+ $multiple = 'multiple="multiple"';
623
+ }
624
+
625
+ $field_content = '<select
626
+ name="' . $field_data['name'] . '[]"
627
+ class="wcf-search-pages" ' . $multiple . '"
628
+ data-action="wcf_json_search_pages">';
629
+
630
+ if ( is_array( $value ) && ! empty( $value ) ) {
631
+
632
+ foreach ( $value as $data_key => $data_value ) {
633
+
634
+ $field_content .= '<option value="' . $data_value . '">' . get_the_title( $data_value ) . '</option>';
635
+ }
636
+ }
637
+
638
+ $field_content .= '</select>';
639
+
640
+ return $this->get_field( $field_data, $field_content );
641
+ }
642
+
643
+ function get_section( $field_data ) {
644
+ $field_html = '<div class="wcf-field-row wcf-field-section">';
645
+ $field_html .= '<div class="wcf-field-section-heading" colspan="2">';
646
+ $field_html .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
647
+
648
+ if ( isset( $field_data['help'] ) ) {
649
+ $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help" title="' . esc_attr( $field_data['help'] ) . '"></i>';
650
+ }
651
+ $field_html .= '</div>';
652
+ $field_html .= '</div>';
653
+ return $field_html;
654
+ }
655
+
656
+ function get_description_field( $field_data ) {
657
+
658
+ $field_html = '<div class="wcf-field-row wcf-field-desc ' . $field_data['name'] . '">';
659
+ $field_html .= '<div class="wcf-field-desc-content">';
660
+ $field_html .= $field_data['content'];
661
+ $field_html .= '</div>';
662
+ $field_html .= '</div>';
663
+
664
+ return $field_html;
665
+ }
666
+
667
+ function get_product_selection_repeater( $field_data ) {
668
+
669
+ $value = $field_data['value'];
670
+
671
+ if ( ! is_array( $value ) ) {
672
+
673
+ $value[0] = array(
674
+ 'product' => '',
675
+ );
676
+ } else {
677
+
678
+ if ( ! isset( $value[0] ) ) {
679
+
680
+ $value[0] = array(
681
+ 'product' => '',
682
+ );
683
+ }
684
+ }
685
+
686
+ $name_class = 'field-' . $field_data['name'];
687
+
688
+ $field_html = '';
689
+
690
+ $field_html .= '<script type="text/html" id="tmpl-wcf-product-repeater">';
691
+ $field_html .= $this->generate_product_repeater_html( '{{id}}' );
692
+ $field_html .= '</script>';
693
+
694
+ $field_html .= '<div class="wcf-field-row wcf-product-repeater-field-row ' . $name_class . '">';
695
+ $field_html .= '<div class="wcf-field-row-content">';
696
+ $field_html .= '<div class="wcf-repeatables-wrap">';
697
+
698
+ if ( is_array( $value ) ) {
699
+
700
+ foreach ( $value as $p_key => $p_data ) {
701
+
702
+ $selected_options = '';
703
+
704
+ if ( isset( $p_data['product'] ) ) {
705
+
706
+ $product = wc_get_product( $p_data['product'] );
707
+
708
+ // posts.
709
+ if ( ! empty( $product ) ) {
710
+ $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
711
+
712
+ $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
713
+ }
714
+ }
715
+
716
+ $field_html .= $this->generate_product_repeater_html( $p_key, $selected_options );
717
+ }
718
+ }
719
+
720
+ $field_html .= '<div class="wcf-add-repeatable-row">';
721
+ $field_html .= '<div class="submit wcf-add-repeatable-wrap">';
722
+ $field_html .= '<button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products">' . __( 'Add New Product', 'cartflows' ) . '</button>';
723
+ $field_html .= '<a href="#!" class="button button-primary wcf-create-woo-product" data-name="wcf-create-woo-product">'. __( 'Create Product', 'cartflows' ) . '</a>';
724
+ $field_html .= '</div>';
725
+ $field_html .= '</div>';
726
+
727
+ $field_html .= '</div>';
728
+ $field_html .= '</div>';
729
+ $field_html .= '</div>';
730
+
731
+ return $field_html;
732
+ }
733
+
734
+ function generate_product_repeater_html( $id, $options = '' ) {
735
+
736
+ $field_html = '<div class="wcf-repeatable-row" data-key="' . $id . '">';
737
+
738
+ $field_html .= '<div class="wcf-repeatable-row-standard-fields">';
739
+
740
+ /* Product Name */
741
+ $field_html .= '<div class="wcf-repeatable-fields wcf-sel-product">';
742
+ $field_html .= '<span class="wcf-repeatable-row-setting-field">';
743
+ $field_html .= '<select
744
+ name="wcf-checkout-products[' . $id . '][product]"
745
+ class="wcf-product-search"
746
+ data-allow_clear="allow_clear"
747
+ data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
748
+ data-action="woocommerce_json_search_products_and_variations">';
749
+ $field_html .= $options;
750
+ $field_html .= '</select>';
751
+ $field_html .= '</span>';
752
+ $field_html .= '<span class="wcf-repeatable-row-actions">';
753
+ $field_html .= '<a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">';
754
+ $field_html .= '<span class="dashicons dashicons-trash"></span>';
755
+ $field_html .= '<span class="wcf-repeatable-remove-button">'. __( 'Remove', 'cartflows' ).'</span>';
756
+ $field_html .= '</a>';
757
+ $field_html .= '</span>';
758
+ $field_html .= '</div>';
759
+ $field_html .= '</div>';
760
+ $field_html .= '</div>';
761
+
762
+ return $field_html;
763
+ }
764
+
765
+ function get_image_field( $field_data ) {
766
+
767
+ global $post;
768
+ $value = $field_data['value'];
769
+
770
+ $attr = '';
771
+
772
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
773
+
774
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
775
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
776
+ }
777
+ }
778
+
779
+ $display_preview_box = ( isset( $value ) && '' != $value ) ? 'display:block;' : 'display:none';
780
+
781
+ $field_content = '<div id="wcf-image-preview" style="'.$display_preview_box.'">';
782
+
783
+ if( isset( $value ) ){
784
+
785
+ $field_content .= '<img src="'. $field_data['value'] .'" class="saved-image" name="'. $field_data['name'] .'" width="150">';
786
+ }
787
+
788
+ $field_content .= '</div>';
789
+
790
+ $image_data = htmlentities( serialize( get_post_meta( $post->ID, $field_data['name'].'-obj') ) );
791
+
792
+ $field_content .= '<input type="hidden" id="'. $field_data['name'] .'" class="wcf-image" name="' . $field_data['name'] . '" value="'.$value.'">';
793
+
794
+ $field_content .= '<input type="hidden" id="'. $field_data['name'].'-obj'.'" class="wcf-image-obj" name="' . $field_data['name'].'-obj'. '" value="'.$image_data.'">';
795
+
796
+
797
+ $field_content .= '<button type="button" ' . $attr . ' class="wcf-select-image button-secondary">Select Image</button>';
798
+
799
+ $display_remove_button = ( isset( $value ) && '' != $value ) ? 'display:inline-block; margin-left: 5px;' : 'display:none';
800
+
801
+ $field_content .= '<button type="button" class="wcf-remove-image button-secondary" style="'.$display_remove_button.'">Remove Image</button>';
802
+
803
+ return $this->get_field( $field_data, $field_content );
804
+ }
805
+
806
+ /**
807
+ * Localize variables in admin
808
+ *
809
+ * @param array $vars variables.
810
+ */
811
+ function localize_vars( $vars ) {
812
+
813
+ $ajax_actions = array(
814
+ 'wcf_json_search_pages',
815
+ 'wcf_json_search_coupons'
816
+ );
817
+
818
+ foreach ( $ajax_actions as $action ) {
819
+
820
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
821
+ }
822
+
823
+ /* Add product from iframe */
824
+ $product_src = esc_url_raw( add_query_arg( array(
825
+ 'post_type' => 'product',
826
+ 'wcf-woo-iframe' => 'true',
827
+ ), admin_url( 'post-new.php' ) ) );
828
+
829
+ $vars['create_product_src'] = $product_src;
830
+ /* Add product from iframe End */
831
+
832
+ return $vars;
833
+ }
834
+ }
835
+ // @codingStandardsIgnoreEnd
classes/class-cartflows-wizard.php CHANGED
@@ -1,688 +1,688 @@
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
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
64
- return;
65
- }
66
-
67
- delete_transient( '_wc_activation_redirect' );
68
- }
69
-
70
- /**
71
- * Show action links on the plugin screen.
72
- *
73
- * @since 1.0.0
74
- * @return void
75
- */
76
- public function show_setup_wizard() {
77
-
78
- $status = get_option( 'wcf_setup_complete', false );
79
- $skip_setup = get_option( 'wcf_setup_skipped', false );
80
-
81
- if ( false === $status && ! $skip_setup ) { ?>
82
- <div class="notice notice-info">
83
- <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
84
- <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
85
- <p>
86
- <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>
87
- <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>
88
- </p>
89
- </div>
90
- <?php
91
- }
92
- }
93
-
94
- /**
95
- * Add admin menus/screens.
96
- */
97
- public function admin_menus() {
98
-
99
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
100
- return;
101
- }
102
-
103
- add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
104
- }
105
-
106
- /**
107
- * Show the setup wizard.
108
- */
109
- public function setup_wizard() {
110
-
111
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
112
- return;
113
- }
114
-
115
- $this->steps = array(
116
- 'basic-config' => array(
117
- 'name' => __( 'Welcome', 'cartflows' ),
118
- 'view' => array( $this, 'welcome_step' ),
119
- 'handler' => array( $this, 'welcome_step_save' ),
120
- ),
121
- 'page-builder' => array(
122
- 'name' => __( 'Page Builder', 'cartflows' ),
123
- 'view' => array( $this, 'page_builder_step' ),
124
- ),
125
- 'checkout' => array(
126
- 'name' => __( 'Checkout', 'cartflows' ),
127
- 'view' => array( $this, 'checkout_step' ),
128
- ),
129
- 'training' => array(
130
- 'name' => __( 'Training', 'cartflows' ),
131
- 'view' => array( $this, 'training_step' ),
132
- ),
133
- 'setup-ready' => array(
134
- 'name' => __( 'Ready!', 'cartflows' ),
135
- 'view' => array( $this, 'ready_step' ),
136
- 'handler' => '',
137
- ),
138
- );
139
-
140
- $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
141
-
142
- wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
143
- wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
144
-
145
- wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
146
-
147
- wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
148
-
149
- wp_enqueue_media();
150
-
151
- if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
152
- call_user_func( $this->steps[ $this->step ]['handler'] );
153
- }
154
-
155
- ob_start();
156
- $this->setup_wizard_header();
157
- $this->setup_wizard_steps();
158
- $this->setup_wizard_content();
159
- $this->setup_wizard_footer();
160
- exit;
161
- }
162
-
163
- /**
164
- * Get current step slug
165
- */
166
- public function get_current_step_slug() {
167
- $keys = array_keys( $this->steps );
168
- return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
169
- }
170
-
171
- /**
172
- * Get previous step link
173
- */
174
- public function get_prev_step_link() {
175
- $keys = array_keys( $this->steps );
176
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
177
- }
178
-
179
- /**
180
- * Get next step link
181
- */
182
- public function get_next_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_plain_link() {
191
- $keys = array_keys( $this->steps );
192
- $step_index = array_search( $this->step, $keys, true );
193
- $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
194
- $step = $keys[ $step_index ];
195
- return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
196
- }
197
-
198
- /**
199
- * Setup Wizard Header.
200
- */
201
- public function setup_wizard_header() {
202
- set_current_screen();
203
- ?>
204
- <html <?php language_attributes(); ?>>
205
- <html>
206
- <head>
207
- <meta name="viewport" content="width=device-width" />
208
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
209
- <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
210
-
211
- <script type="text/javascript">
212
- 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();}}};
213
- var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
214
- var pagenow = '';
215
- </script>
216
- <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
217
- <?php do_action( 'admin_print_styles' ); ?>
218
- <?php do_action( 'admin_head' ); ?>
219
- </head>
220
- <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
221
- <div id="cartflows-logo">
222
- <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
223
- </div>
224
- <?php
225
- }
226
-
227
- /**
228
- * Setup Wizard Footer.
229
- */
230
- public function setup_wizard_footer() {
231
-
232
- $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
233
- ?>
234
- <div class="close-button-wrapper">
235
- <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
236
- </div>
237
- </body>
238
- </html>
239
- <?php
240
- }
241
-
242
- /**
243
- * Output the steps.
244
- */
245
- public function setup_wizard_steps() {
246
-
247
- $ouput_steps = $this->steps;
248
- ?>
249
- <ol class="cartflows-setup-steps">
250
- <?php
251
- foreach ( $ouput_steps as $step_key => $step ) :
252
- $classes = '';
253
- $activated = false;
254
- if ( $step_key === $this->step ) {
255
- $classes = 'active';
256
- $activated = true;
257
- } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
258
- $classes = 'done';
259
- $activated = true;
260
- }
261
- ?>
262
- <li class="<?php echo esc_attr( $classes ); ?>">
263
- <span><?php echo esc_html( $step['name'] ); ?></span>
264
- </li>
265
- <?php endforeach; ?>
266
- </ol>
267
- <?php
268
- }
269
-
270
- /**
271
- * Output the content for the current step.
272
- */
273
- public function setup_wizard_content() {
274
- ?>
275
- <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
276
- <?php
277
-
278
- echo '<div class="cartflows-setup-content">';
279
- call_user_func( $this->steps[ $this->step ]['view'] );
280
- echo '</div>';
281
- }
282
-
283
- /**
284
- * Introduction step.
285
- */
286
- public function welcome_step() {
287
- ?>
288
- <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
289
- <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>
290
- <form method="post">
291
- <div class="cartflows-setup-actions step">
292
- <div class="button-prev-wrap">
293
- </div>
294
- <div class="button-next-wrap">
295
- <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
296
- </div>
297
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
298
- </div>
299
- </form>
300
- <?php
301
- }
302
-
303
- /**
304
- * Save Locale Settings.
305
- */
306
- public function welcome_step_save() {
307
- check_admin_referer( 'cartflow-setup' );
308
-
309
- // Update site title & tagline.
310
- $redirect_url = $this->get_next_step_link();
311
-
312
- wp_safe_redirect( esc_url_raw( $redirect_url ) );
313
- exit;
314
- }
315
-
316
- /**
317
- * Locale settings
318
- */
319
- public function page_builder_step() {
320
- ?>
321
-
322
- <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
323
- <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
324
- <form method="post">
325
- <table class="cartflows-table widefat">
326
- <tr class="cartflows-row">
327
- <td class="cartflows-row-heading">
328
- <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
329
- </td>
330
- <td class="cartflows-row-content">
331
- <?php
332
- $installed_plugins = get_plugins();
333
- $plugins = array(
334
- array(
335
- 'title' => __( 'Elementor', 'cartflows' ),
336
- 'value' => 'elementor',
337
- 'data' => array(
338
- 'slug' => 'elementor',
339
- 'init' => 'elementor/elementor.php',
340
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
341
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
342
- ),
343
- ),
344
- array(
345
- 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
346
- 'value' => 'beaver-builder',
347
- 'data' => array(
348
- 'slug' => 'beaver-builder-lite-version',
349
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
350
- 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
351
- 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
352
- ),
353
- ),
354
- array(
355
- 'title' => __( 'Divi', 'cartflows' ),
356
- 'value' => 'divi',
357
- 'data' => array(
358
- 'slug' => 'divi',
359
- 'init' => 'divi',
360
- 'active' => 'yes',
361
- 'install' => 'NA',
362
- ),
363
- ),
364
- array(
365
- 'title' => __( 'Other', 'cartflows' ),
366
- 'value' => 'other',
367
- 'data' => array(
368
- 'slug' => 'other',
369
- 'init' => false,
370
- 'active' => 'yes',
371
- 'install' => 'NA',
372
- ),
373
- ),
374
- );
375
- ?>
376
- <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
377
- <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
378
- <?php
379
- foreach ( $plugins as $key => $plugin ) {
380
- 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>';
381
- }
382
- ?>
383
- </select>
384
- </td>
385
- </tr>
386
- </table>
387
- <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
388
- <div class="cartflows-setup-actions step">
389
- <div class="button-prev-wrap">
390
- <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>
391
- </div>
392
- <div class="button-next-wrap">
393
- <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>
394
- <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
395
- </div>
396
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
397
- </div>
398
- </form>
399
- <?php
400
- }
401
-
402
- /**
403
- * Render checkout step.
404
- */
405
- public function checkout_step() {
406
-
407
- $installed_plugins = get_plugins();
408
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
409
- $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
410
- $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
411
- $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
412
- ?>
413
- <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
414
- <div class="cartflows-setup-message">
415
- <p>
416
- <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
417
- </p>
418
- <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>
419
- <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>
420
- </div>
421
-
422
- <div class="cartflows-setup-extra-notice">
423
-
424
- <span>
425
- <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
426
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
427
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
428
-
429
- </span>
430
-
431
- </div>
432
-
433
- <div class="cartflows-setup-actions step">
434
- <div class="button-prev-wrap">
435
- <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>
436
- </div>
437
- <div class="button-next-wrap">
438
- <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>
439
- <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
440
- </div>
441
- </div>
442
-
443
- <?php
444
- }
445
-
446
- /**
447
- * Save Locale Settings.
448
- */
449
- public function activate_wc_plugins() {
450
-
451
- check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
452
-
453
- $plugin_slug_arr = array(
454
- 'woocommerce/woocommerce.php' => true,
455
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
456
- );
457
-
458
- $activate = array(
459
- 'woocommerce/woocommerce.php' => false,
460
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
461
- );
462
-
463
- foreach ( $plugin_slug_arr as $slug => $do_silently ) {
464
-
465
- $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
466
- }
467
-
468
- foreach ( $activate as $slug => $data ) {
469
-
470
- if ( is_wp_error( $data ) ) {
471
- wp_send_json_error(
472
- array(
473
- 'success' => false,
474
- 'message' => $data->get_error_message(),
475
- )
476
- );
477
- }
478
- }
479
-
480
- wp_send_json_success();
481
- }
482
-
483
- /**
484
- * Save Locale Settings.
485
- */
486
- public function page_builder_step_save() {
487
-
488
- if ( ! current_user_can( 'manage_options' ) ) {
489
- return;
490
- }
491
-
492
- check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
493
-
494
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
495
- $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
496
- $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
497
-
498
- $do_sliently = true;
499
- if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
500
- $do_sliently = false;
501
- }
502
-
503
- $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
504
-
505
- if ( $save_option ) {
506
- $this->save_page_builder_option();
507
- }
508
-
509
- if ( is_wp_error( $activate ) ) {
510
- wp_send_json_error(
511
- array(
512
- 'success' => false,
513
- 'message' => $activate->get_error_message(),
514
- )
515
- );
516
- }
517
-
518
- wp_send_json_success(
519
- array( 'plugin' => $plugin_slug )
520
- );
521
- }
522
-
523
- /**
524
- * Save selected page builder in options database.
525
- */
526
- public function save_page_builder_option() {
527
-
528
- if ( ! current_user_can( 'manage_options' ) ) {
529
- return;
530
- }
531
-
532
- $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
533
-
534
- $wcf_settings = get_option( '_cartflows_common', array() );
535
-
536
- if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
537
- $page_builder = 'beaver-builder';
538
- }
539
-
540
- $wcf_settings['default_page_builder'] = $page_builder;
541
-
542
- update_option( '_cartflows_common', $wcf_settings );
543
-
544
- wp_send_json_success(
545
- array( 'plugin' => $page_builder )
546
- );
547
-
548
- }
549
-
550
- /**
551
- * Final step.
552
- */
553
- public function ready_step() {
554
-
555
- // Set setup wizard status to complete.
556
- update_option( 'wcf_setup_complete', true );
557
- ?>
558
- <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
559
-
560
- <div class="cartflows-setup-next-steps">
561
- <div class="cartflows-setup-next-steps-last">
562
-
563
- <p class="success">
564
- <?php
565
- 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' )
566
- ?>
567
- </p>
568
-
569
-
570
- <ul class="wcf-wizard-next-steps">
571
- <li class="wcf-wizard-next-step-item">
572
- <div class="wcf-wizard-next-step-description">
573
- <p class="next-step-heading">Next step</p>
574
- <h3 class="next-step-description">Create First Flow</h3>
575
- <p class="next-step-extra-info">You're ready to add flows to your website.</p>
576
- </div>
577
- <div class="wcf-wizard-next-step-action">
578
- <p class="wc-setup-actions step">
579
- <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>
580
- </p>
581
- </div>
582
- </li>
583
- </ul>
584
-
585
- </div>
586
- </div>
587
- <?php
588
- }
589
-
590
- /**
591
- * Training course step.
592
- */
593
- public function training_step() {
594
- $current_user = wp_get_current_user();
595
- ?>
596
- <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
597
-
598
- <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
599
- <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">
600
- <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
601
- <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
602
- <div class="mauticform-innerform">
603
- <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
604
- <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
605
- <div class="cartflows-setup-message">
606
- <p>
607
- <?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' ); ?>
608
- <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
609
- </p>
610
- <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">
611
- </div>
612
- <span class="mauticform-errormsg" style="display: none;"></span>
613
- </div>
614
- </div>
615
- </div>
616
-
617
- <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
618
- <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
619
- <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
620
- <div class="cartflows-setup-actions step">
621
- <div class="button-prev-wrap">
622
- <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>
623
- </div>
624
- <div class="button-next-wrap">
625
- <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>
626
- <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>
627
- </div>
628
- </div>
629
- </form>
630
- </div>
631
- <?php
632
- }
633
-
634
- /**
635
- * Localize variables in admin
636
- */
637
- public function localize_vars() {
638
-
639
- $vars = array();
640
-
641
- $ajax_actions = array(
642
- 'wcf_page_builder_step_save',
643
- 'wcf_wc_plugins_activate',
644
- );
645
-
646
- foreach ( $ajax_actions as $action ) {
647
-
648
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
649
- }
650
-
651
- return $vars;
652
- }
653
-
654
- /**
655
- * Add JS script for mautic form
656
- */
657
- public function add_mautic_form_script() {
658
-
659
- if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
660
- return;
661
- }
662
- ?>
663
-
664
- <script type="text/javascript">
665
- /** This section is only needed once per page if manually copying **/
666
- if (typeof MauticSDKLoaded == 'undefined') {
667
- var MauticSDKLoaded = true;
668
- var head = document.getElementsByTagName('head')[0];
669
- var script = document.createElement('script');
670
- script.type = 'text/javascript';
671
- script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
672
- script.onload = function() {
673
- MauticSDK.onLoad();
674
- };
675
- head.appendChild(script);
676
- var MauticDomain = 'https://go.cartflows.com';
677
- var MauticLang = {
678
- 'submittingMessage': "Please wait..."
679
- };
680
- }
681
- </script>
682
- <?php
683
- }
684
- }
685
-
686
- new CartFlows_Wizard();
687
-
688
- 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
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
64
+ return;
65
+ }
66
+
67
+ delete_transient( '_wc_activation_redirect' );
68
+ }
69
+
70
+ /**
71
+ * Show action links on the plugin screen.
72
+ *
73
+ * @since 1.0.0
74
+ * @return void
75
+ */
76
+ public function show_setup_wizard() {
77
+
78
+ $status = get_option( 'wcf_setup_complete', false );
79
+ $skip_setup = get_option( 'wcf_setup_skipped', false );
80
+
81
+ if ( false === $status && ! $skip_setup ) { ?>
82
+ <div class="notice notice-info">
83
+ <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
84
+ <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
85
+ <p>
86
+ <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>
87
+ <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>
88
+ </p>
89
+ </div>
90
+ <?php
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Add admin menus/screens.
96
+ */
97
+ public function admin_menus() {
98
+
99
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
100
+ return;
101
+ }
102
+
103
+ add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
104
+ }
105
+
106
+ /**
107
+ * Show the setup wizard.
108
+ */
109
+ public function setup_wizard() {
110
+
111
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
112
+ return;
113
+ }
114
+
115
+ $this->steps = array(
116
+ 'basic-config' => array(
117
+ 'name' => __( 'Welcome', 'cartflows' ),
118
+ 'view' => array( $this, 'welcome_step' ),
119
+ 'handler' => array( $this, 'welcome_step_save' ),
120
+ ),
121
+ 'page-builder' => array(
122
+ 'name' => __( 'Page Builder', 'cartflows' ),
123
+ 'view' => array( $this, 'page_builder_step' ),
124
+ ),
125
+ 'checkout' => array(
126
+ 'name' => __( 'Checkout', 'cartflows' ),
127
+ 'view' => array( $this, 'checkout_step' ),
128
+ ),
129
+ 'training' => array(
130
+ 'name' => __( 'Training', 'cartflows' ),
131
+ 'view' => array( $this, 'training_step' ),
132
+ ),
133
+ 'setup-ready' => array(
134
+ 'name' => __( 'Ready!', 'cartflows' ),
135
+ 'view' => array( $this, 'ready_step' ),
136
+ 'handler' => '',
137
+ ),
138
+ );
139
+
140
+ $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
141
+
142
+ wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
143
+ wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
144
+
145
+ wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
146
+
147
+ wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
148
+
149
+ wp_enqueue_media();
150
+
151
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
152
+ call_user_func( $this->steps[ $this->step ]['handler'] );
153
+ }
154
+
155
+ ob_start();
156
+ $this->setup_wizard_header();
157
+ $this->setup_wizard_steps();
158
+ $this->setup_wizard_content();
159
+ $this->setup_wizard_footer();
160
+ exit;
161
+ }
162
+
163
+ /**
164
+ * Get current step slug
165
+ */
166
+ public function get_current_step_slug() {
167
+ $keys = array_keys( $this->steps );
168
+ return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
169
+ }
170
+
171
+ /**
172
+ * Get previous step link
173
+ */
174
+ public function get_prev_step_link() {
175
+ $keys = array_keys( $this->steps );
176
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
177
+ }
178
+
179
+ /**
180
+ * Get next step link
181
+ */
182
+ public function get_next_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_plain_link() {
191
+ $keys = array_keys( $this->steps );
192
+ $step_index = array_search( $this->step, $keys, true );
193
+ $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
194
+ $step = $keys[ $step_index ];
195
+ return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
196
+ }
197
+
198
+ /**
199
+ * Setup Wizard Header.
200
+ */
201
+ public function setup_wizard_header() {
202
+ set_current_screen();
203
+ ?>
204
+ <html <?php language_attributes(); ?>>
205
+ <html>
206
+ <head>
207
+ <meta name="viewport" content="width=device-width" />
208
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
209
+ <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
210
+
211
+ <script type="text/javascript">
212
+ 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();}}};
213
+ var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
214
+ var pagenow = '';
215
+ </script>
216
+ <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
217
+ <?php do_action( 'admin_print_styles' ); ?>
218
+ <?php do_action( 'admin_head' ); ?>
219
+ </head>
220
+ <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
221
+ <div id="cartflows-logo">
222
+ <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
223
+ </div>
224
+ <?php
225
+ }
226
+
227
+ /**
228
+ * Setup Wizard Footer.
229
+ */
230
+ public function setup_wizard_footer() {
231
+
232
+ $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
233
+ ?>
234
+ <div class="close-button-wrapper">
235
+ <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
236
+ </div>
237
+ </body>
238
+ </html>
239
+ <?php
240
+ }
241
+
242
+ /**
243
+ * Output the steps.
244
+ */
245
+ public function setup_wizard_steps() {
246
+
247
+ $ouput_steps = $this->steps;
248
+ ?>
249
+ <ol class="cartflows-setup-steps">
250
+ <?php
251
+ foreach ( $ouput_steps as $step_key => $step ) :
252
+ $classes = '';
253
+ $activated = false;
254
+ if ( $step_key === $this->step ) {
255
+ $classes = 'active';
256
+ $activated = true;
257
+ } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
258
+ $classes = 'done';
259
+ $activated = true;
260
+ }
261
+ ?>
262
+ <li class="<?php echo esc_attr( $classes ); ?>">
263
+ <span><?php echo esc_html( $step['name'] ); ?></span>
264
+ </li>
265
+ <?php endforeach; ?>
266
+ </ol>
267
+ <?php
268
+ }
269
+
270
+ /**
271
+ * Output the content for the current step.
272
+ */
273
+ public function setup_wizard_content() {
274
+ ?>
275
+ <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
276
+ <?php
277
+
278
+ echo '<div class="cartflows-setup-content">';
279
+ call_user_func( $this->steps[ $this->step ]['view'] );
280
+ echo '</div>';
281
+ }
282
+
283
+ /**
284
+ * Introduction step.
285
+ */
286
+ public function welcome_step() {
287
+ ?>
288
+ <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
289
+ <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>
290
+ <form method="post">
291
+ <div class="cartflows-setup-actions step">
292
+ <div class="button-prev-wrap">
293
+ </div>
294
+ <div class="button-next-wrap">
295
+ <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
296
+ </div>
297
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
298
+ </div>
299
+ </form>
300
+ <?php
301
+ }
302
+
303
+ /**
304
+ * Save Locale Settings.
305
+ */
306
+ public function welcome_step_save() {
307
+ check_admin_referer( 'cartflow-setup' );
308
+
309
+ // Update site title & tagline.
310
+ $redirect_url = $this->get_next_step_link();
311
+
312
+ wp_safe_redirect( esc_url_raw( $redirect_url ) );
313
+ exit;
314
+ }
315
+
316
+ /**
317
+ * Locale settings
318
+ */
319
+ public function page_builder_step() {
320
+ ?>
321
+
322
+ <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
323
+ <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
324
+ <form method="post">
325
+ <table class="cartflows-table widefat">
326
+ <tr class="cartflows-row">
327
+ <td class="cartflows-row-heading">
328
+ <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
329
+ </td>
330
+ <td class="cartflows-row-content">
331
+ <?php
332
+ $installed_plugins = get_plugins();
333
+ $plugins = array(
334
+ array(
335
+ 'title' => __( 'Elementor', 'cartflows' ),
336
+ 'value' => 'elementor',
337
+ 'data' => array(
338
+ 'slug' => 'elementor',
339
+ 'init' => 'elementor/elementor.php',
340
+ 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
341
+ 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
342
+ ),
343
+ ),
344
+ array(
345
+ 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
346
+ 'value' => 'beaver-builder',
347
+ 'data' => array(
348
+ 'slug' => 'beaver-builder-lite-version',
349
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
350
+ 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
351
+ 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
352
+ ),
353
+ ),
354
+ array(
355
+ 'title' => __( 'Divi', 'cartflows' ),
356
+ 'value' => 'divi',
357
+ 'data' => array(
358
+ 'slug' => 'divi',
359
+ 'init' => 'divi',
360
+ 'active' => 'yes',
361
+ 'install' => 'NA',
362
+ ),
363
+ ),
364
+ array(
365
+ 'title' => __( 'Other', 'cartflows' ),
366
+ 'value' => 'other',
367
+ 'data' => array(
368
+ 'slug' => 'other',
369
+ 'init' => false,
370
+ 'active' => 'yes',
371
+ 'install' => 'NA',
372
+ ),
373
+ ),
374
+ );
375
+ ?>
376
+ <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
377
+ <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
378
+ <?php
379
+ foreach ( $plugins as $key => $plugin ) {
380
+ 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>';
381
+ }
382
+ ?>
383
+ </select>
384
+ </td>
385
+ </tr>
386
+ </table>
387
+ <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
388
+ <div class="cartflows-setup-actions step">
389
+ <div class="button-prev-wrap">
390
+ <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>
391
+ </div>
392
+ <div class="button-next-wrap">
393
+ <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>
394
+ <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
395
+ </div>
396
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
397
+ </div>
398
+ </form>
399
+ <?php
400
+ }
401
+
402
+ /**
403
+ * Render checkout step.
404
+ */
405
+ public function checkout_step() {
406
+
407
+ $installed_plugins = get_plugins();
408
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
409
+ $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
410
+ $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
411
+ $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
412
+ ?>
413
+ <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
414
+ <div class="cartflows-setup-message">
415
+ <p>
416
+ <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
417
+ </p>
418
+ <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>
419
+ <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>
420
+ </div>
421
+
422
+ <div class="cartflows-setup-extra-notice">
423
+
424
+ <span>
425
+ <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
426
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
427
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
428
+
429
+ </span>
430
+
431
+ </div>
432
+
433
+ <div class="cartflows-setup-actions step">
434
+ <div class="button-prev-wrap">
435
+ <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>
436
+ </div>
437
+ <div class="button-next-wrap">
438
+ <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>
439
+ <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
440
+ </div>
441
+ </div>
442
+
443
+ <?php
444
+ }
445
+
446
+ /**
447
+ * Save Locale Settings.
448
+ */
449
+ public function activate_wc_plugins() {
450
+
451
+ check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
452
+
453
+ $plugin_slug_arr = array(
454
+ 'woocommerce/woocommerce.php' => true,
455
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
456
+ );
457
+
458
+ $activate = array(
459
+ 'woocommerce/woocommerce.php' => false,
460
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
461
+ );
462
+
463
+ foreach ( $plugin_slug_arr as $slug => $do_silently ) {
464
+
465
+ $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
466
+ }
467
+
468
+ foreach ( $activate as $slug => $data ) {
469
+
470
+ if ( is_wp_error( $data ) ) {
471
+ wp_send_json_error(
472
+ array(
473
+ 'success' => false,
474
+ 'message' => $data->get_error_message(),
475
+ )
476
+ );
477
+ }
478
+ }
479
+
480
+ wp_send_json_success();
481
+ }
482
+
483
+ /**
484
+ * Save Locale Settings.
485
+ */
486
+ public function page_builder_step_save() {
487
+
488
+ if ( ! current_user_can( 'manage_options' ) ) {
489
+ return;
490
+ }
491
+
492
+ check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
493
+
494
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
495
+ $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
496
+ $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
497
+
498
+ $do_sliently = true;
499
+ if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
500
+ $do_sliently = false;
501
+ }
502
+
503
+ $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
504
+
505
+ if ( $save_option ) {
506
+ $this->save_page_builder_option();
507
+ }
508
+
509
+ if ( is_wp_error( $activate ) ) {
510
+ wp_send_json_error(
511
+ array(
512
+ 'success' => false,
513
+ 'message' => $activate->get_error_message(),
514
+ )
515
+ );
516
+ }
517
+
518
+ wp_send_json_success(
519
+ array( 'plugin' => $plugin_slug )
520
+ );
521
+ }
522
+
523
+ /**
524
+ * Save selected page builder in options database.
525
+ */
526
+ public function save_page_builder_option() {
527
+
528
+ if ( ! current_user_can( 'manage_options' ) ) {
529
+ return;
530
+ }
531
+
532
+ $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
533
+
534
+ $wcf_settings = get_option( '_cartflows_common', array() );
535
+
536
+ if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
537
+ $page_builder = 'beaver-builder';
538
+ }
539
+
540
+ $wcf_settings['default_page_builder'] = $page_builder;
541
+
542
+ update_option( '_cartflows_common', $wcf_settings );
543
+
544
+ wp_send_json_success(
545
+ array( 'plugin' => $page_builder )
546
+ );
547
+
548
+ }
549
+
550
+ /**
551
+ * Final step.
552
+ */
553
+ public function ready_step() {
554
+
555
+ // Set setup wizard status to complete.
556
+ update_option( 'wcf_setup_complete', true );
557
+ ?>
558
+ <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
559
+
560
+ <div class="cartflows-setup-next-steps">
561
+ <div class="cartflows-setup-next-steps-last">
562
+
563
+ <p class="success">
564
+ <?php
565
+ 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' )
566
+ ?>
567
+ </p>
568
+
569
+
570
+ <ul class="wcf-wizard-next-steps">
571
+ <li class="wcf-wizard-next-step-item">
572
+ <div class="wcf-wizard-next-step-description">
573
+ <p class="next-step-heading">Next step</p>
574
+ <h3 class="next-step-description">Create First Flow</h3>
575
+ <p class="next-step-extra-info">You're ready to add flows to your website.</p>
576
+ </div>
577
+ <div class="wcf-wizard-next-step-action">
578
+ <p class="wc-setup-actions step">
579
+ <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>
580
+ </p>
581
+ </div>
582
+ </li>
583
+ </ul>
584
+
585
+ </div>
586
+ </div>
587
+ <?php
588
+ }
589
+
590
+ /**
591
+ * Training course step.
592
+ */
593
+ public function training_step() {
594
+ $current_user = wp_get_current_user();
595
+ ?>
596
+ <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
597
+
598
+ <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
599
+ <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">
600
+ <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
601
+ <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
602
+ <div class="mauticform-innerform">
603
+ <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
604
+ <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
605
+ <div class="cartflows-setup-message">
606
+ <p>
607
+ <?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' ); ?>
608
+ <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
609
+ </p>
610
+ <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">
611
+ </div>
612
+ <span class="mauticform-errormsg" style="display: none;"></span>
613
+ </div>
614
+ </div>
615
+ </div>
616
+
617
+ <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
618
+ <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
619
+ <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
620
+ <div class="cartflows-setup-actions step">
621
+ <div class="button-prev-wrap">
622
+ <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>
623
+ </div>
624
+ <div class="button-next-wrap">
625
+ <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>
626
+ <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>
627
+ </div>
628
+ </div>
629
+ </form>
630
+ </div>
631
+ <?php
632
+ }
633
+
634
+ /**
635
+ * Localize variables in admin
636
+ */
637
+ public function localize_vars() {
638
+
639
+ $vars = array();
640
+
641
+ $ajax_actions = array(
642
+ 'wcf_page_builder_step_save',
643
+ 'wcf_wc_plugins_activate',
644
+ );
645
+
646
+ foreach ( $ajax_actions as $action ) {
647
+
648
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
649
+ }
650
+
651
+ return $vars;
652
+ }
653
+
654
+ /**
655
+ * Add JS script for mautic form
656
+ */
657
+ public function add_mautic_form_script() {
658
+
659
+ if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
660
+ return;
661
+ }
662
+ ?>
663
+
664
+ <script type="text/javascript">
665
+ /** This section is only needed once per page if manually copying **/
666
+ if (typeof MauticSDKLoaded == 'undefined') {
667
+ var MauticSDKLoaded = true;
668
+ var head = document.getElementsByTagName('head')[0];
669
+ var script = document.createElement('script');
670
+ script.type = 'text/javascript';
671
+ script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
672
+ script.onload = function() {
673
+ MauticSDK.onLoad();
674
+ };
675
+ head.appendChild(script);
676
+ var MauticDomain = 'https://go.cartflows.com';
677
+ var MauticLang = {
678
+ 'submittingMessage': "Please wait..."
679
+ };
680
+ }
681
+ </script>
682
+ <?php
683
+ }
684
+ }
685
+
686
+ new CartFlows_Wizard();
687
+
688
+ endif;
languages/cartflows.pot CHANGED
@@ -1,1991 +1,1991 @@
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.4\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2020-04-07 06:33:57+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
- #: classes/batch-process/class-cartflows-importer-elementor.php:44
28
- msgid "Invalid content."
29
- msgstr ""
30
-
31
- #: classes/batch-process/class-cartflows-importer-elementor.php:52
32
- msgid "Invalid content. Expected an array."
33
- msgstr ""
34
-
35
- #: classes/batch-process/helpers/class-wp-background-process.php:435
36
- msgid "Every %d Minutes"
37
- msgstr ""
38
-
39
- #: classes/class-cartflows-admin-fields.php:231
40
- msgid "Select"
41
- msgstr ""
42
-
43
- #: classes/class-cartflows-admin-fields.php:234
44
- msgid "No Checkout Steps"
45
- msgstr ""
46
-
47
- #: classes/class-cartflows-admin-fields.php:260
48
- #. translators: %s: link
49
- msgid ""
50
- "Be sure not to add any product in above selected Global Checkout step. "
51
- "Please read information about how to set up Global Checkout %1$shere%2$s."
52
- msgstr ""
53
-
54
- #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
55
- #: includes/admin/cartflows-general-bck.php:34
56
- #: modules/optin/classes/class-cartflows-optin-meta.php:150
57
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
58
- msgid "Settings"
59
- msgstr ""
60
-
61
- #: classes/class-cartflows-admin.php:436
62
- msgid "Installing and activating.."
63
- msgstr ""
64
-
65
- #: classes/class-cartflows-admin.php:437
66
- msgid "There was an error with the installation of plugin."
67
- msgstr ""
68
-
69
- #: classes/class-cartflows-admin.php:491
70
- msgid "Flows Library"
71
- msgstr ""
72
-
73
- #: classes/class-cartflows-admin.php:498
74
- #: modules/flow/view/meta-flow-steps.php:156
75
- msgid "Ready Templates"
76
- msgstr ""
77
-
78
- #: classes/class-cartflows-admin.php:501
79
- #: modules/flow/view/meta-flow-steps.php:159
80
- msgid "Create Your Own"
81
- msgstr ""
82
-
83
- #: classes/class-cartflows-admin.php:512
84
- #: modules/flow/view/meta-flow-steps.php:171
85
- msgid "Search Sites"
86
- msgstr ""
87
-
88
- #: classes/class-cartflows-admin.php:513
89
- #: modules/flow/view/meta-flow-steps.php:172
90
- msgid "Search Flow..."
91
- msgstr ""
92
-
93
- #: classes/class-cartflows-admin.php:530
94
- msgid "Design Your Flow"
95
- msgstr ""
96
-
97
- #: classes/class-cartflows-admin.php:531
98
- #: classes/class-cartflows-importer.php:637
99
- #: classes/class-cartflows-importer.php:736
100
- #: modules/flow/view/meta-flow-steps.php:202
101
- msgid "Learn How"
102
- msgstr ""
103
-
104
- #: classes/class-cartflows-api.php:368
105
- msgid "Request successfully processed!"
106
- msgstr ""
107
-
108
- #: classes/class-cartflows-cloning.php:423
109
- msgid "Clone this flow"
110
- msgstr ""
111
-
112
- #: classes/class-cartflows-cloning.php:423
113
- #: modules/flow/view/meta-flow-steps.php:115
114
- msgid "Clone"
115
- msgstr ""
116
-
117
- #: classes/class-cartflows-default-meta.php:741
118
- #: modules/optin/classes/class-cartflows-optin-meta.php:487
119
- msgid "Submit"
120
- msgstr ""
121
-
122
- #: classes/class-cartflows-flow-frontend.php:53
123
- msgid ""
124
- "Test mode is active — which displays random products for previewing. It can "
125
- "be deactivated from the flow settings in the admin dashboard."
126
- msgstr ""
127
-
128
- #: classes/class-cartflows-flow-frontend.php:58
129
- msgid "Click here to disable it"
130
- msgstr ""
131
-
132
- #: classes/class-cartflows-importer.php:81
133
- msgid "Export this flow"
134
- msgstr ""
135
-
136
- #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
137
- msgid "Export"
138
- msgstr ""
139
-
140
- #: classes/class-cartflows-importer.php:92
141
- msgid "Flow Export"
142
- msgstr ""
143
-
144
- #: classes/class-cartflows-importer.php:93
145
- msgid "Flow Import"
146
- msgstr ""
147
-
148
- #: classes/class-cartflows-importer.php:104
149
- msgid "No post to export has been supplied!"
150
- msgstr ""
151
-
152
- #: classes/class-cartflows-importer.php:295
153
- msgid "Please upload a valid .json file"
154
- msgstr ""
155
-
156
- #: classes/class-cartflows-importer.php:301
157
- msgid "Please upload a file to import"
158
- msgstr ""
159
-
160
- #: classes/class-cartflows-importer.php:478
161
- msgid "Successfully imported flows."
162
- msgstr ""
163
-
164
- #: classes/class-cartflows-importer.php:510
165
- msgid "Loading Steps"
166
- msgstr ""
167
-
168
- #: classes/class-cartflows-importer.php:512
169
- msgid "Getting steps from the cloud. Please wait for the moment."
170
- msgstr ""
171
-
172
- #: classes/class-cartflows-importer.php:523
173
- msgid "Searching Template.."
174
- msgstr ""
175
-
176
- #: classes/class-cartflows-importer.php:525
177
- msgid "Getting templates from the cloud. Please wait for the moment."
178
- msgstr ""
179
-
180
- #: classes/class-cartflows-importer.php:534
181
- msgid "Importing.."
182
- msgstr ""
183
-
184
- #: classes/class-cartflows-importer.php:543
185
- #: classes/class-cartflows-importer.php:583
186
- msgid "Imported"
187
- msgstr ""
188
-
189
- #: classes/class-cartflows-importer.php:544
190
- #: classes/class-cartflows-importer.php:584
191
- msgid "Thanks for patience"
192
- msgstr ""
193
-
194
- #: classes/class-cartflows-importer.php:553
195
- #: classes/class-cartflows-importer.php:565
196
- msgid "Coming Soon!"
197
- msgstr ""
198
-
199
- #: classes/class-cartflows-importer.php:584
200
- msgid "Redirecting to the Elementor edit window."
201
- msgstr ""
202
-
203
- #: classes/class-cartflows-importer.php:630
204
- #: classes/class-cartflows-importer.php:746
205
- msgid "Pro"
206
- msgstr ""
207
-
208
- #: classes/class-cartflows-importer.php:671
209
- #: classes/class-cartflows-importer.php:778
210
- msgid "Activate License"
211
- msgstr ""
212
-
213
- #: classes/class-cartflows-importer.php:673
214
- #: classes/class-cartflows-importer.php:780
215
- #: modules/flow/classes/class-cartflows-flow-meta.php:461
216
- msgid "Get Pro"
217
- msgstr ""
218
-
219
- #: classes/class-cartflows-importer.php:698
220
- msgid "Create"
221
- msgstr ""
222
-
223
- #: classes/class-cartflows-importer.php:797
224
- msgid "Under Maintenance.."
225
- msgstr ""
226
-
227
- #: classes/class-cartflows-importer.php:798
228
- msgid ""
229
- "If you are seeing this message, most likely our servers are under routine "
230
- "maintenance and we will be back shortly."
231
- msgstr ""
232
-
233
- #: classes/class-cartflows-importer.php:799
234
- msgid ""
235
- "In rare case, it is possible your website is having trouble connecting with "
236
- "ours. If you need help, please feel free to get in touch with us from our "
237
- "website.."
238
- msgstr ""
239
-
240
- #: classes/class-cartflows-importer.php:829
241
- #. translators: %s: Plugin string
242
- msgid ""
243
- "%1$s to see CartFlows templates. If you prefer another page builder tool, "
244
- "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
245
- msgstr ""
246
-
247
- #: classes/class-cartflows-importer.php:844
248
- msgid "All"
249
- msgstr ""
250
-
251
- #: classes/class-cartflows-importer.php:847
252
- msgid "Select Step Type"
253
- msgstr ""
254
-
255
- #: classes/class-cartflows-importer.php:931
256
- msgid "Import from Cloud"
257
- msgstr ""
258
-
259
- #: classes/class-cartflows-importer.php:1230
260
- msgid "Sales Landing"
261
- msgstr ""
262
-
263
- #: classes/class-cartflows-importer.php:1234
264
- #: modules/flow/classes/class-cartflows-step-post-type.php:251
265
- #: modules/flow/view/meta-flow-steps.php:12
266
- msgid "Checkout (Woo)"
267
- msgstr ""
268
-
269
- #: classes/class-cartflows-importer.php:1238
270
- #: modules/flow/classes/class-cartflows-step-post-type.php:258
271
- #: modules/flow/view/meta-flow-steps.php:13
272
- msgid "Thank You (Woo)"
273
- msgstr ""
274
-
275
- #: classes/class-cartflows-importer.php:1246
276
- #: modules/flow/classes/class-cartflows-step-post-type.php:237
277
- #: modules/flow/view/meta-flow-steps.php:11
278
- msgid "Landing"
279
- msgstr ""
280
-
281
- #: classes/class-cartflows-importer.php:1250
282
- msgid "Thank You"
283
- msgstr ""
284
-
285
- #: classes/class-cartflows-importer.php:1360
286
- #. translators: %s: template ID
287
- msgid "Invalid template id %1$s or post id %2$s."
288
- msgstr ""
289
-
290
- #: classes/class-cartflows-importer.php:1422
291
- #. translators: %s: flow ID
292
- msgid "Invalid flow id %1$s OR step type %2$s."
293
- msgstr ""
294
-
295
- #: classes/class-cartflows-importer.php:1547
296
- msgid ""
297
- "Elementor is not activated. Please activate plugin Elementor Page Builder "
298
- "to import the step."
299
- msgstr ""
300
-
301
- #: classes/class-cartflows-importer.php:1650
302
- msgid "Action failed. Invalid Security Nonce."
303
- msgstr ""
304
-
305
- #: classes/class-cartflows-importer.php:1657
306
- msgid "User have not plugin install permissions."
307
- msgstr ""
308
-
309
- #: classes/class-cartflows-importer.php:1679
310
- msgid "Plugin Successfully Activated"
311
- msgstr ""
312
-
313
- #: classes/class-cartflows-learndash-compatibility.php:86
314
- msgid "None"
315
- msgstr ""
316
-
317
- #: classes/class-cartflows-learndash-compatibility.php:113
318
- #. translators: 1: anchor start, 2: anchor close
319
- msgid ""
320
- "Non-enrolled students will redirect to the selected CartFlows template. If "
321
- "you have not created any Flow already, add new Flow from %1$shere%2$s."
322
- msgstr ""
323
-
324
- #: classes/class-cartflows-learndash-compatibility.php:119
325
- msgid "Select CartFlows Template for this Course"
326
- msgstr ""
327
-
328
- #: classes/class-cartflows-loader.php:222
329
- #. translators: %s: html tags
330
- msgid ""
331
- "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
332
- "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
333
- msgstr ""
334
-
335
- #: classes/class-cartflows-loader.php:462
336
- #. translators: %s: html tags
337
- msgid ""
338
- "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
339
- "activated."
340
- msgstr ""
341
-
342
- #: classes/class-cartflows-loader.php:472
343
- msgid "Activate WooCommerce"
344
- msgstr ""
345
-
346
- #: classes/class-cartflows-loader.php:480
347
- msgid "Install WooCommerce"
348
- msgstr ""
349
-
350
- #: classes/class-cartflows-logger.php:161
351
- msgid "Action failed. Please refresh the page and retry."
352
- msgstr ""
353
-
354
- #: classes/class-cartflows-meta-fields.php:80
355
- msgid "Thin 100"
356
- msgstr ""
357
-
358
- #: classes/class-cartflows-meta-fields.php:81
359
- msgid "Extra-Light 200"
360
- msgstr ""
361
-
362
- #: classes/class-cartflows-meta-fields.php:82
363
- msgid "Light 300"
364
- msgstr ""
365
-
366
- #: classes/class-cartflows-meta-fields.php:83
367
- msgid "Normal 400"
368
- msgstr ""
369
-
370
- #: classes/class-cartflows-meta-fields.php:84
371
- msgid "Medium 500"
372
- msgstr ""
373
-
374
- #: classes/class-cartflows-meta-fields.php:85
375
- msgid "Semi-Bold 600"
376
- msgstr ""
377
-
378
- #: classes/class-cartflows-meta-fields.php:86
379
- msgid "Bold 700"
380
- msgstr ""
381
-
382
- #: classes/class-cartflows-meta-fields.php:87
383
- msgid "Extra-Bold 800"
384
- msgstr ""
385
-
386
- #: classes/class-cartflows-meta-fields.php:88
387
- msgid "Ultra-Bold 900"
388
- msgstr ""
389
-
390
- #: classes/class-cartflows-meta-fields.php:548
391
- #: classes/class-cartflows-meta-fields.php:747
392
- msgid "Search for a product&hellip;"
393
- msgstr ""
394
-
395
- #: classes/class-cartflows-meta-fields.php:589
396
- msgid "Search for a coupon&hellip;"
397
- msgstr ""
398
-
399
- #: classes/class-cartflows-meta-fields.php:722
400
- msgid "Add New Product"
401
- msgstr ""
402
-
403
- #: classes/class-cartflows-meta-fields.php:723
404
- msgid "Create Product"
405
- msgstr ""
406
-
407
- #: classes/class-cartflows-meta-fields.php:755
408
- msgid "Remove"
409
- msgstr ""
410
-
411
- #: classes/class-cartflows-meta.php:34
412
- msgid "Update"
413
- msgstr ""
414
-
415
- #: classes/class-cartflows-meta.php:42
416
- #: modules/flow/classes/class-cartflows-flow-meta.php:82
417
- msgid "Back to edit Flow"
418
- msgstr ""
419
-
420
- #: classes/class-cartflows-meta.php:63
421
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
422
- #: modules/landing/classes/class-cartflows-landing-meta.php:136
423
- #: modules/optin/classes/class-cartflows-optin-meta.php:156
424
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
425
- msgid "Custom Script"
426
- msgstr ""
427
-
428
- #: classes/class-cartflows-meta.php:66
429
- msgid ""
430
- "Custom script lets you add your own custom script on front end of this flow "
431
- "page."
432
- msgstr ""
433
-
434
- #: classes/class-cartflows-metabox.php:59
435
- msgid "Flow Details"
436
- msgstr ""
437
-
438
- #: classes/class-cartflows-wizard.php:83
439
- msgid "Thanks for installing and using CartFlows!"
440
- msgstr ""
441
-
442
- #: classes/class-cartflows-wizard.php:84
443
- msgid ""
444
- "It is easy to use the CartFlows. Please use the setup wizard to quick start "
445
- "setup."
446
- msgstr ""
447
-
448
- #: classes/class-cartflows-wizard.php:86
449
- msgid "Start Wizard"
450
- msgstr ""
451
-
452
- #: classes/class-cartflows-wizard.php:87
453
- msgid "Skip Setup"
454
- msgstr ""
455
-
456
- #: classes/class-cartflows-wizard.php:117
457
- #: includes/admin/cartflows-general-bck.php:24
458
- msgid "Welcome"
459
- msgstr ""
460
-
461
- #: classes/class-cartflows-wizard.php:122
462
- msgid "Page Builder"
463
- msgstr ""
464
-
465
- #: classes/class-cartflows-wizard.php:126
466
- msgid "Checkout"
467
- msgstr ""
468
-
469
- #: classes/class-cartflows-wizard.php:130
470
- msgid "Training"
471
- msgstr ""
472
-
473
- #: classes/class-cartflows-wizard.php:134
474
- msgid "Ready!"
475
- msgstr ""
476
-
477
- #: classes/class-cartflows-wizard.php:209
478
- msgid "CartFlows Setup"
479
- msgstr ""
480
-
481
- #: classes/class-cartflows-wizard.php:235
482
- msgid "Exit Setup Wizard"
483
- msgstr ""
484
-
485
- #: classes/class-cartflows-wizard.php:288
486
- msgid "Welcome to CartFlows!"
487
- msgstr ""
488
-
489
- #: classes/class-cartflows-wizard.php:289
490
- msgid ""
491
- "Thank you for choosing CartFlows to get more leads, increase conversions, & "
492
- "maximize profits. This short setup wizard will guide you though configuring "
493
- "CartFlows and creating your first funnel."
494
- msgstr ""
495
-
496
- #: classes/class-cartflows-wizard.php:295
497
- msgid "Lets Go »"
498
- msgstr ""
499
-
500
- #: classes/class-cartflows-wizard.php:322
501
- msgid "Page Builder Setup"
502
- msgstr ""
503
-
504
- #: classes/class-cartflows-wizard.php:323
505
- msgid "Please select a page builder you would like to use with CartFlows."
506
- msgstr ""
507
-
508
- #: classes/class-cartflows-wizard.php:328
509
- msgid "Select Page Builder"
510
- msgstr ""
511
-
512
- #: classes/class-cartflows-wizard.php:335
513
- #: includes/admin/cartflows-general.php:94
514
- msgid "Elementor"
515
- msgstr ""
516
-
517
- #: classes/class-cartflows-wizard.php:345
518
- msgid "Beaver Builder Plugin (Lite Version)"
519
- msgstr ""
520
-
521
- #: classes/class-cartflows-wizard.php:355
522
- #: includes/admin/cartflows-general.php:96
523
- msgid "Divi"
524
- msgstr ""
525
-
526
- #: classes/class-cartflows-wizard.php:365
527
- #: includes/admin/cartflows-general.php:97
528
- msgid "Other"
529
- msgstr ""
530
-
531
- #: classes/class-cartflows-wizard.php:387
532
- msgid ""
533
- "While CartFlows Should work with most page builders, we offer templates for "
534
- "the above page builders."
535
- msgstr ""
536
-
537
- #: classes/class-cartflows-wizard.php:390
538
- #: classes/class-cartflows-wizard.php:435
539
- #: classes/class-cartflows-wizard.php:622
540
- msgid "« Previous"
541
- msgstr ""
542
-
543
- #: classes/class-cartflows-wizard.php:393
544
- msgid "Skip this step"
545
- msgstr ""
546
-
547
- #: classes/class-cartflows-wizard.php:394
548
- msgid "Next »"
549
- msgstr ""
550
-
551
- #: classes/class-cartflows-wizard.php:413
552
- msgid "Choose a checkout"
553
- msgstr ""
554
-
555
- #: classes/class-cartflows-wizard.php:416
556
- msgid ""
557
- "While CartFlows is designed to use WooCommerce sell digital and physical "
558
- "products, not all funnels need a checkout system."
559
- msgstr ""
560
-
561
- #: classes/class-cartflows-wizard.php:418
562
- msgid ""
563
- "Would you like to install WooCommerce to sell digital and physical products "
564
- "in your funnels?"
565
- msgstr ""
566
-
567
- #: classes/class-cartflows-wizard.php:425
568
- msgid "The following plugin will be installed and activated for you:"
569
- msgstr ""
570
-
571
- #: classes/class-cartflows-wizard.php:426
572
- msgid "WooCommerce"
573
- msgstr ""
574
-
575
- #: classes/class-cartflows-wizard.php:427
576
- msgid "WooCommerce Cart Abandonment Recovery"
577
- msgstr ""
578
-
579
- #: classes/class-cartflows-wizard.php:438
580
- #: classes/class-cartflows-wizard.php:625
581
- msgid "No thanks"
582
- msgstr ""
583
-
584
- #: classes/class-cartflows-wizard.php:439
585
- msgid "Yes"
586
- msgstr ""
587
-
588
- #: classes/class-cartflows-wizard.php:558
589
- msgid "Congratulations, You Did It!"
590
- msgstr ""
591
-
592
- #: classes/class-cartflows-wizard.php:565
593
- msgid ""
594
- "CartFlows is ready to use on your website. You've successfully completed "
595
- "the setup process and all that is left for you to do is create your first "
596
- "flow."
597
- msgstr ""
598
-
599
- #: classes/class-cartflows-wizard.php:579
600
- msgid "Create a flow"
601
- msgstr ""
602
-
603
- #: classes/class-cartflows-wizard.php:596
604
- msgid "Exclusive CartFlows Training Course Offer"
605
- msgstr ""
606
-
607
- #: classes/class-cartflows-wizard.php:607
608
- msgid ""
609
- "We want you to get off to a great start using CartFlows, so we would like "
610
- "to give access to our exclusive training course."
611
- msgstr ""
612
-
613
- #: classes/class-cartflows-wizard.php:608
614
- msgid "Get access to this couse, for free, by entering your email below."
615
- msgstr ""
616
-
617
- #: classes/class-cartflows-wizard.php:610
618
- msgid "Enter Email address"
619
- msgstr ""
620
-
621
- #: classes/class-cartflows-wizard.php:626
622
- msgid "Allow"
623
- msgstr ""
624
-
625
- #: classes/logger/class-cartflows-log-handler-file.php:351
626
- #: classes/logger/class-cartflows-log-handler-file.php:371
627
- msgid "This method should not be called before plugins_loaded."
628
- msgstr ""
629
-
630
- #: classes/logger/class-cartflows-wc-logger.php:58
631
- #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
632
- msgid "The provided handler %1$s does not implement %2$s."
633
- msgstr ""
634
-
635
- #: classes/logger/class-cartflows-wc-logger.php:136
636
- #. translators: 1: Cartflows_WC_Logger::log 2: level
637
- msgid "%1$s was called with an invalid level \"%2$s\"."
638
- msgstr ""
639
-
640
- #: includes/admin/cartflows-admin.php:19
641
- #: includes/admin/cartflows-general.php:48
642
- msgid "Modernizing WordPress eCommerce!"
643
- msgstr ""
644
-
645
- #: includes/admin/cartflows-admin.php:29
646
- msgid "Settings saved successfully."
647
- msgstr ""
648
-
649
- #: includes/admin/cartflows-error-log.php:36
650
- msgid "%1$s at %2$s"
651
- msgstr ""
652
-
653
- #: includes/admin/cartflows-error-log.php:41
654
- #: modules/flow/classes/class-cartflows-flow-post-type.php:225
655
- #: modules/flow/view/meta-flow-steps.php:104
656
- msgid "View"
657
- msgstr ""
658
-
659
- #: includes/admin/cartflows-error-log.php:65
660
- msgid "Delete log"
661
- msgstr ""
662
-
663
- #: includes/admin/cartflows-error-log.php:70
664
- msgid "There are currently no logs to view."
665
- msgstr ""
666
-
667
- #: includes/admin/cartflows-general-bck.php:10
668
- msgid "Selec"
669
- msgstr ""
670
-
671
- #: includes/admin/cartflows-general-bck.php:22
672
- msgid "General"
673
- msgstr ""
674
-
675
- #: includes/admin/cartflows-general.php:31
676
- #: includes/admin/cartflows-general.php:58
677
- msgid "General Settings"
678
- msgstr ""
679
-
680
- #: includes/admin/cartflows-general.php:40
681
- msgid "Getting Started"
682
- msgstr ""
683
-
684
- #: includes/admin/cartflows-general.php:71
685
- msgid "Disallow search engines from indexing flows"
686
- msgstr ""
687
-
688
- #: includes/admin/cartflows-general.php:81
689
- #: modules/flow/view/meta-flow-steps.php:93
690
- msgid "Global Checkout"
691
- msgstr ""
692
-
693
- #: includes/admin/cartflows-general.php:90
694
- msgid "Show Templates designed with"
695
- msgstr ""
696
-
697
- #: includes/admin/cartflows-general.php:91
698
- msgid ""
699
- "CartFlows offers flow templates that can be imported in one click. These "
700
- "templates are available in few different page builders. Please choose your "
701
- "preferred page builder from the list so you will only see templates that "
702
- "are made using that page builder.."
703
- msgstr ""
704
-
705
- #: includes/admin/cartflows-general.php:95
706
- msgid "Beaver Builder"
707
- msgstr ""
708
-
709
- #: includes/admin/cartflows-general.php:106
710
- #: includes/admin/cartflows-general.php:190
711
- #: includes/admin/cartflows-general.php:296
712
- #: includes/admin/cartflows-general.php:413
713
- msgid "Save Changes"
714
- msgstr ""
715
-
716
- #: includes/admin/cartflows-general.php:116
717
- msgid "Permalink Settings"
718
- msgstr ""
719
-
720
- #: includes/admin/cartflows-general.php:131
721
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
722
- #: modules/optin/classes/class-cartflows-optin-meta.php:380
723
- msgid "Default"
724
- msgstr ""
725
-
726
- #: includes/admin/cartflows-general.php:137
727
- msgid "Flow and Step Slug"
728
- msgstr ""
729
-
730
- #: includes/admin/cartflows-general.php:143
731
- msgid "Flow Slug"
732
- msgstr ""
733
-
734
- #: includes/admin/cartflows-general.php:149
735
- msgid "Step Slug"
736
- msgstr ""
737
-
738
- #: includes/admin/cartflows-general.php:161
739
- msgid "Post Type Permalink Base"
740
- msgstr ""
741
-
742
- #: includes/admin/cartflows-general.php:169
743
- msgid "Step Base"
744
- msgstr ""
745
-
746
- #: includes/admin/cartflows-general.php:179
747
- msgid "Flow Base"
748
- msgstr ""
749
-
750
- #: includes/admin/cartflows-general.php:191
751
- msgid "Set Default"
752
- msgstr ""
753
-
754
- #: includes/admin/cartflows-general.php:205
755
- msgid "Facebook Pixel Settings"
756
- msgstr ""
757
-
758
- #: includes/admin/cartflows-general.php:220
759
- msgid "Enable Facebook Pixel Tracking"
760
- msgstr ""
761
-
762
- #: includes/admin/cartflows-general.php:233
763
- msgid "Enable for the whole site"
764
- msgstr ""
765
-
766
- #: includes/admin/cartflows-general.php:241
767
- #: includes/admin/cartflows-general.php:340
768
- msgid "If this option is unchecked, it will only apply to CartFlows steps."
769
- msgstr ""
770
-
771
- #: includes/admin/cartflows-general.php:251
772
- msgid "Enter Facebook pixel ID"
773
- msgstr ""
774
-
775
- #: includes/admin/cartflows-general.php:259
776
- #: includes/admin/cartflows-general.php:358
777
- msgid "Enable Events:"
778
- msgstr ""
779
-
780
- #: includes/admin/cartflows-general.php:268
781
- msgid "Initiate Checkout"
782
- msgstr ""
783
-
784
- #: includes/admin/cartflows-general.php:277
785
- #: includes/admin/cartflows-general.php:384
786
- msgid "Add Payment Info"
787
- msgstr ""
788
-
789
- #: includes/admin/cartflows-general.php:286
790
- msgid "Purchase Complete"
791
- msgstr ""
792
-
793
- #: includes/admin/cartflows-general.php:308
794
- msgid "Google Analytics Settings"
795
- msgstr ""
796
-
797
- #: includes/admin/cartflows-general.php:319
798
- msgid "Enable Google Analytics Tracking"
799
- msgstr ""
800
-
801
- #: includes/admin/cartflows-general.php:332
802
- msgid "Enable for the whole website"
803
- msgstr ""
804
-
805
- #: includes/admin/cartflows-general.php:350
806
- msgid "Google Analytics ID"
807
- msgstr ""
808
-
809
- #: includes/admin/cartflows-general.php:352
810
- msgid ""
811
- "Log into your <a href=\"https://analytics.google.com/\" "
812
- "target=\"_blank\">google analytics account</a> to find your ID. eg: "
813
- "UA-XXXXXX-X&period;"
814
- msgstr ""
815
-
816
- #: includes/admin/cartflows-general.php:366
817
- msgid "Begin Checkout"
818
- msgstr ""
819
-
820
- #: includes/admin/cartflows-general.php:375
821
- msgid "Add To Cart"
822
- msgstr ""
823
-
824
- #: includes/admin/cartflows-general.php:393
825
- msgid "Purchase"
826
- msgstr ""
827
-
828
- #: includes/admin/cartflows-general.php:401
829
- msgid ""
830
- "Google Analytics not working correctly? <a "
831
- "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
832
- "issues/\" > Click here </a> to know more. "
833
- msgstr ""
834
-
835
- #: includes/admin/cartflows-general.php:434
836
- msgid "Knowledge Base"
837
- msgstr ""
838
-
839
- #: includes/admin/cartflows-general.php:438
840
- msgid "Not sure how something works? Take a peek at the knowledge base and learn."
841
- msgstr ""
842
-
843
- #: includes/admin/cartflows-general.php:441
844
- msgid "Visit Knowledge Base »"
845
- msgstr ""
846
-
847
- #: includes/admin/cartflows-general.php:449
848
- msgid "Community"
849
- msgstr ""
850
-
851
- #: includes/admin/cartflows-general.php:453
852
- msgid ""
853
- "Join the community of super helpful CartFlows users. Say hello, ask "
854
- "questions, give feedback and help each other!"
855
- msgstr ""
856
-
857
- #: includes/admin/cartflows-general.php:456
858
- msgid "Join Our Facebook Group »"
859
- msgstr ""
860
-
861
- #: includes/admin/cartflows-general.php:464
862
- msgid "Five Star Support"
863
- msgstr ""
864
-
865
- #: includes/admin/cartflows-general.php:468
866
- msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
867
- msgstr ""
868
-
869
- #: includes/admin/cartflows-general.php:471
870
- msgid "Submit a Ticket »"
871
- msgstr ""
872
-
873
- #: includes/admin/cartflows-general.php:481
874
- msgid "Load Minified CSS"
875
- msgstr ""
876
-
877
- #: includes/admin/cartflows-general.php:486
878
- msgid ""
879
- "Load the Minified CSS from here. Just Enable it by checking the below given "
880
- "checkbox."
881
- msgstr ""
882
-
883
- #: includes/admin/cartflows-general.php:493
884
- msgid "Load minified CSS & JS Files"
885
- msgstr ""
886
-
887
- #: includes/admin/cartflows-general.php:498
888
- msgid "Save"
889
- msgstr ""
890
-
891
- #: includes/exporter.php:12
892
- msgid "Export Flows to a JSON file"
893
- msgstr ""
894
-
895
- #: includes/exporter.php:13
896
- msgid ""
897
- "This tool allows you to generate and download a JSON file containing a list "
898
- "of all flows."
899
- msgstr ""
900
-
901
- #: includes/importer.php:12
902
- msgid "Import Flows to a JSON file"
903
- msgstr ""
904
-
905
- #: includes/importer.php:13
906
- msgid "This tool allows you to import the flows from the JSON file."
907
- msgstr ""
908
-
909
- #: includes/importer.php:21
910
- msgid "Import"
911
- msgstr ""
912
-
913
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:254
914
- #: modules/optin/classes/class-cartflows-optin-markup.php:146
915
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
916
- msgid ""
917
- "WooCommerce functions do not exist. If you are in an IFrame, please reload "
918
- "it."
919
- msgstr ""
920
-
921
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:255
922
- #: modules/optin/classes/class-cartflows-optin-markup.php:147
923
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
924
- msgid "Click Here to Reload"
925
- msgstr ""
926
-
927
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:273
928
- msgid "Checkout ID not found"
929
- msgstr ""
930
-
931
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:336
932
- #: modules/checkout/templates/embed/checkout-template-simple.php:25
933
- #: modules/checkout/templates/wcf-template.php:36
934
- #: modules/optin/templates/optin-template-simple.php:25
935
- msgid "Your cart is currently empty."
936
- msgstr ""
937
-
938
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:401
939
- msgid ""
940
- "No product is selected. Please select products from the checkout meta "
941
- "settings to continue."
942
- msgstr ""
943
-
944
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:454
945
- msgid "Variations Not set"
946
- msgstr ""
947
-
948
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:462
949
- msgid "This product can't be purchased"
950
- msgstr ""
951
-
952
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:901
953
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:944
954
- msgid "Coupon Code"
955
- msgstr ""
956
-
957
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:902
958
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:953
959
- msgid "Apply"
960
- msgstr ""
961
-
962
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1109
963
- msgid "Sorry there was a problem removing this coupon."
964
- msgstr ""
965
-
966
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1112
967
- msgid "Coupon has been removed."
968
- msgstr ""
969
-
970
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1131
971
- msgid "Sorry there was a problem removing "
972
- msgstr ""
973
-
974
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1134
975
- msgid " has been removed."
976
- msgstr ""
977
-
978
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
979
- msgid "Checkout Layout"
980
- msgstr ""
981
-
982
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
983
- #: modules/landing/classes/class-cartflows-landing-meta.php:130
984
- #: modules/optin/classes/class-cartflows-optin-meta.php:126
985
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
986
- msgid "Shortcodes"
987
- msgstr ""
988
-
989
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
990
- #: modules/optin/classes/class-cartflows-optin-meta.php:132
991
- msgid "Select Product"
992
- msgstr ""
993
-
994
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
995
- msgid "Order Bump"
996
- msgstr ""
997
-
998
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
999
- msgid "Checkout Offer"
1000
- msgstr ""
1001
-
1002
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1003
- msgid "Checkout Design"
1004
- msgstr ""
1005
-
1006
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1007
- msgid "Checkout Fields"
1008
- msgstr ""
1009
-
1010
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1011
- msgid "Checkout Settings"
1012
- msgstr ""
1013
-
1014
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:203
1015
- msgid "Logo (Optional)"
1016
- msgstr ""
1017
-
1018
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:265
1019
- msgid "Add this shortcode to your checkout page"
1020
- msgstr ""
1021
-
1022
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:301
1023
- #. translators: %s: link
1024
- msgid ""
1025
- "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon, Product Variations "
1026
- "& Quantity Options."
1027
- msgstr ""
1028
-
1029
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:328
1030
- #. translators: %s: link
1031
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1032
- msgstr ""
1033
-
1034
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:338
1035
- #. translators: %s: link
1036
- msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1037
- msgstr ""
1038
-
1039
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:365
1040
- #. translators: %s: link
1041
- msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1042
- msgstr ""
1043
-
1044
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:375
1045
- #. translators: %s: link
1046
- msgid ""
1047
- "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1048
- "feature"
1049
- msgstr ""
1050
-
1051
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:398
1052
- #. translators: %s: link
1053
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1054
- msgstr ""
1055
-
1056
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:425
1057
- #: modules/optin/classes/class-cartflows-optin-meta.php:267
1058
- #. translators: %s: link
1059
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1060
- msgstr ""
1061
-
1062
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:448
1063
- msgid "Place Order Button Text"
1064
- msgstr ""
1065
-
1066
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:452
1067
- msgid "Place order"
1068
- msgstr ""
1069
-
1070
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:454
1071
- msgid "It will change the Place Order Button text on checkout page."
1072
- msgstr ""
1073
-
1074
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:464
1075
- msgid "Enable cart editing on checkout"
1076
- msgstr ""
1077
-
1078
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:472
1079
- #. translators: %s: link
1080
- msgid "Users will able to remove products from the checkout page."
1081
- msgstr ""
1082
-
1083
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:502
1084
- msgid "One Column (Available in CartFlows Pro) "
1085
- msgstr ""
1086
-
1087
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:503
1088
- msgid "Two Step (Available in CartFlows Pro) "
1089
- msgstr ""
1090
-
1091
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:509
1092
- msgid "Checkout Skin"
1093
- msgstr ""
1094
-
1095
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:513
1096
- msgid "One Column"
1097
- msgstr ""
1098
-
1099
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:514
1100
- msgid "Two Column"
1101
- msgstr ""
1102
-
1103
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:515
1104
- msgid "Two Step"
1105
- msgstr ""
1106
-
1107
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:524
1108
- #: modules/optin/classes/class-cartflows-optin-meta.php:343
1109
- msgid "Primary Color"
1110
- msgstr ""
1111
-
1112
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:533
1113
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1114
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:614
1115
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:706
1116
- #: modules/optin/classes/class-cartflows-optin-meta.php:352
1117
- #: modules/optin/classes/class-cartflows-optin-meta.php:391
1118
- #: modules/optin/classes/class-cartflows-optin-meta.php:503
1119
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1120
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1121
- msgid "Font Family"
1122
- msgstr ""
1123
-
1124
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:541
1125
- msgid "Advance Options"
1126
- msgstr ""
1127
-
1128
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1129
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1130
- msgid "Heading"
1131
- msgstr ""
1132
-
1133
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1134
- msgid "Heading Color"
1135
- msgstr ""
1136
-
1137
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1138
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:623
1139
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1140
- #: modules/optin/classes/class-cartflows-optin-meta.php:400
1141
- #: modules/optin/classes/class-cartflows-optin-meta.php:512
1142
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1143
- msgid "Font Weight"
1144
- msgstr ""
1145
-
1146
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1147
- #: modules/optin/classes/class-cartflows-optin-meta.php:363
1148
- msgid "Input Fields"
1149
- msgstr ""
1150
-
1151
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:593
1152
- #: modules/optin/classes/class-cartflows-optin-meta.php:370
1153
- msgid "Floating Labels (Available in CartFlows Pro)"
1154
- msgstr ""
1155
-
1156
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:599
1157
- #: modules/optin/classes/class-cartflows-optin-meta.php:376
1158
- msgid "Style"
1159
- msgstr ""
1160
-
1161
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:604
1162
- #: modules/optin/classes/class-cartflows-optin-meta.php:381
1163
- msgid "Floating Labels"
1164
- msgstr ""
1165
-
1166
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:631
1167
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1168
- #: modules/optin/classes/class-cartflows-optin-meta.php:408
1169
- #: modules/optin/classes/class-cartflows-optin-meta.php:520
1170
- msgid "Size"
1171
- msgstr ""
1172
-
1173
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:635
1174
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:727
1175
- #: modules/optin/classes/class-cartflows-optin-meta.php:412
1176
- #: modules/optin/classes/class-cartflows-optin-meta.php:524
1177
- msgid "Extra Small"
1178
- msgstr ""
1179
-
1180
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:636
1181
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:728
1182
- #: modules/optin/classes/class-cartflows-optin-meta.php:413
1183
- #: modules/optin/classes/class-cartflows-optin-meta.php:525
1184
- msgid "Small"
1185
- msgstr ""
1186
-
1187
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1188
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:729
1189
- #: modules/optin/classes/class-cartflows-optin-meta.php:414
1190
- #: modules/optin/classes/class-cartflows-optin-meta.php:526
1191
- msgid "Medium"
1192
- msgstr ""
1193
-
1194
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:638
1195
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1196
- #: modules/optin/classes/class-cartflows-optin-meta.php:415
1197
- #: modules/optin/classes/class-cartflows-optin-meta.php:527
1198
- msgid "Large"
1199
- msgstr ""
1200
-
1201
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:639
1202
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:731
1203
- #: modules/optin/classes/class-cartflows-optin-meta.php:416
1204
- #: modules/optin/classes/class-cartflows-optin-meta.php:528
1205
- msgid "Extra Large"
1206
- msgstr ""
1207
-
1208
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:640
1209
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:732
1210
- #: modules/optin/classes/class-cartflows-optin-meta.php:417
1211
- #: modules/optin/classes/class-cartflows-optin-meta.php:529
1212
- msgid "Custom"
1213
- msgstr ""
1214
-
1215
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
1216
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:739
1217
- #: modules/optin/classes/class-cartflows-optin-meta.php:424
1218
- #: modules/optin/classes/class-cartflows-optin-meta.php:536
1219
- msgid "Top Bottom Spacing"
1220
- msgstr ""
1221
-
1222
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:655
1223
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:747
1224
- #: modules/optin/classes/class-cartflows-optin-meta.php:432
1225
- #: modules/optin/classes/class-cartflows-optin-meta.php:544
1226
- msgid "Left Right Spacing"
1227
- msgstr ""
1228
-
1229
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:663
1230
- #: modules/optin/classes/class-cartflows-optin-meta.php:448
1231
- msgid "Text / Placeholder Color"
1232
- msgstr ""
1233
-
1234
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:671
1235
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1236
- #: modules/optin/classes/class-cartflows-optin-meta.php:456
1237
- #: modules/optin/classes/class-cartflows-optin-meta.php:581
1238
- msgid "Background Color"
1239
- msgstr ""
1240
-
1241
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1242
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:787
1243
- #: modules/optin/classes/class-cartflows-optin-meta.php:464
1244
- #: modules/optin/classes/class-cartflows-optin-meta.php:597
1245
- msgid "Border Color"
1246
- msgstr ""
1247
-
1248
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:686
1249
- #: modules/optin/classes/class-cartflows-optin-meta.php:440
1250
- msgid "Label Color"
1251
- msgstr ""
1252
-
1253
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1254
- msgid "Buttons"
1255
- msgstr ""
1256
-
1257
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:755
1258
- #: modules/optin/classes/class-cartflows-optin-meta.php:565
1259
- msgid "Text Color"
1260
- msgstr ""
1261
-
1262
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:763
1263
- #: modules/optin/classes/class-cartflows-optin-meta.php:573
1264
- msgid "Text Hover Color"
1265
- msgstr ""
1266
-
1267
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:779
1268
- #: modules/optin/classes/class-cartflows-optin-meta.php:589
1269
- msgid "Background Hover Color"
1270
- msgstr ""
1271
-
1272
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:795
1273
- #: modules/optin/classes/class-cartflows-optin-meta.php:605
1274
- msgid "Border Hover Color"
1275
- msgstr ""
1276
-
1277
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:808
1278
- msgid "Sections"
1279
- msgstr ""
1280
-
1281
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:814
1282
- msgid "Highlight Area Background Color"
1283
- msgstr ""
1284
-
1285
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:853
1286
- msgid "Header Logo"
1287
- msgstr ""
1288
-
1289
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:861
1290
- msgid "Logo Width (In px)"
1291
- msgstr ""
1292
-
1293
- #: modules/checkout/templates/wcf-template.php:46
1294
- msgid "Copyright &copy;"
1295
- msgstr ""
1296
-
1297
- #: modules/checkout/templates/wcf-template.php:50
1298
- msgid "All Rights Reserved"
1299
- msgstr ""
1300
-
1301
- #: modules/flow/classes/class-cartflows-flow-meta.php:250
1302
- #. translators: %s flow id
1303
- msgid "Step not deleted for flow - %s"
1304
- msgstr ""
1305
-
1306
- #: modules/flow/classes/class-cartflows-flow-meta.php:281
1307
- #. translators: %s flow id
1308
- msgid "Step deleted for flow - %s"
1309
- msgstr ""
1310
-
1311
- #: modules/flow/classes/class-cartflows-flow-meta.php:309
1312
- #. translators: %s flow id
1313
- msgid "Steps not sorted for flow - %s"
1314
- msgstr ""
1315
-
1316
- #: modules/flow/classes/class-cartflows-flow-meta.php:332
1317
- #. translators: %s flow id
1318
- msgid "Steps sorted for flow - %s"
1319
- msgstr ""
1320
-
1321
- #: modules/flow/classes/class-cartflows-flow-meta.php:443
1322
- msgid "Analytics"
1323
- msgstr ""
1324
-
1325
- #: modules/flow/classes/class-cartflows-flow-meta.php:460
1326
- #. translators: %s: link
1327
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1328
- msgstr ""
1329
-
1330
- #: modules/flow/classes/class-cartflows-flow-meta.php:478
1331
- msgid "Flow Settings"
1332
- msgstr ""
1333
-
1334
- #: modules/flow/classes/class-cartflows-flow-meta.php:563
1335
- msgid "Enable Test Mode"
1336
- msgstr ""
1337
-
1338
- #: modules/flow/classes/class-cartflows-flow-meta.php:570
1339
- msgid ""
1340
- "If you are using WooCommerce plugin then test mode will add random products "
1341
- "in your flow, so you can preview it easily while testing."
1342
- msgstr ""
1343
-
1344
- #: modules/flow/classes/class-cartflows-flow-meta.php:689
1345
- #: modules/flow/view/meta-flow-steps.php:133
1346
- msgid "Add New Step"
1347
- msgstr ""
1348
-
1349
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1350
- msgid "Flow: "
1351
- msgstr ""
1352
-
1353
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1354
- msgid "Name: "
1355
- msgstr ""
1356
-
1357
- #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1358
- msgid "Search Flows"
1359
- msgstr ""
1360
-
1361
- #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1362
- msgid "All Flows"
1363
- msgstr ""
1364
-
1365
- #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1366
- msgid "Edit Flow"
1367
- msgstr ""
1368
-
1369
- #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1370
- msgid "View Flow"
1371
- msgstr ""
1372
-
1373
- #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1374
- #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1375
- #: modules/flow/classes/class-cartflows-step-post-type.php:166
1376
- #: modules/flow/classes/class-cartflows-step-post-type.php:168
1377
- msgid "Add New"
1378
- msgstr ""
1379
-
1380
- #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1381
- msgid "Update Flow"
1382
- msgstr ""
1383
-
1384
- #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1385
- msgid "New Flow Name"
1386
- msgstr ""
1387
-
1388
- #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1389
- msgid "Upgrade to CartFlows Pro"
1390
- msgstr ""
1391
-
1392
- #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1393
- msgid "Slug"
1394
- msgstr ""
1395
-
1396
- #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1397
- msgid "Flows"
1398
- msgstr ""
1399
-
1400
- #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1401
- #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1402
- #: modules/flow/classes/class-cartflows-step-post-type.php:397
1403
- #: modules/flow/classes/class-cartflows-step-post-type.php:403
1404
- #. translators: %s: singular custom post type name
1405
- msgid "%s updated."
1406
- msgstr ""
1407
-
1408
- #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1409
- #: modules/flow/classes/class-cartflows-step-post-type.php:399
1410
- #. translators: %s: singular custom post type name
1411
- msgid "Custom %s updated."
1412
- msgstr ""
1413
-
1414
- #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1415
- #: modules/flow/classes/class-cartflows-step-post-type.php:401
1416
- #. translators: %s: singular custom post type name
1417
- msgid "Custom %s deleted."
1418
- msgstr ""
1419
-
1420
- #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1421
- #: modules/flow/classes/class-cartflows-step-post-type.php:405
1422
- #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1423
- #. the revision
1424
- msgid "%1$s restored to revision from %2$s"
1425
- msgstr ""
1426
-
1427
- #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1428
- #: modules/flow/classes/class-cartflows-step-post-type.php:407
1429
- #. translators: %s: singular custom post type name
1430
- msgid "%s published."
1431
- msgstr ""
1432
-
1433
- #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1434
- #: modules/flow/classes/class-cartflows-step-post-type.php:409
1435
- #. translators: %s: singular custom post type name
1436
- msgid "%s saved."
1437
- msgstr ""
1438
-
1439
- #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1440
- #: modules/flow/classes/class-cartflows-step-post-type.php:411
1441
- #. translators: %s: singular custom post type name
1442
- msgid "%s submitted."
1443
- msgstr ""
1444
-
1445
- #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1446
- #: modules/flow/classes/class-cartflows-step-post-type.php:413
1447
- #. translators: %s: singular custom post type name
1448
- msgid "%s scheduled for."
1449
- msgstr ""
1450
-
1451
- #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1452
- #: modules/flow/classes/class-cartflows-step-post-type.php:415
1453
- #. translators: %s: singular custom post type name
1454
- msgid "%s draft updated."
1455
- msgstr ""
1456
-
1457
- #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1458
- #: modules/widgets/class-cartflows-next-step.php:78
1459
- msgid "Next Step"
1460
- msgstr ""
1461
-
1462
- #: modules/flow/classes/class-cartflows-step-post-type.php:162
1463
- msgid "Search Steps"
1464
- msgstr ""
1465
-
1466
- #: modules/flow/classes/class-cartflows-step-post-type.php:163
1467
- msgid "All Steps"
1468
- msgstr ""
1469
-
1470
- #: modules/flow/classes/class-cartflows-step-post-type.php:164
1471
- #: modules/flow/view/meta-flow-steps.php:106
1472
- msgid "Edit Step"
1473
- msgstr ""
1474
-
1475
- #: modules/flow/classes/class-cartflows-step-post-type.php:165
1476
- #: modules/flow/view/meta-flow-steps.php:102
1477
- msgid "View Step"
1478
- msgstr ""
1479
-
1480
- #: modules/flow/classes/class-cartflows-step-post-type.php:167
1481
- msgid "Update Step"
1482
- msgstr ""
1483
-
1484
- #: modules/flow/classes/class-cartflows-step-post-type.php:169
1485
- msgid "New Step Name"
1486
- msgstr ""
1487
-
1488
- #: modules/flow/classes/class-cartflows-step-post-type.php:209
1489
- msgid "Step Type"
1490
- msgstr ""
1491
-
1492
- #: modules/flow/classes/class-cartflows-step-post-type.php:219
1493
- msgid "Step Flow"
1494
- msgstr ""
1495
-
1496
- #: modules/flow/classes/class-cartflows-step-post-type.php:244
1497
- #: modules/flow/view/meta-flow-steps.php:16
1498
- msgid "Optin (Woo)"
1499
- msgstr ""
1500
-
1501
- #: modules/flow/classes/class-cartflows-step-post-type.php:265
1502
- #: modules/flow/view/meta-flow-steps.php:14
1503
- msgid "Upsell (Woo)"
1504
- msgstr ""
1505
-
1506
- #: modules/flow/classes/class-cartflows-step-post-type.php:272
1507
- #: modules/flow/view/meta-flow-steps.php:15
1508
- msgid "Downsell (Woo)"
1509
- msgstr ""
1510
-
1511
- #: modules/flow/view/meta-flow-steps.php:85
1512
- msgid "No Product Assigned"
1513
- msgstr ""
1514
-
1515
- #: modules/flow/view/meta-flow-steps.php:89
1516
- msgid "Global Checkout - Remove selected checkout product"
1517
- msgstr ""
1518
-
1519
- #: modules/flow/view/meta-flow-steps.php:108
1520
- msgid "Edit"
1521
- msgstr ""
1522
-
1523
- #: modules/flow/view/meta-flow-steps.php:113
1524
- msgid "Clone Step"
1525
- msgstr ""
1526
-
1527
- #: modules/flow/view/meta-flow-steps.php:118
1528
- msgid "Delete Step"
1529
- msgstr ""
1530
-
1531
- #: modules/flow/view/meta-flow-steps.php:120
1532
- msgid "Delete"
1533
- msgstr ""
1534
-
1535
- #: modules/flow/view/meta-flow-steps.php:149
1536
- msgid "Steps Library"
1537
- msgstr ""
1538
-
1539
- #: modules/flow/view/meta-flow-steps.php:198
1540
- msgid "Create Step"
1541
- msgstr ""
1542
-
1543
- #: modules/flow/view/meta-flow-steps.php:200
1544
- msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1545
- msgstr ""
1546
-
1547
- #: modules/landing/classes/class-cartflows-landing-meta.php:66
1548
- msgid "Landing Page Settings"
1549
- msgstr ""
1550
-
1551
- #: modules/landing/classes/class-cartflows-landing-meta.php:169
1552
- msgid "Next Step Link"
1553
- msgstr ""
1554
-
1555
- #: modules/optin/classes/class-cartflows-optin-markup.php:165
1556
- msgid "Please place shortcode on Optin step-type only."
1557
- msgstr ""
1558
-
1559
- #: modules/optin/classes/class-cartflows-optin-markup.php:225
1560
- msgid ""
1561
- "No product is selected. Please select a Simple, Virtual and Free product "
1562
- "from the meta settings."
1563
- msgstr ""
1564
-
1565
- #: modules/optin/classes/class-cartflows-optin-markup.php:242
1566
- msgid "Please update the selected product's price to zero (0)."
1567
- msgstr ""
1568
-
1569
- #: modules/optin/classes/class-cartflows-optin-markup.php:251
1570
- #: modules/optin/classes/class-cartflows-optin-markup.php:255
1571
- msgid "Please select a Simple, Virtual and Free product."
1572
- msgstr ""
1573
-
1574
- #: modules/optin/classes/class-cartflows-optin-meta.php:65
1575
- msgid "Optin Settings"
1576
- msgstr ""
1577
-
1578
- #: modules/optin/classes/class-cartflows-optin-meta.php:138
1579
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1580
- msgid "Design"
1581
- msgstr ""
1582
-
1583
- #: modules/optin/classes/class-cartflows-optin-meta.php:144
1584
- msgid "Form Fields"
1585
- msgstr ""
1586
-
1587
- #: modules/optin/classes/class-cartflows-optin-meta.php:213
1588
- msgid "Add this shortcode to your optin page"
1589
- msgstr ""
1590
-
1591
- #: modules/optin/classes/class-cartflows-optin-meta.php:238
1592
- msgid "Select Free Product"
1593
- msgstr ""
1594
-
1595
- #: modules/optin/classes/class-cartflows-optin-meta.php:239
1596
- msgid "Select Free and Virtual product only."
1597
- msgstr ""
1598
-
1599
- #: modules/optin/classes/class-cartflows-optin-meta.php:290
1600
- msgid "Pass Fields as URL Parameters"
1601
- msgstr ""
1602
-
1603
- #: modules/optin/classes/class-cartflows-optin-meta.php:293
1604
- msgid "Enable"
1605
- msgstr ""
1606
-
1607
- #: modules/optin/classes/class-cartflows-optin-meta.php:294
1608
- msgid ""
1609
- "You can pass specific fields from the form to next step as URL query "
1610
- "parameters."
1611
- msgstr ""
1612
-
1613
- #: modules/optin/classes/class-cartflows-optin-meta.php:305
1614
- msgid "Enter form field"
1615
- msgstr ""
1616
-
1617
- #: modules/optin/classes/class-cartflows-optin-meta.php:308
1618
- #: modules/optin/classes/class-cartflows-optin-meta.php:318
1619
- msgid "Enter comma seprated field name. E.g. first_name, last_name"
1620
- msgstr ""
1621
-
1622
- #: modules/optin/classes/class-cartflows-optin-meta.php:310
1623
- msgid "Fields to pass, separated by commas"
1624
- msgstr ""
1625
-
1626
- #: modules/optin/classes/class-cartflows-optin-meta.php:320
1627
- #. translators: %s: link
1628
- msgid ""
1629
- "You can pass field value as a URL parameter to the next step. %1$sClick "
1630
- "here%2$s for more information."
1631
- msgstr ""
1632
-
1633
- #: modules/optin/classes/class-cartflows-optin-meta.php:477
1634
- msgid "Submit Button"
1635
- msgstr ""
1636
-
1637
- #: modules/optin/classes/class-cartflows-optin-meta.php:483
1638
- msgid "Button Text"
1639
- msgstr ""
1640
-
1641
- #: modules/optin/classes/class-cartflows-optin-meta.php:494
1642
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1643
- msgid "Font Size"
1644
- msgstr ""
1645
-
1646
- #: modules/optin/classes/class-cartflows-optin-meta.php:552
1647
- msgid "Position"
1648
- msgstr ""
1649
-
1650
- #: modules/optin/classes/class-cartflows-optin-meta.php:556
1651
- msgid "Left"
1652
- msgstr ""
1653
-
1654
- #: modules/optin/classes/class-cartflows-optin-meta.php:557
1655
- msgid "Center"
1656
- msgstr ""
1657
-
1658
- #: modules/optin/classes/class-cartflows-optin-meta.php:558
1659
- msgid "Right"
1660
- msgstr ""
1661
-
1662
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1663
- msgid "Thank You Page Settings"
1664
- msgstr ""
1665
-
1666
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1667
- msgid "Edit Fields"
1668
- msgstr ""
1669
-
1670
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1671
- msgid "Order Details"
1672
- msgstr ""
1673
-
1674
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1675
- msgid "Text"
1676
- msgstr ""
1677
-
1678
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1679
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1680
- msgid "Color"
1681
- msgstr ""
1682
-
1683
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1684
- msgid "Advanced Options"
1685
- msgstr ""
1686
-
1687
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1688
- msgid "Container Width (In px)"
1689
- msgstr ""
1690
-
1691
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1692
- msgid "Section Background Color"
1693
- msgstr ""
1694
-
1695
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1696
- msgid "Enable Order Overview "
1697
- msgstr ""
1698
-
1699
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1700
- msgid "Enable Order Details "
1701
- msgstr ""
1702
-
1703
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1704
- msgid "Enable Billing Details "
1705
- msgstr ""
1706
-
1707
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1708
- msgid "Enable Shipping Details "
1709
- msgstr ""
1710
-
1711
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1712
- msgid "Thank You Page Text"
1713
- msgstr ""
1714
-
1715
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1716
- #: woocommerce/template/checkout/thankyou.php:41
1717
- #: woocommerce/template/checkout/thankyou.php:83
1718
- msgid "Thank you. Your order has been received."
1719
- msgstr ""
1720
-
1721
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1722
- msgid "It will change the default text on thank you page."
1723
- msgstr ""
1724
-
1725
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1726
- msgid "Redirect After Purchase"
1727
- msgstr ""
1728
-
1729
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1730
- msgid "Redirect Link"
1731
- msgstr ""
1732
-
1733
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1734
- msgid "https://"
1735
- msgstr ""
1736
-
1737
- #: modules/widgets/class-cartflows-next-step.php:24
1738
- msgid "CartFlows Next Step"
1739
- msgstr ""
1740
-
1741
- #: modules/widgets/class-cartflows-next-step.php:26
1742
- msgid "Next Step Widgets"
1743
- msgstr ""
1744
-
1745
- #: modules/widgets/class-cartflows-next-step.php:106
1746
- msgid "New title"
1747
- msgstr ""
1748
-
1749
- #: modules/widgets/class-cartflows-next-step.php:123
1750
- msgid "Title:"
1751
- msgstr ""
1752
-
1753
- #: modules/widgets/class-cartflows-next-step.php:127
1754
- msgid "Flow ID:"
1755
- msgstr ""
1756
-
1757
- #: modules/widgets/class-cartflows-next-step.php:131
1758
- msgid "Step ID:"
1759
- msgstr ""
1760
-
1761
- #: woocommerce/template/cart/cart-shipping.php:51
1762
- #. Translators: $s shipping destination.
1763
- msgid "Estimate for %s."
1764
- msgstr ""
1765
-
1766
- #: woocommerce/template/cart/cart-shipping.php:52
1767
- msgid "Change address"
1768
- msgstr ""
1769
-
1770
- #: woocommerce/template/cart/cart-shipping.php:54
1771
- msgid "This is only an estimate. Prices will be updated during checkout."
1772
- msgstr ""
1773
-
1774
- #: woocommerce/template/cart/cart-shipping.php:61
1775
- msgid "Enter your address to view shipping options."
1776
- msgstr ""
1777
-
1778
- #: woocommerce/template/cart/cart-shipping.php:63
1779
- msgid ""
1780
- "There are no shipping methods available. Please ensure that your address "
1781
- "has been entered correctly, or contact us if you need any help."
1782
- msgstr ""
1783
-
1784
- #: woocommerce/template/cart/cart-shipping.php:66
1785
- #. Translators: $s shipping destination.
1786
- msgid "No shipping options were found for %s."
1787
- msgstr ""
1788
-
1789
- #: woocommerce/template/cart/cart-shipping.php:67
1790
- msgid "Enter a different address"
1791
- msgstr ""
1792
-
1793
- #: woocommerce/template/checkout/form-billing.php:27
1794
- msgid "Billing &amp; Shipping"
1795
- msgstr ""
1796
-
1797
- #: woocommerce/template/checkout/form-billing.php:31
1798
- msgid "Billing details"
1799
- msgstr ""
1800
-
1801
- #: woocommerce/template/checkout/form-billing.php:59
1802
- msgid "Create an account?"
1803
- msgstr ""
1804
-
1805
- #: woocommerce/template/checkout/form-checkout.php:26
1806
- msgid "You must be logged in to checkout."
1807
- msgstr ""
1808
-
1809
- #: woocommerce/template/checkout/form-checkout.php:52
1810
- msgid "Your order"
1811
- msgstr ""
1812
-
1813
- #: woocommerce/template/checkout/form-coupon.php:26
1814
- msgid "Have a coupon?"
1815
- msgstr ""
1816
-
1817
- #: woocommerce/template/checkout/form-coupon.php:26
1818
- msgid "Click here to enter your code"
1819
- msgstr ""
1820
-
1821
- #: woocommerce/template/checkout/form-coupon.php:31
1822
- msgid "If you have a coupon code, please apply it below."
1823
- msgstr ""
1824
-
1825
- #: woocommerce/template/checkout/form-coupon.php:34
1826
- msgid "Coupon code"
1827
- msgstr ""
1828
-
1829
- #: woocommerce/template/checkout/form-coupon.php:38
1830
- msgid "Apply coupon"
1831
- msgstr ""
1832
-
1833
- #: woocommerce/template/checkout/form-login.php:26
1834
- msgid "Returning customer?"
1835
- msgstr ""
1836
-
1837
- #: woocommerce/template/checkout/form-login.php:26
1838
- msgid "Click here to login"
1839
- msgstr ""
1840
-
1841
- #: woocommerce/template/checkout/form-login.php:32
1842
- msgid ""
1843
- "If you have shopped with us before, please enter your details below. If you "
1844
- "are a new customer, please proceed to the Billing &amp; Shipping section."
1845
- msgstr ""
1846
-
1847
- #: woocommerce/template/checkout/form-shipping.php:26
1848
- msgid "Ship to a different address?"
1849
- msgstr ""
1850
-
1851
- #: woocommerce/template/checkout/form-shipping.php:57
1852
- msgid "Additional information"
1853
- msgstr ""
1854
-
1855
- #: woocommerce/template/checkout/payment.php:33
1856
- msgid ""
1857
- "Sorry, it seems that there are no available payment methods for your state. "
1858
- "Please contact us if you require assistance or wish to make alternate "
1859
- "arrangements."
1860
- msgstr ""
1861
-
1862
- #: woocommerce/template/checkout/payment.php:33
1863
- msgid "Please fill in your details above to see available payment methods."
1864
- msgstr ""
1865
-
1866
- #: woocommerce/template/checkout/payment.php:42
1867
- #. translators: $1 and $2 opening and closing emphasis tags respectively
1868
- msgid ""
1869
- "Since your browser does not support JavaScript, or it is disabled, please "
1870
- "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1871
- "order. You may be charged more than the amount stated above if you fail to "
1872
- "do so."
1873
- msgstr ""
1874
-
1875
- #: woocommerce/template/checkout/payment.php:44
1876
- msgid "Update totals"
1877
- msgstr ""
1878
-
1879
- #: woocommerce/template/checkout/review-order.php:26
1880
- msgid "Product"
1881
- msgstr ""
1882
-
1883
- #: woocommerce/template/checkout/review-order.php:27
1884
- #: woocommerce/template/checkout/review-order.php:107
1885
- msgid "Total"
1886
- msgstr ""
1887
-
1888
- #: woocommerce/template/checkout/review-order.php:60
1889
- msgid "Subtotal"
1890
- msgstr ""
1891
-
1892
- #: woocommerce/template/checkout/thankyou.php:30
1893
- msgid ""
1894
- "Unfortunately your order cannot be processed as the originating "
1895
- "bank/merchant has declined your transaction. Please attempt your purchase "
1896
- "again."
1897
- msgstr ""
1898
-
1899
- #: woocommerce/template/checkout/thankyou.php:33
1900
- msgid "Pay"
1901
- msgstr ""
1902
-
1903
- #: woocommerce/template/checkout/thankyou.php:35
1904
- msgid "My account"
1905
- msgstr ""
1906
-
1907
- #: woocommerce/template/checkout/thankyou.php:46
1908
- msgid "Order number:"
1909
- msgstr ""
1910
-
1911
- #: woocommerce/template/checkout/thankyou.php:51
1912
- msgid "Date:"
1913
- msgstr ""
1914
-
1915
- #: woocommerce/template/checkout/thankyou.php:57
1916
- msgid "Email:"
1917
- msgstr ""
1918
-
1919
- #: woocommerce/template/checkout/thankyou.php:63
1920
- msgid "Total:"
1921
- msgstr ""
1922
-
1923
- #: woocommerce/template/checkout/thankyou.php:69
1924
- msgid "Payment method:"
1925
- msgstr ""
1926
-
1927
- #: woocommerce/template/global/form-login.php:34
1928
- msgid "Username or email"
1929
- msgstr ""
1930
-
1931
- #: woocommerce/template/global/form-login.php:38
1932
- msgid "Password"
1933
- msgstr ""
1934
-
1935
- #: woocommerce/template/global/form-login.php:48
1936
- msgid "Login"
1937
- msgstr ""
1938
-
1939
- #: woocommerce/template/global/form-login.php:53
1940
- msgid "Remember me"
1941
- msgstr ""
1942
-
1943
- #: woocommerce/template/global/form-login.php:57
1944
- msgid "Lost your password?"
1945
- msgstr ""
1946
-
1947
- #. Plugin Name of the plugin/theme
1948
- msgid "CartFlows"
1949
- msgstr ""
1950
-
1951
- #. Author URI of the plugin/theme
1952
- msgid "https://cartflows.com/"
1953
- msgstr ""
1954
-
1955
- #. Description of the plugin/theme
1956
- msgid "Create beautiful checkout pages & sales flows for WooCommerce."
1957
- msgstr ""
1958
-
1959
- #. Author of the plugin/theme
1960
- msgid "CartFlows Inc"
1961
- msgstr ""
1962
-
1963
- #: modules/flow/classes/class-cartflows-flow-post-type.php:99
1964
- msgctxt "flow general name"
1965
- msgid "Flows"
1966
- msgstr ""
1967
-
1968
- #: modules/flow/classes/class-cartflows-flow-post-type.php:100
1969
- msgctxt "flow singular name"
1970
- msgid "Flow"
1971
- msgstr ""
1972
-
1973
- #: modules/flow/classes/class-cartflows-step-post-type.php:160
1974
- msgctxt "flow step general name"
1975
- msgid "Steps"
1976
- msgstr ""
1977
-
1978
- #: modules/flow/classes/class-cartflows-step-post-type.php:161
1979
- msgctxt "flow step singular name"
1980
- msgid "Step"
1981
- msgstr ""
1982
-
1983
- #: modules/flow/classes/class-cartflows-step-post-type.php:313
1984
- msgctxt "cartflows"
1985
- msgid "CartFlows — Boxed"
1986
- msgstr ""
1987
-
1988
- #: modules/flow/classes/class-cartflows-step-post-type.php:314
1989
- msgctxt "cartflows"
1990
- msgid "Template for Page Builders"
1991
  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.5\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-04-14 10:14:33+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
+ #: classes/batch-process/class-cartflows-importer-elementor.php:44
28
+ msgid "Invalid content."
29
+ msgstr ""
30
+
31
+ #: classes/batch-process/class-cartflows-importer-elementor.php:52
32
+ msgid "Invalid content. Expected an array."
33
+ msgstr ""
34
+
35
+ #: classes/batch-process/helpers/class-wp-background-process.php:435
36
+ msgid "Every %d Minutes"
37
+ msgstr ""
38
+
39
+ #: classes/class-cartflows-admin-fields.php:231
40
+ msgid "Select"
41
+ msgstr ""
42
+
43
+ #: classes/class-cartflows-admin-fields.php:234
44
+ msgid "No Checkout Steps"
45
+ msgstr ""
46
+
47
+ #: classes/class-cartflows-admin-fields.php:260
48
+ #. translators: %s: link
49
+ msgid ""
50
+ "Be sure not to add any product in above selected Global Checkout step. "
51
+ "Please read information about how to set up Global Checkout %1$shere%2$s."
52
+ msgstr ""
53
+
54
+ #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
55
+ #: includes/admin/cartflows-general-bck.php:34
56
+ #: modules/optin/classes/class-cartflows-optin-meta.php:150
57
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
58
+ msgid "Settings"
59
+ msgstr ""
60
+
61
+ #: classes/class-cartflows-admin.php:436
62
+ msgid "Installing and activating.."
63
+ msgstr ""
64
+
65
+ #: classes/class-cartflows-admin.php:437
66
+ msgid "There was an error with the installation of plugin."
67
+ msgstr ""
68
+
69
+ #: classes/class-cartflows-admin.php:491
70
+ msgid "Flows Library"
71
+ msgstr ""
72
+
73
+ #: classes/class-cartflows-admin.php:498
74
+ #: modules/flow/view/meta-flow-steps.php:156
75
+ msgid "Ready Templates"
76
+ msgstr ""
77
+
78
+ #: classes/class-cartflows-admin.php:501
79
+ #: modules/flow/view/meta-flow-steps.php:159
80
+ msgid "Create Your Own"
81
+ msgstr ""
82
+
83
+ #: classes/class-cartflows-admin.php:512
84
+ #: modules/flow/view/meta-flow-steps.php:171
85
+ msgid "Search Sites"
86
+ msgstr ""
87
+
88
+ #: classes/class-cartflows-admin.php:513
89
+ #: modules/flow/view/meta-flow-steps.php:172
90
+ msgid "Search Flow..."
91
+ msgstr ""
92
+
93
+ #: classes/class-cartflows-admin.php:530
94
+ msgid "Design Your Flow"
95
+ msgstr ""
96
+
97
+ #: classes/class-cartflows-admin.php:531
98
+ #: classes/class-cartflows-importer.php:637
99
+ #: classes/class-cartflows-importer.php:736
100
+ #: modules/flow/view/meta-flow-steps.php:202
101
+ msgid "Learn How"
102
+ msgstr ""
103
+
104
+ #: classes/class-cartflows-api.php:368
105
+ msgid "Request successfully processed!"
106
+ msgstr ""
107
+
108
+ #: classes/class-cartflows-cloning.php:423
109
+ msgid "Clone this flow"
110
+ msgstr ""
111
+
112
+ #: classes/class-cartflows-cloning.php:423
113
+ #: modules/flow/view/meta-flow-steps.php:115
114
+ msgid "Clone"
115
+ msgstr ""
116
+
117
+ #: classes/class-cartflows-default-meta.php:741
118
+ #: modules/optin/classes/class-cartflows-optin-meta.php:487
119
+ msgid "Submit"
120
+ msgstr ""
121
+
122
+ #: classes/class-cartflows-flow-frontend.php:53
123
+ msgid ""
124
+ "Test mode is active — which displays random products for previewing. It can "
125
+ "be deactivated from the flow settings in the admin dashboard."
126
+ msgstr ""
127
+
128
+ #: classes/class-cartflows-flow-frontend.php:58
129
+ msgid "Click here to disable it"
130
+ msgstr ""
131
+
132
+ #: classes/class-cartflows-importer.php:81
133
+ msgid "Export this flow"
134
+ msgstr ""
135
+
136
+ #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
137
+ msgid "Export"
138
+ msgstr ""
139
+
140
+ #: classes/class-cartflows-importer.php:92
141
+ msgid "Flow Export"
142
+ msgstr ""
143
+
144
+ #: classes/class-cartflows-importer.php:93
145
+ msgid "Flow Import"
146
+ msgstr ""
147
+
148
+ #: classes/class-cartflows-importer.php:104
149
+ msgid "No post to export has been supplied!"
150
+ msgstr ""
151
+
152
+ #: classes/class-cartflows-importer.php:295
153
+ msgid "Please upload a valid .json file"
154
+ msgstr ""
155
+
156
+ #: classes/class-cartflows-importer.php:301
157
+ msgid "Please upload a file to import"
158
+ msgstr ""
159
+
160
+ #: classes/class-cartflows-importer.php:478
161
+ msgid "Successfully imported flows."
162
+ msgstr ""
163
+
164
+ #: classes/class-cartflows-importer.php:510
165
+ msgid "Loading Steps"
166
+ msgstr ""
167
+
168
+ #: classes/class-cartflows-importer.php:512
169
+ msgid "Getting steps from the cloud. Please wait for the moment."
170
+ msgstr ""
171
+
172
+ #: classes/class-cartflows-importer.php:523
173
+ msgid "Searching Template.."
174
+ msgstr ""
175
+
176
+ #: classes/class-cartflows-importer.php:525
177
+ msgid "Getting templates from the cloud. Please wait for the moment."
178
+ msgstr ""
179
+
180
+ #: classes/class-cartflows-importer.php:534
181
+ msgid "Importing.."
182
+ msgstr ""
183
+
184
+ #: classes/class-cartflows-importer.php:543
185
+ #: classes/class-cartflows-importer.php:583
186
+ msgid "Imported"
187
+ msgstr ""
188
+
189
+ #: classes/class-cartflows-importer.php:544
190
+ #: classes/class-cartflows-importer.php:584
191
+ msgid "Thanks for patience"
192
+ msgstr ""
193
+
194
+ #: classes/class-cartflows-importer.php:553
195
+ #: classes/class-cartflows-importer.php:565
196
+ msgid "Coming Soon!"
197
+ msgstr ""
198
+
199
+ #: classes/class-cartflows-importer.php:584
200
+ msgid "Redirecting to the Elementor edit window."
201
+ msgstr ""
202
+
203
+ #: classes/class-cartflows-importer.php:630
204
+ #: classes/class-cartflows-importer.php:746
205
+ msgid "Pro"
206
+ msgstr ""
207
+
208
+ #: classes/class-cartflows-importer.php:671
209
+ #: classes/class-cartflows-importer.php:778
210
+ msgid "Activate License"
211
+ msgstr ""
212
+
213
+ #: classes/class-cartflows-importer.php:673
214
+ #: classes/class-cartflows-importer.php:780
215
+ #: modules/flow/classes/class-cartflows-flow-meta.php:461
216
+ msgid "Get Pro"
217
+ msgstr ""
218
+
219
+ #: classes/class-cartflows-importer.php:698
220
+ msgid "Create"
221
+ msgstr ""
222
+
223
+ #: classes/class-cartflows-importer.php:797
224
+ msgid "Under Maintenance.."
225
+ msgstr ""
226
+
227
+ #: classes/class-cartflows-importer.php:798
228
+ msgid ""
229
+ "If you are seeing this message, most likely our servers are under routine "
230
+ "maintenance and we will be back shortly."
231
+ msgstr ""
232
+
233
+ #: classes/class-cartflows-importer.php:799
234
+ msgid ""
235
+ "In rare case, it is possible your website is having trouble connecting with "
236
+ "ours. If you need help, please feel free to get in touch with us from our "
237
+ "website.."
238
+ msgstr ""
239
+
240
+ #: classes/class-cartflows-importer.php:829
241
+ #. translators: %s: Plugin string
242
+ msgid ""
243
+ "%1$s to see CartFlows templates. If you prefer another page builder tool, "
244
+ "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
245
+ msgstr ""
246
+
247
+ #: classes/class-cartflows-importer.php:844
248
+ msgid "All"
249
+ msgstr ""
250
+
251
+ #: classes/class-cartflows-importer.php:847
252
+ msgid "Select Step Type"
253
+ msgstr ""
254
+
255
+ #: classes/class-cartflows-importer.php:931
256
+ msgid "Import from Cloud"
257
+ msgstr ""
258
+
259
+ #: classes/class-cartflows-importer.php:1230
260
+ msgid "Sales Landing"
261
+ msgstr ""
262
+
263
+ #: classes/class-cartflows-importer.php:1234
264
+ #: modules/flow/classes/class-cartflows-step-post-type.php:251
265
+ #: modules/flow/view/meta-flow-steps.php:12
266
+ msgid "Checkout (Woo)"
267
+ msgstr ""
268
+
269
+ #: classes/class-cartflows-importer.php:1238
270
+ #: modules/flow/classes/class-cartflows-step-post-type.php:258
271
+ #: modules/flow/view/meta-flow-steps.php:13
272
+ msgid "Thank You (Woo)"
273
+ msgstr ""
274
+
275
+ #: classes/class-cartflows-importer.php:1246
276
+ #: modules/flow/classes/class-cartflows-step-post-type.php:237
277
+ #: modules/flow/view/meta-flow-steps.php:11
278
+ msgid "Landing"
279
+ msgstr ""
280
+
281
+ #: classes/class-cartflows-importer.php:1250
282
+ msgid "Thank You"
283
+ msgstr ""
284
+
285
+ #: classes/class-cartflows-importer.php:1360
286
+ #. translators: %s: template ID
287
+ msgid "Invalid template id %1$s or post id %2$s."
288
+ msgstr ""
289
+
290
+ #: classes/class-cartflows-importer.php:1422
291
+ #. translators: %s: flow ID
292
+ msgid "Invalid flow id %1$s OR step type %2$s."
293
+ msgstr ""
294
+
295
+ #: classes/class-cartflows-importer.php:1547
296
+ msgid ""
297
+ "Elementor is not activated. Please activate plugin Elementor Page Builder "
298
+ "to import the step."
299
+ msgstr ""
300
+
301
+ #: classes/class-cartflows-importer.php:1650
302
+ msgid "Action failed. Invalid Security Nonce."
303
+ msgstr ""
304
+
305
+ #: classes/class-cartflows-importer.php:1657
306
+ msgid "User have not plugin install permissions."
307
+ msgstr ""
308
+
309
+ #: classes/class-cartflows-importer.php:1679
310
+ msgid "Plugin Successfully Activated"
311
+ msgstr ""
312
+
313
+ #: classes/class-cartflows-learndash-compatibility.php:86
314
+ msgid "None"
315
+ msgstr ""
316
+
317
+ #: classes/class-cartflows-learndash-compatibility.php:113
318
+ #. translators: 1: anchor start, 2: anchor close
319
+ msgid ""
320
+ "Non-enrolled students will redirect to the selected CartFlows template. If "
321
+ "you have not created any Flow already, add new Flow from %1$shere%2$s."
322
+ msgstr ""
323
+
324
+ #: classes/class-cartflows-learndash-compatibility.php:119
325
+ msgid "Select CartFlows Template for this Course"
326
+ msgstr ""
327
+
328
+ #: classes/class-cartflows-loader.php:222
329
+ #. translators: %s: html tags
330
+ msgid ""
331
+ "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
332
+ "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
333
+ msgstr ""
334
+
335
+ #: classes/class-cartflows-loader.php:462
336
+ #. translators: %s: html tags
337
+ msgid ""
338
+ "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
339
+ "activated."
340
+ msgstr ""
341
+
342
+ #: classes/class-cartflows-loader.php:472
343
+ msgid "Activate WooCommerce"
344
+ msgstr ""
345
+
346
+ #: classes/class-cartflows-loader.php:480
347
+ msgid "Install WooCommerce"
348
+ msgstr ""
349
+
350
+ #: classes/class-cartflows-logger.php:161
351
+ msgid "Action failed. Please refresh the page and retry."
352
+ msgstr ""
353
+
354
+ #: classes/class-cartflows-meta-fields.php:80
355
+ msgid "Thin 100"
356
+ msgstr ""
357
+
358
+ #: classes/class-cartflows-meta-fields.php:81
359
+ msgid "Extra-Light 200"
360
+ msgstr ""
361
+
362
+ #: classes/class-cartflows-meta-fields.php:82
363
+ msgid "Light 300"
364
+ msgstr ""
365
+
366
+ #: classes/class-cartflows-meta-fields.php:83
367
+ msgid "Normal 400"
368
+ msgstr ""
369
+
370
+ #: classes/class-cartflows-meta-fields.php:84
371
+ msgid "Medium 500"
372
+ msgstr ""
373
+
374
+ #: classes/class-cartflows-meta-fields.php:85
375
+ msgid "Semi-Bold 600"
376
+ msgstr ""
377
+
378
+ #: classes/class-cartflows-meta-fields.php:86
379
+ msgid "Bold 700"
380
+ msgstr ""
381
+
382
+ #: classes/class-cartflows-meta-fields.php:87
383
+ msgid "Extra-Bold 800"
384
+ msgstr ""
385
+
386
+ #: classes/class-cartflows-meta-fields.php:88
387
+ msgid "Ultra-Bold 900"
388
+ msgstr ""
389
+
390
+ #: classes/class-cartflows-meta-fields.php:548
391
+ #: classes/class-cartflows-meta-fields.php:747
392
+ msgid "Search for a product&hellip;"
393
+ msgstr ""
394
+
395
+ #: classes/class-cartflows-meta-fields.php:589
396
+ msgid "Search for a coupon&hellip;"
397
+ msgstr ""
398
+
399
+ #: classes/class-cartflows-meta-fields.php:722
400
+ msgid "Add New Product"
401
+ msgstr ""
402
+
403
+ #: classes/class-cartflows-meta-fields.php:723
404
+ msgid "Create Product"
405
+ msgstr ""
406
+
407
+ #: classes/class-cartflows-meta-fields.php:755
408
+ msgid "Remove"
409
+ msgstr ""
410
+
411
+ #: classes/class-cartflows-meta.php:34
412
+ msgid "Update"
413
+ msgstr ""
414
+
415
+ #: classes/class-cartflows-meta.php:42
416
+ #: modules/flow/classes/class-cartflows-flow-meta.php:82
417
+ msgid "Back to edit Flow"
418
+ msgstr ""
419
+
420
+ #: classes/class-cartflows-meta.php:63
421
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
422
+ #: modules/landing/classes/class-cartflows-landing-meta.php:136
423
+ #: modules/optin/classes/class-cartflows-optin-meta.php:156
424
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
425
+ msgid "Custom Script"
426
+ msgstr ""
427
+
428
+ #: classes/class-cartflows-meta.php:66
429
+ msgid ""
430
+ "Custom script lets you add your own custom script on front end of this flow "
431
+ "page."
432
+ msgstr ""
433
+
434
+ #: classes/class-cartflows-metabox.php:59
435
+ msgid "Flow Details"
436
+ msgstr ""
437
+
438
+ #: classes/class-cartflows-wizard.php:83
439
+ msgid "Thanks for installing and using CartFlows!"
440
+ msgstr ""
441
+
442
+ #: classes/class-cartflows-wizard.php:84
443
+ msgid ""
444
+ "It is easy to use the CartFlows. Please use the setup wizard to quick start "
445
+ "setup."
446
+ msgstr ""
447
+
448
+ #: classes/class-cartflows-wizard.php:86
449
+ msgid "Start Wizard"
450
+ msgstr ""
451
+
452
+ #: classes/class-cartflows-wizard.php:87
453
+ msgid "Skip Setup"
454
+ msgstr ""
455
+
456
+ #: classes/class-cartflows-wizard.php:117
457
+ #: includes/admin/cartflows-general-bck.php:24
458
+ msgid "Welcome"
459
+ msgstr ""
460
+
461
+ #: classes/class-cartflows-wizard.php:122
462
+ msgid "Page Builder"
463
+ msgstr ""
464
+
465
+ #: classes/class-cartflows-wizard.php:126
466
+ msgid "Checkout"
467
+ msgstr ""
468
+
469
+ #: classes/class-cartflows-wizard.php:130
470
+ msgid "Training"
471
+ msgstr ""
472
+
473
+ #: classes/class-cartflows-wizard.php:134
474
+ msgid "Ready!"
475
+ msgstr ""
476
+
477
+ #: classes/class-cartflows-wizard.php:209
478
+ msgid "CartFlows Setup"
479
+ msgstr ""
480
+
481
+ #: classes/class-cartflows-wizard.php:235
482
+ msgid "Exit Setup Wizard"
483
+ msgstr ""
484
+
485
+ #: classes/class-cartflows-wizard.php:288
486
+ msgid "Welcome to CartFlows!"
487
+ msgstr ""
488
+
489
+ #: classes/class-cartflows-wizard.php:289
490
+ msgid ""
491
+ "Thank you for choosing CartFlows to get more leads, increase conversions, & "
492
+ "maximize profits. This short setup wizard will guide you though configuring "
493
+ "CartFlows and creating your first funnel."
494
+ msgstr ""
495
+
496
+ #: classes/class-cartflows-wizard.php:295
497
+ msgid "Lets Go »"
498
+ msgstr ""
499
+
500
+ #: classes/class-cartflows-wizard.php:322
501
+ msgid "Page Builder Setup"
502
+ msgstr ""
503
+
504
+ #: classes/class-cartflows-wizard.php:323
505
+ msgid "Please select a page builder you would like to use with CartFlows."
506
+ msgstr ""
507
+
508
+ #: classes/class-cartflows-wizard.php:328
509
+ msgid "Select Page Builder"
510
+ msgstr ""
511
+
512
+ #: classes/class-cartflows-wizard.php:335
513
+ #: includes/admin/cartflows-general.php:94
514
+ msgid "Elementor"
515
+ msgstr ""
516
+
517
+ #: classes/class-cartflows-wizard.php:345
518
+ msgid "Beaver Builder Plugin (Lite Version)"
519
+ msgstr ""
520
+
521
+ #: classes/class-cartflows-wizard.php:355
522
+ #: includes/admin/cartflows-general.php:96
523
+ msgid "Divi"
524
+ msgstr ""
525
+
526
+ #: classes/class-cartflows-wizard.php:365
527
+ #: includes/admin/cartflows-general.php:97
528
+ msgid "Other"
529
+ msgstr ""
530
+
531
+ #: classes/class-cartflows-wizard.php:387
532
+ msgid ""
533
+ "While CartFlows Should work with most page builders, we offer templates for "
534
+ "the above page builders."
535
+ msgstr ""
536
+
537
+ #: classes/class-cartflows-wizard.php:390
538
+ #: classes/class-cartflows-wizard.php:435
539
+ #: classes/class-cartflows-wizard.php:622
540
+ msgid "« Previous"
541
+ msgstr ""
542
+
543
+ #: classes/class-cartflows-wizard.php:393
544
+ msgid "Skip this step"
545
+ msgstr ""
546
+
547
+ #: classes/class-cartflows-wizard.php:394
548
+ msgid "Next »"
549
+ msgstr ""
550
+
551
+ #: classes/class-cartflows-wizard.php:413
552
+ msgid "Choose a checkout"
553
+ msgstr ""
554
+
555
+ #: classes/class-cartflows-wizard.php:416
556
+ msgid ""
557
+ "While CartFlows is designed to use WooCommerce sell digital and physical "
558
+ "products, not all funnels need a checkout system."
559
+ msgstr ""
560
+
561
+ #: classes/class-cartflows-wizard.php:418
562
+ msgid ""
563
+ "Would you like to install WooCommerce to sell digital and physical products "
564
+ "in your funnels?"
565
+ msgstr ""
566
+
567
+ #: classes/class-cartflows-wizard.php:425
568
+ msgid "The following plugin will be installed and activated for you:"
569
+ msgstr ""
570
+
571
+ #: classes/class-cartflows-wizard.php:426
572
+ msgid "WooCommerce"
573
+ msgstr ""
574
+
575
+ #: classes/class-cartflows-wizard.php:427
576
+ msgid "WooCommerce Cart Abandonment Recovery"
577
+ msgstr ""
578
+
579
+ #: classes/class-cartflows-wizard.php:438
580
+ #: classes/class-cartflows-wizard.php:625
581
+ msgid "No thanks"
582
+ msgstr ""
583
+
584
+ #: classes/class-cartflows-wizard.php:439
585
+ msgid "Yes"
586
+ msgstr ""
587
+
588
+ #: classes/class-cartflows-wizard.php:558
589
+ msgid "Congratulations, You Did It!"
590
+ msgstr ""
591
+
592
+ #: classes/class-cartflows-wizard.php:565
593
+ msgid ""
594
+ "CartFlows is ready to use on your website. You've successfully completed "
595
+ "the setup process and all that is left for you to do is create your first "
596
+ "flow."
597
+ msgstr ""
598
+
599
+ #: classes/class-cartflows-wizard.php:579
600
+ msgid "Create a flow"
601
+ msgstr ""
602
+
603
+ #: classes/class-cartflows-wizard.php:596
604
+ msgid "Exclusive CartFlows Training Course Offer"
605
+ msgstr ""
606
+
607
+ #: classes/class-cartflows-wizard.php:607
608
+ msgid ""
609
+ "We want you to get off to a great start using CartFlows, so we would like "
610
+ "to give access to our exclusive training course."
611
+ msgstr ""
612
+
613
+ #: classes/class-cartflows-wizard.php:608
614
+ msgid "Get access to this couse, for free, by entering your email below."
615
+ msgstr ""
616
+
617
+ #: classes/class-cartflows-wizard.php:610
618
+ msgid "Enter Email address"
619
+ msgstr ""
620
+
621
+ #: classes/class-cartflows-wizard.php:626
622
+ msgid "Allow"
623
+ msgstr ""
624
+
625
+ #: classes/logger/class-cartflows-log-handler-file.php:351
626
+ #: classes/logger/class-cartflows-log-handler-file.php:371
627
+ msgid "This method should not be called before plugins_loaded."
628
+ msgstr ""
629
+
630
+ #: classes/logger/class-cartflows-wc-logger.php:58
631
+ #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
632
+ msgid "The provided handler %1$s does not implement %2$s."
633
+ msgstr ""
634
+
635
+ #: classes/logger/class-cartflows-wc-logger.php:136
636
+ #. translators: 1: Cartflows_WC_Logger::log 2: level
637
+ msgid "%1$s was called with an invalid level \"%2$s\"."
638
+ msgstr ""
639
+
640
+ #: includes/admin/cartflows-admin.php:19
641
+ #: includes/admin/cartflows-general.php:48
642
+ msgid "Modernizing WordPress eCommerce!"
643
+ msgstr ""
644
+
645
+ #: includes/admin/cartflows-admin.php:29
646
+ msgid "Settings saved successfully."
647
+ msgstr ""
648
+
649
+ #: includes/admin/cartflows-error-log.php:36
650
+ msgid "%1$s at %2$s"
651
+ msgstr ""
652
+
653
+ #: includes/admin/cartflows-error-log.php:41
654
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:225
655
+ #: modules/flow/view/meta-flow-steps.php:104
656
+ msgid "View"
657
+ msgstr ""
658
+
659
+ #: includes/admin/cartflows-error-log.php:65
660
+ msgid "Delete log"
661
+ msgstr ""
662
+
663
+ #: includes/admin/cartflows-error-log.php:70
664
+ msgid "There are currently no logs to view."
665
+ msgstr ""
666
+
667
+ #: includes/admin/cartflows-general-bck.php:10
668
+ msgid "Selec"
669
+ msgstr ""
670
+
671
+ #: includes/admin/cartflows-general-bck.php:22
672
+ msgid "General"
673
+ msgstr ""
674
+
675
+ #: includes/admin/cartflows-general.php:31
676
+ #: includes/admin/cartflows-general.php:58
677
+ msgid "General Settings"
678
+ msgstr ""
679
+
680
+ #: includes/admin/cartflows-general.php:40
681
+ msgid "Getting Started"
682
+ msgstr ""
683
+
684
+ #: includes/admin/cartflows-general.php:71
685
+ msgid "Disallow search engines from indexing flows"
686
+ msgstr ""
687
+
688
+ #: includes/admin/cartflows-general.php:81
689
+ #: modules/flow/view/meta-flow-steps.php:93
690
+ msgid "Global Checkout"
691
+ msgstr ""
692
+
693
+ #: includes/admin/cartflows-general.php:90
694
+ msgid "Show Templates designed with"
695
+ msgstr ""
696
+
697
+ #: includes/admin/cartflows-general.php:91
698
+ msgid ""
699
+ "CartFlows offers flow templates that can be imported in one click. These "
700
+ "templates are available in few different page builders. Please choose your "
701
+ "preferred page builder from the list so you will only see templates that "
702
+ "are made using that page builder.."
703
+ msgstr ""
704
+
705
+ #: includes/admin/cartflows-general.php:95
706
+ msgid "Beaver Builder"
707
+ msgstr ""
708
+
709
+ #: includes/admin/cartflows-general.php:106
710
+ #: includes/admin/cartflows-general.php:190
711
+ #: includes/admin/cartflows-general.php:296
712
+ #: includes/admin/cartflows-general.php:413
713
+ msgid "Save Changes"
714
+ msgstr ""
715
+
716
+ #: includes/admin/cartflows-general.php:116
717
+ msgid "Permalink Settings"
718
+ msgstr ""
719
+
720
+ #: includes/admin/cartflows-general.php:131
721
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
722
+ #: modules/optin/classes/class-cartflows-optin-meta.php:380
723
+ msgid "Default"
724
+ msgstr ""
725
+
726
+ #: includes/admin/cartflows-general.php:137
727
+ msgid "Flow and Step Slug"
728
+ msgstr ""
729
+
730
+ #: includes/admin/cartflows-general.php:143
731
+ msgid "Flow Slug"
732
+ msgstr ""
733
+
734
+ #: includes/admin/cartflows-general.php:149
735
+ msgid "Step Slug"
736
+ msgstr ""
737
+
738
+ #: includes/admin/cartflows-general.php:161
739
+ msgid "Post Type Permalink Base"
740
+ msgstr ""
741
+
742
+ #: includes/admin/cartflows-general.php:169
743
+ msgid "Step Base"
744
+ msgstr ""
745
+
746
+ #: includes/admin/cartflows-general.php:179
747
+ msgid "Flow Base"
748
+ msgstr ""
749
+
750
+ #: includes/admin/cartflows-general.php:191
751
+ msgid "Set Default"
752
+ msgstr ""
753
+
754
+ #: includes/admin/cartflows-general.php:205
755
+ msgid "Facebook Pixel Settings"
756
+ msgstr ""
757
+
758
+ #: includes/admin/cartflows-general.php:220
759
+ msgid "Enable Facebook Pixel Tracking"
760
+ msgstr ""
761
+
762
+ #: includes/admin/cartflows-general.php:233
763
+ msgid "Enable for the whole site"
764
+ msgstr ""
765
+
766
+ #: includes/admin/cartflows-general.php:241
767
+ #: includes/admin/cartflows-general.php:340
768
+ msgid "If this option is unchecked, it will only apply to CartFlows steps."
769
+ msgstr ""
770
+
771
+ #: includes/admin/cartflows-general.php:251
772
+ msgid "Enter Facebook pixel ID"
773
+ msgstr ""
774
+
775
+ #: includes/admin/cartflows-general.php:259
776
+ #: includes/admin/cartflows-general.php:358
777
+ msgid "Enable Events:"
778
+ msgstr ""
779
+
780
+ #: includes/admin/cartflows-general.php:268
781
+ msgid "Initiate Checkout"
782
+ msgstr ""
783
+
784
+ #: includes/admin/cartflows-general.php:277
785
+ #: includes/admin/cartflows-general.php:384
786
+ msgid "Add Payment Info"
787
+ msgstr ""
788
+
789
+ #: includes/admin/cartflows-general.php:286
790
+ msgid "Purchase Complete"
791
+ msgstr ""
792
+
793
+ #: includes/admin/cartflows-general.php:308
794
+ msgid "Google Analytics Settings"
795
+ msgstr ""
796
+
797
+ #: includes/admin/cartflows-general.php:319
798
+ msgid "Enable Google Analytics Tracking"
799
+ msgstr ""
800
+
801
+ #: includes/admin/cartflows-general.php:332
802
+ msgid "Enable for the whole website"
803
+ msgstr ""
804
+
805
+ #: includes/admin/cartflows-general.php:350
806
+ msgid "Google Analytics ID"
807
+ msgstr ""
808
+
809
+ #: includes/admin/cartflows-general.php:352
810
+ msgid ""
811
+ "Log into your <a href=\"https://analytics.google.com/\" "
812
+ "target=\"_blank\">google analytics account</a> to find your ID. eg: "
813
+ "UA-XXXXXX-X&period;"
814
+ msgstr ""
815
+
816
+ #: includes/admin/cartflows-general.php:366
817
+ msgid "Begin Checkout"
818
+ msgstr ""
819
+
820
+ #: includes/admin/cartflows-general.php:375
821
+ msgid "Add To Cart"
822
+ msgstr ""
823
+
824
+ #: includes/admin/cartflows-general.php:393
825
+ msgid "Purchase"
826
+ msgstr ""
827
+
828
+ #: includes/admin/cartflows-general.php:401
829
+ msgid ""
830
+ "Google Analytics not working correctly? <a "
831
+ "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
832
+ "issues/\" > Click here </a> to know more. "
833
+ msgstr ""
834
+
835
+ #: includes/admin/cartflows-general.php:434
836
+ msgid "Knowledge Base"
837
+ msgstr ""
838
+
839
+ #: includes/admin/cartflows-general.php:438
840
+ msgid "Not sure how something works? Take a peek at the knowledge base and learn."
841
+ msgstr ""
842
+
843
+ #: includes/admin/cartflows-general.php:441
844
+ msgid "Visit Knowledge Base »"
845
+ msgstr ""
846
+
847
+ #: includes/admin/cartflows-general.php:449
848
+ msgid "Community"
849
+ msgstr ""
850
+
851
+ #: includes/admin/cartflows-general.php:453
852
+ msgid ""
853
+ "Join the community of super helpful CartFlows users. Say hello, ask "
854
+ "questions, give feedback and help each other!"
855
+ msgstr ""
856
+
857
+ #: includes/admin/cartflows-general.php:456
858
+ msgid "Join Our Facebook Group »"
859
+ msgstr ""
860
+
861
+ #: includes/admin/cartflows-general.php:464
862
+ msgid "Five Star Support"
863
+ msgstr ""
864
+
865
+ #: includes/admin/cartflows-general.php:468
866
+ msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
867
+ msgstr ""
868
+
869
+ #: includes/admin/cartflows-general.php:471
870
+ msgid "Submit a Ticket »"
871
+ msgstr ""
872
+
873
+ #: includes/admin/cartflows-general.php:481
874
+ msgid "Load Minified CSS"
875
+ msgstr ""
876
+
877
+ #: includes/admin/cartflows-general.php:486
878
+ msgid ""
879
+ "Load the Minified CSS from here. Just Enable it by checking the below given "
880
+ "checkbox."
881
+ msgstr ""
882
+
883
+ #: includes/admin/cartflows-general.php:493
884
+ msgid "Load minified CSS & JS Files"
885
+ msgstr ""
886
+
887
+ #: includes/admin/cartflows-general.php:498
888
+ msgid "Save"
889
+ msgstr ""
890
+
891
+ #: includes/exporter.php:12
892
+ msgid "Export Flows to a JSON file"
893
+ msgstr ""
894
+
895
+ #: includes/exporter.php:13
896
+ msgid ""
897
+ "This tool allows you to generate and download a JSON file containing a list "
898
+ "of all flows."
899
+ msgstr ""
900
+
901
+ #: includes/importer.php:12
902
+ msgid "Import Flows to a JSON file"
903
+ msgstr ""
904
+
905
+ #: includes/importer.php:13
906
+ msgid "This tool allows you to import the flows from the JSON file."
907
+ msgstr ""
908
+
909
+ #: includes/importer.php:21
910
+ msgid "Import"
911
+ msgstr ""
912
+
913
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:254
914
+ #: modules/optin/classes/class-cartflows-optin-markup.php:146
915
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
916
+ msgid ""
917
+ "WooCommerce functions do not exist. If you are in an IFrame, please reload "
918
+ "it."
919
+ msgstr ""
920
+
921
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:255
922
+ #: modules/optin/classes/class-cartflows-optin-markup.php:147
923
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
924
+ msgid "Click Here to Reload"
925
+ msgstr ""
926
+
927
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:273
928
+ msgid "Checkout ID not found"
929
+ msgstr ""
930
+
931
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:336
932
+ #: modules/checkout/templates/embed/checkout-template-simple.php:25
933
+ #: modules/checkout/templates/wcf-template.php:36
934
+ #: modules/optin/templates/optin-template-simple.php:25
935
+ msgid "Your cart is currently empty."
936
+ msgstr ""
937
+
938
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:401
939
+ msgid ""
940
+ "No product is selected. Please select products from the checkout meta "
941
+ "settings to continue."
942
+ msgstr ""
943
+
944
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:454
945
+ msgid "Variations Not set"
946
+ msgstr ""
947
+
948
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:462
949
+ msgid "This product can't be purchased"
950
+ msgstr ""
951
+
952
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:901
953
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:944
954
+ msgid "Coupon Code"
955
+ msgstr ""
956
+
957
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:902
958
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:953
959
+ msgid "Apply"
960
+ msgstr ""
961
+
962
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1109
963
+ msgid "Sorry there was a problem removing this coupon."
964
+ msgstr ""
965
+
966
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1112
967
+ msgid "Coupon has been removed."
968
+ msgstr ""
969
+
970
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1131
971
+ msgid "Sorry there was a problem removing "
972
+ msgstr ""
973
+
974
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1134
975
+ msgid " has been removed."
976
+ msgstr ""
977
+
978
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
979
+ msgid "Checkout Layout"
980
+ msgstr ""
981
+
982
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
983
+ #: modules/landing/classes/class-cartflows-landing-meta.php:130
984
+ #: modules/optin/classes/class-cartflows-optin-meta.php:126
985
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
986
+ msgid "Shortcodes"
987
+ msgstr ""
988
+
989
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
990
+ #: modules/optin/classes/class-cartflows-optin-meta.php:132
991
+ msgid "Select Product"
992
+ msgstr ""
993
+
994
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
995
+ msgid "Order Bump"
996
+ msgstr ""
997
+
998
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
999
+ msgid "Checkout Offer"
1000
+ msgstr ""
1001
+
1002
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1003
+ msgid "Checkout Design"
1004
+ msgstr ""
1005
+
1006
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1007
+ msgid "Checkout Fields"
1008
+ msgstr ""
1009
+
1010
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1011
+ msgid "Checkout Settings"
1012
+ msgstr ""
1013
+
1014
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:203
1015
+ msgid "Logo (Optional)"
1016
+ msgstr ""
1017
+
1018
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:265
1019
+ msgid "Add this shortcode to your checkout page"
1020
+ msgstr ""
1021
+
1022
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:301
1023
+ #. translators: %s: link
1024
+ msgid ""
1025
+ "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon, Product Variations "
1026
+ "& Quantity Options."
1027
+ msgstr ""
1028
+
1029
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:328
1030
+ #. translators: %s: link
1031
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1032
+ msgstr ""
1033
+
1034
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:338
1035
+ #. translators: %s: link
1036
+ msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1037
+ msgstr ""
1038
+
1039
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:365
1040
+ #. translators: %s: link
1041
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1042
+ msgstr ""
1043
+
1044
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:375
1045
+ #. translators: %s: link
1046
+ msgid ""
1047
+ "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1048
+ "feature"
1049
+ msgstr ""
1050
+
1051
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:398
1052
+ #. translators: %s: link
1053
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1054
+ msgstr ""
1055
+
1056
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:425
1057
+ #: modules/optin/classes/class-cartflows-optin-meta.php:267
1058
+ #. translators: %s: link
1059
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1060
+ msgstr ""
1061
+
1062
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:448
1063
+ msgid "Place Order Button Text"
1064
+ msgstr ""
1065
+
1066
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:452
1067
+ msgid "Place order"
1068
+ msgstr ""
1069
+
1070
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:454
1071
+ msgid "It will change the Place Order Button text on checkout page."
1072
+ msgstr ""
1073
+
1074
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:464
1075
+ msgid "Enable cart editing on checkout"
1076
+ msgstr ""
1077
+
1078
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:472
1079
+ #. translators: %s: link
1080
+ msgid "Users will able to remove products from the checkout page."
1081
+ msgstr ""
1082
+
1083
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:502
1084
+ msgid "One Column (Available in CartFlows Pro) "
1085
+ msgstr ""
1086
+
1087
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:503
1088
+ msgid "Two Step (Available in CartFlows Pro) "
1089
+ msgstr ""
1090
+
1091
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:509
1092
+ msgid "Checkout Skin"
1093
+ msgstr ""
1094
+
1095
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:513
1096
+ msgid "One Column"
1097
+ msgstr ""
1098
+
1099
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:514
1100
+ msgid "Two Column"
1101
+ msgstr ""
1102
+
1103
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:515
1104
+ msgid "Two Step"
1105
+ msgstr ""
1106
+
1107
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:524
1108
+ #: modules/optin/classes/class-cartflows-optin-meta.php:343
1109
+ msgid "Primary Color"
1110
+ msgstr ""
1111
+
1112
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:533
1113
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1114
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:614
1115
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:706
1116
+ #: modules/optin/classes/class-cartflows-optin-meta.php:352
1117
+ #: modules/optin/classes/class-cartflows-optin-meta.php:391
1118
+ #: modules/optin/classes/class-cartflows-optin-meta.php:503
1119
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1120
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1121
+ msgid "Font Family"
1122
+ msgstr ""
1123
+
1124
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:541
1125
+ msgid "Advance Options"
1126
+ msgstr ""
1127
+
1128
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1129
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1130
+ msgid "Heading"
1131
+ msgstr ""
1132
+
1133
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1134
+ msgid "Heading Color"
1135
+ msgstr ""
1136
+
1137
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1138
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:623
1139
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1140
+ #: modules/optin/classes/class-cartflows-optin-meta.php:400
1141
+ #: modules/optin/classes/class-cartflows-optin-meta.php:512
1142
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1143
+ msgid "Font Weight"
1144
+ msgstr ""
1145
+
1146
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1147
+ #: modules/optin/classes/class-cartflows-optin-meta.php:363
1148
+ msgid "Input Fields"
1149
+ msgstr ""
1150
+
1151
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:593
1152
+ #: modules/optin/classes/class-cartflows-optin-meta.php:370
1153
+ msgid "Floating Labels (Available in CartFlows Pro)"
1154
+ msgstr ""
1155
+
1156
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:599
1157
+ #: modules/optin/classes/class-cartflows-optin-meta.php:376
1158
+ msgid "Style"
1159
+ msgstr ""
1160
+
1161
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:604
1162
+ #: modules/optin/classes/class-cartflows-optin-meta.php:381
1163
+ msgid "Floating Labels"
1164
+ msgstr ""
1165
+
1166
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:631
1167
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1168
+ #: modules/optin/classes/class-cartflows-optin-meta.php:408
1169
+ #: modules/optin/classes/class-cartflows-optin-meta.php:520
1170
+ msgid "Size"
1171
+ msgstr ""
1172
+
1173
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:635
1174
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:727
1175
+ #: modules/optin/classes/class-cartflows-optin-meta.php:412
1176
+ #: modules/optin/classes/class-cartflows-optin-meta.php:524
1177
+ msgid "Extra Small"
1178
+ msgstr ""
1179
+
1180
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:636
1181
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:728
1182
+ #: modules/optin/classes/class-cartflows-optin-meta.php:413
1183
+ #: modules/optin/classes/class-cartflows-optin-meta.php:525
1184
+ msgid "Small"
1185
+ msgstr ""
1186
+
1187
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1188
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:729
1189
+ #: modules/optin/classes/class-cartflows-optin-meta.php:414
1190
+ #: modules/optin/classes/class-cartflows-optin-meta.php:526
1191
+ msgid "Medium"
1192
+ msgstr ""
1193
+
1194
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:638
1195
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1196
+ #: modules/optin/classes/class-cartflows-optin-meta.php:415
1197
+ #: modules/optin/classes/class-cartflows-optin-meta.php:527
1198
+ msgid "Large"
1199
+ msgstr ""
1200
+
1201
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:639
1202
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:731
1203
+ #: modules/optin/classes/class-cartflows-optin-meta.php:416
1204
+ #: modules/optin/classes/class-cartflows-optin-meta.php:528
1205
+ msgid "Extra Large"
1206
+ msgstr ""
1207
+
1208
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:640
1209
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:732
1210
+ #: modules/optin/classes/class-cartflows-optin-meta.php:417
1211
+ #: modules/optin/classes/class-cartflows-optin-meta.php:529
1212
+ msgid "Custom"
1213
+ msgstr ""
1214
+
1215
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
1216
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:739
1217
+ #: modules/optin/classes/class-cartflows-optin-meta.php:424
1218
+ #: modules/optin/classes/class-cartflows-optin-meta.php:536
1219
+ msgid "Top Bottom Spacing"
1220
+ msgstr ""
1221
+
1222
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:655
1223
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:747
1224
+ #: modules/optin/classes/class-cartflows-optin-meta.php:432
1225
+ #: modules/optin/classes/class-cartflows-optin-meta.php:544
1226
+ msgid "Left Right Spacing"
1227
+ msgstr ""
1228
+
1229
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:663
1230
+ #: modules/optin/classes/class-cartflows-optin-meta.php:448
1231
+ msgid "Text / Placeholder Color"
1232
+ msgstr ""
1233
+
1234
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:671
1235
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1236
+ #: modules/optin/classes/class-cartflows-optin-meta.php:456
1237
+ #: modules/optin/classes/class-cartflows-optin-meta.php:581
1238
+ msgid "Background Color"
1239
+ msgstr ""
1240
+
1241
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1242
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:787
1243
+ #: modules/optin/classes/class-cartflows-optin-meta.php:464
1244
+ #: modules/optin/classes/class-cartflows-optin-meta.php:597
1245
+ msgid "Border Color"
1246
+ msgstr ""
1247
+
1248
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:686
1249
+ #: modules/optin/classes/class-cartflows-optin-meta.php:440
1250
+ msgid "Label Color"
1251
+ msgstr ""
1252
+
1253
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1254
+ msgid "Buttons"
1255
+ msgstr ""
1256
+
1257
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:755
1258
+ #: modules/optin/classes/class-cartflows-optin-meta.php:565
1259
+ msgid "Text Color"
1260
+ msgstr ""
1261
+
1262
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:763
1263
+ #: modules/optin/classes/class-cartflows-optin-meta.php:573
1264
+ msgid "Text Hover Color"
1265
+ msgstr ""
1266
+
1267
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:779
1268
+ #: modules/optin/classes/class-cartflows-optin-meta.php:589
1269
+ msgid "Background Hover Color"
1270
+ msgstr ""
1271
+
1272
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:795
1273
+ #: modules/optin/classes/class-cartflows-optin-meta.php:605
1274
+ msgid "Border Hover Color"
1275
+ msgstr ""
1276
+
1277
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:808
1278
+ msgid "Sections"
1279
+ msgstr ""
1280
+
1281
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:814
1282
+ msgid "Highlight Area Background Color"
1283
+ msgstr ""
1284
+
1285
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:853
1286
+ msgid "Header Logo"
1287
+ msgstr ""
1288
+
1289
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:861
1290
+ msgid "Logo Width (In px)"
1291
+ msgstr ""
1292
+
1293
+ #: modules/checkout/templates/wcf-template.php:46
1294
+ msgid "Copyright &copy;"
1295
+ msgstr ""
1296
+
1297
+ #: modules/checkout/templates/wcf-template.php:50
1298
+ msgid "All Rights Reserved"
1299
+ msgstr ""
1300
+
1301
+ #: modules/flow/classes/class-cartflows-flow-meta.php:250
1302
+ #. translators: %s flow id
1303
+ msgid "Step not deleted for flow - %s"
1304
+ msgstr ""
1305
+
1306
+ #: modules/flow/classes/class-cartflows-flow-meta.php:281
1307
+ #. translators: %s flow id
1308
+ msgid "Step deleted for flow - %s"
1309
+ msgstr ""
1310
+
1311
+ #: modules/flow/classes/class-cartflows-flow-meta.php:309
1312
+ #. translators: %s flow id
1313
+ msgid "Steps not sorted for flow - %s"
1314
+ msgstr ""
1315
+
1316
+ #: modules/flow/classes/class-cartflows-flow-meta.php:332
1317
+ #. translators: %s flow id
1318
+ msgid "Steps sorted for flow - %s"
1319
+ msgstr ""
1320
+
1321
+ #: modules/flow/classes/class-cartflows-flow-meta.php:443
1322
+ msgid "Analytics"
1323
+ msgstr ""
1324
+
1325
+ #: modules/flow/classes/class-cartflows-flow-meta.php:460
1326
+ #. translators: %s: link
1327
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1328
+ msgstr ""
1329
+
1330
+ #: modules/flow/classes/class-cartflows-flow-meta.php:478
1331
+ msgid "Flow Settings"
1332
+ msgstr ""
1333
+
1334
+ #: modules/flow/classes/class-cartflows-flow-meta.php:563
1335
+ msgid "Enable Test Mode"
1336
+ msgstr ""
1337
+
1338
+ #: modules/flow/classes/class-cartflows-flow-meta.php:570
1339
+ msgid ""
1340
+ "If you are using WooCommerce plugin then test mode will add random products "
1341
+ "in your flow, so you can preview it easily while testing."
1342
+ msgstr ""
1343
+
1344
+ #: modules/flow/classes/class-cartflows-flow-meta.php:689
1345
+ #: modules/flow/view/meta-flow-steps.php:133
1346
+ msgid "Add New Step"
1347
+ msgstr ""
1348
+
1349
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1350
+ msgid "Flow: "
1351
+ msgstr ""
1352
+
1353
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1354
+ msgid "Name: "
1355
+ msgstr ""
1356
+
1357
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1358
+ msgid "Search Flows"
1359
+ msgstr ""
1360
+
1361
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1362
+ msgid "All Flows"
1363
+ msgstr ""
1364
+
1365
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1366
+ msgid "Edit Flow"
1367
+ msgstr ""
1368
+
1369
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1370
+ msgid "View Flow"
1371
+ msgstr ""
1372
+
1373
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1374
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1375
+ #: modules/flow/classes/class-cartflows-step-post-type.php:166
1376
+ #: modules/flow/classes/class-cartflows-step-post-type.php:168
1377
+ msgid "Add New"
1378
+ msgstr ""
1379
+
1380
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1381
+ msgid "Update Flow"
1382
+ msgstr ""
1383
+
1384
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1385
+ msgid "New Flow Name"
1386
+ msgstr ""
1387
+
1388
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1389
+ msgid "Upgrade to CartFlows Pro"
1390
+ msgstr ""
1391
+
1392
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1393
+ msgid "Slug"
1394
+ msgstr ""
1395
+
1396
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1397
+ msgid "Flows"
1398
+ msgstr ""
1399
+
1400
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1401
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1402
+ #: modules/flow/classes/class-cartflows-step-post-type.php:397
1403
+ #: modules/flow/classes/class-cartflows-step-post-type.php:403
1404
+ #. translators: %s: singular custom post type name
1405
+ msgid "%s updated."
1406
+ msgstr ""
1407
+
1408
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1409
+ #: modules/flow/classes/class-cartflows-step-post-type.php:399
1410
+ #. translators: %s: singular custom post type name
1411
+ msgid "Custom %s updated."
1412
+ msgstr ""
1413
+
1414
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1415
+ #: modules/flow/classes/class-cartflows-step-post-type.php:401
1416
+ #. translators: %s: singular custom post type name
1417
+ msgid "Custom %s deleted."
1418
+ msgstr ""
1419
+
1420
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1421
+ #: modules/flow/classes/class-cartflows-step-post-type.php:405
1422
+ #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1423
+ #. the revision
1424
+ msgid "%1$s restored to revision from %2$s"
1425
+ msgstr ""
1426
+
1427
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1428
+ #: modules/flow/classes/class-cartflows-step-post-type.php:407
1429
+ #. translators: %s: singular custom post type name
1430
+ msgid "%s published."
1431
+ msgstr ""
1432
+
1433
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1434
+ #: modules/flow/classes/class-cartflows-step-post-type.php:409
1435
+ #. translators: %s: singular custom post type name
1436
+ msgid "%s saved."
1437
+ msgstr ""
1438
+
1439
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1440
+ #: modules/flow/classes/class-cartflows-step-post-type.php:411
1441
+ #. translators: %s: singular custom post type name
1442
+ msgid "%s submitted."
1443
+ msgstr ""
1444
+
1445
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1446
+ #: modules/flow/classes/class-cartflows-step-post-type.php:413
1447
+ #. translators: %s: singular custom post type name
1448
+ msgid "%s scheduled for."
1449
+ msgstr ""
1450
+
1451
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1452
+ #: modules/flow/classes/class-cartflows-step-post-type.php:415
1453
+ #. translators: %s: singular custom post type name
1454
+ msgid "%s draft updated."
1455
+ msgstr ""
1456
+
1457
+ #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1458
+ #: modules/widgets/class-cartflows-next-step.php:78
1459
+ msgid "Next Step"
1460
+ msgstr ""
1461
+
1462
+ #: modules/flow/classes/class-cartflows-step-post-type.php:162
1463
+ msgid "Search Steps"
1464
+ msgstr ""
1465
+
1466
+ #: modules/flow/classes/class-cartflows-step-post-type.php:163
1467
+ msgid "All Steps"
1468
+ msgstr ""
1469
+
1470
+ #: modules/flow/classes/class-cartflows-step-post-type.php:164
1471
+ #: modules/flow/view/meta-flow-steps.php:106
1472
+ msgid "Edit Step"
1473
+ msgstr ""
1474
+
1475
+ #: modules/flow/classes/class-cartflows-step-post-type.php:165
1476
+ #: modules/flow/view/meta-flow-steps.php:102
1477
+ msgid "View Step"
1478
+ msgstr ""
1479
+
1480
+ #: modules/flow/classes/class-cartflows-step-post-type.php:167
1481
+ msgid "Update Step"
1482
+ msgstr ""
1483
+
1484
+ #: modules/flow/classes/class-cartflows-step-post-type.php:169
1485
+ msgid "New Step Name"
1486
+ msgstr ""
1487
+
1488
+ #: modules/flow/classes/class-cartflows-step-post-type.php:209
1489
+ msgid "Step Type"
1490
+ msgstr ""
1491
+
1492
+ #: modules/flow/classes/class-cartflows-step-post-type.php:219
1493
+ msgid "Step Flow"
1494
+ msgstr ""
1495
+
1496
+ #: modules/flow/classes/class-cartflows-step-post-type.php:244
1497
+ #: modules/flow/view/meta-flow-steps.php:16
1498
+ msgid "Optin (Woo)"
1499
+ msgstr ""
1500
+
1501
+ #: modules/flow/classes/class-cartflows-step-post-type.php:265
1502
+ #: modules/flow/view/meta-flow-steps.php:14
1503
+ msgid "Upsell (Woo)"
1504
+ msgstr ""
1505
+
1506
+ #: modules/flow/classes/class-cartflows-step-post-type.php:272
1507
+ #: modules/flow/view/meta-flow-steps.php:15
1508
+ msgid "Downsell (Woo)"
1509
+ msgstr ""
1510
+
1511
+ #: modules/flow/view/meta-flow-steps.php:85
1512
+ msgid "No Product Assigned"
1513
+ msgstr ""
1514
+
1515
+ #: modules/flow/view/meta-flow-steps.php:89
1516
+ msgid "Global Checkout - Remove selected checkout product"
1517
+ msgstr ""
1518
+
1519
+ #: modules/flow/view/meta-flow-steps.php:108
1520
+ msgid "Edit"
1521
+ msgstr ""
1522
+
1523
+ #: modules/flow/view/meta-flow-steps.php:113
1524
+ msgid "Clone Step"
1525
+ msgstr ""
1526
+
1527
+ #: modules/flow/view/meta-flow-steps.php:118
1528
+ msgid "Delete Step"
1529
+ msgstr ""
1530
+
1531
+ #: modules/flow/view/meta-flow-steps.php:120
1532
+ msgid "Delete"
1533
+ msgstr ""
1534
+
1535
+ #: modules/flow/view/meta-flow-steps.php:149
1536
+ msgid "Steps Library"
1537
+ msgstr ""
1538
+
1539
+ #: modules/flow/view/meta-flow-steps.php:198
1540
+ msgid "Create Step"
1541
+ msgstr ""
1542
+
1543
+ #: modules/flow/view/meta-flow-steps.php:200
1544
+ msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1545
+ msgstr ""
1546
+
1547
+ #: modules/landing/classes/class-cartflows-landing-meta.php:66
1548
+ msgid "Landing Page Settings"
1549
+ msgstr ""
1550
+
1551
+ #: modules/landing/classes/class-cartflows-landing-meta.php:169
1552
+ msgid "Next Step Link"
1553
+ msgstr ""
1554
+
1555
+ #: modules/optin/classes/class-cartflows-optin-markup.php:165
1556
+ msgid "Please place shortcode on Optin step-type only."
1557
+ msgstr ""
1558
+
1559
+ #: modules/optin/classes/class-cartflows-optin-markup.php:225
1560
+ msgid ""
1561
+ "No product is selected. Please select a Simple, Virtual and Free product "
1562
+ "from the meta settings."
1563
+ msgstr ""
1564
+
1565
+ #: modules/optin/classes/class-cartflows-optin-markup.php:242
1566
+ msgid "Please update the selected product's price to zero (0)."
1567
+ msgstr ""
1568
+
1569
+ #: modules/optin/classes/class-cartflows-optin-markup.php:251
1570
+ #: modules/optin/classes/class-cartflows-optin-markup.php:255
1571
+ msgid "Please select a Simple, Virtual and Free product."
1572
+ msgstr ""
1573
+
1574
+ #: modules/optin/classes/class-cartflows-optin-meta.php:65
1575
+ msgid "Optin Settings"
1576
+ msgstr ""
1577
+
1578
+ #: modules/optin/classes/class-cartflows-optin-meta.php:138
1579
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1580
+ msgid "Design"
1581
+ msgstr ""
1582
+
1583
+ #: modules/optin/classes/class-cartflows-optin-meta.php:144
1584
+ msgid "Form Fields"
1585
+ msgstr ""
1586
+
1587
+ #: modules/optin/classes/class-cartflows-optin-meta.php:213
1588
+ msgid "Add this shortcode to your optin page"
1589
+ msgstr ""
1590
+
1591
+ #: modules/optin/classes/class-cartflows-optin-meta.php:238
1592
+ msgid "Select Free Product"
1593
+ msgstr ""
1594
+
1595
+ #: modules/optin/classes/class-cartflows-optin-meta.php:239
1596
+ msgid "Select Free and Virtual product only."
1597
+ msgstr ""
1598
+
1599
+ #: modules/optin/classes/class-cartflows-optin-meta.php:290
1600
+ msgid "Pass Fields as URL Parameters"
1601
+ msgstr ""
1602
+
1603
+ #: modules/optin/classes/class-cartflows-optin-meta.php:293
1604
+ msgid "Enable"
1605
+ msgstr ""
1606
+
1607
+ #: modules/optin/classes/class-cartflows-optin-meta.php:294
1608
+ msgid ""
1609
+ "You can pass specific fields from the form to next step as URL query "
1610
+ "parameters."
1611
+ msgstr ""
1612
+
1613
+ #: modules/optin/classes/class-cartflows-optin-meta.php:305
1614
+ msgid "Enter form field"
1615
+ msgstr ""
1616
+
1617
+ #: modules/optin/classes/class-cartflows-optin-meta.php:308
1618
+ #: modules/optin/classes/class-cartflows-optin-meta.php:318
1619
+ msgid "Enter comma seprated field name. E.g. first_name, last_name"
1620
+ msgstr ""
1621
+
1622
+ #: modules/optin/classes/class-cartflows-optin-meta.php:310
1623
+ msgid "Fields to pass, separated by commas"
1624
+ msgstr ""
1625
+
1626
+ #: modules/optin/classes/class-cartflows-optin-meta.php:320
1627
+ #. translators: %s: link
1628
+ msgid ""
1629
+ "You can pass field value as a URL parameter to the next step. %1$sClick "
1630
+ "here%2$s for more information."
1631
+ msgstr ""
1632
+
1633
+ #: modules/optin/classes/class-cartflows-optin-meta.php:477
1634
+ msgid "Submit Button"
1635
+ msgstr ""
1636
+
1637
+ #: modules/optin/classes/class-cartflows-optin-meta.php:483
1638
+ msgid "Button Text"
1639
+ msgstr ""
1640
+
1641
+ #: modules/optin/classes/class-cartflows-optin-meta.php:494
1642
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1643
+ msgid "Font Size"
1644
+ msgstr ""
1645
+
1646
+ #: modules/optin/classes/class-cartflows-optin-meta.php:552
1647
+ msgid "Position"
1648
+ msgstr ""
1649
+
1650
+ #: modules/optin/classes/class-cartflows-optin-meta.php:556
1651
+ msgid "Left"
1652
+ msgstr ""
1653
+
1654
+ #: modules/optin/classes/class-cartflows-optin-meta.php:557
1655
+ msgid "Center"
1656
+ msgstr ""
1657
+
1658
+ #: modules/optin/classes/class-cartflows-optin-meta.php:558
1659
+ msgid "Right"
1660
+ msgstr ""
1661
+
1662
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1663
+ msgid "Thank You Page Settings"
1664
+ msgstr ""
1665
+
1666
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1667
+ msgid "Edit Fields"
1668
+ msgstr ""
1669
+
1670
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1671
+ msgid "Order Details"
1672
+ msgstr ""
1673
+
1674
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1675
+ msgid "Text"
1676
+ msgstr ""
1677
+
1678
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1679
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1680
+ msgid "Color"
1681
+ msgstr ""
1682
+
1683
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1684
+ msgid "Advanced Options"
1685
+ msgstr ""
1686
+
1687
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1688
+ msgid "Container Width (In px)"
1689
+ msgstr ""
1690
+
1691
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1692
+ msgid "Section Background Color"
1693
+ msgstr ""
1694
+
1695
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1696
+ msgid "Enable Order Overview "
1697
+ msgstr ""
1698
+
1699
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1700
+ msgid "Enable Order Details "
1701
+ msgstr ""
1702
+
1703
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1704
+ msgid "Enable Billing Details "
1705
+ msgstr ""
1706
+
1707
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1708
+ msgid "Enable Shipping Details "
1709
+ msgstr ""
1710
+
1711
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1712
+ msgid "Thank You Page Text"
1713
+ msgstr ""
1714
+
1715
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1716
+ #: woocommerce/template/checkout/thankyou.php:41
1717
+ #: woocommerce/template/checkout/thankyou.php:83
1718
+ msgid "Thank you. Your order has been received."
1719
+ msgstr ""
1720
+
1721
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1722
+ msgid "It will change the default text on thank you page."
1723
+ msgstr ""
1724
+
1725
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1726
+ msgid "Redirect After Purchase"
1727
+ msgstr ""
1728
+
1729
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1730
+ msgid "Redirect Link"
1731
+ msgstr ""
1732
+
1733
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1734
+ msgid "https://"
1735
+ msgstr ""
1736
+
1737
+ #: modules/widgets/class-cartflows-next-step.php:24
1738
+ msgid "CartFlows Next Step"
1739
+ msgstr ""
1740
+
1741
+ #: modules/widgets/class-cartflows-next-step.php:26
1742
+ msgid "Next Step Widgets"
1743
+ msgstr ""
1744
+
1745
+ #: modules/widgets/class-cartflows-next-step.php:106
1746
+ msgid "New title"
1747
+ msgstr ""
1748
+
1749
+ #: modules/widgets/class-cartflows-next-step.php:123
1750
+ msgid "Title:"
1751
+ msgstr ""
1752
+
1753
+ #: modules/widgets/class-cartflows-next-step.php:127
1754
+ msgid "Flow ID:"
1755
+ msgstr ""
1756
+
1757
+ #: modules/widgets/class-cartflows-next-step.php:131
1758
+ msgid "Step ID:"
1759
+ msgstr ""
1760
+
1761
+ #: woocommerce/template/cart/cart-shipping.php:51
1762
+ #. Translators: $s shipping destination.
1763
+ msgid "Estimate for %s."
1764
+ msgstr ""
1765
+
1766
+ #: woocommerce/template/cart/cart-shipping.php:52
1767
+ msgid "Change address"
1768
+ msgstr ""
1769
+
1770
+ #: woocommerce/template/cart/cart-shipping.php:54
1771
+ msgid "This is only an estimate. Prices will be updated during checkout."
1772
+ msgstr ""
1773
+
1774
+ #: woocommerce/template/cart/cart-shipping.php:61
1775
+ msgid "Enter your address to view shipping options."
1776
+ msgstr ""
1777
+
1778
+ #: woocommerce/template/cart/cart-shipping.php:63
1779
+ msgid ""
1780
+ "There are no shipping methods available. Please ensure that your address "
1781
+ "has been entered correctly, or contact us if you need any help."
1782
+ msgstr ""
1783
+
1784
+ #: woocommerce/template/cart/cart-shipping.php:66
1785
+ #. Translators: $s shipping destination.
1786
+ msgid "No shipping options were found for %s."
1787
+ msgstr ""
1788
+
1789
+ #: woocommerce/template/cart/cart-shipping.php:67
1790
+ msgid "Enter a different address"
1791
+ msgstr ""
1792
+
1793
+ #: woocommerce/template/checkout/form-billing.php:27
1794
+ msgid "Billing &amp; Shipping"
1795
+ msgstr ""
1796
+
1797
+ #: woocommerce/template/checkout/form-billing.php:31
1798
+ msgid "Billing details"
1799
+ msgstr ""
1800
+
1801
+ #: woocommerce/template/checkout/form-billing.php:59
1802
+ msgid "Create an account?"
1803
+ msgstr ""
1804
+
1805
+ #: woocommerce/template/checkout/form-checkout.php:26
1806
+ msgid "You must be logged in to checkout."
1807
+ msgstr ""
1808
+
1809
+ #: woocommerce/template/checkout/form-checkout.php:52
1810
+ msgid "Your order"
1811
+ msgstr ""
1812
+
1813
+ #: woocommerce/template/checkout/form-coupon.php:26
1814
+ msgid "Have a coupon?"
1815
+ msgstr ""
1816
+
1817
+ #: woocommerce/template/checkout/form-coupon.php:26
1818
+ msgid "Click here to enter your code"
1819
+ msgstr ""
1820
+
1821
+ #: woocommerce/template/checkout/form-coupon.php:31
1822
+ msgid "If you have a coupon code, please apply it below."
1823
+ msgstr ""
1824
+
1825
+ #: woocommerce/template/checkout/form-coupon.php:34
1826
+ msgid "Coupon code"
1827
+ msgstr ""
1828
+
1829
+ #: woocommerce/template/checkout/form-coupon.php:38
1830
+ msgid "Apply coupon"
1831
+ msgstr ""
1832
+
1833
+ #: woocommerce/template/checkout/form-login.php:26
1834
+ msgid "Returning customer?"
1835
+ msgstr ""
1836
+
1837
+ #: woocommerce/template/checkout/form-login.php:26
1838
+ msgid "Click here to login"
1839
+ msgstr ""
1840
+
1841
+ #: woocommerce/template/checkout/form-login.php:32
1842
+ msgid ""
1843
+ "If you have shopped with us before, please enter your details below. If you "
1844
+ "are a new customer, please proceed to the Billing &amp; Shipping section."
1845
+ msgstr ""
1846
+
1847
+ #: woocommerce/template/checkout/form-shipping.php:26
1848
+ msgid "Ship to a different address?"
1849
+ msgstr ""
1850
+
1851
+ #: woocommerce/template/checkout/form-shipping.php:57
1852
+ msgid "Additional information"
1853
+ msgstr ""
1854
+
1855
+ #: woocommerce/template/checkout/payment.php:33
1856
+ msgid ""
1857
+ "Sorry, it seems that there are no available payment methods for your state. "
1858
+ "Please contact us if you require assistance or wish to make alternate "
1859
+ "arrangements."
1860
+ msgstr ""
1861
+
1862
+ #: woocommerce/template/checkout/payment.php:33
1863
+ msgid "Please fill in your details above to see available payment methods."
1864
+ msgstr ""
1865
+
1866
+ #: woocommerce/template/checkout/payment.php:42
1867
+ #. translators: $1 and $2 opening and closing emphasis tags respectively
1868
+ msgid ""
1869
+ "Since your browser does not support JavaScript, or it is disabled, please "
1870
+ "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1871
+ "order. You may be charged more than the amount stated above if you fail to "
1872
+ "do so."
1873
+ msgstr ""
1874
+
1875
+ #: woocommerce/template/checkout/payment.php:44
1876
+ msgid "Update totals"
1877
+ msgstr ""
1878
+
1879
+ #: woocommerce/template/checkout/review-order.php:26
1880
+ msgid "Product"
1881
+ msgstr ""
1882
+
1883
+ #: woocommerce/template/checkout/review-order.php:27
1884
+ #: woocommerce/template/checkout/review-order.php:107
1885
+ msgid "Total"
1886
+ msgstr ""
1887
+
1888
+ #: woocommerce/template/checkout/review-order.php:60
1889
+ msgid "Subtotal"
1890
+ msgstr ""
1891
+
1892
+ #: woocommerce/template/checkout/thankyou.php:30
1893
+ msgid ""
1894
+ "Unfortunately your order cannot be processed as the originating "
1895
+ "bank/merchant has declined your transaction. Please attempt your purchase "
1896
+ "again."
1897
+ msgstr ""
1898
+
1899
+ #: woocommerce/template/checkout/thankyou.php:33
1900
+ msgid "Pay"
1901
+ msgstr ""
1902
+
1903
+ #: woocommerce/template/checkout/thankyou.php:35
1904
+ msgid "My account"
1905
+ msgstr ""
1906
+
1907
+ #: woocommerce/template/checkout/thankyou.php:46
1908
+ msgid "Order number:"
1909
+ msgstr ""
1910
+
1911
+ #: woocommerce/template/checkout/thankyou.php:51
1912
+ msgid "Date:"
1913
+ msgstr ""
1914
+
1915
+ #: woocommerce/template/checkout/thankyou.php:57
1916
+ msgid "Email:"
1917
+ msgstr ""
1918
+
1919
+ #: woocommerce/template/checkout/thankyou.php:63
1920
+ msgid "Total:"
1921
+ msgstr ""
1922
+
1923
+ #: woocommerce/template/checkout/thankyou.php:69
1924
+ msgid "Payment method:"
1925
+ msgstr ""
1926
+
1927
+ #: woocommerce/template/global/form-login.php:34
1928
+ msgid "Username or email"
1929
+ msgstr ""
1930
+
1931
+ #: woocommerce/template/global/form-login.php:38
1932
+ msgid "Password"
1933
+ msgstr ""
1934
+
1935
+ #: woocommerce/template/global/form-login.php:48
1936
+ msgid "Login"
1937
+ msgstr ""
1938
+
1939
+ #: woocommerce/template/global/form-login.php:53
1940
+ msgid "Remember me"
1941
+ msgstr ""
1942
+
1943
+ #: woocommerce/template/global/form-login.php:57
1944
+ msgid "Lost your password?"
1945
+ msgstr ""
1946
+
1947
+ #. Plugin Name of the plugin/theme
1948
+ msgid "CartFlows"
1949
+ msgstr ""
1950
+
1951
+ #. Author URI of the plugin/theme
1952
+ msgid "https://cartflows.com/"
1953
+ msgstr ""
1954
+
1955
+ #. Description of the plugin/theme
1956
+ msgid "Create beautiful checkout pages & sales flows for WooCommerce."
1957
+ msgstr ""
1958
+
1959
+ #. Author of the plugin/theme
1960
+ msgid "CartFlows Inc"
1961
+ msgstr ""
1962
+
1963
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:99
1964
+ msgctxt "flow general name"
1965
+ msgid "Flows"
1966
+ msgstr ""
1967
+
1968
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:100
1969
+ msgctxt "flow singular name"
1970
+ msgid "Flow"
1971
+ msgstr ""
1972
+
1973
+ #: modules/flow/classes/class-cartflows-step-post-type.php:160
1974
+ msgctxt "flow step general name"
1975
+ msgid "Steps"
1976
+ msgstr ""
1977
+
1978
+ #: modules/flow/classes/class-cartflows-step-post-type.php:161
1979
+ msgctxt "flow step singular name"
1980
+ msgid "Step"
1981
+ msgstr ""
1982
+
1983
+ #: modules/flow/classes/class-cartflows-step-post-type.php:313
1984
+ msgctxt "cartflows"
1985
+ msgid "CartFlows — Boxed"
1986
+ msgstr ""
1987
+
1988
+ #: modules/flow/classes/class-cartflows-step-post-type.php:314
1989
+ msgctxt "cartflows"
1990
+ msgid "Template for Page Builders"
1991
  msgstr ""
modules/flow/classes/class-cartflows-flow-meta.php CHANGED
@@ -1,700 +1,700 @@
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
- * Initiator
30
- */
31
- public static function get_instance() {
32
- if ( ! isset( self::$instance ) ) {
33
- self::$instance = new self();
34
- }
35
-
36
- return self::$instance;
37
- }
38
-
39
- /**
40
- * Constructor
41
- */
42
- public function __construct() {
43
-
44
- add_action( 'admin_head', array( $this, 'menu_highlight' ) );
45
-
46
- add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
47
-
48
- /* Init Metabox */
49
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
50
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
51
-
52
- /* Add Scripts */
53
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
54
-
55
- add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
56
- add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
57
-
58
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
59
-
60
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
61
- }
62
-
63
- /**
64
- * Display admin notices.
65
- *
66
- * @since 1.0.0
67
- *
68
- * @return void
69
- */
70
- public function admin_notices() {
71
-
72
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
73
- return;
74
- }
75
-
76
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
77
- if ( $flow_id ) { ?>
78
- <div class="wcf-notice-back-edit-flow">
79
- <p>
80
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero" style="text-decoration: none;">
81
- <i class="dashicons dashicons-arrow-left-alt"></i>
82
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
83
- </a>
84
- </p>
85
- </div>
86
- <?php
87
- }
88
- }
89
-
90
- /**
91
- * Initialize admin actions.
92
- *
93
- * @since 1.0.0
94
- *
95
- * @return void
96
- */
97
- public function admin_init_actions() {
98
- add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
99
- add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
100
- add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
101
- }
102
-
103
- /**
104
- * Delete term data and steps data after deleting flow.
105
- *
106
- * @since 1.0.0
107
- * @param int $pid post id.
108
- *
109
- * @return void
110
- */
111
- public function step_post_sync( $pid ) {
112
-
113
- global $post_type;
114
-
115
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
116
-
117
- $steps = get_post_meta( $pid, 'wcf-steps', true );
118
-
119
- if ( $steps && is_array( $steps ) ) {
120
- foreach ( $steps as $i => $step ) {
121
- wp_delete_post( $step['id'], true );
122
- }
123
- }
124
-
125
- $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
126
-
127
- if ( is_array( $term_data ) ) {
128
- wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
129
- }
130
- }
131
- }
132
-
133
- /**
134
- * Trash steps data after trashing flow.
135
- *
136
- * @since 1.0.0
137
- * @param int $pid post id.
138
- *
139
- * @return void
140
- */
141
- public function step_post_trash_sync( $pid ) {
142
-
143
- global $post_type;
144
-
145
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
146
-
147
- $steps = get_post_meta( $pid, 'wcf-steps', true );
148
-
149
- if ( $steps && is_array( $steps ) ) {
150
- foreach ( $steps as $i => $step ) {
151
- wp_trash_post( $step['id'] );
152
- }
153
- }
154
- }
155
- }
156
-
157
- /**
158
- * Untrash steps data after restoring flow.
159
- *
160
- * @since 1.0.0
161
- * @param int $pid post id.
162
- *
163
- * @return void
164
- */
165
- public function step_post_untrash_sync( $pid ) {
166
-
167
- global $post_type;
168
-
169
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
170
-
171
- $steps = get_post_meta( $pid, 'wcf-steps', true );
172
-
173
- if ( $steps && is_array( $steps ) ) {
174
- foreach ( $steps as $i => $step ) {
175
- wp_untrash_post( $step['id'] );
176
- }
177
- }
178
- }
179
- }
180
-
181
- /**
182
- * Create step for given flow.
183
- *
184
- * @param int $flow_id flow ID.
185
- * @param int $step_type step type.
186
- * @param int $step_title step title.
187
- * @since 1.0.0
188
- *
189
- * @return int
190
- */
191
- public function create_step( $flow_id, $step_type, $step_title ) {
192
-
193
- $new_step_id = wp_insert_post(
194
- array(
195
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
196
- 'post_title' => $step_title,
197
- 'post_status' => 'publish',
198
- )
199
- );
200
-
201
- if ( $new_step_id ) {
202
-
203
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
204
-
205
- if ( ! is_array( $flow_steps ) ) {
206
- $flow_steps = array();
207
- }
208
-
209
- $flow_steps[] = array(
210
- 'id' => $new_step_id,
211
- 'title' => $step_title,
212
- 'type' => $step_type,
213
- );
214
-
215
- // insert post meta.
216
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
217
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
218
-
219
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
220
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
221
- }
222
-
223
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
224
-
225
- return $new_step_id;
226
- }
227
-
228
- /**
229
- * Delete step for flow
230
- *
231
- * @since 1.0.0
232
- *
233
- * @return void
234
- */
235
- public function cartflows_delete_flow_step() {
236
-
237
- if ( ! current_user_can( 'manage_options' ) ) {
238
- return;
239
- }
240
-
241
- check_ajax_referer( 'wcf-delete-flow-step', 'security' );
242
-
243
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
244
- $flow_id = intval( $_POST['post_id'] );
245
- $step_id = intval( $_POST['step_id'] );
246
- }
247
- $result = array(
248
- 'status' => false,
249
- /* translators: %s flow id */
250
- 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
251
- );
252
-
253
- if ( ! $flow_id || ! $step_id ) {
254
- wp_send_json( $result );
255
- }
256
-
257
- wp_delete_post( $step_id, true );
258
-
259
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
260
-
261
- if ( ! is_array( $flow_steps ) ) {
262
- wp_send_json( $result );
263
- }
264
-
265
- foreach ( $flow_steps as $index => $data ) {
266
-
267
- if ( intval( $data['id'] ) === $step_id ) {
268
- unset( $flow_steps[ $index ] );
269
- break;
270
- }
271
- }
272
-
273
- /* Set index order properly */
274
- $flow_steps = array_merge( $flow_steps );
275
-
276
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
277
-
278
- $result = array(
279
- 'status' => true,
280
- /* translators: %s flow id */
281
- 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
282
- );
283
-
284
- wp_send_json( $result );
285
- }
286
-
287
- /**
288
- * Reorder step flow
289
- *
290
- * @since 1.0.0
291
- *
292
- * @return void
293
- */
294
- public function cartflows_reorder_flow_steps() {
295
-
296
- if ( ! current_user_can( 'manage_options' ) ) {
297
- return;
298
- }
299
-
300
- check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
301
-
302
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
303
- $flow_id = intval( $_POST['post_id'] );
304
- $step_ids = array_map( 'intval', $_POST['step_ids'] );
305
- }
306
- $result = array(
307
- 'status' => false,
308
- /* translators: %s flow id */
309
- 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
310
- );
311
-
312
- if ( ! $flow_id || ! is_array( $step_ids ) ) {
313
- wp_send_json( $result );
314
- }
315
-
316
- $new_flow_steps = array();
317
-
318
- foreach ( $step_ids as $index => $step_id ) {
319
-
320
- $new_flow_steps[] = array(
321
- 'id' => intval( $step_id ),
322
- 'title' => get_the_title( $step_id ),
323
- 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
324
- );
325
- }
326
-
327
- update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
328
-
329
- $result = array(
330
- 'status' => true,
331
- /* translators: %s flow id */
332
- 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
333
- );
334
-
335
- wp_send_json( $result );
336
- }
337
-
338
-
339
- /**
340
- * Load admin scripts
341
- *
342
- * @since 1.0.0
343
- *
344
- * @return void
345
- */
346
- public function admin_scripts() {
347
-
348
- global $pagenow;
349
- global $post;
350
-
351
- $screen = get_current_screen();
352
-
353
- if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
354
-
355
- wp_enqueue_script(
356
- 'wcf-flow-meta',
357
- CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
358
- array( 'jquery', 'jquery-ui-sortable' ),
359
- CARTFLOWS_VER,
360
- true
361
- );
362
-
363
- wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
364
- wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
365
-
366
- $localize = array(
367
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
368
- );
369
-
370
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
371
- }
372
- }
373
-
374
- /**
375
- * Initialize meta box
376
- *
377
- * @since 1.0.0
378
- *
379
- * @return void
380
- */
381
- public function init_metabox() {
382
-
383
- /**
384
- * Fires after the title field.
385
- *
386
- * @param WP_Post $post Post object.
387
- */
388
- add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
389
- add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
390
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
391
- }
392
-
393
- /**
394
- * Is first time import?
395
- *
396
- * @param integer $post_id post ID.
397
- * @return bool
398
- */
399
- public function is_flow_imported( $post_id = 0 ) {
400
-
401
- if ( 0 === $post_id ) {
402
- $post_id = get_the_ID();
403
- }
404
-
405
- $steps = get_post_meta( $post_id, 'wcf-steps', true );
406
- $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
407
-
408
- if ( empty( $steps ) && 'import' === $choice ) {
409
- return true;
410
- }
411
-
412
- return false;
413
- }
414
-
415
- /**
416
- * Setup meta box.
417
- *
418
- * @return void
419
- */
420
- public function setup_meta_box() {
421
- if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
422
- return;
423
- }
424
-
425
- /**
426
- * Adding Add new step button to the top*/
427
- echo $this->add_add_new_step_button();
428
-
429
- $this->markup_meta_box();
430
-
431
- $this->add_upgrade_to_pro_metabox();
432
- }
433
-
434
-
435
- /**
436
- * Add metabox when cartflows pro is not enabled.
437
- */
438
- public function add_upgrade_to_pro_metabox() {
439
-
440
- if ( ! _is_cartflows_pro() ) {
441
- add_meta_box(
442
- 'wcf-upgrade-pro',
443
- __( 'Analytics', 'cartflows' ),
444
- array( $this, 'upgrade_to_pro' ),
445
- CARTFLOWS_FLOW_POST_TYPE,
446
- 'side',
447
- 'high'
448
- );
449
- }
450
-
451
- }
452
-
453
- /**
454
- * Show Upgrade To Pro markup.
455
- */
456
- public function upgrade_to_pro() {
457
-
458
- echo '<div>';
459
- /* translators: %s: link */
460
- 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>';
461
- echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
462
- echo '</div>';
463
-
464
- }
465
-
466
- /**
467
- * Settings meta box.
468
- *
469
- * @return void
470
- */
471
- public function settings_meta_box() {
472
-
473
- if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
474
-
475
- /* No need of sandbox will delete it later */
476
- add_meta_box(
477
- 'wcf-sandbox-settings', // Id.
478
- __( 'Flow Settings', 'cartflows' ), // Title.
479
- array( $this, 'sandbox_meta_box' ), // Callback.
480
- CARTFLOWS_FLOW_POST_TYPE, // Post_type.
481
- 'side', // Context.
482
- 'high' // Priority.
483
- );
484
-
485
- do_action( 'cartflows_add_flow_metabox' );
486
- }
487
- }
488
-
489
- /**
490
- * Metabox Markup
491
- *
492
- * @return void
493
- */
494
- public function markup_meta_box() {
495
- global $post;
496
-
497
- wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
498
-
499
- // Get defaults.
500
- $meta = self::get_current_post_meta( $post->ID );
501
-
502
- /**
503
- * Get options
504
- */
505
- $updated_data = array(
506
- 'steps' => $meta['wcf-steps']['default'],
507
- );
508
-
509
- do_action( 'wcf_flow_settings_markup_before', $meta );
510
- $this->page_header_tab( $updated_data );
511
- do_action( 'wcf_flow_settings_markup_after', $meta );
512
- }
513
-
514
- /**
515
- * Metabox Markup
516
- *
517
- * @param object $post Post object.
518
- * @return void
519
- */
520
- public function sandbox_meta_box( $post ) {
521
-
522
- // Get defaults.
523
- $meta = self::get_current_post_meta( $post->ID );
524
-
525
- /**
526
- * Get options
527
- */
528
- foreach ( $meta as $key => $value ) {
529
- $updated_data[ $key ] = $meta[ $key ]['default'];
530
- }
531
-
532
- do_action( 'wcf_flow_sandbox_markup_before', $meta );
533
- $this->sandbox_markup( $updated_data );
534
- do_action( 'wcf_flow_sandbox_markup_after', $meta );
535
- }
536
-
537
- /**
538
- * Page Header Tabs
539
- *
540
- * @param array $options Post meta.
541
- * @return void
542
- */
543
- public function page_header_tab( $options ) {
544
-
545
- include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
546
- }
547
-
548
- /**
549
- * Sandbox Markup
550
- *
551
- * @param array $options Post meta.
552
- * @return void
553
- */
554
- public function sandbox_markup( $options ) {
555
- ?>
556
- <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
557
- <div class="wcf-flow-sandbox-table-container">
558
- <?php
559
- echo wcf()->meta->get_checkbox_field(
560
- array(
561
- 'name' => 'wcf-testing',
562
- 'value' => $options['wcf-testing'],
563
- 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
564
- )
565
- );
566
-
567
- echo wcf()->meta->get_description_field(
568
- array(
569
- 'name' => 'wcf-testing-note',
570
- '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' ),
571
- )
572
- );
573
-
574
- ?>
575
- </div>
576
- </div>
577
- <?php
578
- }
579
-
580
- /**
581
- * Keep the menu open when editing the flows.
582
- * Highlights the wanted admin (sub-) menu items for the CPT.
583
- *
584
- * @since 1.0.0
585
- */
586
- public function menu_highlight() {
587
- global $parent_file, $submenu_file, $post_type;
588
- if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
589
- $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
590
- $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
591
- endif;
592
- }
593
-
594
- /**
595
- * Get metabox options
596
- *
597
- * @param int $post_id post id.
598
- * @return array
599
- */
600
- public static function get_meta_option( $post_id ) {
601
-
602
- if ( null === self::$meta_option ) {
603
- /**
604
- * Set metabox options
605
- */
606
- self::$meta_option = wcf()->options->get_flow_fields( $post_id );
607
- }
608
-
609
- return self::$meta_option;
610
- }
611
-
612
- /**
613
- * Get metabox options
614
- *
615
- * @param int $post_id post ID.
616
- * @return array
617
- */
618
- public static function get_current_post_meta( $post_id ) {
619
-
620
- $stored = get_post_meta( $post_id );
621
-
622
- $default_meta = self::get_meta_option( $post_id );
623
-
624
- // Set stored and override defaults.
625
- foreach ( $stored as $key => $value ) {
626
- if ( array_key_exists( $key, $default_meta ) ) {
627
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
628
- } else {
629
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
630
- }
631
- }
632
-
633
- return self::get_meta_option( $post_id );
634
- }
635
-
636
- /**
637
- * Metabox Save
638
- *
639
- * @param number $post_id Post ID.
640
- * @return void
641
- */
642
- public function save_meta_box( $post_id ) {
643
-
644
- // Checks save status.
645
- $is_autosave = wp_is_post_autosave( $post_id );
646
- $is_revision = wp_is_post_revision( $post_id );
647
-
648
- $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;
649
-
650
- // Exits script depending on save status.
651
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
652
- return;
653
- }
654
-
655
- wcf()->options->save_flow_fields( $post_id );
656
- }
657
-
658
- /**
659
- * Localize variables in admin
660
- *
661
- * @param array $vars variables.
662
- */
663
- public function localize_vars( $vars ) {
664
-
665
- $ajax_actions = array(
666
- 'wcf_setup_default_steps',
667
- 'wcf_add_flow_step',
668
- 'wcf_delete_flow_step',
669
- 'wcf_reorder_flow_steps',
670
- );
671
-
672
- foreach ( $ajax_actions as $action ) {
673
-
674
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
675
- }
676
-
677
- return $vars;
678
- }
679
-
680
- /**
681
- * Add New Step Button
682
- *
683
- * @return string
684
- */
685
- public function add_add_new_step_button() {
686
- $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
687
- $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
688
- $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
689
- $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
690
- $add_new_btn_markup .= '</button>';
691
- $add_new_btn_markup .= '</div>';
692
-
693
- return $add_new_btn_markup;
694
- }
695
- }
696
-
697
- /**
698
- * Kicking this off by calling 'get_instance()' method
699
- */
700
- 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
+ * Initiator
30
+ */
31
+ public static function get_instance() {
32
+ if ( ! isset( self::$instance ) ) {
33
+ self::$instance = new self();
34
+ }
35
+
36
+ return self::$instance;
37
+ }
38
+
39
+ /**
40
+ * Constructor
41
+ */
42
+ public function __construct() {
43
+
44
+ add_action( 'admin_head', array( $this, 'menu_highlight' ) );
45
+
46
+ add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
47
+
48
+ /* Init Metabox */
49
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
50
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
51
+
52
+ /* Add Scripts */
53
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
54
+
55
+ add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
56
+ add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
57
+
58
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
59
+
60
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
61
+ }
62
+
63
+ /**
64
+ * Display admin notices.
65
+ *
66
+ * @since 1.0.0
67
+ *
68
+ * @return void
69
+ */
70
+ public function admin_notices() {
71
+
72
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
73
+ return;
74
+ }
75
+
76
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
77
+ if ( $flow_id ) { ?>
78
+ <div class="wcf-notice-back-edit-flow">
79
+ <p>
80
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero" style="text-decoration: none;">
81
+ <i class="dashicons dashicons-arrow-left-alt"></i>
82
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
83
+ </a>
84
+ </p>
85
+ </div>
86
+ <?php
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Initialize admin actions.
92
+ *
93
+ * @since 1.0.0
94
+ *
95
+ * @return void
96
+ */
97
+ public function admin_init_actions() {
98
+ add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
99
+ add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
100
+ add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
101
+ }
102
+
103
+ /**
104
+ * Delete term data and steps data after deleting flow.
105
+ *
106
+ * @since 1.0.0
107
+ * @param int $pid post id.
108
+ *
109
+ * @return void
110
+ */
111
+ public function step_post_sync( $pid ) {
112
+
113
+ global $post_type;
114
+
115
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
116
+
117
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
118
+
119
+ if ( $steps && is_array( $steps ) ) {
120
+ foreach ( $steps as $i => $step ) {
121
+ wp_delete_post( $step['id'], true );
122
+ }
123
+ }
124
+
125
+ $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
126
+
127
+ if ( is_array( $term_data ) ) {
128
+ wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
129
+ }
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Trash steps data after trashing flow.
135
+ *
136
+ * @since 1.0.0
137
+ * @param int $pid post id.
138
+ *
139
+ * @return void
140
+ */
141
+ public function step_post_trash_sync( $pid ) {
142
+
143
+ global $post_type;
144
+
145
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
146
+
147
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
148
+
149
+ if ( $steps && is_array( $steps ) ) {
150
+ foreach ( $steps as $i => $step ) {
151
+ wp_trash_post( $step['id'] );
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Untrash steps data after restoring flow.
159
+ *
160
+ * @since 1.0.0
161
+ * @param int $pid post id.
162
+ *
163
+ * @return void
164
+ */
165
+ public function step_post_untrash_sync( $pid ) {
166
+
167
+ global $post_type;
168
+
169
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
170
+
171
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
172
+
173
+ if ( $steps && is_array( $steps ) ) {
174
+ foreach ( $steps as $i => $step ) {
175
+ wp_untrash_post( $step['id'] );
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Create step for given flow.
183
+ *
184
+ * @param int $flow_id flow ID.
185
+ * @param int $step_type step type.
186
+ * @param int $step_title step title.
187
+ * @since 1.0.0
188
+ *
189
+ * @return int
190
+ */
191
+ public function create_step( $flow_id, $step_type, $step_title ) {
192
+
193
+ $new_step_id = wp_insert_post(
194
+ array(
195
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
196
+ 'post_title' => $step_title,
197
+ 'post_status' => 'publish',
198
+ )
199
+ );
200
+
201
+ if ( $new_step_id ) {
202
+
203
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
204
+
205
+ if ( ! is_array( $flow_steps ) ) {
206
+ $flow_steps = array();
207
+ }
208
+
209
+ $flow_steps[] = array(
210
+ 'id' => $new_step_id,
211
+ 'title' => $step_title,
212
+ 'type' => $step_type,
213
+ );
214
+
215
+ // insert post meta.
216
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
217
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
218
+
219
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
220
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
221
+ }
222
+
223
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
224
+
225
+ return $new_step_id;
226
+ }
227
+
228
+ /**
229
+ * Delete step for flow
230
+ *
231
+ * @since 1.0.0
232
+ *
233
+ * @return void
234
+ */
235
+ public function cartflows_delete_flow_step() {
236
+
237
+ if ( ! current_user_can( 'manage_options' ) ) {
238
+ return;
239
+ }
240
+
241
+ check_ajax_referer( 'wcf-delete-flow-step', 'security' );
242
+
243
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
244
+ $flow_id = intval( $_POST['post_id'] );
245
+ $step_id = intval( $_POST['step_id'] );
246
+ }
247
+ $result = array(
248
+ 'status' => false,
249
+ /* translators: %s flow id */
250
+ 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
251
+ );
252
+
253
+ if ( ! $flow_id || ! $step_id ) {
254
+ wp_send_json( $result );
255
+ }
256
+
257
+ wp_delete_post( $step_id, true );
258
+
259
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
260
+
261
+ if ( ! is_array( $flow_steps ) ) {
262
+ wp_send_json( $result );
263
+ }
264
+
265
+ foreach ( $flow_steps as $index => $data ) {
266
+
267
+ if ( intval( $data['id'] ) === $step_id ) {
268
+ unset( $flow_steps[ $index ] );
269
+ break;
270
+ }
271
+ }
272
+
273
+ /* Set index order properly */
274
+ $flow_steps = array_merge( $flow_steps );
275
+
276
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
277
+
278
+ $result = array(
279
+ 'status' => true,
280
+ /* translators: %s flow id */
281
+ 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
282
+ );
283
+
284
+ wp_send_json( $result );
285
+ }
286
+
287
+ /**
288
+ * Reorder step flow
289
+ *
290
+ * @since 1.0.0
291
+ *
292
+ * @return void
293
+ */
294
+ public function cartflows_reorder_flow_steps() {
295
+
296
+ if ( ! current_user_can( 'manage_options' ) ) {
297
+ return;
298
+ }
299
+
300
+ check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
301
+
302
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
303
+ $flow_id = intval( $_POST['post_id'] );
304
+ $step_ids = array_map( 'intval', $_POST['step_ids'] );
305
+ }
306
+ $result = array(
307
+ 'status' => false,
308
+ /* translators: %s flow id */
309
+ 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
310
+ );
311
+
312
+ if ( ! $flow_id || ! is_array( $step_ids ) ) {
313
+ wp_send_json( $result );
314
+ }
315
+
316
+ $new_flow_steps = array();
317
+
318
+ foreach ( $step_ids as $index => $step_id ) {
319
+
320
+ $new_flow_steps[] = array(
321
+ 'id' => intval( $step_id ),
322
+ 'title' => get_the_title( $step_id ),
323
+ 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
324
+ );
325
+ }
326
+
327
+ update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
328
+
329
+ $result = array(
330
+ 'status' => true,
331
+ /* translators: %s flow id */
332
+ 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
333
+ );
334
+
335
+ wp_send_json( $result );
336
+ }
337
+
338
+
339
+ /**
340
+ * Load admin scripts
341
+ *
342
+ * @since 1.0.0
343
+ *
344
+ * @return void
345
+ */
346
+ public function admin_scripts() {
347
+
348
+ global $pagenow;
349
+ global $post;
350
+
351
+ $screen = get_current_screen();
352
+
353
+ if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
354
+
355
+ wp_enqueue_script(
356
+ 'wcf-flow-meta',
357
+ CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
358
+ array( 'jquery', 'jquery-ui-sortable' ),
359
+ CARTFLOWS_VER,
360
+ true
361
+ );
362
+
363
+ wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
364
+ wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
365
+
366
+ $localize = array(
367
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
368
+ );
369
+
370
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Initialize meta box
376
+ *
377
+ * @since 1.0.0
378
+ *
379
+ * @return void
380
+ */
381
+ public function init_metabox() {
382
+
383
+ /**
384
+ * Fires after the title field.
385
+ *
386
+ * @param WP_Post $post Post object.
387
+ */
388
+ add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
389
+ add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
390
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
391
+ }
392
+
393
+ /**
394
+ * Is first time import?
395
+ *
396
+ * @param integer $post_id post ID.
397
+ * @return bool
398
+ */
399
+ public function is_flow_imported( $post_id = 0 ) {
400
+
401
+ if ( 0 === $post_id ) {
402
+ $post_id = get_the_ID();
403
+ }
404
+
405
+ $steps = get_post_meta( $post_id, 'wcf-steps', true );
406
+ $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
407
+
408
+ if ( empty( $steps ) && 'import' === $choice ) {
409
+ return true;
410
+ }
411
+
412
+ return false;
413
+ }
414
+
415
+ /**
416
+ * Setup meta box.
417
+ *
418
+ * @return void
419
+ */
420
+ public function setup_meta_box() {
421
+ if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
422
+ return;
423
+ }
424
+
425
+ /**
426
+ * Adding Add new step button to the top*/
427
+ echo $this->add_add_new_step_button();
428
+
429
+ $this->markup_meta_box();
430
+
431
+ $this->add_upgrade_to_pro_metabox();
432
+ }
433
+
434
+
435
+ /**
436
+ * Add metabox when cartflows pro is not enabled.
437
+ */
438
+ public function add_upgrade_to_pro_metabox() {
439
+
440
+ if ( ! _is_cartflows_pro() ) {
441
+ add_meta_box(
442
+ 'wcf-upgrade-pro',
443
+ __( 'Analytics', 'cartflows' ),
444
+ array( $this, 'upgrade_to_pro' ),
445
+ CARTFLOWS_FLOW_POST_TYPE,
446
+ 'side',
447
+ 'high'
448
+ );
449
+ }
450
+
451
+ }
452
+
453
+ /**
454
+ * Show Upgrade To Pro markup.
455
+ */
456
+ public function upgrade_to_pro() {
457
+
458
+ echo '<div>';
459
+ /* translators: %s: link */
460
+ 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>';
461
+ echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
462
+ echo '</div>';
463
+
464
+ }
465
+
466
+ /**
467
+ * Settings meta box.
468
+ *
469
+ * @return void
470
+ */
471
+ public function settings_meta_box() {
472
+
473
+ if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
474
+
475
+ /* No need of sandbox will delete it later */
476
+ add_meta_box(
477
+ 'wcf-sandbox-settings', // Id.
478
+ __( 'Flow Settings', 'cartflows' ), // Title.
479
+ array( $this, 'sandbox_meta_box' ), // Callback.
480
+ CARTFLOWS_FLOW_POST_TYPE, // Post_type.
481
+ 'side', // Context.
482
+ 'high' // Priority.
483
+ );
484
+
485
+ do_action( 'cartflows_add_flow_metabox' );
486
+ }
487
+ }
488
+
489
+ /**
490
+ * Metabox Markup
491
+ *
492
+ * @return void
493
+ */
494
+ public function markup_meta_box() {
495
+ global $post;
496
+
497
+ wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
498
+
499
+ // Get defaults.
500
+ $meta = self::get_current_post_meta( $post->ID );
501
+
502
+ /**
503
+ * Get options
504
+ */
505
+ $updated_data = array(
506
+ 'steps' => $meta['wcf-steps']['default'],
507
+ );
508
+
509
+ do_action( 'wcf_flow_settings_markup_before', $meta );
510
+ $this->page_header_tab( $updated_data );
511
+ do_action( 'wcf_flow_settings_markup_after', $meta );
512
+ }
513
+
514
+ /**
515
+ * Metabox Markup
516
+ *
517
+ * @param object $post Post object.
518
+ * @return void
519
+ */
520
+ public function sandbox_meta_box( $post ) {
521
+
522
+ // Get defaults.
523
+ $meta = self::get_current_post_meta( $post->ID );
524
+
525
+ /**
526
+ * Get options
527
+ */
528
+ foreach ( $meta as $key => $value ) {
529
+ $updated_data[ $key ] = $meta[ $key ]['default'];
530
+ }
531
+
532
+ do_action( 'wcf_flow_sandbox_markup_before', $meta );
533
+ $this->sandbox_markup( $updated_data );
534
+ do_action( 'wcf_flow_sandbox_markup_after', $meta );
535
+ }
536
+
537
+ /**
538
+ * Page Header Tabs
539
+ *
540
+ * @param array $options Post meta.
541
+ * @return void
542
+ */
543
+ public function page_header_tab( $options ) {
544
+
545
+ include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
546
+ }
547
+
548
+ /**
549
+ * Sandbox Markup
550
+ *
551
+ * @param array $options Post meta.
552
+ * @return void
553
+ */
554
+ public function sandbox_markup( $options ) {
555
+ ?>
556
+ <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
557
+ <div class="wcf-flow-sandbox-table-container">
558
+ <?php
559
+ echo wcf()->meta->get_checkbox_field(
560
+ array(
561
+ 'name' => 'wcf-testing',
562
+ 'value' => $options['wcf-testing'],
563
+ 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
564
+ )
565
+ );
566
+
567
+ echo wcf()->meta->get_description_field(
568
+ array(
569
+ 'name' => 'wcf-testing-note',
570
+ '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' ),
571
+ )
572
+ );
573
+
574
+ ?>
575
+ </div>
576
+ </div>
577
+ <?php
578
+ }
579
+
580
+ /**
581
+ * Keep the menu open when editing the flows.
582
+ * Highlights the wanted admin (sub-) menu items for the CPT.
583
+ *
584
+ * @since 1.0.0
585
+ */
586
+ public function menu_highlight() {
587
+ global $parent_file, $submenu_file, $post_type;
588
+ if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
589
+ $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
590
+ $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
591
+ endif;
592
+ }
593
+
594
+ /**
595
+ * Get metabox options
596
+ *
597
+ * @param int $post_id post id.
598
+ * @return array
599
+ */
600
+ public static function get_meta_option( $post_id ) {
601
+
602
+ if ( null === self::$meta_option ) {
603
+ /**
604
+ * Set metabox options
605
+ */
606
+ self::$meta_option = wcf()->options->get_flow_fields( $post_id );
607
+ }
608
+
609
+ return self::$meta_option;
610
+ }
611
+
612
+ /**
613
+ * Get metabox options
614
+ *
615
+ * @param int $post_id post ID.
616
+ * @return array
617
+ */
618
+ public static function get_current_post_meta( $post_id ) {
619
+
620
+ $stored = get_post_meta( $post_id );
621
+
622
+ $default_meta = self::get_meta_option( $post_id );
623
+
624
+ // Set stored and override defaults.
625
+ foreach ( $stored as $key => $value ) {
626
+ if ( array_key_exists( $key, $default_meta ) ) {
627
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
628
+ } else {
629
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
630
+ }
631
+ }
632
+
633
+ return self::get_meta_option( $post_id );
634
+ }
635
+
636
+ /**
637
+ * Metabox Save
638
+ *
639
+ * @param number $post_id Post ID.
640
+ * @return void
641
+ */
642
+ public function save_meta_box( $post_id ) {
643
+
644
+ // Checks save status.
645
+ $is_autosave = wp_is_post_autosave( $post_id );
646
+ $is_revision = wp_is_post_revision( $post_id );
647
+
648
+ $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;
649
+
650
+ // Exits script depending on save status.
651
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
652
+ return;
653
+ }
654
+
655
+ wcf()->options->save_flow_fields( $post_id );
656
+ }
657
+
658
+ /**
659
+ * Localize variables in admin
660
+ *
661
+ * @param array $vars variables.
662
+ */
663
+ public function localize_vars( $vars ) {
664
+
665
+ $ajax_actions = array(
666
+ 'wcf_setup_default_steps',
667
+ 'wcf_add_flow_step',
668
+ 'wcf_delete_flow_step',
669
+ 'wcf_reorder_flow_steps',
670
+ );
671
+
672
+ foreach ( $ajax_actions as $action ) {
673
+
674
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
675
+ }
676
+
677
+ return $vars;
678
+ }
679
+
680
+ /**
681
+ * Add New Step Button
682
+ *
683
+ * @return string
684
+ */
685
+ public function add_add_new_step_button() {
686
+ $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
687
+ $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
688
+ $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
689
+ $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
690
+ $add_new_btn_markup .= '</button>';
691
+ $add_new_btn_markup .= '</div>';
692
+
693
+ return $add_new_btn_markup;
694
+ }
695
+ }
696
+
697
+ /**
698
+ * Kicking this off by calling 'get_instance()' method
699
+ */
700
+ Cartflows_Flow_Meta::get_instance();
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4
7
- Stable tag: 1.5.4
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -125,6 +125,9 @@ Glad you asked! CartFlows Pro is an optional add-on to CartFlows that adds addit
125
 
126
  == Changelog ==
127
 
 
 
 
128
  = Version 1.5.4 - Tuesday, 7th April 2020 =
129
  * Improvement: Hardened the security of the plugin.
130
  * Fix: Older flows were not displaying in the library.
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4
7
+ Stable tag: 1.5.5
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
125
 
126
  == Changelog ==
127
 
128
+ = Version 1.5.5 - Tuesday, 14th April 2020 =
129
+ * Fix: CSS conflict with the latest release of Astra theme.
130
+
131
  = Version 1.5.4 - Tuesday, 7th April 2020 =
132
  * Improvement: Hardened the security of the plugin.
133
  * Fix: Older flows were not displaying in the library.
theme-support/astra/astra.php CHANGED
@@ -1,31 +1,33 @@
1
- <?php
2
- /**
3
- * Action call to remove the astra two step action hooks.
4
- *
5
- * @since X.X.X
6
- *
7
- * @package CartFlows
8
- */
9
-
10
- add_action( 'cartflows_checkout_before_shortcode', 'cartflows_theme_compatibility_astra' );
11
-
12
- if ( ! function_exists( 'cartflows_theme_compatibility_astra' ) ) {
13
-
14
- /**
15
- * Function to remove the astra hooks.
16
- *
17
- * @since X.X.X
18
- *
19
- * @return void
20
- */
21
- function cartflows_theme_compatibility_astra() {
22
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_wrapper_div', 1 );
23
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_ul_wrapper', 2 );
24
- remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_div_wrapper_close', 30 );
25
- remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_ul_close', 30 );
26
- remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_address_li_wrapper', 5 );
27
- remove_action( 'woocommerce_checkout_after_customer_details', 'astra_woocommerce_li_close' );
28
- remove_action( 'woocommerce_checkout_before_order_review', 'astra_two_step_checkout_order_review_wrap', 1 );
29
- remove_action( 'woocommerce_checkout_after_order_review', 'astra_woocommerce_li_close', 40 );
30
- }
31
- }
 
 
1
+ <?php
2
+ /**
3
+ * Action call to remove the astra two step action hooks.
4
+ *
5
+ * @since X.X.X
6
+ *
7
+ * @package CartFlows
8
+ */
9
+
10
+ add_action( 'cartflows_checkout_before_shortcode', 'cartflows_theme_compatibility_astra' );
11
+
12
+ if ( ! function_exists( 'cartflows_theme_compatibility_astra' ) ) {
13
+
14
+ /**
15
+ * Function to remove the astra hooks.
16
+ *
17
+ * @since X.X.X
18
+ *
19
+ * @return void
20
+ */
21
+ function cartflows_theme_compatibility_astra() {
22
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_wrapper_div', 1 );
23
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_form_ul_wrapper', 2 );
24
+ remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_div_wrapper_close', 30 );
25
+ remove_action( 'woocommerce_checkout_order_review', 'astra_woocommerce_ul_close', 30 );
26
+ remove_action( 'woocommerce_checkout_before_customer_details', 'astra_two_step_checkout_address_li_wrapper', 5 );
27
+ remove_action( 'woocommerce_checkout_after_customer_details', 'astra_woocommerce_li_close' );
28
+ remove_action( 'woocommerce_checkout_before_order_review', 'astra_two_step_checkout_order_review_wrap', 1 );
29
+ remove_action( 'woocommerce_checkout_after_order_review', 'astra_woocommerce_li_close', 40 );
30
+
31
+ add_filter( 'astra_theme_woocommerce_dynamic_css', '__return_empty_string' );
32
+ }
33
+ }