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

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

Code changes from version 1.5.12 to 1.5.13

Files changed (46) hide show
  1. admin/assets/css/setup-wizard-rtl.css +17 -2
  2. admin/assets/css/setup-wizard.css +17 -2
  3. admin/assets/js/setup-wizard.js +37 -1
  4. admin/bsf-analytics/Gruntfile.js +210 -0
  5. admin/bsf-analytics/assets/css/minified/style-rtl.min.css +1 -1
  6. admin/bsf-analytics/assets/css/minified/style.min.css +1 -1
  7. admin/bsf-analytics/assets/css/unminified/style-rtl.css +5 -5
  8. admin/bsf-analytics/assets/css/unminified/style.css +5 -5
  9. admin/bsf-analytics/class-bsf-analytics-loader.php +115 -0
  10. admin/bsf-analytics/class-bsf-analytics.php +560 -528
  11. admin/bsf-analytics/composer.json +22 -0
  12. admin/bsf-analytics/composer.lock +711 -0
  13. admin/bsf-analytics/package-lock.json +3978 -0
  14. admin/bsf-analytics/package.json +30 -0
  15. admin/bsf-analytics/phpcs.xml.dist +19 -0
  16. admin/bsf-analytics/version.json +1 -0
  17. admin/meta-assets/js/admin-edit.js +40 -44
  18. assets/js/checkout-template.js +1 -1
  19. assets/js/optin-template.js +1 -1
  20. assets/min-js/checkout-template.min.js +1 -1
  21. assets/min-js/optin-template.min.js +1 -1
  22. cartflows.php +2 -2
  23. changelog.txt +4 -0
  24. classes/class-cartflows-default-meta.php +871 -871
  25. classes/class-cartflows-flow-frontend.php +247 -247
  26. classes/class-cartflows-frontend.php +654 -654
  27. classes/class-cartflows-functions.php +539 -539
  28. classes/class-cartflows-importer.php +1742 -1742
  29. classes/class-cartflows-loader.php +17 -3
  30. classes/class-cartflows-meta-fields.php +84 -41
  31. classes/class-cartflows-tracking.php +287 -287
  32. classes/class-cartflows-update.php +168 -146
  33. classes/class-cartflows-utils.php +591 -591
  34. classes/class-cartflows-wizard.php +745 -706
  35. classes/deprecated/deprecated-hooks.php +51 -31
  36. includes/meta-fields/generate-product-repeater.php +1 -1
  37. languages/cartflows.pot +2118 -2098
  38. modules/checkout/classes/class-cartflows-checkout-markup.php +1288 -1288
  39. modules/checkout/templates/embed/checkout-template-simple.php +33 -33
  40. modules/flow/classes/class-cartflows-flow-meta.php +760 -760
  41. modules/flow/view/meta-flow-steps.php +210 -210
  42. modules/optin/classes/class-cartflows-optin-meta.php +3 -1
  43. modules/thankyou/classes/class-cartflows-thankyou-markup.php +314 -314
  44. modules/thankyou/includes/thankyou-dynamic-css.php +3 -0
  45. modules/thankyou/includes/thankyou-dynamic-divi-css.php +79 -79
  46. readme.txt +5 -1
admin/assets/css/setup-wizard-rtl.css CHANGED
@@ -521,7 +521,7 @@
521
  font-size: 14px;
522
  }
523
 
524
- .cartflows-setup .cartflows-setup-message input{
525
  width: 100%;
526
  height: 45px;
527
  }
@@ -1233,4 +1233,19 @@
1233
 
1234
  input.wcf-error{
1235
  border: 1px solid #ff0000;
1236
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  font-size: 14px;
522
  }
523
 
524
+ .cartflows-setup .cartflows-setup-message input:not([type='checkbox']){
525
  width: 100%;
526
  height: 45px;
527
  }
1233
 
1234
  input.wcf-error{
1235
  border: 1px solid #ff0000;
1236
+ }
1237
+
1238
+ /* Usage tracking option css */
1239
+ .cartflows-usage-tracking .usage-tracking-wrap h4{
1240
+ margin: 0 0 12px 0;
1241
+ font-weight: 600;
1242
+ }
1243
+
1244
+ .cartflows-usage-tracking .usage-tracking-wrap p{
1245
+ margin: 0 0 12px 0;
1246
+ }
1247
+
1248
+ .cartflows-usage-tracking .usage-tracking-wrap p,
1249
+ .cartflows-usage-tracking .usage-tracking-wrap label{
1250
+ font-size: 14px;
1251
+ }
admin/assets/css/setup-wizard.css CHANGED
@@ -521,7 +521,7 @@
521
  font-size: 14px;
522
  }
523
 
524
- .cartflows-setup .cartflows-setup-message input{
525
  width: 100%;
526
  height: 45px;
527
  }
@@ -1233,4 +1233,19 @@
1233
 
1234
  input.wcf-error{
1235
  border: 1px solid #ff0000;
1236
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  font-size: 14px;
522
  }
523
 
524
+ .cartflows-setup .cartflows-setup-message input:not([type='checkbox']){
525
  width: 100%;
526
  height: 45px;
527
  }
1233
 
1234
  input.wcf-error{
1235
  border: 1px solid #ff0000;
1236
+ }
1237
+
1238
+ /* Usage tracking option css */
1239
+ .cartflows-usage-tracking .usage-tracking-wrap h4{
1240
+ margin: 0 0 12px 0;
1241
+ font-weight: 600;
1242
+ }
1243
+
1244
+ .cartflows-usage-tracking .usage-tracking-wrap p{
1245
+ margin: 0 0 12px 0;
1246
+ }
1247
+
1248
+ .cartflows-usage-tracking .usage-tracking-wrap p,
1249
+ .cartflows-usage-tracking .usage-tracking-wrap label{
1250
+ font-size: 14px;
1251
+ }
admin/assets/js/setup-wizard.js CHANGED
@@ -11,6 +11,7 @@
11
  */
12
  _bind: function() {
13
  $( document ).on('click', '.wcf-install-plugins', CartFlowsWizard._installNow );
 
14
  $( document ).on('click', '.wcf-install-wc', CartFlowsWizard._installWc );
15
  $( document ).on('wp-plugin-installing' , CartFlowsWizard._pluginInstalling);
16
  $( document ).on('wp-plugin-install-error' , CartFlowsWizard._installError);
@@ -18,6 +19,41 @@
18
  $( document ).on('click', '.mautic-form-submit', CartFlowsWizard._onMauticSubmit );
19
  },
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  _onMauticSubmit: function( event ) {
22
 
23
  event.preventDefault();
@@ -104,7 +140,7 @@
104
  _activatePlugin: function( plugin_init, plugin_slug ) {
105
  var redirect_link = $( '.wcf-redirect-link' ).data('redirect-link') || '';
106
  var save_builder_option = ( '1' == $( "#save-pb-option" ).val() ) || false;
107
-
108
  $.ajax({
109
  url : ajaxurl,
110
  method : 'POST',
11
  */
12
  _bind: function() {
13
  $( document ).on('click', '.wcf-install-plugins', CartFlowsWizard._installNow );
14
+ $( document ).on('click', '.button-next-wrap', CartFlowsWizard._usage_tracking );
15
  $( document ).on('click', '.wcf-install-wc', CartFlowsWizard._installWc );
16
  $( document ).on('wp-plugin-installing' , CartFlowsWizard._pluginInstalling);
17
  $( document ).on('wp-plugin-install-error' , CartFlowsWizard._installError);
19
  $( document ).on('click', '.mautic-form-submit', CartFlowsWizard._onMauticSubmit );
20
  },
21
 
22
+
23
+ _usage_tracking: function( event ){
24
+
25
+ var allow_usage_tracking = document.getElementById("cartflows-usage-tracking-option");
26
+
27
+ if( allow_usage_tracking && allow_usage_tracking.checked ){
28
+ allow_usage_tracking = true;
29
+ }
30
+ else{
31
+ allow_usage_tracking = false;
32
+ }
33
+
34
+ $.ajax({
35
+ url : ajaxurl,
36
+ method : 'POST',
37
+ data : {
38
+ action : 'usage_tracking_option',
39
+ allow_usage_tracking : allow_usage_tracking,
40
+ security : cartflows_setup_vars.wcf_usage_tracking_option_nonce
41
+ },
42
+ })
43
+ .done(function( response ) {
44
+ if( response.success ) {
45
+ console.log("Option Updated.");
46
+ }
47
+ })
48
+ .fail(function() {
49
+ console.log("error");
50
+ })
51
+ .always(function() {
52
+ console.log("complete");
53
+ });
54
+
55
+ },
56
+
57
  _onMauticSubmit: function( event ) {
58
 
59
  event.preventDefault();
140
  _activatePlugin: function( plugin_init, plugin_slug ) {
141
  var redirect_link = $( '.wcf-redirect-link' ).data('redirect-link') || '';
142
  var save_builder_option = ( '1' == $( "#save-pb-option" ).val() ) || false;
143
+
144
  $.ajax({
145
  url : ajaxurl,
146
  method : 'POST',
admin/bsf-analytics/Gruntfile.js ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = function (grunt) {
2
+ 'use strict';
3
+ // Project configuration
4
+ var autoprefixer = require('autoprefixer');
5
+ var flexibility = require('postcss-flexibility');
6
+
7
+ var pkgInfo = grunt.file.readJSON('package.json');
8
+
9
+ grunt.initConfig({
10
+ pkg: grunt.file.readJSON('package.json'),
11
+
12
+ rtlcss: {
13
+ options: {
14
+ // rtlcss options
15
+ config: {
16
+ preserveComments: true,
17
+ greedy: true
18
+ },
19
+ // generate source maps
20
+ map: false
21
+ },
22
+ dist: {
23
+ files: [
24
+ {
25
+ expand: true,
26
+ cwd: 'assets/css/unminified',
27
+ src: [
28
+ '*.css',
29
+ '!*-rtl.css',
30
+ ],
31
+ dest: 'assets/css/unminified',
32
+ ext: '-rtl.css'
33
+ },
34
+ ]
35
+ }
36
+ },
37
+
38
+ postcss: {
39
+ options: {
40
+ map: false,
41
+ processors: [
42
+ flexibility,
43
+ autoprefixer({
44
+ browsers: [
45
+ 'Android >= 2.1',
46
+ 'Chrome >= 21',
47
+ 'Edge >= 12',
48
+ 'Explorer >= 7',
49
+ 'Firefox >= 17',
50
+ 'Opera >= 12.1',
51
+ 'Safari >= 6.0'
52
+ ],
53
+ cascade: false
54
+ })
55
+ ]
56
+ },
57
+ style: {
58
+ expand: true,
59
+ src: [
60
+ 'assets/css/unminified/**.css',
61
+ '!assets/css/unminified/**-rtl.css'
62
+ ]
63
+ }
64
+ },
65
+
66
+ cssmin: {
67
+ options: {
68
+ keepSpecialComments: 0
69
+ },
70
+ css: {
71
+ files: [
72
+ {
73
+ src: 'assets/css/unminified/style.css',
74
+ dest: 'assets/css/minified/style.min.css',
75
+ },
76
+ {
77
+ src: 'assets/css/unminified/style-rtl.css',
78
+ dest: 'assets/css/minified/style-rtl.min.css',
79
+ },
80
+ ]
81
+ }
82
+ },
83
+
84
+ copy: {
85
+ main: {
86
+ options: {
87
+ mode: true
88
+ },
89
+ src: [
90
+ '**',
91
+ '!node_modules/**',
92
+ '!build/**',
93
+ '!css/sourcemap/**',
94
+ '!.git/**',
95
+ '!bin/**',
96
+ '!.gitlab-ci.yml',
97
+ '!bin/**',
98
+ '!tests/**',
99
+ '!phpunit.xml.dist',
100
+ '!*.sh',
101
+ '!*.map',
102
+ '!Gruntfile.js',
103
+ '!package.json',
104
+ '!.gitignore',
105
+ '!phpunit.xml',
106
+ '!README.md',
107
+ '!sass/**',
108
+ '!codesniffer.ruleset.xml',
109
+ '!vendor/**',
110
+ '!composer.json',
111
+ '!composer.lock',
112
+ '!package-lock.json',
113
+ '!phpcs.xml.dist',
114
+ ],
115
+ dest: 'bsf-analytics/'
116
+ }
117
+ },
118
+
119
+ compress: {
120
+ main: {
121
+ options: {
122
+ archive: 'bsf-analytics-' + pkgInfo.version + '.zip',
123
+ mode: 'zip'
124
+ },
125
+ files: [
126
+ {
127
+ src: [
128
+ './bsf-analytics/**'
129
+ ]
130
+
131
+ }
132
+ ]
133
+ }
134
+ },
135
+
136
+ clean: {
137
+ main: ["bsf-analytics"],
138
+ zip: ["*.zip"]
139
+
140
+ },
141
+
142
+ replace: {
143
+
144
+ analytics_const: {
145
+ src: ['class-bsf-analytics.php'],
146
+ overwrite: true,
147
+ replacements: [
148
+ {
149
+ from: /BSF_ANALYTICS_VERSION', '.*?'/g,
150
+ to: 'BSF_ANALYTICS_VERSION\', \'<%= pkg.version %>\''
151
+ }
152
+ ]
153
+ },
154
+
155
+ analytics_function_comment: {
156
+ src: [
157
+ '*.php',
158
+ '**/*.php',
159
+ '!node_modules/**',
160
+ '!php-tests/**',
161
+ '!bin/**',
162
+ ],
163
+ overwrite: true,
164
+ replacements: [
165
+ {
166
+ from: 'x.x.x',
167
+ to: '<%=pkg.version %>'
168
+ }
169
+ ]
170
+ },
171
+ },
172
+ }
173
+ );
174
+
175
+ // Load grunt tasks
176
+ grunt.loadNpmTasks('grunt-rtlcss');
177
+ grunt.loadNpmTasks( 'grunt-postcss' );
178
+
179
+ grunt.loadNpmTasks('grunt-contrib-cssmin');
180
+ grunt.loadNpmTasks('grunt-contrib-copy');
181
+ grunt.loadNpmTasks('grunt-contrib-compress');
182
+ grunt.loadNpmTasks('grunt-contrib-clean');
183
+
184
+ /* Version Bump Task */
185
+ grunt.loadNpmTasks( 'grunt-bumpup' );
186
+ grunt.loadNpmTasks( 'grunt-text-replace' );
187
+
188
+ // rtlcss, you will still need to install ruby and sass on your system manually to run this
189
+ grunt.registerTask('rtl', ['rtlcss']);
190
+
191
+ // Style
192
+ grunt.registerTask('style', ['rtl']);
193
+
194
+ // min all
195
+ grunt.registerTask('minify', ['style', 'cssmin:css']);
196
+
197
+ // Grunt release - Create installable package of the local files
198
+ grunt.registerTask('release', ['clean:zip', 'copy:main', 'compress:main', 'clean:main']);
199
+
200
+ // Version Bump `grunt bump-version --ver=<version-number>`
201
+ grunt.registerTask( 'bump-version', function() {
202
+
203
+ var newVersion = grunt.option('ver');
204
+
205
+ if ( newVersion ) {
206
+ grunt.task.run( 'bumpup:' + newVersion );
207
+ grunt.task.run( 'replace' );
208
+ }
209
+ } );
210
+ };
admin/bsf-analytics/assets/css/minified/style-rtl.min.css CHANGED
@@ -1 +1 @@
1
- #bsf-optin-notice{padding:1px 12px;border-right-color:#007cba}#bsf-optin-notice .notice-container{padding-top:10px;padding-bottom:12px}#bsf-optin-notice .notice-content{margin:0}#bsf-optin-notice .notice-heading{padding:0 0 12px 20px}#bsf-optin-notice .button-primary{margin-left:5px}
1
+ [ID*="-optin-notice"]{padding:1px 12px;border-right-color:#007cba}[ID*="-optin-notice"] .notice-container{padding-top:10px;padding-bottom:12px}[ID*="-optin-notice"] .notice-content{margin:0}[ID*="-optin-notice"] .notice-heading{padding:0 0 12px 20px}[ID*="-optin-notice"] .button-primary{margin-left:5px}
admin/bsf-analytics/assets/css/minified/style.min.css CHANGED
@@ -1 +1 @@
1
- #bsf-optin-notice{padding:1px 12px;border-left-color:#007cba}#bsf-optin-notice .notice-container{padding-top:10px;padding-bottom:12px}#bsf-optin-notice .notice-content{margin:0}#bsf-optin-notice .notice-heading{padding:0 20px 12px 0}#bsf-optin-notice .button-primary{margin-right:5px}
1
+ [ID*="-optin-notice"]{padding:1px 12px;border-left-color:#007cba}[ID*="-optin-notice"] .notice-container{padding-top:10px;padding-bottom:12px}[ID*="-optin-notice"] .notice-content{margin:0}[ID*="-optin-notice"] .notice-heading{padding:0 20px 12px 0}[ID*="-optin-notice"] .button-primary{margin-right:5px}
admin/bsf-analytics/assets/css/unminified/style-rtl.css CHANGED
@@ -1,21 +1,21 @@
1
- #bsf-optin-notice {
2
  padding: 1px 12px;
3
  border-right-color: #007cba;
4
  }
5
 
6
- #bsf-optin-notice .notice-container {
7
  padding-top: 10px;
8
  padding-bottom: 12px;
9
  }
10
 
11
- #bsf-optin-notice .notice-content {
12
  margin: 0;
13
  }
14
 
15
- #bsf-optin-notice .notice-heading {
16
  padding: 0 0 12px 20px;
17
  }
18
 
19
- #bsf-optin-notice .button-primary {
20
  margin-left: 5px;
21
  }
1
+ [ID*="-optin-notice"] {
2
  padding: 1px 12px;
3
  border-right-color: #007cba;
4
  }
5
 
6
+ [ID*="-optin-notice"] .notice-container {
7
  padding-top: 10px;
8
  padding-bottom: 12px;
9
  }
10
 
11
+ [ID*="-optin-notice"] .notice-content {
12
  margin: 0;
13
  }
14
 
15
+ [ID*="-optin-notice"] .notice-heading {
16
  padding: 0 0 12px 20px;
17
  }
18
 
19
+ [ID*="-optin-notice"] .button-primary {
20
  margin-left: 5px;
21
  }
admin/bsf-analytics/assets/css/unminified/style.css CHANGED
@@ -1,21 +1,21 @@
1
- #bsf-optin-notice {
2
  padding: 1px 12px;
3
  border-left-color: #007cba;
4
  }
5
 
6
- #bsf-optin-notice .notice-container {
7
  padding-top: 10px;
8
  padding-bottom: 12px;
9
  }
10
 
11
- #bsf-optin-notice .notice-content {
12
  margin: 0;
13
  }
14
 
15
- #bsf-optin-notice .notice-heading {
16
  padding: 0 20px 12px 0;
17
  }
18
 
19
- #bsf-optin-notice .button-primary {
20
  margin-right: 5px;
21
  }
1
+ [ID*="-optin-notice"] {
2
  padding: 1px 12px;
3
  border-left-color: #007cba;
4
  }
5
 
6
+ [ID*="-optin-notice"] .notice-container {
7
  padding-top: 10px;
8
  padding-bottom: 12px;
9
  }
10
 
11
+ [ID*="-optin-notice"] .notice-content {
12
  margin: 0;
13
  }
14
 
15
+ [ID*="-optin-notice"] .notice-heading {
16
  padding: 0 20px 12px 0;
17
  }
18
 
19
+ [ID*="-optin-notice"] .button-primary {
20
  margin-right: 5px;
21
  }
admin/bsf-analytics/class-bsf-analytics-loader.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BSF analytics loader file.
4
+ *
5
+ * @version 1.0.0
6
+ *
7
+ * @package bsf-analytics
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit();
12
+ }
13
+
14
+ /**
15
+ * Class BSF_Analytics_Loader.
16
+ */
17
+ class BSF_Analytics_Loader {
18
+
19
+ /**
20
+ * Analytics Entities.
21
+ *
22
+ * @access private
23
+ * @var array Entities array.
24
+ */
25
+ private $entities = array();
26
+
27
+ /**
28
+ * Analytics Version.
29
+ *
30
+ * @access private
31
+ * @var float analytics version.
32
+ */
33
+ private $analytics_version = '';
34
+
35
+ /**
36
+ * Analytics path.
37
+ *
38
+ * @access private
39
+ * @var string path array.
40
+ */
41
+ private $analytics_path = '';
42
+
43
+ /**
44
+ * Instance
45
+ *
46
+ * @access private
47
+ * @var object Class object.
48
+ */
49
+ private static $instance = null;
50
+
51
+ /**
52
+ * Get instace of class.
53
+ *
54
+ * @return object
55
+ */
56
+ public static function get_instance() {
57
+ if ( null === self::$instance ) {
58
+ self::$instance = new self();
59
+ }
60
+
61
+ return self::$instance;
62
+ }
63
+
64
+ /**
65
+ * Constructor
66
+ */
67
+ public function __construct() {
68
+ add_action( 'init', array( $this, 'load_analytics' ) );
69
+ }
70
+
71
+ /**
72
+ * Set entity for analytics.
73
+ *
74
+ * @param string $data Entity attributes data.
75
+ * @return void
76
+ */
77
+ public function set_entity( $data ) {
78
+ array_push( $this->entities, $data );
79
+ }
80
+
81
+ /**
82
+ * Load Analytics library.
83
+ *
84
+ * @return void
85
+ */
86
+ public function load_analytics() {
87
+ $unique_entities = array();
88
+
89
+ if ( ! empty( $this->entities ) ) {
90
+ foreach ( $this->entities as $entity ) {
91
+ foreach ( $entity as $key => $data ) {
92
+
93
+ if ( isset( $data['path'] ) ) {
94
+ if ( file_exists( $data['path'] . '/version.json' ) ) {
95
+ $analytics_version = file_get_contents( $data['path'] . '/version.json' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
96
+ if ( version_compare( $analytics_version, $this->analytics_version, '>' ) ) {
97
+ $this->analytics_version = $analytics_version;
98
+ $this->analytics_path = $data['path'];
99
+ }
100
+ }
101
+ }
102
+
103
+ if ( ! isset( $unique_entities[ $key ] ) ) {
104
+ $unique_entities[ $key ] = $data;
105
+ }
106
+ }
107
+ }
108
+
109
+ if ( file_exists( $this->analytics_path ) && ! class_exists( 'BSF_Analytics' ) ) {
110
+ require_once $this->analytics_path . '/class-bsf-analytics.php';
111
+ new BSF_Analytics( $unique_entities );
112
+ }
113
+ }
114
+ }
115
+ }
admin/bsf-analytics/class-bsf-analytics.php CHANGED
@@ -1,528 +1,560 @@
1
- <?php
2
- /**
3
- * BSF analytics class file.
4
- *
5
- * @version 1.0.0
6
- *
7
- * @package bsf-analytics
8
- */
9
-
10
- if ( ! defined( 'ABSPATH' ) ) {
11
- exit; // Exit if accessed directly.
12
- }
13
-
14
- if ( ! class_exists( 'BSF_Analytics' ) ) {
15
-
16
- /**
17
- * BSF analytics
18
- */
19
- class BSF_Analytics {
20
-
21
- /**
22
- * Member Variable
23
- *
24
- * @var string Usage tracking document URL
25
- */
26
- private $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
27
-
28
- /**
29
- * Setup actions, load files.
30
- *
31
- * @since 1.0.0
32
- */
33
- public function __construct() {
34
-
35
- define( 'BSF_ANALYTICS_FILE', __FILE__ );
36
- define( 'BSF_ANALYTICS_VERSION', '1.0.2' );
37
- define( 'BSF_ANALYTICS_PATH', dirname( __FILE__ ) );
38
- define( 'BSF_ANALYTICS_URI', $this->bsf_analytics_url() );
39
-
40
- add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
41
- add_action( 'cron_schedules', array( $this, 'every_two_days_schedule' ) );
42
- add_action( 'admin_notices', array( $this, 'option_notice' ) );
43
- add_action( 'astra_notice_before_markup_bsf-optin-notice', array( $this, 'enqueue_assets' ) );
44
-
45
- add_action( 'init', array( $this, 'schedule_unschedule_event' ) );
46
-
47
- if ( ! has_action( 'bsf_analytics_send', array( $this, 'send' ) ) ) {
48
- add_action( 'bsf_analytics_send', array( $this, 'send' ) );
49
- }
50
-
51
- add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
52
-
53
- add_action( 'update_option_bsf_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
54
- add_action( 'add_option_bsf_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
55
-
56
- $this->includes();
57
- }
58
-
59
- /**
60
- * BSF Analytics URL
61
- *
62
- * @return String URL of bsf-analytics directory.
63
- * @since 1.0.0
64
- */
65
- public function bsf_analytics_url() {
66
-
67
- $path = wp_normalize_path( BSF_ANALYTICS_PATH );
68
- $theme_dir = wp_normalize_path( get_template_directory() );
69
-
70
- if ( strpos( $path, $theme_dir ) !== false ) {
71
- return rtrim( get_template_directory_uri() . '/admin/bsf-analytics/', '/' );
72
- } else {
73
- return rtrim( plugin_dir_url( BSF_ANALYTICS_FILE ), '/' );
74
- }
75
- }
76
-
77
- /**
78
- * Get API URL for sending analytics.
79
- *
80
- * @return string API URL.
81
- * @since 1.0.0
82
- */
83
- private function get_api_url() {
84
- return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
85
- }
86
-
87
- /**
88
- * Enqueue Scripts.
89
- *
90
- * @since 1.0.0
91
- * @return void
92
- */
93
- public function enqueue_assets() {
94
-
95
- /**
96
- * Load unminified if SCRIPT_DEBUG is true.
97
- *
98
- * Directory and Extensions.
99
- */
100
- $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
101
- $file_rtl = ( is_rtl() ) ? '-rtl' : '';
102
- $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
103
-
104
- $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
105
-
106
- wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, BSF_ANALYTICS_VERSION, 'all' );
107
- }
108
-
109
- /**
110
- * Send analytics API call.
111
- *
112
- * @since 1.0.0
113
- */
114
- public function send() {
115
- wp_remote_post(
116
- $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
117
- array(
118
- 'body' => BSF_Analytics_Stats::instance()->get_stats(),
119
- 'timeout' => 5,
120
- 'blocking' => false,
121
- )
122
- );
123
- }
124
-
125
- /**
126
- * Check if usage tracking is enabled.
127
- *
128
- * @return bool
129
- * @since 1.0.0
130
- */
131
- public function is_tracking_enabled() {
132
- $is_enabled = get_site_option( 'bsf_analytics_optin' ) === 'yes' ? true : false;
133
- $is_enabled = $this->is_white_label_enabled() ? false : $is_enabled;
134
-
135
- return apply_filters( 'bsf_tracking_enabled', $is_enabled );
136
- }
137
-
138
- /**
139
- * Check if WHITE label is enabled for BSF products.
140
- *
141
- * @return bool
142
- * @since 1.0.0
143
- */
144
- public function is_white_label_enabled() {
145
-
146
- $options = apply_filters( 'bsf_white_label_options', array() );
147
- $is_enabled = false;
148
-
149
- if ( is_array( $options ) ) {
150
- foreach ( $options as $option ) {
151
- if ( true === $option ) {
152
- $is_enabled = true;
153
- break;
154
- }
155
- }
156
- }
157
-
158
- return $is_enabled;
159
- }
160
-
161
- /**
162
- * Display admin notice for usage tracking.
163
- *
164
- * @since 1.0.0
165
- */
166
- public function option_notice() {
167
-
168
- if ( ! current_user_can( 'manage_options' ) ) {
169
- return;
170
- }
171
-
172
- // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
173
- if ( false !== get_site_option( 'bsf_analytics_optin', false ) || $this->is_white_label_enabled() ) {
174
- return;
175
- }
176
-
177
- // Show tracker consent notice after 24 hours from installed time.
178
- if ( strtotime( '+24 hours', $this->get_analytics_install_time() ) > time() ) {
179
- return;
180
- }
181
-
182
- /* translators: %s product name */
183
- $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'cartflows' );
184
-
185
- if ( is_multisite() ) {
186
- $notice_string .= __( 'This will be applicable for all sites from the network.', 'cartflows' );
187
- }
188
-
189
- $language_dir = is_rtl() ? 'rtl' : 'ltr';
190
-
191
- Astra_Notices::add_notice(
192
- array(
193
- 'id' => 'bsf-optin-notice',
194
- 'type' => '',
195
- 'message' => sprintf(
196
- '<div class="notice-content">
197
- <div class="notice-heading">
198
- %1$s
199
- </div>
200
- <div class="astra-notices-container">
201
- <a href="%2$s" class="astra-notices button-primary">
202
- %3$s
203
- </a>
204
- <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
205
- %6$s
206
- </a>
207
- </div>
208
- </div>',
209
- /* translators: %s usage doc link */
210
- sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $this->get_product_name() ), $language_dir, esc_url( $this->usage_doc_link ), __( ' Know More.', 'cartflows' ) ),
211
- add_query_arg(
212
- array(
213
- 'bsf_analytics_optin' => 'yes',
214
- 'bsf_analytics_nonce' => wp_create_nonce( 'bsf_analytics_optin' ),
215
- )
216
- ),
217
- __( 'Yes! Allow it', 'cartflows' ),
218
- add_query_arg(
219
- array(
220
- 'bsf_analytics_optin' => 'no',
221
- 'bsf_analytics_nonce' => wp_create_nonce( 'bsf_analytics_optin' ),
222
- )
223
- ),
224
- MONTH_IN_SECONDS,
225
- __( 'No Thanks', 'cartflows' )
226
- ),
227
- 'show_if' => true,
228
- 'repeat-notice-after' => false,
229
- 'priority' => 18,
230
- 'display-with-other-notices' => true,
231
- )
232
- );
233
- }
234
-
235
- /**
236
- * Process usage tracking opt out.
237
- *
238
- * @since 1.0.0
239
- */
240
- public function handle_optin_optout() {
241
- if ( ! isset( $_GET['bsf_analytics_nonce'] ) ) {
242
- return;
243
- }
244
-
245
- if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['bsf_analytics_nonce'] ) ), 'bsf_analytics_optin' ) ) {
246
- return;
247
- }
248
-
249
- $optin_status = isset( $_GET['bsf_analytics_optin'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_optin'] ) ) : '';
250
-
251
- if ( 'yes' === $optin_status ) {
252
- $this->optin();
253
- } elseif ( 'no' === $optin_status ) {
254
- $this->optout();
255
- }
256
-
257
- wp_safe_redirect(
258
- remove_query_arg(
259
- array(
260
- 'bsf_analytics_optin',
261
- 'bsf_analytics_nonce',
262
- )
263
- )
264
- );
265
- }
266
-
267
- /**
268
- * Opt in to usage tracking.
269
- *
270
- * @since 1.0.0
271
- */
272
- private function optin() {
273
- update_site_option( 'bsf_analytics_optin', 'yes' );
274
- }
275
-
276
- /**
277
- * Opt out to usage tracking.
278
- *
279
- * @since 1.0.0
280
- */
281
- private function optout() {
282
- update_site_option( 'bsf_analytics_optin', 'no' );
283
- }
284
-
285
- /**
286
- * Add two days event schedule variables.
287
- *
288
- * @param array $schedules scheduled array data.
289
- * @since 1.0.0
290
- */
291
- public function every_two_days_schedule( $schedules ) {
292
- $schedules['every_two_days'] = array(
293
- 'interval' => 2 * DAY_IN_SECONDS,
294
- 'display' => __( 'Every two days', 'cartflows' ),
295
- );
296
-
297
- return $schedules;
298
- }
299
-
300
- /**
301
- * Schedule usage tracking event.
302
- *
303
- * @since 1.0.0
304
- */
305
- private function schedule_event() {
306
- if ( ! wp_next_scheduled( 'bsf_analytics_send' ) && $this->is_tracking_enabled() ) {
307
- wp_schedule_event( time(), 'every_two_days', 'bsf_analytics_send' );
308
- }
309
- }
310
-
311
- /**
312
- * Unschedule usage tracking event.
313
- *
314
- * @since 1.0.0
315
- */
316
- private function unschedule_event() {
317
- wp_clear_scheduled_hook( 'bsf_analytics_send' );
318
- }
319
-
320
- /**
321
- * Load analytics stat class.
322
- *
323
- * @since 1.0.0
324
- */
325
- private function includes() {
326
- require_once __DIR__ . '/class-bsf-analytics-stats.php';
327
- }
328
-
329
- /**
330
- * Register usage tracking option in General settings page.
331
- *
332
- * @since 1.0.0
333
- */
334
- public function register_usage_tracking_setting() {
335
-
336
- if ( ! apply_filters( 'bsf_tracking_enabled', true ) || $this->is_white_label_enabled() ) {
337
- return;
338
- }
339
-
340
- register_setting(
341
- 'general', // Options group.
342
- 'bsf_analytics_optin', // Option name/database.
343
- array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
344
- );
345
-
346
- add_settings_field(
347
- 'bsf-analytics-optin', // Field ID.
348
- __( 'Usage Tracking', 'cartflows' ), // Field title.
349
- array( $this, 'render_settings_field_html' ), // Field callback function.
350
- 'general' // Settings page slug.
351
- );
352
- }
353
-
354
- /**
355
- * Sanitize Callback Function
356
- *
357
- * @param bool $input Option value.
358
- * @since 1.0.0
359
- */
360
- public function sanitize_option( $input ) {
361
-
362
- if ( ! $input || 'no' === $input ) {
363
- return 'no';
364
- }
365
-
366
- return 'yes';
367
- }
368
-
369
- /**
370
- * Print settings field HTML.
371
- *
372
- * @since 1.0.0
373
- */
374
- public function render_settings_field_html() {
375
- ?>
376
- <fieldset>
377
- <label for="bsf-analytics-optin">
378
- <input id="bsf-analytics-optin" type="checkbox" value="1" name="bsf_analytics_optin" <?php checked( get_site_option( 'bsf_analytics_optin', 'no' ), 'yes' ); ?>>
379
- <?php
380
- esc_html_e( 'Allow Brainstorm Force products to track non-sensitive usage tracking data.', 'cartflows' );
381
-
382
- if ( is_multisite() ) {
383
- esc_html_e( ' This will be applicable for all sites from the network.', 'cartflows' );
384
- }
385
- ?>
386
- </label>
387
- <?php
388
- echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $this->usage_doc_link ), __( 'Learn More.', 'cartflows' ) ) );
389
- ?>
390
- </fieldset>
391
- <?php
392
- }
393
-
394
- /**
395
- * Get current product name.
396
- *
397
- * @return string $plugin_data['Name] Name of plugin.
398
- * @since 1.0.0
399
- */
400
- private function get_product_name() {
401
-
402
- $base = wp_normalize_path( dirname( __FILE__ ) );
403
- $theme_dir = wp_normalize_path( get_template_directory() );
404
-
405
- if ( false !== strpos( $base, $theme_dir ) ) {
406
- $theme = wp_get_theme( get_template() );
407
- return $theme->get( 'Name' );
408
- }
409
-
410
- $base = plugin_basename( __FILE__ );
411
-
412
- $exploded_path = explode( '/', $base, 2 );
413
- $plugin_slug = $exploded_path[0];
414
-
415
- return $this->get_plugin_name( $plugin_slug );
416
- }
417
-
418
- /**
419
- * Get plugin name by plugin slug.
420
- *
421
- * @param string $plugin_slug Plugin slug.
422
- * @return string $plugin_info['Name'] Plugin name.
423
- */
424
- private function get_plugin_name( $plugin_slug ) {
425
-
426
- $plugins = get_option( 'active_plugins' );
427
-
428
- if ( ! function_exists( 'get_plugin_data' ) ) {
429
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
430
- }
431
-
432
- foreach ( $plugins as $plugin_file ) {
433
-
434
- $plugin_folder = explode( '/', $plugin_file );
435
- $plugin_folder = $plugin_folder[0];
436
- if ( $plugin_folder === $plugin_slug ) {
437
- $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_file;
438
- $plugin_data = get_plugin_data( $plugin_path );
439
- return $plugin_data['Name'];
440
- }
441
- }
442
- }
443
-
444
- /**
445
- * Set analytics installed time in option.
446
- *
447
- * @return string $time analytics installed time.
448
- * @since 1.0.0
449
- */
450
- private function get_analytics_install_time() {
451
-
452
- $time = get_site_option( 'bsf_analytics_installed_time' );
453
-
454
- if ( ! $time ) {
455
- $time = time();
456
- update_site_option( 'bsf_analytics_installed_time', time() );
457
- }
458
-
459
- return $time;
460
- }
461
-
462
- /**
463
- * Schedule/unschedule cron event on updation of option.
464
- *
465
- * @param string $old_value old value of option.
466
- * @param string $value value of option.
467
- * @param string $option Option name.
468
- * @since 1.0.0
469
- */
470
- public function update_analytics_option_callback( $old_value, $value, $option ) {
471
- $this->add_option_to_network( $value );
472
- }
473
-
474
- /**
475
- * Analytics option add callback.
476
- *
477
- * @param string $option Option name.
478
- * @param string $value value of option.
479
- * @since 1.0.0
480
- */
481
- public function add_analytics_option_callback( $option, $value ) {
482
- $this->add_option_to_network( $value );
483
- }
484
-
485
- /**
486
- * Schedule or unschedule event based on analytics option value.
487
- *
488
- * @since 1.0.0
489
- */
490
- public function schedule_unschedule_event() {
491
-
492
- if ( true === $this->is_white_label_enabled() ) {
493
- $this->unschedule_event();
494
- return;
495
- }
496
-
497
- $analytics_option = get_site_option( 'bsf_analytics_optin' );
498
-
499
- if ( 'no' === $analytics_option ) {
500
- $this->unschedule_event();
501
- } elseif ( 'yes' === $analytics_option ) {
502
- $this->schedule_event();
503
- }
504
- }
505
-
506
- /**
507
- * Save analytics option to network.
508
- *
509
- * @param string $value value of option.
510
- * @since 1.0.0
511
- */
512
- public function add_option_to_network( $value ) {
513
-
514
- // If action coming from general settings page.
515
- if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
516
-
517
- if ( get_site_option( 'bsf_analytics_optin' ) ) {
518
- update_site_option( 'bsf_analytics_optin', $value );
519
- } else {
520
- add_site_option( 'bsf_analytics_optin', $value );
521
- }
522
- }
523
- }
524
- }
525
-
526
- new BSF_Analytics();
527
-
528
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BSF analytics class file.
4
+ *
5
+ * @version 1.0.0
6
+ *
7
+ * @package bsf-analytics
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly.
12
+ }
13
+
14
+ if ( ! class_exists( 'BSF_Analytics' ) ) {
15
+
16
+ /**
17
+ * BSF analytics
18
+ */
19
+ class BSF_Analytics {
20
+
21
+ /**
22
+ * Member Variable
23
+ *
24
+ * @var string Product name
25
+ */
26
+ public $product_name = '';
27
+
28
+ /**
29
+ * Member Variable
30
+ *
31
+ * @var array Entities data.
32
+ */
33
+ private $entities;
34
+
35
+ /**
36
+ * Member Variable
37
+ *
38
+ * @var string Usage tracking document URL
39
+ */
40
+ public $usage_doc_link = 'https://store.brainstormforce.com/usage-tracking/?utm_source=wp_dashboard&utm_medium=general_settings&utm_campaign=usage_tracking';
41
+
42
+ /**
43
+ * Setup actions, load files.
44
+ *
45
+ * @param array $args entity data for analytics.
46
+ * @since 1.0.0
47
+ */
48
+ public function __construct( $args ) {
49
+
50
+ // Bail when no analytics entities are registered.
51
+ if ( empty( $args ) ) {
52
+ return;
53
+ }
54
+
55
+ $this->entities = $args;
56
+
57
+ define( 'BSF_ANALYTICS_FILE', __FILE__ );
58
+ define( 'BSF_ANALYTICS_URI', $this->bsf_analytics_url() );
59
+
60
+ add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
61
+ add_action( 'cron_schedules', array( $this, 'every_two_days_schedule' ) );
62
+ add_action( 'admin_notices', array( $this, 'option_notice' ) );
63
+ add_action( 'init', array( $this, 'schedule_unschedule_event' ), 99 );
64
+
65
+ $this->set_actions();
66
+
67
+ if ( ! has_action( 'bsf_analytics_send', array( $this, 'send' ) ) ) {
68
+ add_action( 'bsf_analytics_send', array( $this, 'send' ) );
69
+ }
70
+
71
+ add_action( 'admin_init', array( $this, 'register_usage_tracking_setting' ) );
72
+
73
+ $this->includes();
74
+ }
75
+
76
+ /**
77
+ * Setup actions for admin notice style and analytics cron event.
78
+ *
79
+ * @since 1.0.4
80
+ */
81
+ public function set_actions() {
82
+
83
+ foreach ( $this->entities as $key => $data ) {
84
+ add_action( 'astra_notice_before_markup_' . $key . '-optin-notice', array( $this, 'enqueue_assets' ) );
85
+ add_action( 'update_option_' . $key . '_analytics_optin', array( $this, 'update_analytics_option_callback' ), 10, 3 );
86
+ add_action( 'add_option_' . $key . '_analytics_optin', array( $this, 'add_analytics_option_callback' ), 10, 2 );
87
+ }
88
+ }
89
+
90
+ /**
91
+ * BSF Analytics URL
92
+ *
93
+ * @return String URL of bsf-analytics directory.
94
+ * @since 1.0.0
95
+ */
96
+ public function bsf_analytics_url() {
97
+
98
+ $path = wp_normalize_path( dirname( __FILE__ ) );
99
+ $theme_dir = wp_normalize_path( get_template_directory() );
100
+
101
+ if ( strpos( $path, $theme_dir ) !== false ) {
102
+ return rtrim( get_template_directory_uri() . '/admin/bsf-analytics/', '/' );
103
+ } else {
104
+ return rtrim( plugin_dir_url( BSF_ANALYTICS_FILE ), '/' );
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Get API URL for sending analytics.
110
+ *
111
+ * @return string API URL.
112
+ * @since 1.0.0
113
+ */
114
+ private function get_api_url() {
115
+ return defined( 'BSF_API_URL' ) ? BSF_API_URL : 'https://support.brainstormforce.com/';
116
+ }
117
+
118
+ /**
119
+ * Enqueue Scripts.
120
+ *
121
+ * @since 1.0.0
122
+ * @return void
123
+ */
124
+ public function enqueue_assets() {
125
+
126
+ global $bsf_analytics_version;
127
+ /**
128
+ * Load unminified if SCRIPT_DEBUG is true.
129
+ *
130
+ * Directory and Extensions.
131
+ */
132
+ $dir_name = ( SCRIPT_DEBUG ) ? 'unminified' : 'minified';
133
+ $file_rtl = ( is_rtl() ) ? '-rtl' : '';
134
+ $css_ext = ( SCRIPT_DEBUG ) ? '.css' : '.min.css';
135
+
136
+ $css_uri = BSF_ANALYTICS_URI . '/assets/css/' . $dir_name . '/style' . $file_rtl . $css_ext;
137
+
138
+ wp_enqueue_style( 'bsf-analytics-admin-style', $css_uri, false, $bsf_analytics_version, 'all' );
139
+ }
140
+
141
+ /**
142
+ * Send analytics API call.
143
+ *
144
+ * @since 1.0.0
145
+ */
146
+ public function send() {
147
+ wp_remote_post(
148
+ $this->get_api_url() . 'wp-json/bsf-core/v1/analytics/',
149
+ array(
150
+ 'body' => BSF_Analytics_Stats::instance()->get_stats(),
151
+ 'timeout' => 5,
152
+ 'blocking' => false,
153
+ )
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Check if usage tracking is enabled.
159
+ *
160
+ * @return bool
161
+ * @since 1.0.0
162
+ */
163
+ public function is_tracking_enabled() {
164
+
165
+ foreach ( $this->entities as $key => $data ) {
166
+
167
+ $is_enabled = get_site_option( $key . '_analytics_optin' ) === 'yes' ? true : false;
168
+ $is_enabled = $this->is_white_label_enabled( $key ) ? false : $is_enabled;
169
+
170
+ if ( apply_filters( $key . '_tracking_enabled', $is_enabled ) ) {
171
+ return true;
172
+ }
173
+ }
174
+
175
+ return false;
176
+ }
177
+
178
+ /**
179
+ * Check if WHITE label is enabled for BSF products.
180
+ *
181
+ * @param string $source source of analytics.
182
+ * @return bool
183
+ * @since 1.0.0
184
+ */
185
+ public function is_white_label_enabled( $source ) {
186
+
187
+ $options = apply_filters( $source . '_white_label_options', array() );
188
+ $is_enabled = false;
189
+
190
+ if ( is_array( $options ) ) {
191
+ foreach ( $options as $option ) {
192
+ if ( true === $option ) {
193
+ $is_enabled = true;
194
+ break;
195
+ }
196
+ }
197
+ }
198
+
199
+ return $is_enabled;
200
+ }
201
+
202
+ /**
203
+ * Display admin notice for usage tracking.
204
+ *
205
+ * @since 1.0.0
206
+ */
207
+ public function option_notice() {
208
+
209
+ if ( ! current_user_can( 'manage_options' ) ) {
210
+ return;
211
+ }
212
+
213
+ foreach ( $this->entities as $key => $data ) {
214
+
215
+ $time_to_display = isset( $data['time_to_display'] ) ? $data['time_to_display'] : '+24 hours';
216
+ $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
217
+
218
+ // Don't display the notice if tracking is disabled or White Label is enabled for any of our plugins.
219
+ if ( false !== get_site_option( $key . '_analytics_optin', false ) || $this->is_white_label_enabled( $key ) ) {
220
+ continue;
221
+ }
222
+
223
+ // Show tracker consent notice after 24 hours from installed time.
224
+ if ( strtotime( $time_to_display, $this->get_analytics_install_time( $key ) ) > time() ) {
225
+ continue;
226
+ }
227
+
228
+ /* translators: %s product name */
229
+ $notice_string = __( 'Want to help make <strong>%1s</strong> even more awesome? Allow us to collect non-sensitive diagnostic data and usage information. ', 'cartflows' );
230
+
231
+ if ( is_multisite() ) {
232
+ $notice_string .= __( 'This will be applicable for all sites from the network.', 'cartflows' );
233
+ }
234
+
235
+ $language_dir = is_rtl() ? 'rtl' : 'ltr';
236
+
237
+ Astra_Notices::add_notice(
238
+ array(
239
+ 'id' => $key . '-optin-notice',
240
+ 'type' => '',
241
+ 'message' => sprintf(
242
+ '<div class="notice-content">
243
+ <div class="notice-heading">
244
+ %1$s
245
+ </div>
246
+ <div class="astra-notices-container">
247
+ <a href="%2$s" class="astra-notices button-primary">
248
+ %3$s
249
+ </a>
250
+ <a href="%4$s" data-repeat-notice-after="%5$s" class="astra-notices button-secondary">
251
+ %6$s
252
+ </a>
253
+ </div>
254
+ </div>',
255
+ /* translators: %s usage doc link */
256
+ sprintf( $notice_string . '<span dir="%2s"><a href="%3s" target="_blank" rel="noreferrer noopener">%4s</a><span>', esc_html( $data['product_name'] ), $language_dir, esc_url( $usage_doc_link ), __( ' Know More.', 'cartflows' ) ),
257
+ add_query_arg(
258
+ array(
259
+ $key . '_analytics_optin' => 'yes',
260
+ $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
261
+ 'bsf_analytics_source' => $key,
262
+ )
263
+ ),
264
+ __( 'Yes! Allow it', 'cartflows' ),
265
+ add_query_arg(
266
+ array(
267
+ $key . '_analytics_optin' => 'no',
268
+ $key . '_analytics_nonce' => wp_create_nonce( $key . '_analytics_optin' ),
269
+ 'bsf_analytics_source' => $key,
270
+ )
271
+ ),
272
+ MONTH_IN_SECONDS,
273
+ __( 'No Thanks', 'cartflows' )
274
+ ),
275
+ 'show_if' => true,
276
+ 'repeat-notice-after' => false,
277
+ 'priority' => 18,
278
+ 'display-with-other-notices' => true,
279
+ )
280
+ );
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Process usage tracking opt out.
286
+ *
287
+ * @since 1.0.0
288
+ */
289
+ public function handle_optin_optout() {
290
+
291
+ if ( ! current_user_can( 'manage_options' ) ) {
292
+ return;
293
+ }
294
+
295
+ $source = isset( $_GET['bsf_analytics_source'] ) ? sanitize_text_field( wp_unslash( $_GET['bsf_analytics_source'] ) ) : '';
296
+
297
+ if ( ! isset( $_GET[ $source . '_analytics_nonce' ] ) ) {
298
+ return;
299
+ }
300
+
301
+ if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_nonce' ] ) ), $source . '_analytics_optin' ) ) {
302
+ return;
303
+ }
304
+
305
+ $optin_status = isset( $_GET[ $source . '_analytics_optin' ] ) ? sanitize_text_field( wp_unslash( $_GET[ $source . '_analytics_optin' ] ) ) : '';
306
+
307
+ if ( 'yes' === $optin_status ) {
308
+ $this->optin( $source );
309
+ } elseif ( 'no' === $optin_status ) {
310
+ $this->optout( $source );
311
+ }
312
+
313
+ wp_safe_redirect(
314
+ remove_query_arg(
315
+ array(
316
+ $source . '_analytics_optin',
317
+ $source . '_analytics_nonce',
318
+ 'bsf_analytics_source',
319
+ )
320
+ )
321
+ );
322
+ }
323
+
324
+ /**
325
+ * Opt in to usage tracking.
326
+ *
327
+ * @param string $source source of analytics.
328
+ * @since 1.0.0
329
+ */
330
+ private function optin( $source ) {
331
+ update_site_option( $source . '_analytics_optin', 'yes' );
332
+ }
333
+
334
+ /**
335
+ * Opt out to usage tracking.
336
+ *
337
+ * @param string $source source of analytics.
338
+ * @since 1.0.0
339
+ */
340
+ private function optout( $source ) {
341
+ update_site_option( $source . '_analytics_optin', 'no' );
342
+ }
343
+
344
+ /**
345
+ * Add two days event schedule variables.
346
+ *
347
+ * @param array $schedules scheduled array data.
348
+ * @since 1.0.0
349
+ */
350
+ public function every_two_days_schedule( $schedules ) {
351
+ $schedules['every_two_days'] = array(
352
+ 'interval' => 2 * DAY_IN_SECONDS,
353
+ 'display' => __( 'Every two days', 'cartflows' ),
354
+ );
355
+
356
+ return $schedules;
357
+ }
358
+
359
+ /**
360
+ * Schedule usage tracking event.
361
+ *
362
+ * @since 1.0.0
363
+ */
364
+ private function schedule_event() {
365
+ if ( ! wp_next_scheduled( 'bsf_analytics_send' ) && $this->is_tracking_enabled() ) {
366
+ wp_schedule_event( time(), 'every_two_days', 'bsf_analytics_send' );
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Unschedule usage tracking event.
372
+ *
373
+ * @since 1.0.0
374
+ */
375
+ private function unschedule_event() {
376
+ wp_clear_scheduled_hook( 'bsf_analytics_send' );
377
+ }
378
+
379
+ /**
380
+ * Load analytics stat class.
381
+ *
382
+ * @since 1.0.0
383
+ */
384
+ private function includes() {
385
+ require_once __DIR__ . '/class-bsf-analytics-stats.php';
386
+ }
387
+
388
+ /**
389
+ * Register usage tracking option in General settings page.
390
+ *
391
+ * @since 1.0.0
392
+ */
393
+ public function register_usage_tracking_setting() {
394
+
395
+ foreach ( $this->entities as $key => $data ) {
396
+
397
+ if ( ! apply_filters( $key . 'tracking_enabled', true ) || $this->is_white_label_enabled( $key ) ) {
398
+ return;
399
+ }
400
+
401
+ $usage_doc_link = isset( $data['usage_doc_link'] ) ? $data['usage_doc_link'] : $this->usage_doc_link;
402
+ $author = isset( $data['author'] ) ? $data['author'] : 'Brainstorm Force';
403
+
404
+ register_setting(
405
+ 'general', // Options group.
406
+ $key . '_analytics_optin', // Option name/database.
407
+ array( 'sanitize_callback' => array( $this, 'sanitize_option' ) ) // sanitize callback function.
408
+ );
409
+
410
+ add_settings_field(
411
+ $key . '-analytics-optin', // Field ID.
412
+ __( 'Usage Tracking', 'cartflows' ), // Field title.
413
+ array( $this, 'render_settings_field_html' ), // Field callback function.
414
+ 'general',
415
+ 'default', // Settings page slug.
416
+ array(
417
+ 'type' => 'checkbox',
418
+ 'title' => $author,
419
+ 'name' => $key . '_analytics_optin',
420
+ 'label_for' => $key . '-analytics-optin',
421
+ 'id' => $key . '-analytics-optin',
422
+ 'usage_doc_link' => $usage_doc_link,
423
+ )
424
+ );
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Sanitize Callback Function
430
+ *
431
+ * @param bool $input Option value.
432
+ * @since 1.0.0
433
+ */
434
+ public function sanitize_option( $input ) {
435
+
436
+ if ( ! $input || 'no' === $input ) {
437
+ return 'no';
438
+ }
439
+
440
+ return 'yes';
441
+ }
442
+
443
+ /**
444
+ * Print settings field HTML.
445
+ *
446
+ * @param array $args arguments to field.
447
+ * @since 1.0.0
448
+ */
449
+ public function render_settings_field_html( $args ) {
450
+ ?>
451
+ <fieldset>
452
+ <label for="<?php echo esc_attr( $args['label_for'] ); ?>">
453
+ <input id="<?php echo esc_attr( $args['id'] ); ?>" type="checkbox" value="1" name="<?php echo esc_attr( $args['name'] ); ?>" <?php checked( get_site_option( $args['name'], 'no' ), 'yes' ); ?>>
454
+ <?php
455
+ /* translators: %s Product title */
456
+ esc_html_e( sprintf( 'Allow %s products to track non-sensitive usage tracking data.', $args['cartflows'] ) );// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText
457
+
458
+ if ( is_multisite() ) {
459
+ esc_html_e( ' This will be applicable for all sites from the network.', 'cartflows' );
460
+ }
461
+ ?>
462
+ </label>
463
+ <?php
464
+ echo wp_kses_post( sprintf( '<a href="%1s" target="_blank" rel="noreferrer noopener">%2s</a>', esc_url( $args['usage_doc_link'] ), __( 'Learn More.', 'cartflows' ) ) );
465
+ ?>
466
+ </fieldset>
467
+ <?php
468
+ }
469
+
470
+ /**
471
+ * Set analytics installed time in option.
472
+ *
473
+ * @param string $source source of analytics.
474
+ * @return string $time analytics installed time.
475
+ * @since 1.0.0
476
+ */
477
+ private function get_analytics_install_time( $source ) {
478
+
479
+ $time = get_site_option( $source . '_analytics_installed_time' );
480
+
481
+ if ( ! $time ) {
482
+ $time = time();
483
+ update_site_option( $source . '_analytics_installed_time', time() );
484
+ }
485
+
486
+ return $time;
487
+ }
488
+
489
+ /**
490
+ * Schedule/unschedule cron event on updation of option.
491
+ *
492
+ * @param string $old_value old value of option.
493
+ * @param string $value value of option.
494
+ * @param string $option Option name.
495
+ * @since 1.0.0
496
+ */
497
+ public function update_analytics_option_callback( $old_value, $value, $option ) {
498
+ if ( is_multisite() ) {
499
+ $this->add_option_to_network( $option, $value );
500
+ }
501
+ }
502
+
503
+ /**
504
+ * Analytics option add callback.
505
+ *
506
+ * @param string $option Option name.
507
+ * @param string $value value of option.
508
+ * @since 1.0.0
509
+ */
510
+ public function add_analytics_option_callback( $option, $value ) {
511
+ if ( is_multisite() ) {
512
+ $this->add_option_to_network( $option, $value );
513
+ }
514
+ }
515
+
516
+ /**
517
+ * Schedule or unschedule event based on analytics option value.
518
+ *
519
+ * @since 1.0.0
520
+ */
521
+ public function schedule_unschedule_event() {
522
+
523
+ foreach ( $this->entities as $key => $source ) {
524
+
525
+ if ( true === $this->is_white_label_enabled( $key ) ) {
526
+ $this->unschedule_event();
527
+ return;
528
+ }
529
+
530
+ $analytics_option = get_site_option( $key . '_analytics_optin' );
531
+
532
+ if ( 'yes' === $analytics_option ) {
533
+ $this->schedule_event();
534
+ } else {
535
+ $this->unschedule_event();
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Save analytics option to network.
542
+ *
543
+ * @param string $option name of option.
544
+ * @param string $value value of option.
545
+ * @since 1.0.0
546
+ */
547
+ public function add_option_to_network( $option, $value ) {
548
+
549
+ // If action coming from general settings page.
550
+ if ( isset( $_POST['option_page'] ) && 'general' === $_POST['option_page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
551
+
552
+ if ( get_site_option( $option ) ) {
553
+ update_site_option( $option, $value );
554
+ } else {
555
+ add_site_option( $option, $value );
556
+ }
557
+ }
558
+ }
559
+ }
560
+ }
admin/bsf-analytics/composer.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "require-dev": {
3
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
4
+ "wp-coding-standards/wpcs": "2.2.1",
5
+ "phpcompatibility/phpcompatibility-wp": "2.1.0",
6
+ "brainmaestro/composer-git-hooks": "^2.6"
7
+ },
8
+ "scripts": {
9
+ "format": "phpcbf --standard=phpcs.xml.dist --report-summary --report-source",
10
+ "lint": "phpcs --standard=phpcs.xml.dist --report-summary --report-source",
11
+ "post-install-cmd": "vendor/bin/cghooks add --ignore-lock",
12
+ "post-update-cmd": "vendor/bin/cghooks update"
13
+ },
14
+ "extra": {
15
+ "hooks": {
16
+ "pre-commit": [
17
+ "echo committing as $(git config user.name)",
18
+ "sh bin/block-commits-with-merge-conflict.sh"
19
+ ]
20
+ }
21
+ }
22
+ }
admin/bsf-analytics/composer.lock ADDED
@@ -0,0 +1,711 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "content-hash": "3fea1d501a95bbd7e1f1492dae0a3847",
8
+ "packages": [],
9
+ "packages-dev": [
10
+ {
11
+ "name": "brainmaestro/composer-git-hooks",
12
+ "version": "v2.8.3",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/BrainMaestro/composer-git-hooks.git",
16
+ "reference": "97888dd34e900931117747cd34a42fdfcf271142"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/BrainMaestro/composer-git-hooks/zipball/97888dd34e900931117747cd34a42fdfcf271142",
21
+ "reference": "97888dd34e900931117747cd34a42fdfcf271142",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "php": "^5.6 || >=7.0",
26
+ "symfony/console": "^3.2 || ^4.0 || ^5.0"
27
+ },
28
+ "require-dev": {
29
+ "ext-json": "*",
30
+ "friendsofphp/php-cs-fixer": "^2.9",
31
+ "phpunit/phpunit": "^5.7 || ^7.0"
32
+ },
33
+ "bin": [
34
+ "cghooks"
35
+ ],
36
+ "type": "library",
37
+ "extra": {
38
+ "hooks": {
39
+ "pre-commit": "composer check-style",
40
+ "pre-push": [
41
+ "composer test",
42
+ "appver=$(grep -o -E '\\d.\\d.\\d' cghooks)",
43
+ "tag=$(git describe --tags --abbrev=0)",
44
+ "if [ \"$tag\" != \"v$appver\" ]; then",
45
+ "echo \"The most recent tag $tag does not match the application version $appver\\n\"",
46
+ "tag=${tag#v}",
47
+ "sed -i -E \"s/$appver/$tag/\" cghooks",
48
+ "exit 1",
49
+ "fi"
50
+ ]
51
+ }
52
+ },
53
+ "autoload": {
54
+ "psr-4": {
55
+ "BrainMaestro\\GitHooks\\": "src/"
56
+ },
57
+ "files": [
58
+ "src/helpers.php"
59
+ ]
60
+ },
61
+ "notification-url": "https://packagist.org/downloads/",
62
+ "license": [
63
+ "MIT"
64
+ ],
65
+ "authors": [
66
+ {
67
+ "name": "Ezinwa Okpoechi",
68
+ "email": "brainmaestro@outlook.com"
69
+ }
70
+ ],
71
+ "description": "Easily manage git hooks in your composer config",
72
+ "keywords": [
73
+ "HOOK",
74
+ "composer",
75
+ "git"
76
+ ],
77
+ "time": "2019-12-09T09:49:20+00:00"
78
+ },
79
+ {
80
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
81
+ "version": "v0.4.4",
82
+ "source": {
83
+ "type": "git",
84
+ "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
85
+ "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08"
86
+ },
87
+ "dist": {
88
+ "type": "zip",
89
+ "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/2e41850d5f7797cbb1af7b030d245b3b24e63a08",
90
+ "reference": "2e41850d5f7797cbb1af7b030d245b3b24e63a08",
91
+ "shasum": ""
92
+ },
93
+ "require": {
94
+ "composer-plugin-api": "^1.0",
95
+ "php": "^5.3|^7",
96
+ "squizlabs/php_codesniffer": "*"
97
+ },
98
+ "require-dev": {
99
+ "composer/composer": "*",
100
+ "wimg/php-compatibility": "^8.0"
101
+ },
102
+ "suggest": {
103
+ "dealerdirect/qa-tools": "All the PHP QA tools you'll need"
104
+ },
105
+ "type": "composer-plugin",
106
+ "extra": {
107
+ "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
108
+ },
109
+ "autoload": {
110
+ "psr-4": {
111
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
112
+ }
113
+ },
114
+ "notification-url": "https://packagist.org/downloads/",
115
+ "license": [
116
+ "MIT"
117
+ ],
118
+ "authors": [
119
+ {
120
+ "name": "Franck Nijhof",
121
+ "email": "f.nijhof@dealerdirect.nl",
122
+ "homepage": "http://workingatdealerdirect.eu",
123
+ "role": "Developer"
124
+ }
125
+ ],
126
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
127
+ "homepage": "http://workingatdealerdirect.eu",
128
+ "keywords": [
129
+ "PHPCodeSniffer",
130
+ "PHP_CodeSniffer",
131
+ "code quality",
132
+ "codesniffer",
133
+ "composer",
134
+ "installer",
135
+ "phpcs",
136
+ "plugin",
137
+ "qa",
138
+ "quality",
139
+ "standard",
140
+ "standards",
141
+ "style guide",
142
+ "stylecheck",
143
+ "tests"
144
+ ],
145
+ "time": "2017-12-06T16:27:17+00:00"
146
+ },
147
+ {
148
+ "name": "phpcompatibility/php-compatibility",
149
+ "version": "9.3.5",
150
+ "source": {
151
+ "type": "git",
152
+ "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
153
+ "reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
154
+ },
155
+ "dist": {
156
+ "type": "zip",
157
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
158
+ "reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
159
+ "shasum": ""
160
+ },
161
+ "require": {
162
+ "php": ">=5.3",
163
+ "squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
164
+ },
165
+ "conflict": {
166
+ "squizlabs/php_codesniffer": "2.6.2"
167
+ },
168
+ "require-dev": {
169
+ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
170
+ },
171
+ "suggest": {
172
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
173
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
174
+ },
175
+ "type": "phpcodesniffer-standard",
176
+ "notification-url": "https://packagist.org/downloads/",
177
+ "license": [
178
+ "LGPL-3.0-or-later"
179
+ ],
180
+ "authors": [
181
+ {
182
+ "name": "Wim Godden",
183
+ "homepage": "https://github.com/wimg",
184
+ "role": "lead"
185
+ },
186
+ {
187
+ "name": "Juliette Reinders Folmer",
188
+ "homepage": "https://github.com/jrfnl",
189
+ "role": "lead"
190
+ },
191
+ {
192
+ "name": "Contributors",
193
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
194
+ }
195
+ ],
196
+ "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
197
+ "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
198
+ "keywords": [
199
+ "compatibility",
200
+ "phpcs",
201
+ "standards"
202
+ ],
203
+ "time": "2019-12-27T09:44:58+00:00"
204
+ },
205
+ {
206
+ "name": "phpcompatibility/phpcompatibility-paragonie",
207
+ "version": "1.3.0",
208
+ "source": {
209
+ "type": "git",
210
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
211
+ "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c"
212
+ },
213
+ "dist": {
214
+ "type": "zip",
215
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c",
216
+ "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c",
217
+ "shasum": ""
218
+ },
219
+ "require": {
220
+ "phpcompatibility/php-compatibility": "^9.0"
221
+ },
222
+ "require-dev": {
223
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5",
224
+ "paragonie/random_compat": "dev-master",
225
+ "paragonie/sodium_compat": "dev-master"
226
+ },
227
+ "suggest": {
228
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
229
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
230
+ },
231
+ "type": "phpcodesniffer-standard",
232
+ "notification-url": "https://packagist.org/downloads/",
233
+ "license": [
234
+ "LGPL-3.0-or-later"
235
+ ],
236
+ "authors": [
237
+ {
238
+ "name": "Wim Godden",
239
+ "role": "lead"
240
+ },
241
+ {
242
+ "name": "Juliette Reinders Folmer",
243
+ "role": "lead"
244
+ }
245
+ ],
246
+ "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
247
+ "homepage": "http://phpcompatibility.com/",
248
+ "keywords": [
249
+ "compatibility",
250
+ "paragonie",
251
+ "phpcs",
252
+ "polyfill",
253
+ "standards"
254
+ ],
255
+ "time": "2019-11-04T15:17:54+00:00"
256
+ },
257
+ {
258
+ "name": "phpcompatibility/phpcompatibility-wp",
259
+ "version": "2.1.0",
260
+ "source": {
261
+ "type": "git",
262
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
263
+ "reference": "41bef18ba688af638b7310666db28e1ea9158b2f"
264
+ },
265
+ "dist": {
266
+ "type": "zip",
267
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f",
268
+ "reference": "41bef18ba688af638b7310666db28e1ea9158b2f",
269
+ "shasum": ""
270
+ },
271
+ "require": {
272
+ "phpcompatibility/php-compatibility": "^9.0",
273
+ "phpcompatibility/phpcompatibility-paragonie": "^1.0"
274
+ },
275
+ "require-dev": {
276
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5"
277
+ },
278
+ "suggest": {
279
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
280
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
281
+ },
282
+ "type": "phpcodesniffer-standard",
283
+ "notification-url": "https://packagist.org/downloads/",
284
+ "license": [
285
+ "LGPL-3.0-or-later"
286
+ ],
287
+ "authors": [
288
+ {
289
+ "name": "Wim Godden",
290
+ "role": "lead"
291
+ },
292
+ {
293
+ "name": "Juliette Reinders Folmer",
294
+ "role": "lead"
295
+ }
296
+ ],
297
+ "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
298
+ "homepage": "http://phpcompatibility.com/",
299
+ "keywords": [
300
+ "compatibility",
301
+ "phpcs",
302
+ "standards",
303
+ "wordpress"
304
+ ],
305
+ "time": "2019-08-28T14:22:28+00:00"
306
+ },
307
+ {
308
+ "name": "psr/container",
309
+ "version": "1.0.0",
310
+ "source": {
311
+ "type": "git",
312
+ "url": "https://github.com/php-fig/container.git",
313
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
314
+ },
315
+ "dist": {
316
+ "type": "zip",
317
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
318
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
319
+ "shasum": ""
320
+ },
321
+ "require": {
322
+ "php": ">=5.3.0"
323
+ },
324
+ "type": "library",
325
+ "extra": {
326
+ "branch-alias": {
327
+ "dev-master": "1.0.x-dev"
328
+ }
329
+ },
330
+ "autoload": {
331
+ "psr-4": {
332
+ "Psr\\Container\\": "src/"
333
+ }
334
+ },
335
+ "notification-url": "https://packagist.org/downloads/",
336
+ "license": [
337
+ "MIT"
338
+ ],
339
+ "authors": [
340
+ {
341
+ "name": "PHP-FIG",
342
+ "homepage": "http://www.php-fig.org/"
343
+ }
344
+ ],
345
+ "description": "Common Container Interface (PHP FIG PSR-11)",
346
+ "homepage": "https://github.com/php-fig/container",
347
+ "keywords": [
348
+ "PSR-11",
349
+ "container",
350
+ "container-interface",
351
+ "container-interop",
352
+ "psr"
353
+ ],
354
+ "time": "2017-02-14T16:28:37+00:00"
355
+ },
356
+ {
357
+ "name": "squizlabs/php_codesniffer",
358
+ "version": "3.5.4",
359
+ "source": {
360
+ "type": "git",
361
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
362
+ "reference": "dceec07328401de6211037abbb18bda423677e26"
363
+ },
364
+ "dist": {
365
+ "type": "zip",
366
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dceec07328401de6211037abbb18bda423677e26",
367
+ "reference": "dceec07328401de6211037abbb18bda423677e26",
368
+ "shasum": ""
369
+ },
370
+ "require": {
371
+ "ext-simplexml": "*",
372
+ "ext-tokenizer": "*",
373
+ "ext-xmlwriter": "*",
374
+ "php": ">=5.4.0"
375
+ },
376
+ "require-dev": {
377
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
378
+ },
379
+ "bin": [
380
+ "bin/phpcs",
381
+ "bin/phpcbf"
382
+ ],
383
+ "type": "library",
384
+ "extra": {
385
+ "branch-alias": {
386
+ "dev-master": "3.x-dev"
387
+ }
388
+ },
389
+ "notification-url": "https://packagist.org/downloads/",
390
+ "license": [
391
+ "BSD-3-Clause"
392
+ ],
393
+ "authors": [
394
+ {
395
+ "name": "Greg Sherwood",
396
+ "role": "lead"
397
+ }
398
+ ],
399
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
400
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
401
+ "keywords": [
402
+ "phpcs",
403
+ "standards"
404
+ ],
405
+ "time": "2020-01-30T22:20:29+00:00"
406
+ },
407
+ {
408
+ "name": "symfony/console",
409
+ "version": "v5.0.5",
410
+ "source": {
411
+ "type": "git",
412
+ "url": "https://github.com/symfony/console.git",
413
+ "reference": "d29e2d36941de13600c399e393a60b8cfe59ac49"
414
+ },
415
+ "dist": {
416
+ "type": "zip",
417
+ "url": "https://api.github.com/repos/symfony/console/zipball/d29e2d36941de13600c399e393a60b8cfe59ac49",
418
+ "reference": "d29e2d36941de13600c399e393a60b8cfe59ac49",
419
+ "shasum": ""
420
+ },
421
+ "require": {
422
+ "php": "^7.2.5",
423
+ "symfony/polyfill-mbstring": "~1.0",
424
+ "symfony/polyfill-php73": "^1.8",
425
+ "symfony/service-contracts": "^1.1|^2"
426
+ },
427
+ "conflict": {
428
+ "symfony/dependency-injection": "<4.4",
429
+ "symfony/event-dispatcher": "<4.4",
430
+ "symfony/lock": "<4.4",
431
+ "symfony/process": "<4.4"
432
+ },
433
+ "provide": {
434
+ "psr/log-implementation": "1.0"
435
+ },
436
+ "require-dev": {
437
+ "psr/log": "~1.0",
438
+ "symfony/config": "^4.4|^5.0",
439
+ "symfony/dependency-injection": "^4.4|^5.0",
440
+ "symfony/event-dispatcher": "^4.4|^5.0",
441
+ "symfony/lock": "^4.4|^5.0",
442
+ "symfony/process": "^4.4|^5.0",
443
+ "symfony/var-dumper": "^4.4|^5.0"
444
+ },
445
+ "suggest": {
446
+ "psr/log": "For using the console logger",
447
+ "symfony/event-dispatcher": "",
448
+ "symfony/lock": "",
449
+ "symfony/process": ""
450
+ },
451
+ "type": "library",
452
+ "extra": {
453
+ "branch-alias": {
454
+ "dev-master": "5.0-dev"
455
+ }
456
+ },
457
+ "autoload": {
458
+ "psr-4": {
459
+ "Symfony\\Component\\Console\\": ""
460
+ },
461
+ "exclude-from-classmap": [
462
+ "/Tests/"
463
+ ]
464
+ },
465
+ "notification-url": "https://packagist.org/downloads/",
466
+ "license": [
467
+ "MIT"
468
+ ],
469
+ "authors": [
470
+ {
471
+ "name": "Fabien Potencier",
472
+ "email": "fabien@symfony.com"
473
+ },
474
+ {
475
+ "name": "Symfony Community",
476
+ "homepage": "https://symfony.com/contributors"
477
+ }
478
+ ],
479
+ "description": "Symfony Console Component",
480
+ "homepage": "https://symfony.com",
481
+ "time": "2020-02-24T15:05:31+00:00"
482
+ },
483
+ {
484
+ "name": "symfony/polyfill-mbstring",
485
+ "version": "v1.14.0",
486
+ "source": {
487
+ "type": "git",
488
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
489
+ "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2"
490
+ },
491
+ "dist": {
492
+ "type": "zip",
493
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2",
494
+ "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2",
495
+ "shasum": ""
496
+ },
497
+ "require": {
498
+ "php": ">=5.3.3"
499
+ },
500
+ "suggest": {
501
+ "ext-mbstring": "For best performance"
502
+ },
503
+ "type": "library",
504
+ "extra": {
505
+ "branch-alias": {
506
+ "dev-master": "1.14-dev"
507
+ }
508
+ },
509
+ "autoload": {
510
+ "psr-4": {
511
+ "Symfony\\Polyfill\\Mbstring\\": ""
512
+ },
513
+ "files": [
514
+ "bootstrap.php"
515
+ ]
516
+ },
517
+ "notification-url": "https://packagist.org/downloads/",
518
+ "license": [
519
+ "MIT"
520
+ ],
521
+ "authors": [
522
+ {
523
+ "name": "Nicolas Grekas",
524
+ "email": "p@tchwork.com"
525
+ },
526
+ {
527
+ "name": "Symfony Community",
528
+ "homepage": "https://symfony.com/contributors"
529
+ }
530
+ ],
531
+ "description": "Symfony polyfill for the Mbstring extension",
532
+ "homepage": "https://symfony.com",
533
+ "keywords": [
534
+ "compatibility",
535
+ "mbstring",
536
+ "polyfill",
537
+ "portable",
538
+ "shim"
539
+ ],
540
+ "time": "2020-01-13T11:15:53+00:00"
541
+ },
542
+ {
543
+ "name": "symfony/polyfill-php73",
544
+ "version": "v1.14.0",
545
+ "source": {
546
+ "type": "git",
547
+ "url": "https://github.com/symfony/polyfill-php73.git",
548
+ "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675"
549
+ },
550
+ "dist": {
551
+ "type": "zip",
552
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/5e66a0fa1070bf46bec4bea7962d285108edd675",
553
+ "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675",
554
+ "shasum": ""
555
+ },
556
+ "require": {
557
+ "php": ">=5.3.3"
558
+ },
559
+ "type": "library",
560
+ "extra": {
561
+ "branch-alias": {
562
+ "dev-master": "1.14-dev"
563
+ }
564
+ },
565
+ "autoload": {
566
+ "psr-4": {
567
+ "Symfony\\Polyfill\\Php73\\": ""
568
+ },
569
+ "files": [
570
+ "bootstrap.php"
571
+ ],
572
+ "classmap": [
573
+ "Resources/stubs"
574
+ ]
575
+ },
576
+ "notification-url": "https://packagist.org/downloads/",
577
+ "license": [
578
+ "MIT"
579
+ ],
580
+ "authors": [
581
+ {
582
+ "name": "Nicolas Grekas",
583
+ "email": "p@tchwork.com"
584
+ },
585
+ {
586
+ "name": "Symfony Community",
587
+ "homepage": "https://symfony.com/contributors"
588
+ }
589
+ ],
590
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
591
+ "homepage": "https://symfony.com",
592
+ "keywords": [
593
+ "compatibility",
594
+ "polyfill",
595
+ "portable",
596
+ "shim"
597
+ ],
598
+ "time": "2020-01-13T11:15:53+00:00"
599
+ },
600
+ {
601
+ "name": "symfony/service-contracts",
602
+ "version": "v2.0.1",
603
+ "source": {
604
+ "type": "git",
605
+ "url": "https://github.com/symfony/service-contracts.git",
606
+ "reference": "144c5e51266b281231e947b51223ba14acf1a749"
607
+ },
608
+ "dist": {
609
+ "type": "zip",
610
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749",
611
+ "reference": "144c5e51266b281231e947b51223ba14acf1a749",
612
+ "shasum": ""
613
+ },
614
+ "require": {
615
+ "php": "^7.2.5",
616
+ "psr/container": "^1.0"
617
+ },
618
+ "suggest": {
619
+ "symfony/service-implementation": ""
620
+ },
621
+ "type": "library",
622
+ "extra": {
623
+ "branch-alias": {
624
+ "dev-master": "2.0-dev"
625
+ }
626
+ },
627
+ "autoload": {
628
+ "psr-4": {
629
+ "Symfony\\Contracts\\Service\\": ""
630
+ }
631
+ },
632
+ "notification-url": "https://packagist.org/downloads/",
633
+ "license": [
634
+ "MIT"
635
+ ],
636
+ "authors": [
637
+ {
638
+ "name": "Nicolas Grekas",
639
+ "email": "p@tchwork.com"
640
+ },
641
+ {
642
+ "name": "Symfony Community",
643
+ "homepage": "https://symfony.com/contributors"
644
+ }
645
+ ],
646
+ "description": "Generic abstractions related to writing services",
647
+ "homepage": "https://symfony.com",
648
+ "keywords": [
649
+ "abstractions",
650
+ "contracts",
651
+ "decoupling",
652
+ "interfaces",
653
+ "interoperability",
654
+ "standards"
655
+ ],
656
+ "time": "2019-11-18T17:27:11+00:00"
657
+ },
658
+ {
659
+ "name": "wp-coding-standards/wpcs",
660
+ "version": "2.2.1",
661
+ "source": {
662
+ "type": "git",
663
+ "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
664
+ "reference": "b5a453203114cc2284b1a614c4953456fbe4f546"
665
+ },
666
+ "dist": {
667
+ "type": "zip",
668
+ "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/b5a453203114cc2284b1a614c4953456fbe4f546",
669
+ "reference": "b5a453203114cc2284b1a614c4953456fbe4f546",
670
+ "shasum": ""
671
+ },
672
+ "require": {
673
+ "php": ">=5.4",
674
+ "squizlabs/php_codesniffer": "^3.3.1"
675
+ },
676
+ "require-dev": {
677
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6",
678
+ "phpcompatibility/php-compatibility": "^9.0",
679
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
680
+ },
681
+ "suggest": {
682
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
683
+ },
684
+ "type": "phpcodesniffer-standard",
685
+ "notification-url": "https://packagist.org/downloads/",
686
+ "license": [
687
+ "MIT"
688
+ ],
689
+ "authors": [
690
+ {
691
+ "name": "Contributors",
692
+ "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
693
+ }
694
+ ],
695
+ "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
696
+ "keywords": [
697
+ "phpcs",
698
+ "standards",
699
+ "wordpress"
700
+ ],
701
+ "time": "2020-02-04T02:52:06+00:00"
702
+ }
703
+ ],
704
+ "aliases": [],
705
+ "minimum-stability": "stable",
706
+ "stability-flags": [],
707
+ "prefer-stable": false,
708
+ "prefer-lowest": false,
709
+ "platform": [],
710
+ "platform-dev": []
711
+ }
admin/bsf-analytics/package-lock.json ADDED
@@ -0,0 +1,3978 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "bsf-analytics",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 1,
5
+ "requires": true,
6
+ "dependencies": {
7
+ "abbrev": {
8
+ "version": "1.1.1",
9
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
10
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
11
+ },
12
+ "ajv": {
13
+ "version": "6.12.0",
14
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
15
+ "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
16
+ "dev": true,
17
+ "requires": {
18
+ "fast-deep-equal": "^3.1.1",
19
+ "fast-json-stable-stringify": "^2.0.0",
20
+ "json-schema-traverse": "^0.4.1",
21
+ "uri-js": "^4.2.2"
22
+ }
23
+ },
24
+ "amdefine": {
25
+ "version": "1.0.1",
26
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
27
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
28
+ "dev": true
29
+ },
30
+ "ansi-regex": {
31
+ "version": "2.1.1",
32
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
33
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
34
+ "dev": true
35
+ },
36
+ "ansi-styles": {
37
+ "version": "3.2.1",
38
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
39
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
40
+ "dev": true,
41
+ "requires": {
42
+ "color-convert": "^1.9.0"
43
+ }
44
+ },
45
+ "aproba": {
46
+ "version": "1.2.0",
47
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
48
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
49
+ "dev": true
50
+ },
51
+ "archiver": {
52
+ "version": "1.3.0",
53
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
54
+ "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
55
+ "dev": true,
56
+ "requires": {
57
+ "archiver-utils": "^1.3.0",
58
+ "async": "^2.0.0",
59
+ "buffer-crc32": "^0.2.1",
60
+ "glob": "^7.0.0",
61
+ "lodash": "^4.8.0",
62
+ "readable-stream": "^2.0.0",
63
+ "tar-stream": "^1.5.0",
64
+ "walkdir": "^0.0.11",
65
+ "zip-stream": "^1.1.0"
66
+ },
67
+ "dependencies": {
68
+ "async": {
69
+ "version": "2.6.3",
70
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
71
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
72
+ "dev": true,
73
+ "requires": {
74
+ "lodash": "^4.17.14"
75
+ }
76
+ }
77
+ }
78
+ },
79
+ "archiver-utils": {
80
+ "version": "1.3.0",
81
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
82
+ "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
83
+ "dev": true,
84
+ "requires": {
85
+ "glob": "^7.0.0",
86
+ "graceful-fs": "^4.1.0",
87
+ "lazystream": "^1.0.0",
88
+ "lodash": "^4.8.0",
89
+ "normalize-path": "^2.0.0",
90
+ "readable-stream": "^2.0.0"
91
+ }
92
+ },
93
+ "are-we-there-yet": {
94
+ "version": "1.1.5",
95
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
96
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
97
+ "dev": true,
98
+ "requires": {
99
+ "delegates": "^1.0.0",
100
+ "readable-stream": "^2.0.6"
101
+ }
102
+ },
103
+ "argparse": {
104
+ "version": "1.0.10",
105
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
106
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
107
+ "dev": true,
108
+ "requires": {
109
+ "sprintf-js": "~1.0.2"
110
+ },
111
+ "dependencies": {
112
+ "sprintf-js": {
113
+ "version": "1.0.3",
114
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
115
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
116
+ "dev": true
117
+ }
118
+ }
119
+ },
120
+ "arr-diff": {
121
+ "version": "4.0.0",
122
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
123
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
124
+ },
125
+ "arr-flatten": {
126
+ "version": "1.1.0",
127
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
128
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
129
+ },
130
+ "arr-union": {
131
+ "version": "3.1.0",
132
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
133
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
134
+ },
135
+ "array-each": {
136
+ "version": "1.0.1",
137
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
138
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8="
139
+ },
140
+ "array-find-index": {
141
+ "version": "1.0.2",
142
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
143
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
144
+ "dev": true
145
+ },
146
+ "array-slice": {
147
+ "version": "1.1.0",
148
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
149
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="
150
+ },
151
+ "array-unique": {
152
+ "version": "0.3.2",
153
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
154
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
155
+ },
156
+ "asn1": {
157
+ "version": "0.2.4",
158
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
159
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
160
+ "dev": true,
161
+ "requires": {
162
+ "safer-buffer": "~2.1.0"
163
+ }
164
+ },
165
+ "assert-plus": {
166
+ "version": "1.0.0",
167
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
168
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
169
+ "dev": true
170
+ },
171
+ "assign-symbols": {
172
+ "version": "1.0.0",
173
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
174
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
175
+ },
176
+ "async": {
177
+ "version": "1.5.2",
178
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
179
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
180
+ "dev": true
181
+ },
182
+ "async-foreach": {
183
+ "version": "0.1.3",
184
+ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
185
+ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
186
+ "dev": true
187
+ },
188
+ "asynckit": {
189
+ "version": "0.4.0",
190
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
191
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
192
+ "dev": true
193
+ },
194
+ "atob": {
195
+ "version": "2.1.2",
196
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
197
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
198
+ },
199
+ "autoprefixer": {
200
+ "version": "9.7.6",
201
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.6.tgz",
202
+ "integrity": "sha512-F7cYpbN7uVVhACZTeeIeealwdGM6wMtfWARVLTy5xmKtgVdBNJvbDRoCK3YO1orcs7gv/KwYlb3iXwu9Ug9BkQ==",
203
+ "dev": true,
204
+ "requires": {
205
+ "browserslist": "^4.11.1",
206
+ "caniuse-lite": "^1.0.30001039",
207
+ "chalk": "^2.4.2",
208
+ "normalize-range": "^0.1.2",
209
+ "num2fraction": "^1.2.2",
210
+ "postcss": "^7.0.27",
211
+ "postcss-value-parser": "^4.0.3"
212
+ }
213
+ },
214
+ "aws-sign2": {
215
+ "version": "0.7.0",
216
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
217
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
218
+ "dev": true
219
+ },
220
+ "aws4": {
221
+ "version": "1.9.1",
222
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
223
+ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
224
+ "dev": true
225
+ },
226
+ "balanced-match": {
227
+ "version": "1.0.0",
228
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
229
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
230
+ "dev": true
231
+ },
232
+ "base": {
233
+ "version": "0.11.2",
234
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
235
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
236
+ "requires": {
237
+ "cache-base": "^1.0.1",
238
+ "class-utils": "^0.3.5",
239
+ "component-emitter": "^1.2.1",
240
+ "define-property": "^1.0.0",
241
+ "isobject": "^3.0.1",
242
+ "mixin-deep": "^1.2.0",
243
+ "pascalcase": "^0.1.1"
244
+ },
245
+ "dependencies": {
246
+ "define-property": {
247
+ "version": "1.0.0",
248
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
249
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
250
+ "requires": {
251
+ "is-descriptor": "^1.0.0"
252
+ }
253
+ },
254
+ "is-accessor-descriptor": {
255
+ "version": "1.0.0",
256
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
257
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
258
+ "requires": {
259
+ "kind-of": "^6.0.0"
260
+ }
261
+ },
262
+ "is-data-descriptor": {
263
+ "version": "1.0.0",
264
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
265
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
266
+ "requires": {
267
+ "kind-of": "^6.0.0"
268
+ }
269
+ },
270
+ "is-descriptor": {
271
+ "version": "1.0.2",
272
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
273
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
274
+ "requires": {
275
+ "is-accessor-descriptor": "^1.0.0",
276
+ "is-data-descriptor": "^1.0.0",
277
+ "kind-of": "^6.0.2"
278
+ }
279
+ }
280
+ }
281
+ },
282
+ "base64-js": {
283
+ "version": "1.3.1",
284
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
285
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
286
+ "dev": true
287
+ },
288
+ "bcrypt-pbkdf": {
289
+ "version": "1.0.2",
290
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
291
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
292
+ "dev": true,
293
+ "requires": {
294
+ "tweetnacl": "^0.14.3"
295
+ }
296
+ },
297
+ "bl": {
298
+ "version": "1.2.2",
299
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
300
+ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
301
+ "dev": true,
302
+ "requires": {
303
+ "readable-stream": "^2.3.5",
304
+ "safe-buffer": "^5.1.1"
305
+ }
306
+ },
307
+ "block-stream": {
308
+ "version": "0.0.9",
309
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
310
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
311
+ "dev": true,
312
+ "requires": {
313
+ "inherits": "~2.0.0"
314
+ }
315
+ },
316
+ "brace-expansion": {
317
+ "version": "1.1.11",
318
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
319
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
320
+ "dev": true,
321
+ "requires": {
322
+ "balanced-match": "^1.0.0",
323
+ "concat-map": "0.0.1"
324
+ }
325
+ },
326
+ "braces": {
327
+ "version": "2.3.2",
328
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
329
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
330
+ "requires": {
331
+ "arr-flatten": "^1.1.0",
332
+ "array-unique": "^0.3.2",
333
+ "extend-shallow": "^2.0.1",
334
+ "fill-range": "^4.0.0",
335
+ "isobject": "^3.0.1",
336
+ "repeat-element": "^1.1.2",
337
+ "snapdragon": "^0.8.1",
338
+ "snapdragon-node": "^2.0.1",
339
+ "split-string": "^3.0.2",
340
+ "to-regex": "^3.0.1"
341
+ },
342
+ "dependencies": {
343
+ "extend-shallow": {
344
+ "version": "2.0.1",
345
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
346
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
347
+ "requires": {
348
+ "is-extendable": "^0.1.0"
349
+ }
350
+ }
351
+ }
352
+ },
353
+ "browserslist": {
354
+ "version": "4.11.1",
355
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz",
356
+ "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==",
357
+ "dev": true,
358
+ "requires": {
359
+ "caniuse-lite": "^1.0.30001038",
360
+ "electron-to-chromium": "^1.3.390",
361
+ "node-releases": "^1.1.53",
362
+ "pkg-up": "^2.0.0"
363
+ }
364
+ },
365
+ "buffer": {
366
+ "version": "5.6.0",
367
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
368
+ "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
369
+ "dev": true,
370
+ "requires": {
371
+ "base64-js": "^1.0.2",
372
+ "ieee754": "^1.1.4"
373
+ }
374
+ },
375
+ "buffer-alloc": {
376
+ "version": "1.2.0",
377
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
378
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
379
+ "dev": true,
380
+ "requires": {
381
+ "buffer-alloc-unsafe": "^1.1.0",
382
+ "buffer-fill": "^1.0.0"
383
+ }
384
+ },
385
+ "buffer-alloc-unsafe": {
386
+ "version": "1.1.0",
387
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
388
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
389
+ "dev": true
390
+ },
391
+ "buffer-crc32": {
392
+ "version": "0.2.13",
393
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
394
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
395
+ "dev": true
396
+ },
397
+ "buffer-fill": {
398
+ "version": "1.0.0",
399
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
400
+ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
401
+ "dev": true
402
+ },
403
+ "cache-base": {
404
+ "version": "1.0.1",
405
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
406
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
407
+ "requires": {
408
+ "collection-visit": "^1.0.0",
409
+ "component-emitter": "^1.2.1",
410
+ "get-value": "^2.0.6",
411
+ "has-value": "^1.0.0",
412
+ "isobject": "^3.0.1",
413
+ "set-value": "^2.0.0",
414
+ "to-object-path": "^0.3.0",
415
+ "union-value": "^1.0.0",
416
+ "unset-value": "^1.0.0"
417
+ }
418
+ },
419
+ "camelcase": {
420
+ "version": "2.1.1",
421
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
422
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
423
+ "dev": true
424
+ },
425
+ "camelcase-keys": {
426
+ "version": "2.1.0",
427
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
428
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
429
+ "dev": true,
430
+ "requires": {
431
+ "camelcase": "^2.0.0",
432
+ "map-obj": "^1.0.0"
433
+ }
434
+ },
435
+ "caniuse-lite": {
436
+ "version": "1.0.30001042",
437
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001042.tgz",
438
+ "integrity": "sha512-igMQ4dlqnf4tWv0xjaaE02op9AJ2oQzXKjWf4EuAHFN694Uo9/EfPVIPJcmn2WkU9RqozCxx5e2KPcVClHDbDw==",
439
+ "dev": true
440
+ },
441
+ "caseless": {
442
+ "version": "0.12.0",
443
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
444
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
445
+ "dev": true
446
+ },
447
+ "chalk": {
448
+ "version": "2.4.2",
449
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
450
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
451
+ "dev": true,
452
+ "requires": {
453
+ "ansi-styles": "^3.2.1",
454
+ "escape-string-regexp": "^1.0.5",
455
+ "supports-color": "^5.3.0"
456
+ }
457
+ },
458
+ "chownr": {
459
+ "version": "1.1.4",
460
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
461
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
462
+ "dev": true,
463
+ "optional": true
464
+ },
465
+ "class-utils": {
466
+ "version": "0.3.6",
467
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
468
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
469
+ "requires": {
470
+ "arr-union": "^3.1.0",
471
+ "define-property": "^0.2.5",
472
+ "isobject": "^3.0.0",
473
+ "static-extend": "^0.1.1"
474
+ },
475
+ "dependencies": {
476
+ "define-property": {
477
+ "version": "0.2.5",
478
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
479
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
480
+ "requires": {
481
+ "is-descriptor": "^0.1.0"
482
+ }
483
+ }
484
+ }
485
+ },
486
+ "clean-css": {
487
+ "version": "4.2.3",
488
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
489
+ "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
490
+ "dev": true,
491
+ "requires": {
492
+ "source-map": "~0.6.0"
493
+ },
494
+ "dependencies": {
495
+ "source-map": {
496
+ "version": "0.6.1",
497
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
498
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
499
+ "dev": true
500
+ }
501
+ }
502
+ },
503
+ "cliui": {
504
+ "version": "3.2.0",
505
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
506
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
507
+ "dev": true,
508
+ "requires": {
509
+ "string-width": "^1.0.1",
510
+ "strip-ansi": "^3.0.1",
511
+ "wrap-ansi": "^2.0.0"
512
+ }
513
+ },
514
+ "code-point-at": {
515
+ "version": "1.1.0",
516
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
517
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
518
+ "dev": true
519
+ },
520
+ "coffeescript": {
521
+ "version": "1.10.0",
522
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
523
+ "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
524
+ "dev": true
525
+ },
526
+ "collection-visit": {
527
+ "version": "1.0.0",
528
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
529
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
530
+ "requires": {
531
+ "map-visit": "^1.0.0",
532
+ "object-visit": "^1.0.0"
533
+ }
534
+ },
535
+ "color-convert": {
536
+ "version": "1.9.3",
537
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
538
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
539
+ "dev": true,
540
+ "requires": {
541
+ "color-name": "1.1.3"
542
+ }
543
+ },
544
+ "color-name": {
545
+ "version": "1.1.3",
546
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
547
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
548
+ "dev": true
549
+ },
550
+ "colors": {
551
+ "version": "1.1.2",
552
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
553
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
554
+ "dev": true
555
+ },
556
+ "combined-stream": {
557
+ "version": "1.0.8",
558
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
559
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
560
+ "dev": true,
561
+ "requires": {
562
+ "delayed-stream": "~1.0.0"
563
+ }
564
+ },
565
+ "commander": {
566
+ "version": "2.1.0",
567
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
568
+ "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
569
+ "dev": true
570
+ },
571
+ "component-emitter": {
572
+ "version": "1.3.0",
573
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
574
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
575
+ },
576
+ "compress-commons": {
577
+ "version": "1.2.2",
578
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
579
+ "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
580
+ "dev": true,
581
+ "requires": {
582
+ "buffer-crc32": "^0.2.1",
583
+ "crc32-stream": "^2.0.0",
584
+ "normalize-path": "^2.0.0",
585
+ "readable-stream": "^2.0.0"
586
+ }
587
+ },
588
+ "concat-map": {
589
+ "version": "0.0.1",
590
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
591
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
592
+ "dev": true
593
+ },
594
+ "console-control-strings": {
595
+ "version": "1.1.0",
596
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
597
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
598
+ "dev": true
599
+ },
600
+ "copy-descriptor": {
601
+ "version": "0.1.1",
602
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
603
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
604
+ },
605
+ "core-util-is": {
606
+ "version": "1.0.2",
607
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
608
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
609
+ "dev": true
610
+ },
611
+ "crc": {
612
+ "version": "3.8.0",
613
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
614
+ "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
615
+ "dev": true,
616
+ "requires": {
617
+ "buffer": "^5.1.0"
618
+ }
619
+ },
620
+ "crc32-stream": {
621
+ "version": "2.0.0",
622
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
623
+ "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
624
+ "dev": true,
625
+ "requires": {
626
+ "crc": "^3.4.4",
627
+ "readable-stream": "^2.0.0"
628
+ }
629
+ },
630
+ "cross-spawn": {
631
+ "version": "3.0.1",
632
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
633
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
634
+ "dev": true,
635
+ "requires": {
636
+ "lru-cache": "^4.0.1",
637
+ "which": "^1.2.9"
638
+ }
639
+ },
640
+ "currently-unhandled": {
641
+ "version": "0.4.1",
642
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
643
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
644
+ "dev": true,
645
+ "requires": {
646
+ "array-find-index": "^1.0.1"
647
+ }
648
+ },
649
+ "dashdash": {
650
+ "version": "1.14.1",
651
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
652
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
653
+ "dev": true,
654
+ "requires": {
655
+ "assert-plus": "^1.0.0"
656
+ }
657
+ },
658
+ "dateformat": {
659
+ "version": "1.0.12",
660
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
661
+ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
662
+ "dev": true,
663
+ "requires": {
664
+ "get-stdin": "^4.0.1",
665
+ "meow": "^3.3.0"
666
+ }
667
+ },
668
+ "debug": {
669
+ "version": "2.6.9",
670
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
671
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
672
+ "requires": {
673
+ "ms": "2.0.0"
674
+ }
675
+ },
676
+ "decamelize": {
677
+ "version": "1.2.0",
678
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
679
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
680
+ "dev": true
681
+ },
682
+ "decode-uri-component": {
683
+ "version": "0.2.0",
684
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
685
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
686
+ },
687
+ "decompress-response": {
688
+ "version": "4.2.1",
689
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
690
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
691
+ "dev": true,
692
+ "optional": true,
693
+ "requires": {
694
+ "mimic-response": "^2.0.0"
695
+ }
696
+ },
697
+ "deep-extend": {
698
+ "version": "0.6.0",
699
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
700
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
701
+ "dev": true,
702
+ "optional": true
703
+ },
704
+ "define-property": {
705
+ "version": "2.0.2",
706
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
707
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
708
+ "requires": {
709
+ "is-descriptor": "^1.0.2",
710
+ "isobject": "^3.0.1"
711
+ },
712
+ "dependencies": {
713
+ "is-accessor-descriptor": {
714
+ "version": "1.0.0",
715
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
716
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
717
+ "requires": {
718
+ "kind-of": "^6.0.0"
719
+ }
720
+ },
721
+ "is-data-descriptor": {
722
+ "version": "1.0.0",
723
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
724
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
725
+ "requires": {
726
+ "kind-of": "^6.0.0"
727
+ }
728
+ },
729
+ "is-descriptor": {
730
+ "version": "1.0.2",
731
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
732
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
733
+ "requires": {
734
+ "is-accessor-descriptor": "^1.0.0",
735
+ "is-data-descriptor": "^1.0.0",
736
+ "kind-of": "^6.0.2"
737
+ }
738
+ }
739
+ }
740
+ },
741
+ "delayed-stream": {
742
+ "version": "1.0.0",
743
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
744
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
745
+ "dev": true
746
+ },
747
+ "delegates": {
748
+ "version": "1.0.0",
749
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
750
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
751
+ "dev": true
752
+ },
753
+ "detect-file": {
754
+ "version": "1.0.0",
755
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
756
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
757
+ },
758
+ "detect-libc": {
759
+ "version": "1.0.3",
760
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
761
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
762
+ "dev": true,
763
+ "optional": true
764
+ },
765
+ "diff": {
766
+ "version": "3.5.0",
767
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
768
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
769
+ "dev": true
770
+ },
771
+ "duplexer": {
772
+ "version": "0.1.1",
773
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
774
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
775
+ "dev": true
776
+ },
777
+ "ecc-jsbn": {
778
+ "version": "0.1.2",
779
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
780
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
781
+ "dev": true,
782
+ "requires": {
783
+ "jsbn": "~0.1.0",
784
+ "safer-buffer": "^2.1.0"
785
+ }
786
+ },
787
+ "electron-to-chromium": {
788
+ "version": "1.3.409",
789
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.409.tgz",
790
+ "integrity": "sha512-CB2HUXiMsaVYY5VvcpELhDShiTRhI2FfN7CuacEZ5mDmMFuSG/ZVm8HoSya0+S61RvUd3TjIjFSKywqHZpRPzQ==",
791
+ "dev": true
792
+ },
793
+ "end-of-stream": {
794
+ "version": "1.4.4",
795
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
796
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
797
+ "dev": true,
798
+ "requires": {
799
+ "once": "^1.4.0"
800
+ }
801
+ },
802
+ "error-ex": {
803
+ "version": "1.3.2",
804
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
805
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
806
+ "dev": true,
807
+ "requires": {
808
+ "is-arrayish": "^0.2.1"
809
+ }
810
+ },
811
+ "escape-string-regexp": {
812
+ "version": "1.0.5",
813
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
814
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
815
+ "dev": true
816
+ },
817
+ "esprima": {
818
+ "version": "4.0.1",
819
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
820
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
821
+ "dev": true
822
+ },
823
+ "eventemitter2": {
824
+ "version": "0.4.14",
825
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
826
+ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
827
+ "dev": true
828
+ },
829
+ "exit": {
830
+ "version": "0.1.2",
831
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
832
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
833
+ "dev": true
834
+ },
835
+ "expand-brackets": {
836
+ "version": "2.1.4",
837
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
838
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
839
+ "requires": {
840
+ "debug": "^2.3.3",
841
+ "define-property": "^0.2.5",
842
+ "extend-shallow": "^2.0.1",
843
+ "posix-character-classes": "^0.1.0",
844
+ "regex-not": "^1.0.0",
845
+ "snapdragon": "^0.8.1",
846
+ "to-regex": "^3.0.1"
847
+ },
848
+ "dependencies": {
849
+ "define-property": {
850
+ "version": "0.2.5",
851
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
852
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
853
+ "requires": {
854
+ "is-descriptor": "^0.1.0"
855
+ }
856
+ },
857
+ "extend-shallow": {
858
+ "version": "2.0.1",
859
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
860
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
861
+ "requires": {
862
+ "is-extendable": "^0.1.0"
863
+ }
864
+ }
865
+ }
866
+ },
867
+ "expand-template": {
868
+ "version": "2.0.3",
869
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
870
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
871
+ "dev": true,
872
+ "optional": true
873
+ },
874
+ "expand-tilde": {
875
+ "version": "2.0.2",
876
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
877
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
878
+ "requires": {
879
+ "homedir-polyfill": "^1.0.1"
880
+ }
881
+ },
882
+ "extend": {
883
+ "version": "3.0.2",
884
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
885
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
886
+ },
887
+ "extend-shallow": {
888
+ "version": "3.0.2",
889
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
890
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
891
+ "requires": {
892
+ "assign-symbols": "^1.0.0",
893
+ "is-extendable": "^1.0.1"
894
+ },
895
+ "dependencies": {
896
+ "is-extendable": {
897
+ "version": "1.0.1",
898
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
899
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
900
+ "requires": {
901
+ "is-plain-object": "^2.0.4"
902
+ }
903
+ }
904
+ }
905
+ },
906
+ "extglob": {
907
+ "version": "2.0.4",
908
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
909
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
910
+ "requires": {
911
+ "array-unique": "^0.3.2",
912
+ "define-property": "^1.0.0",
913
+ "expand-brackets": "^2.1.4",
914
+ "extend-shallow": "^2.0.1",
915
+ "fragment-cache": "^0.2.1",
916
+ "regex-not": "^1.0.0",
917
+ "snapdragon": "^0.8.1",
918
+ "to-regex": "^3.0.1"
919
+ },
920
+ "dependencies": {
921
+ "define-property": {
922
+ "version": "1.0.0",
923
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
924
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
925
+ "requires": {
926
+ "is-descriptor": "^1.0.0"
927
+ }
928
+ },
929
+ "extend-shallow": {
930
+ "version": "2.0.1",
931
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
932
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
933
+ "requires": {
934
+ "is-extendable": "^0.1.0"
935
+ }
936
+ },
937
+ "is-accessor-descriptor": {
938
+ "version": "1.0.0",
939
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
940
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
941
+ "requires": {
942
+ "kind-of": "^6.0.0"
943
+ }
944
+ },
945
+ "is-data-descriptor": {
946
+ "version": "1.0.0",
947
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
948
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
949
+ "requires": {
950
+ "kind-of": "^6.0.0"
951
+ }
952
+ },
953
+ "is-descriptor": {
954
+ "version": "1.0.2",
955
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
956
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
957
+ "requires": {
958
+ "is-accessor-descriptor": "^1.0.0",
959
+ "is-data-descriptor": "^1.0.0",
960
+ "kind-of": "^6.0.2"
961
+ }
962
+ }
963
+ }
964
+ },
965
+ "extsprintf": {
966
+ "version": "1.3.0",
967
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
968
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
969
+ "dev": true
970
+ },
971
+ "fast-deep-equal": {
972
+ "version": "3.1.1",
973
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
974
+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
975
+ "dev": true
976
+ },
977
+ "fast-json-stable-stringify": {
978
+ "version": "2.1.0",
979
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
980
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
981
+ "dev": true
982
+ },
983
+ "figures": {
984
+ "version": "1.7.0",
985
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
986
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
987
+ "dev": true,
988
+ "requires": {
989
+ "escape-string-regexp": "^1.0.5",
990
+ "object-assign": "^4.1.0"
991
+ }
992
+ },
993
+ "file-sync-cmp": {
994
+ "version": "0.1.1",
995
+ "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz",
996
+ "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=",
997
+ "dev": true
998
+ },
999
+ "fill-range": {
1000
+ "version": "4.0.0",
1001
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
1002
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
1003
+ "requires": {
1004
+ "extend-shallow": "^2.0.1",
1005
+ "is-number": "^3.0.0",
1006
+ "repeat-string": "^1.6.1",
1007
+ "to-regex-range": "^2.1.0"
1008
+ },
1009
+ "dependencies": {
1010
+ "extend-shallow": {
1011
+ "version": "2.0.1",
1012
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
1013
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
1014
+ "requires": {
1015
+ "is-extendable": "^0.1.0"
1016
+ }
1017
+ }
1018
+ }
1019
+ },
1020
+ "find-up": {
1021
+ "version": "2.1.0",
1022
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
1023
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
1024
+ "dev": true,
1025
+ "requires": {
1026
+ "locate-path": "^2.0.0"
1027
+ }
1028
+ },
1029
+ "findup": {
1030
+ "version": "0.1.5",
1031
+ "resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz",
1032
+ "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=",
1033
+ "dev": true,
1034
+ "requires": {
1035
+ "colors": "~0.6.0-1",
1036
+ "commander": "~2.1.0"
1037
+ },
1038
+ "dependencies": {
1039
+ "colors": {
1040
+ "version": "0.6.2",
1041
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
1042
+ "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
1043
+ "dev": true
1044
+ }
1045
+ }
1046
+ },
1047
+ "findup-sync": {
1048
+ "version": "2.0.0",
1049
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
1050
+ "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
1051
+ "requires": {
1052
+ "detect-file": "^1.0.0",
1053
+ "is-glob": "^3.1.0",
1054
+ "micromatch": "^3.0.4",
1055
+ "resolve-dir": "^1.0.1"
1056
+ }
1057
+ },
1058
+ "fined": {
1059
+ "version": "1.2.0",
1060
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
1061
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
1062
+ "requires": {
1063
+ "expand-tilde": "^2.0.2",
1064
+ "is-plain-object": "^2.0.3",
1065
+ "object.defaults": "^1.1.0",
1066
+ "object.pick": "^1.2.0",
1067
+ "parse-filepath": "^1.0.1"
1068
+ }
1069
+ },
1070
+ "flagged-respawn": {
1071
+ "version": "1.0.1",
1072
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
1073
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q=="
1074
+ },
1075
+ "for-in": {
1076
+ "version": "1.0.2",
1077
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
1078
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
1079
+ },
1080
+ "for-own": {
1081
+ "version": "1.0.0",
1082
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
1083
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
1084
+ "requires": {
1085
+ "for-in": "^1.0.1"
1086
+ }
1087
+ },
1088
+ "forever-agent": {
1089
+ "version": "0.6.1",
1090
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
1091
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
1092
+ "dev": true
1093
+ },
1094
+ "form-data": {
1095
+ "version": "2.3.3",
1096
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
1097
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
1098
+ "dev": true,
1099
+ "requires": {
1100
+ "asynckit": "^0.4.0",
1101
+ "combined-stream": "^1.0.6",
1102
+ "mime-types": "^2.1.12"
1103
+ }
1104
+ },
1105
+ "fragment-cache": {
1106
+ "version": "0.2.1",
1107
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
1108
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
1109
+ "requires": {
1110
+ "map-cache": "^0.2.2"
1111
+ }
1112
+ },
1113
+ "fs-constants": {
1114
+ "version": "1.0.0",
1115
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
1116
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
1117
+ "dev": true
1118
+ },
1119
+ "fs.realpath": {
1120
+ "version": "1.0.0",
1121
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1122
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
1123
+ "dev": true
1124
+ },
1125
+ "fstream": {
1126
+ "version": "1.0.12",
1127
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
1128
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
1129
+ "dev": true,
1130
+ "requires": {
1131
+ "graceful-fs": "^4.1.2",
1132
+ "inherits": "~2.0.0",
1133
+ "mkdirp": ">=0.5 0",
1134
+ "rimraf": "2"
1135
+ },
1136
+ "dependencies": {
1137
+ "mkdirp": {
1138
+ "version": "0.5.5",
1139
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
1140
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1141
+ "dev": true,
1142
+ "requires": {
1143
+ "minimist": "^1.2.5"
1144
+ }
1145
+ }
1146
+ }
1147
+ },
1148
+ "gauge": {
1149
+ "version": "2.7.4",
1150
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
1151
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
1152
+ "dev": true,
1153
+ "requires": {
1154
+ "aproba": "^1.0.3",
1155
+ "console-control-strings": "^1.0.0",
1156
+ "has-unicode": "^2.0.0",
1157
+ "object-assign": "^4.1.0",
1158
+ "signal-exit": "^3.0.0",
1159
+ "string-width": "^1.0.1",
1160
+ "strip-ansi": "^3.0.1",
1161
+ "wide-align": "^1.1.0"
1162
+ }
1163
+ },
1164
+ "gaze": {
1165
+ "version": "1.1.3",
1166
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
1167
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
1168
+ "dev": true,
1169
+ "requires": {
1170
+ "globule": "^1.0.0"
1171
+ }
1172
+ },
1173
+ "get-caller-file": {
1174
+ "version": "1.0.3",
1175
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
1176
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
1177
+ "dev": true
1178
+ },
1179
+ "get-stdin": {
1180
+ "version": "4.0.1",
1181
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
1182
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
1183
+ "dev": true
1184
+ },
1185
+ "get-value": {
1186
+ "version": "2.0.6",
1187
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
1188
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
1189
+ },
1190
+ "getobject": {
1191
+ "version": "0.1.0",
1192
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
1193
+ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
1194
+ "dev": true
1195
+ },
1196
+ "getpass": {
1197
+ "version": "0.1.7",
1198
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
1199
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
1200
+ "dev": true,
1201
+ "requires": {
1202
+ "assert-plus": "^1.0.0"
1203
+ }
1204
+ },
1205
+ "github-from-package": {
1206
+ "version": "0.0.0",
1207
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
1208
+ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
1209
+ "dev": true,
1210
+ "optional": true
1211
+ },
1212
+ "glob": {
1213
+ "version": "7.0.6",
1214
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
1215
+ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
1216
+ "dev": true,
1217
+ "requires": {
1218
+ "fs.realpath": "^1.0.0",
1219
+ "inflight": "^1.0.4",
1220
+ "inherits": "2",
1221
+ "minimatch": "^3.0.2",
1222
+ "once": "^1.3.0",
1223
+ "path-is-absolute": "^1.0.0"
1224
+ }
1225
+ },
1226
+ "global-modules": {
1227
+ "version": "1.0.0",
1228
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
1229
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
1230
+ "requires": {
1231
+ "global-prefix": "^1.0.1",
1232
+ "is-windows": "^1.0.1",
1233
+ "resolve-dir": "^1.0.0"
1234
+ }
1235
+ },
1236
+ "global-prefix": {
1237
+ "version": "1.0.2",
1238
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
1239
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
1240
+ "requires": {
1241
+ "expand-tilde": "^2.0.2",
1242
+ "homedir-polyfill": "^1.0.1",
1243
+ "ini": "^1.3.4",
1244
+ "is-windows": "^1.0.1",
1245
+ "which": "^1.2.14"
1246
+ }
1247
+ },
1248
+ "globule": {
1249
+ "version": "1.3.1",
1250
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
1251
+ "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
1252
+ "dev": true,
1253
+ "requires": {
1254
+ "glob": "~7.1.1",
1255
+ "lodash": "~4.17.12",
1256
+ "minimatch": "~3.0.2"
1257
+ },
1258
+ "dependencies": {
1259
+ "glob": {
1260
+ "version": "7.1.6",
1261
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
1262
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
1263
+ "dev": true,
1264
+ "requires": {
1265
+ "fs.realpath": "^1.0.0",
1266
+ "inflight": "^1.0.4",
1267
+ "inherits": "2",
1268
+ "minimatch": "^3.0.4",
1269
+ "once": "^1.3.0",
1270
+ "path-is-absolute": "^1.0.0"
1271
+ }
1272
+ }
1273
+ }
1274
+ },
1275
+ "graceful-fs": {
1276
+ "version": "4.2.3",
1277
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
1278
+ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
1279
+ "dev": true
1280
+ },
1281
+ "grunt": {
1282
+ "version": "1.1.0",
1283
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.1.0.tgz",
1284
+ "integrity": "sha512-+NGod0grmviZ7Nzdi9am7vuRS/h76PcWDsV635mEXF0PEQMUV6Kb+OjTdsVxbi0PZmfQOjCMKb3w8CVZcqsn1g==",
1285
+ "dev": true,
1286
+ "requires": {
1287
+ "coffeescript": "~1.10.0",
1288
+ "dateformat": "~1.0.12",
1289
+ "eventemitter2": "~0.4.13",
1290
+ "exit": "~0.1.1",
1291
+ "findup-sync": "~0.3.0",
1292
+ "glob": "~7.0.0",
1293
+ "grunt-cli": "~1.2.0",
1294
+ "grunt-known-options": "~1.1.0",
1295
+ "grunt-legacy-log": "~2.0.0",
1296
+ "grunt-legacy-util": "~1.1.1",
1297
+ "iconv-lite": "~0.4.13",
1298
+ "js-yaml": "~3.13.1",
1299
+ "minimatch": "~3.0.2",
1300
+ "mkdirp": "~1.0.3",
1301
+ "nopt": "~3.0.6",
1302
+ "path-is-absolute": "~1.0.0",
1303
+ "rimraf": "~2.6.2"
1304
+ },
1305
+ "dependencies": {
1306
+ "findup-sync": {
1307
+ "version": "0.3.0",
1308
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
1309
+ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
1310
+ "dev": true,
1311
+ "requires": {
1312
+ "glob": "~5.0.0"
1313
+ },
1314
+ "dependencies": {
1315
+ "glob": {
1316
+ "version": "5.0.15",
1317
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
1318
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
1319
+ "dev": true,
1320
+ "requires": {
1321
+ "inflight": "^1.0.4",
1322
+ "inherits": "2",
1323
+ "minimatch": "2 || 3",
1324
+ "once": "^1.3.0",
1325
+ "path-is-absolute": "^1.0.0"
1326
+ }
1327
+ }
1328
+ }
1329
+ },
1330
+ "grunt-cli": {
1331
+ "version": "1.2.0",
1332
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
1333
+ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
1334
+ "dev": true,
1335
+ "requires": {
1336
+ "findup-sync": "~0.3.0",
1337
+ "grunt-known-options": "~1.1.0",
1338
+ "nopt": "~3.0.6",
1339
+ "resolve": "~1.1.0"
1340
+ }
1341
+ },
1342
+ "nopt": {
1343
+ "version": "3.0.6",
1344
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
1345
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
1346
+ "dev": true,
1347
+ "requires": {
1348
+ "abbrev": "1"
1349
+ }
1350
+ },
1351
+ "resolve": {
1352
+ "version": "1.1.7",
1353
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
1354
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
1355
+ "dev": true
1356
+ }
1357
+ }
1358
+ },
1359
+ "grunt-cli": {
1360
+ "version": "1.3.2",
1361
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz",
1362
+ "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==",
1363
+ "requires": {
1364
+ "grunt-known-options": "~1.1.0",
1365
+ "interpret": "~1.1.0",
1366
+ "liftoff": "~2.5.0",
1367
+ "nopt": "~4.0.1",
1368
+ "v8flags": "~3.1.1"
1369
+ }
1370
+ },
1371
+ "grunt-contrib-clean": {
1372
+ "version": "2.0.0",
1373
+ "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-2.0.0.tgz",
1374
+ "integrity": "sha512-g5ZD3ORk6gMa5ugZosLDQl3dZO7cI3R14U75hTM+dVLVxdMNJCPVmwf9OUt4v4eWgpKKWWoVK9DZc1amJp4nQw==",
1375
+ "dev": true,
1376
+ "requires": {
1377
+ "async": "^2.6.1",
1378
+ "rimraf": "^2.6.2"
1379
+ },
1380
+ "dependencies": {
1381
+ "async": {
1382
+ "version": "2.6.3",
1383
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
1384
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
1385
+ "dev": true,
1386
+ "requires": {
1387
+ "lodash": "^4.17.14"
1388
+ }
1389
+ }
1390
+ }
1391
+ },
1392
+ "grunt-contrib-compress": {
1393
+ "version": "1.6.0",
1394
+ "resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-1.6.0.tgz",
1395
+ "integrity": "sha512-wIFuvk+/Ny4E+OgEfJYFZgoH7KcU/nnNFbYasB7gRvrcRyW6vmTp3Pj8a4rFSR3tbFMjrGvTUszdO6fgLajgZQ==",
1396
+ "dev": true,
1397
+ "requires": {
1398
+ "archiver": "^1.3.0",
1399
+ "chalk": "^1.1.1",
1400
+ "iltorb": "^2.4.3",
1401
+ "lodash": "^4.7.0",
1402
+ "pretty-bytes": "^4.0.2",
1403
+ "stream-buffers": "^2.1.0"
1404
+ },
1405
+ "dependencies": {
1406
+ "ansi-styles": {
1407
+ "version": "2.2.1",
1408
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
1409
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
1410
+ "dev": true
1411
+ },
1412
+ "chalk": {
1413
+ "version": "1.1.3",
1414
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
1415
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
1416
+ "dev": true,
1417
+ "requires": {
1418
+ "ansi-styles": "^2.2.1",
1419
+ "escape-string-regexp": "^1.0.2",
1420
+ "has-ansi": "^2.0.0",
1421
+ "strip-ansi": "^3.0.0",
1422
+ "supports-color": "^2.0.0"
1423
+ }
1424
+ },
1425
+ "supports-color": {
1426
+ "version": "2.0.0",
1427
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1428
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
1429
+ "dev": true
1430
+ }
1431
+ }
1432
+ },
1433
+ "grunt-contrib-copy": {
1434
+ "version": "1.0.0",
1435
+ "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz",
1436
+ "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=",
1437
+ "dev": true,
1438
+ "requires": {
1439
+ "chalk": "^1.1.1",
1440
+ "file-sync-cmp": "^0.1.0"
1441
+ },
1442
+ "dependencies": {
1443
+ "ansi-styles": {
1444
+ "version": "2.2.1",
1445
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
1446
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
1447
+ "dev": true
1448
+ },
1449
+ "chalk": {
1450
+ "version": "1.1.3",
1451
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
1452
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
1453
+ "dev": true,
1454
+ "requires": {
1455
+ "ansi-styles": "^2.2.1",
1456
+ "escape-string-regexp": "^1.0.2",
1457
+ "has-ansi": "^2.0.0",
1458
+ "strip-ansi": "^3.0.0",
1459
+ "supports-color": "^2.0.0"
1460
+ }
1461
+ },
1462
+ "supports-color": {
1463
+ "version": "2.0.0",
1464
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1465
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
1466
+ "dev": true
1467
+ }
1468
+ }
1469
+ },
1470
+ "grunt-contrib-cssmin": {
1471
+ "version": "3.0.0",
1472
+ "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-3.0.0.tgz",
1473
+ "integrity": "sha512-eXpooYmVGKMs/xV7DzTLgJFPVOfMuawPD3x0JwhlH0mumq2NtH3xsxaHxp1Y3NKxp0j0tRhFS6kSBRsz6TuTGg==",
1474
+ "dev": true,
1475
+ "requires": {
1476
+ "chalk": "^2.4.1",
1477
+ "clean-css": "~4.2.1",
1478
+ "maxmin": "^2.1.0"
1479
+ }
1480
+ },
1481
+ "grunt-known-options": {
1482
+ "version": "1.1.1",
1483
+ "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
1484
+ "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ=="
1485
+ },
1486
+ "grunt-legacy-log": {
1487
+ "version": "2.0.0",
1488
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
1489
+ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
1490
+ "dev": true,
1491
+ "requires": {
1492
+ "colors": "~1.1.2",
1493
+ "grunt-legacy-log-utils": "~2.0.0",
1494
+ "hooker": "~0.2.3",
1495
+ "lodash": "~4.17.5"
1496
+ }
1497
+ },
1498
+ "grunt-legacy-log-utils": {
1499
+ "version": "2.0.1",
1500
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
1501
+ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
1502
+ "dev": true,
1503
+ "requires": {
1504
+ "chalk": "~2.4.1",
1505
+ "lodash": "~4.17.10"
1506
+ }
1507
+ },
1508
+ "grunt-legacy-util": {
1509
+ "version": "1.1.1",
1510
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
1511
+ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
1512
+ "dev": true,
1513
+ "requires": {
1514
+ "async": "~1.5.2",
1515
+ "exit": "~0.1.1",
1516
+ "getobject": "~0.1.0",
1517
+ "hooker": "~0.2.3",
1518
+ "lodash": "~4.17.10",
1519
+ "underscore.string": "~3.3.4",
1520
+ "which": "~1.3.0"
1521
+ }
1522
+ },
1523
+ "grunt-postcss": {
1524
+ "version": "0.9.0",
1525
+ "resolved": "https://registry.npmjs.org/grunt-postcss/-/grunt-postcss-0.9.0.tgz",
1526
+ "integrity": "sha512-lglLcVaoOIqH0sFv7RqwUKkEFGQwnlqyAKbatxZderwZGV1nDyKHN7gZS9LUiTx1t5GOvRBx0BEalHMyVwFAIA==",
1527
+ "dev": true,
1528
+ "requires": {
1529
+ "chalk": "^2.1.0",
1530
+ "diff": "^3.0.0",
1531
+ "postcss": "^6.0.11"
1532
+ },
1533
+ "dependencies": {
1534
+ "postcss": {
1535
+ "version": "6.0.23",
1536
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
1537
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
1538
+ "dev": true,
1539
+ "requires": {
1540
+ "chalk": "^2.4.1",
1541
+ "source-map": "^0.6.1",
1542
+ "supports-color": "^5.4.0"
1543
+ }
1544
+ },
1545
+ "source-map": {
1546
+ "version": "0.6.1",
1547
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1548
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1549
+ "dev": true
1550
+ }
1551
+ }
1552
+ },
1553
+ "grunt-rtlcss": {
1554
+ "version": "2.0.2",
1555
+ "resolved": "https://registry.npmjs.org/grunt-rtlcss/-/grunt-rtlcss-2.0.2.tgz",
1556
+ "integrity": "sha512-WbI2thnwlF04N+xvJu+NxqEaCyPuLyar196SYhEQFZ2EJHkOS8YYE+Zkh+X9cWhwAtKp7ZEpR/IKXcyQggOIsQ==",
1557
+ "dev": true,
1558
+ "requires": {
1559
+ "chalk": "^1.0.0",
1560
+ "rtlcss": "^2.0.0"
1561
+ },
1562
+ "dependencies": {
1563
+ "ansi-styles": {
1564
+ "version": "2.2.1",
1565
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
1566
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
1567
+ "dev": true
1568
+ },
1569
+ "chalk": {
1570
+ "version": "1.1.3",
1571
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
1572
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
1573
+ "dev": true,
1574
+ "requires": {
1575
+ "ansi-styles": "^2.2.1",
1576
+ "escape-string-regexp": "^1.0.2",
1577
+ "has-ansi": "^2.0.0",
1578
+ "strip-ansi": "^3.0.0",
1579
+ "supports-color": "^2.0.0"
1580
+ }
1581
+ },
1582
+ "supports-color": {
1583
+ "version": "2.0.0",
1584
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1585
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
1586
+ "dev": true
1587
+ }
1588
+ }
1589
+ },
1590
+ "grunt-text-replace": {
1591
+ "version": "0.4.0",
1592
+ "resolved": "https://registry.npmjs.org/grunt-text-replace/-/grunt-text-replace-0.4.0.tgz",
1593
+ "integrity": "sha1-252c5Z4v5J2id+nbwZXD4Rz7FsI=",
1594
+ "dev": true
1595
+ },
1596
+ "gzip-size": {
1597
+ "version": "3.0.0",
1598
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
1599
+ "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=",
1600
+ "dev": true,
1601
+ "requires": {
1602
+ "duplexer": "^0.1.1"
1603
+ }
1604
+ },
1605
+ "har-schema": {
1606
+ "version": "2.0.0",
1607
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
1608
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
1609
+ "dev": true
1610
+ },
1611
+ "har-validator": {
1612
+ "version": "5.1.3",
1613
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
1614
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
1615
+ "dev": true,
1616
+ "requires": {
1617
+ "ajv": "^6.5.5",
1618
+ "har-schema": "^2.0.0"
1619
+ }
1620
+ },
1621
+ "has-ansi": {
1622
+ "version": "2.0.0",
1623
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
1624
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
1625
+ "dev": true,
1626
+ "requires": {
1627
+ "ansi-regex": "^2.0.0"
1628
+ }
1629
+ },
1630
+ "has-flag": {
1631
+ "version": "3.0.0",
1632
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1633
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
1634
+ "dev": true
1635
+ },
1636
+ "has-unicode": {
1637
+ "version": "2.0.1",
1638
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
1639
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
1640
+ "dev": true
1641
+ },
1642
+ "has-value": {
1643
+ "version": "1.0.0",
1644
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
1645
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
1646
+ "requires": {
1647
+ "get-value": "^2.0.6",
1648
+ "has-values": "^1.0.0",
1649
+ "isobject": "^3.0.0"
1650
+ }
1651
+ },
1652
+ "has-values": {
1653
+ "version": "1.0.0",
1654
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
1655
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
1656
+ "requires": {
1657
+ "is-number": "^3.0.0",
1658
+ "kind-of": "^4.0.0"
1659
+ },
1660
+ "dependencies": {
1661
+ "kind-of": {
1662
+ "version": "4.0.0",
1663
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
1664
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
1665
+ "requires": {
1666
+ "is-buffer": "^1.1.5"
1667
+ }
1668
+ }
1669
+ }
1670
+ },
1671
+ "homedir-polyfill": {
1672
+ "version": "1.0.3",
1673
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
1674
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
1675
+ "requires": {
1676
+ "parse-passwd": "^1.0.0"
1677
+ }
1678
+ },
1679
+ "hooker": {
1680
+ "version": "0.2.3",
1681
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
1682
+ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
1683
+ "dev": true
1684
+ },
1685
+ "hosted-git-info": {
1686
+ "version": "2.8.8",
1687
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
1688
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
1689
+ "dev": true
1690
+ },
1691
+ "http-signature": {
1692
+ "version": "1.2.0",
1693
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
1694
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
1695
+ "dev": true,
1696
+ "requires": {
1697
+ "assert-plus": "^1.0.0",
1698
+ "jsprim": "^1.2.2",
1699
+ "sshpk": "^1.7.0"
1700
+ }
1701
+ },
1702
+ "iconv-lite": {
1703
+ "version": "0.4.24",
1704
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1705
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1706
+ "dev": true,
1707
+ "requires": {
1708
+ "safer-buffer": ">= 2.1.2 < 3"
1709
+ }
1710
+ },
1711
+ "ieee754": {
1712
+ "version": "1.1.13",
1713
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
1714
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
1715
+ "dev": true
1716
+ },
1717
+ "iltorb": {
1718
+ "version": "2.4.5",
1719
+ "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-2.4.5.tgz",
1720
+ "integrity": "sha512-EMCMl3LnnNSZJS5QrxyZmMTaAC4+TJkM5woD+xbpm9RB+mFYCr7C05GFE3TEGCsVQSVHmjX+3sf5AiwsylNInQ==",
1721
+ "dev": true,
1722
+ "optional": true,
1723
+ "requires": {
1724
+ "detect-libc": "^1.0.3",
1725
+ "nan": "^2.14.0",
1726
+ "npmlog": "^4.1.2",
1727
+ "prebuild-install": "^5.3.3",
1728
+ "which-pm-runs": "^1.0.0"
1729
+ }
1730
+ },
1731
+ "in-publish": {
1732
+ "version": "2.0.1",
1733
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
1734
+ "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==",
1735
+ "dev": true
1736
+ },
1737
+ "indent-string": {
1738
+ "version": "2.1.0",
1739
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
1740
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
1741
+ "dev": true,
1742
+ "requires": {
1743
+ "repeating": "^2.0.0"
1744
+ }
1745
+ },
1746
+ "inflight": {
1747
+ "version": "1.0.6",
1748
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1749
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1750
+ "dev": true,
1751
+ "requires": {
1752
+ "once": "^1.3.0",
1753
+ "wrappy": "1"
1754
+ }
1755
+ },
1756
+ "inherits": {
1757
+ "version": "2.0.4",
1758
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1759
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1760
+ "dev": true
1761
+ },
1762
+ "ini": {
1763
+ "version": "1.3.5",
1764
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
1765
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
1766
+ },
1767
+ "interpret": {
1768
+ "version": "1.1.0",
1769
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
1770
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ="
1771
+ },
1772
+ "invert-kv": {
1773
+ "version": "1.0.0",
1774
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
1775
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
1776
+ "dev": true
1777
+ },
1778
+ "is-absolute": {
1779
+ "version": "1.0.0",
1780
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
1781
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
1782
+ "requires": {
1783
+ "is-relative": "^1.0.0",
1784
+ "is-windows": "^1.0.1"
1785
+ }
1786
+ },
1787
+ "is-accessor-descriptor": {
1788
+ "version": "0.1.6",
1789
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
1790
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
1791
+ "requires": {
1792
+ "kind-of": "^3.0.2"
1793
+ },
1794
+ "dependencies": {
1795
+ "kind-of": {
1796
+ "version": "3.2.2",
1797
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1798
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1799
+ "requires": {
1800
+ "is-buffer": "^1.1.5"
1801
+ }
1802
+ }
1803
+ }
1804
+ },
1805
+ "is-arrayish": {
1806
+ "version": "0.2.1",
1807
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
1808
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
1809
+ "dev": true
1810
+ },
1811
+ "is-buffer": {
1812
+ "version": "1.1.6",
1813
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
1814
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
1815
+ },
1816
+ "is-data-descriptor": {
1817
+ "version": "0.1.4",
1818
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
1819
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
1820
+ "requires": {
1821
+ "kind-of": "^3.0.2"
1822
+ },
1823
+ "dependencies": {
1824
+ "kind-of": {
1825
+ "version": "3.2.2",
1826
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1827
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1828
+ "requires": {
1829
+ "is-buffer": "^1.1.5"
1830
+ }
1831
+ }
1832
+ }
1833
+ },
1834
+ "is-descriptor": {
1835
+ "version": "0.1.6",
1836
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
1837
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
1838
+ "requires": {
1839
+ "is-accessor-descriptor": "^0.1.6",
1840
+ "is-data-descriptor": "^0.1.4",
1841
+ "kind-of": "^5.0.0"
1842
+ },
1843
+ "dependencies": {
1844
+ "kind-of": {
1845
+ "version": "5.1.0",
1846
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
1847
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
1848
+ }
1849
+ }
1850
+ },
1851
+ "is-extendable": {
1852
+ "version": "0.1.1",
1853
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
1854
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
1855
+ },
1856
+ "is-extglob": {
1857
+ "version": "2.1.1",
1858
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1859
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
1860
+ },
1861
+ "is-finite": {
1862
+ "version": "1.1.0",
1863
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
1864
+ "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
1865
+ "dev": true
1866
+ },
1867
+ "is-fullwidth-code-point": {
1868
+ "version": "1.0.0",
1869
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
1870
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
1871
+ "dev": true,
1872
+ "requires": {
1873
+ "number-is-nan": "^1.0.0"
1874
+ }
1875
+ },
1876
+ "is-glob": {
1877
+ "version": "3.1.0",
1878
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
1879
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
1880
+ "requires": {
1881
+ "is-extglob": "^2.1.0"
1882
+ }
1883
+ },
1884
+ "is-number": {
1885
+ "version": "3.0.0",
1886
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
1887
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
1888
+ "requires": {
1889
+ "kind-of": "^3.0.2"
1890
+ },
1891
+ "dependencies": {
1892
+ "kind-of": {
1893
+ "version": "3.2.2",
1894
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
1895
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
1896
+ "requires": {
1897
+ "is-buffer": "^1.1.5"
1898
+ }
1899
+ }
1900
+ }
1901
+ },
1902
+ "is-plain-object": {
1903
+ "version": "2.0.4",
1904
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
1905
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
1906
+ "requires": {
1907
+ "isobject": "^3.0.1"
1908
+ }
1909
+ },
1910
+ "is-relative": {
1911
+ "version": "1.0.0",
1912
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
1913
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
1914
+ "requires": {
1915
+ "is-unc-path": "^1.0.0"
1916
+ }
1917
+ },
1918
+ "is-typedarray": {
1919
+ "version": "1.0.0",
1920
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
1921
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
1922
+ "dev": true
1923
+ },
1924
+ "is-unc-path": {
1925
+ "version": "1.0.0",
1926
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
1927
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
1928
+ "requires": {
1929
+ "unc-path-regex": "^0.1.2"
1930
+ }
1931
+ },
1932
+ "is-utf8": {
1933
+ "version": "0.2.1",
1934
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
1935
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
1936
+ "dev": true
1937
+ },
1938
+ "is-windows": {
1939
+ "version": "1.0.2",
1940
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
1941
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
1942
+ },
1943
+ "isarray": {
1944
+ "version": "1.0.0",
1945
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1946
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1947
+ },
1948
+ "isexe": {
1949
+ "version": "2.0.0",
1950
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1951
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
1952
+ },
1953
+ "isobject": {
1954
+ "version": "3.0.1",
1955
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
1956
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
1957
+ },
1958
+ "isstream": {
1959
+ "version": "0.1.2",
1960
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
1961
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
1962
+ "dev": true
1963
+ },
1964
+ "js-base64": {
1965
+ "version": "2.5.2",
1966
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
1967
+ "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==",
1968
+ "dev": true
1969
+ },
1970
+ "js-yaml": {
1971
+ "version": "3.13.1",
1972
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1973
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1974
+ "dev": true,
1975
+ "requires": {
1976
+ "argparse": "^1.0.7",
1977
+ "esprima": "^4.0.0"
1978
+ }
1979
+ },
1980
+ "jsbn": {
1981
+ "version": "0.1.1",
1982
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
1983
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
1984
+ "dev": true
1985
+ },
1986
+ "json-schema": {
1987
+ "version": "0.2.3",
1988
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
1989
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
1990
+ "dev": true
1991
+ },
1992
+ "json-schema-traverse": {
1993
+ "version": "0.4.1",
1994
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1995
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
1996
+ "dev": true
1997
+ },
1998
+ "json-stringify-safe": {
1999
+ "version": "5.0.1",
2000
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
2001
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
2002
+ "dev": true
2003
+ },
2004
+ "jsprim": {
2005
+ "version": "1.4.1",
2006
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
2007
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
2008
+ "dev": true,
2009
+ "requires": {
2010
+ "assert-plus": "1.0.0",
2011
+ "extsprintf": "1.3.0",
2012
+ "json-schema": "0.2.3",
2013
+ "verror": "1.10.0"
2014
+ }
2015
+ },
2016
+ "kind-of": {
2017
+ "version": "6.0.3",
2018
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
2019
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
2020
+ },
2021
+ "lazystream": {
2022
+ "version": "1.0.0",
2023
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
2024
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
2025
+ "dev": true,
2026
+ "requires": {
2027
+ "readable-stream": "^2.0.5"
2028
+ }
2029
+ },
2030
+ "lcid": {
2031
+ "version": "1.0.0",
2032
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
2033
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
2034
+ "dev": true,
2035
+ "requires": {
2036
+ "invert-kv": "^1.0.0"
2037
+ }
2038
+ },
2039
+ "liftoff": {
2040
+ "version": "2.5.0",
2041
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
2042
+ "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=",
2043
+ "requires": {
2044
+ "extend": "^3.0.0",
2045
+ "findup-sync": "^2.0.0",
2046
+ "fined": "^1.0.1",
2047
+ "flagged-respawn": "^1.0.0",
2048
+ "is-plain-object": "^2.0.4",
2049
+ "object.map": "^1.0.0",
2050
+ "rechoir": "^0.6.2",
2051
+ "resolve": "^1.1.7"
2052
+ }
2053
+ },
2054
+ "load-json-file": {
2055
+ "version": "1.1.0",
2056
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
2057
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
2058
+ "dev": true,
2059
+ "requires": {
2060
+ "graceful-fs": "^4.1.2",
2061
+ "parse-json": "^2.2.0",
2062
+ "pify": "^2.0.0",
2063
+ "pinkie-promise": "^2.0.0",
2064
+ "strip-bom": "^2.0.0"
2065
+ }
2066
+ },
2067
+ "locate-path": {
2068
+ "version": "2.0.0",
2069
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
2070
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
2071
+ "dev": true,
2072
+ "requires": {
2073
+ "p-locate": "^2.0.0",
2074
+ "path-exists": "^3.0.0"
2075
+ }
2076
+ },
2077
+ "lodash": {
2078
+ "version": "4.17.15",
2079
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
2080
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
2081
+ "dev": true
2082
+ },
2083
+ "loud-rejection": {
2084
+ "version": "1.6.0",
2085
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
2086
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
2087
+ "dev": true,
2088
+ "requires": {
2089
+ "currently-unhandled": "^0.4.1",
2090
+ "signal-exit": "^3.0.0"
2091
+ }
2092
+ },
2093
+ "lru-cache": {
2094
+ "version": "4.1.5",
2095
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
2096
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
2097
+ "dev": true,
2098
+ "requires": {
2099
+ "pseudomap": "^1.0.2",
2100
+ "yallist": "^2.1.2"
2101
+ }
2102
+ },
2103
+ "make-iterator": {
2104
+ "version": "1.0.1",
2105
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
2106
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
2107
+ "requires": {
2108
+ "kind-of": "^6.0.2"
2109
+ }
2110
+ },
2111
+ "map-cache": {
2112
+ "version": "0.2.2",
2113
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
2114
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
2115
+ },
2116
+ "map-obj": {
2117
+ "version": "1.0.1",
2118
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
2119
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
2120
+ "dev": true
2121
+ },
2122
+ "map-visit": {
2123
+ "version": "1.0.0",
2124
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
2125
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
2126
+ "requires": {
2127
+ "object-visit": "^1.0.0"
2128
+ }
2129
+ },
2130
+ "maxmin": {
2131
+ "version": "2.1.0",
2132
+ "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz",
2133
+ "integrity": "sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY=",
2134
+ "dev": true,
2135
+ "requires": {
2136
+ "chalk": "^1.0.0",
2137
+ "figures": "^1.0.1",
2138
+ "gzip-size": "^3.0.0",
2139
+ "pretty-bytes": "^3.0.0"
2140
+ },
2141
+ "dependencies": {
2142
+ "ansi-styles": {
2143
+ "version": "2.2.1",
2144
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
2145
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
2146
+ "dev": true
2147
+ },
2148
+ "chalk": {
2149
+ "version": "1.1.3",
2150
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
2151
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
2152
+ "dev": true,
2153
+ "requires": {
2154
+ "ansi-styles": "^2.2.1",
2155
+ "escape-string-regexp": "^1.0.2",
2156
+ "has-ansi": "^2.0.0",
2157
+ "strip-ansi": "^3.0.0",
2158
+ "supports-color": "^2.0.0"
2159
+ }
2160
+ },
2161
+ "pretty-bytes": {
2162
+ "version": "3.0.1",
2163
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
2164
+ "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=",
2165
+ "dev": true,
2166
+ "requires": {
2167
+ "number-is-nan": "^1.0.0"
2168
+ }
2169
+ },
2170
+ "supports-color": {
2171
+ "version": "2.0.0",
2172
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
2173
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
2174
+ "dev": true
2175
+ }
2176
+ }
2177
+ },
2178
+ "meow": {
2179
+ "version": "3.7.0",
2180
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
2181
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
2182
+ "dev": true,
2183
+ "requires": {
2184
+ "camelcase-keys": "^2.0.0",
2185
+ "decamelize": "^1.1.2",
2186
+ "loud-rejection": "^1.0.0",
2187
+ "map-obj": "^1.0.1",
2188
+ "minimist": "^1.1.3",
2189
+ "normalize-package-data": "^2.3.4",
2190
+ "object-assign": "^4.0.1",
2191
+ "read-pkg-up": "^1.0.1",
2192
+ "redent": "^1.0.0",
2193
+ "trim-newlines": "^1.0.0"
2194
+ }
2195
+ },
2196
+ "micromatch": {
2197
+ "version": "3.1.10",
2198
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
2199
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
2200
+ "requires": {
2201
+ "arr-diff": "^4.0.0",
2202
+ "array-unique": "^0.3.2",
2203
+ "braces": "^2.3.1",
2204
+ "define-property": "^2.0.2",
2205
+ "extend-shallow": "^3.0.2",
2206
+ "extglob": "^2.0.4",
2207
+ "fragment-cache": "^0.2.1",
2208
+ "kind-of": "^6.0.2",
2209
+ "nanomatch": "^1.2.9",
2210
+ "object.pick": "^1.3.0",
2211
+ "regex-not": "^1.0.0",
2212
+ "snapdragon": "^0.8.1",
2213
+ "to-regex": "^3.0.2"
2214
+ }
2215
+ },
2216
+ "mime-db": {
2217
+ "version": "1.43.0",
2218
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
2219
+ "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
2220
+ "dev": true
2221
+ },
2222
+ "mime-types": {
2223
+ "version": "2.1.26",
2224
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
2225
+ "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
2226
+ "dev": true,
2227
+ "requires": {
2228
+ "mime-db": "1.43.0"
2229
+ }
2230
+ },
2231
+ "mimic-response": {
2232
+ "version": "2.1.0",
2233
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
2234
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
2235
+ "dev": true,
2236
+ "optional": true
2237
+ },
2238
+ "minimatch": {
2239
+ "version": "3.0.4",
2240
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
2241
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
2242
+ "dev": true,
2243
+ "requires": {
2244
+ "brace-expansion": "^1.1.7"
2245
+ }
2246
+ },
2247
+ "minimist": {
2248
+ "version": "1.2.5",
2249
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
2250
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
2251
+ "dev": true
2252
+ },
2253
+ "mixin-deep": {
2254
+ "version": "1.3.2",
2255
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
2256
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
2257
+ "requires": {
2258
+ "for-in": "^1.0.2",
2259
+ "is-extendable": "^1.0.1"
2260
+ },
2261
+ "dependencies": {
2262
+ "is-extendable": {
2263
+ "version": "1.0.1",
2264
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
2265
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
2266
+ "requires": {
2267
+ "is-plain-object": "^2.0.4"
2268
+ }
2269
+ }
2270
+ }
2271
+ },
2272
+ "mkdirp": {
2273
+ "version": "1.0.4",
2274
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
2275
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
2276
+ "dev": true
2277
+ },
2278
+ "mkdirp-classic": {
2279
+ "version": "0.5.2",
2280
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz",
2281
+ "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==",
2282
+ "dev": true,
2283
+ "optional": true
2284
+ },
2285
+ "ms": {
2286
+ "version": "2.0.0",
2287
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
2288
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
2289
+ },
2290
+ "nan": {
2291
+ "version": "2.14.0",
2292
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
2293
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
2294
+ "dev": true
2295
+ },
2296
+ "nanomatch": {
2297
+ "version": "1.2.13",
2298
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
2299
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
2300
+ "requires": {
2301
+ "arr-diff": "^4.0.0",
2302
+ "array-unique": "^0.3.2",
2303
+ "define-property": "^2.0.2",
2304
+ "extend-shallow": "^3.0.2",
2305
+ "fragment-cache": "^0.2.1",
2306
+ "is-windows": "^1.0.2",
2307
+ "kind-of": "^6.0.2",
2308
+ "object.pick": "^1.3.0",
2309
+ "regex-not": "^1.0.0",
2310
+ "snapdragon": "^0.8.1",
2311
+ "to-regex": "^3.0.1"
2312
+ }
2313
+ },
2314
+ "napi-build-utils": {
2315
+ "version": "1.0.2",
2316
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
2317
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
2318
+ "dev": true,
2319
+ "optional": true
2320
+ },
2321
+ "node-abi": {
2322
+ "version": "2.15.0",
2323
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
2324
+ "integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
2325
+ "dev": true,
2326
+ "optional": true,
2327
+ "requires": {
2328
+ "semver": "^5.4.1"
2329
+ }
2330
+ },
2331
+ "node-gyp": {
2332
+ "version": "3.8.0",
2333
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
2334
+ "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
2335
+ "dev": true,
2336
+ "requires": {
2337
+ "fstream": "^1.0.0",
2338
+ "glob": "^7.0.3",
2339
+ "graceful-fs": "^4.1.2",
2340
+ "mkdirp": "^0.5.0",
2341
+ "nopt": "2 || 3",
2342
+ "npmlog": "0 || 1 || 2 || 3 || 4",
2343
+ "osenv": "0",
2344
+ "request": "^2.87.0",
2345
+ "rimraf": "2",
2346
+ "semver": "~5.3.0",
2347
+ "tar": "^2.0.0",
2348
+ "which": "1"
2349
+ },
2350
+ "dependencies": {
2351
+ "mkdirp": {
2352
+ "version": "0.5.5",
2353
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
2354
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
2355
+ "dev": true,
2356
+ "requires": {
2357
+ "minimist": "^1.2.5"
2358
+ }
2359
+ },
2360
+ "nopt": {
2361
+ "version": "3.0.6",
2362
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
2363
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
2364
+ "dev": true,
2365
+ "requires": {
2366
+ "abbrev": "1"
2367
+ }
2368
+ },
2369
+ "semver": {
2370
+ "version": "5.3.0",
2371
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
2372
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
2373
+ "dev": true
2374
+ }
2375
+ }
2376
+ },
2377
+ "node-releases": {
2378
+ "version": "1.1.53",
2379
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz",
2380
+ "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==",
2381
+ "dev": true
2382
+ },
2383
+ "node-sass": {
2384
+ "version": "4.13.1",
2385
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
2386
+ "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
2387
+ "dev": true,
2388
+ "requires": {
2389
+ "async-foreach": "^0.1.3",
2390
+ "chalk": "^1.1.1",
2391
+ "cross-spawn": "^3.0.0",
2392
+ "gaze": "^1.0.0",
2393
+ "get-stdin": "^4.0.1",
2394
+ "glob": "^7.0.3",
2395
+ "in-publish": "^2.0.0",
2396
+ "lodash": "^4.17.15",
2397
+ "meow": "^3.7.0",
2398
+ "mkdirp": "^0.5.1",
2399
+ "nan": "^2.13.2",
2400
+ "node-gyp": "^3.8.0",
2401
+ "npmlog": "^4.0.0",
2402
+ "request": "^2.88.0",
2403
+ "sass-graph": "^2.2.4",
2404
+ "stdout-stream": "^1.4.0",
2405
+ "true-case-path": "^1.0.2"
2406
+ },
2407
+ "dependencies": {
2408
+ "ansi-styles": {
2409
+ "version": "2.2.1",
2410
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
2411
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
2412
+ "dev": true
2413
+ },
2414
+ "chalk": {
2415
+ "version": "1.1.3",
2416
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
2417
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
2418
+ "dev": true,
2419
+ "requires": {
2420
+ "ansi-styles": "^2.2.1",
2421
+ "escape-string-regexp": "^1.0.2",
2422
+ "has-ansi": "^2.0.0",
2423
+ "strip-ansi": "^3.0.0",
2424
+ "supports-color": "^2.0.0"
2425
+ }
2426
+ },
2427
+ "mkdirp": {
2428
+ "version": "0.5.5",
2429
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
2430
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
2431
+ "dev": true,
2432
+ "requires": {
2433
+ "minimist": "^1.2.5"
2434
+ }
2435
+ },
2436
+ "supports-color": {
2437
+ "version": "2.0.0",
2438
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
2439
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
2440
+ "dev": true
2441
+ }
2442
+ }
2443
+ },
2444
+ "noop-logger": {
2445
+ "version": "0.1.1",
2446
+ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
2447
+ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
2448
+ "dev": true,
2449
+ "optional": true
2450
+ },
2451
+ "nopt": {
2452
+ "version": "4.0.3",
2453
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
2454
+ "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
2455
+ "requires": {
2456
+ "abbrev": "1",
2457
+ "osenv": "^0.1.4"
2458
+ }
2459
+ },
2460
+ "normalize-package-data": {
2461
+ "version": "2.5.0",
2462
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
2463
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
2464
+ "dev": true,
2465
+ "requires": {
2466
+ "hosted-git-info": "^2.1.4",
2467
+ "resolve": "^1.10.0",
2468
+ "semver": "2 || 3 || 4 || 5",
2469
+ "validate-npm-package-license": "^3.0.1"
2470
+ }
2471
+ },
2472
+ "normalize-path": {
2473
+ "version": "2.1.1",
2474
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
2475
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
2476
+ "dev": true,
2477
+ "requires": {
2478
+ "remove-trailing-separator": "^1.0.1"
2479
+ }
2480
+ },
2481
+ "normalize-range": {
2482
+ "version": "0.1.2",
2483
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
2484
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
2485
+ "dev": true
2486
+ },
2487
+ "npmlog": {
2488
+ "version": "4.1.2",
2489
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
2490
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
2491
+ "dev": true,
2492
+ "requires": {
2493
+ "are-we-there-yet": "~1.1.2",
2494
+ "console-control-strings": "~1.1.0",
2495
+ "gauge": "~2.7.3",
2496
+ "set-blocking": "~2.0.0"
2497
+ }
2498
+ },
2499
+ "num2fraction": {
2500
+ "version": "1.2.2",
2501
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
2502
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
2503
+ "dev": true
2504
+ },
2505
+ "number-is-nan": {
2506
+ "version": "1.0.1",
2507
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
2508
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
2509
+ "dev": true
2510
+ },
2511
+ "oauth-sign": {
2512
+ "version": "0.9.0",
2513
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
2514
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
2515
+ "dev": true
2516
+ },
2517
+ "object-assign": {
2518
+ "version": "4.1.1",
2519
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
2520
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
2521
+ "dev": true
2522
+ },
2523
+ "object-copy": {
2524
+ "version": "0.1.0",
2525
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
2526
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
2527
+ "requires": {
2528
+ "copy-descriptor": "^0.1.0",
2529
+ "define-property": "^0.2.5",
2530
+ "kind-of": "^3.0.3"
2531
+ },
2532
+ "dependencies": {
2533
+ "define-property": {
2534
+ "version": "0.2.5",
2535
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
2536
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
2537
+ "requires": {
2538
+ "is-descriptor": "^0.1.0"
2539
+ }
2540
+ },
2541
+ "kind-of": {
2542
+ "version": "3.2.2",
2543
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
2544
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
2545
+ "requires": {
2546
+ "is-buffer": "^1.1.5"
2547
+ }
2548
+ }
2549
+ }
2550
+ },
2551
+ "object-visit": {
2552
+ "version": "1.0.1",
2553
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
2554
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
2555
+ "requires": {
2556
+ "isobject": "^3.0.0"
2557
+ }
2558
+ },
2559
+ "object.defaults": {
2560
+ "version": "1.1.0",
2561
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
2562
+ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
2563
+ "requires": {
2564
+ "array-each": "^1.0.1",
2565
+ "array-slice": "^1.0.0",
2566
+ "for-own": "^1.0.0",
2567
+ "isobject": "^3.0.0"
2568
+ }
2569
+ },
2570
+ "object.map": {
2571
+ "version": "1.0.1",
2572
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
2573
+ "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
2574
+ "requires": {
2575
+ "for-own": "^1.0.0",
2576
+ "make-iterator": "^1.0.0"
2577
+ }
2578
+ },
2579
+ "object.pick": {
2580
+ "version": "1.3.0",
2581
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
2582
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
2583
+ "requires": {
2584
+ "isobject": "^3.0.1"
2585
+ }
2586
+ },
2587
+ "once": {
2588
+ "version": "1.4.0",
2589
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
2590
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
2591
+ "dev": true,
2592
+ "requires": {
2593
+ "wrappy": "1"
2594
+ }
2595
+ },
2596
+ "os-homedir": {
2597
+ "version": "1.0.2",
2598
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
2599
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
2600
+ },
2601
+ "os-locale": {
2602
+ "version": "1.4.0",
2603
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
2604
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
2605
+ "dev": true,
2606
+ "requires": {
2607
+ "lcid": "^1.0.0"
2608
+ }
2609
+ },
2610
+ "os-tmpdir": {
2611
+ "version": "1.0.2",
2612
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
2613
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
2614
+ },
2615
+ "osenv": {
2616
+ "version": "0.1.5",
2617
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
2618
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
2619
+ "requires": {
2620
+ "os-homedir": "^1.0.0",
2621
+ "os-tmpdir": "^1.0.0"
2622
+ }
2623
+ },
2624
+ "p-limit": {
2625
+ "version": "1.3.0",
2626
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
2627
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
2628
+ "dev": true,
2629
+ "requires": {
2630
+ "p-try": "^1.0.0"
2631
+ }
2632
+ },
2633
+ "p-locate": {
2634
+ "version": "2.0.0",
2635
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
2636
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
2637
+ "dev": true,
2638
+ "requires": {
2639
+ "p-limit": "^1.1.0"
2640
+ }
2641
+ },
2642
+ "p-try": {
2643
+ "version": "1.0.0",
2644
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
2645
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
2646
+ "dev": true
2647
+ },
2648
+ "parse-filepath": {
2649
+ "version": "1.0.2",
2650
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
2651
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
2652
+ "requires": {
2653
+ "is-absolute": "^1.0.0",
2654
+ "map-cache": "^0.2.0",
2655
+ "path-root": "^0.1.1"
2656
+ }
2657
+ },
2658
+ "parse-json": {
2659
+ "version": "2.2.0",
2660
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
2661
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
2662
+ "dev": true,
2663
+ "requires": {
2664
+ "error-ex": "^1.2.0"
2665
+ }
2666
+ },
2667
+ "parse-passwd": {
2668
+ "version": "1.0.0",
2669
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
2670
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
2671
+ },
2672
+ "pascalcase": {
2673
+ "version": "0.1.1",
2674
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
2675
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
2676
+ },
2677
+ "path-exists": {
2678
+ "version": "3.0.0",
2679
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
2680
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
2681
+ "dev": true
2682
+ },
2683
+ "path-is-absolute": {
2684
+ "version": "1.0.1",
2685
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
2686
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
2687
+ "dev": true
2688
+ },
2689
+ "path-parse": {
2690
+ "version": "1.0.6",
2691
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
2692
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
2693
+ },
2694
+ "path-root": {
2695
+ "version": "0.1.1",
2696
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
2697
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
2698
+ "requires": {
2699
+ "path-root-regex": "^0.1.0"
2700
+ }
2701
+ },
2702
+ "path-root-regex": {
2703
+ "version": "0.1.2",
2704
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
2705
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0="
2706
+ },
2707
+ "path-type": {
2708
+ "version": "1.1.0",
2709
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
2710
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
2711
+ "dev": true,
2712
+ "requires": {
2713
+ "graceful-fs": "^4.1.2",
2714
+ "pify": "^2.0.0",
2715
+ "pinkie-promise": "^2.0.0"
2716
+ }
2717
+ },
2718
+ "performance-now": {
2719
+ "version": "2.1.0",
2720
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
2721
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
2722
+ "dev": true
2723
+ },
2724
+ "pify": {
2725
+ "version": "2.3.0",
2726
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
2727
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
2728
+ "dev": true
2729
+ },
2730
+ "pinkie": {
2731
+ "version": "2.0.4",
2732
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
2733
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
2734
+ "dev": true
2735
+ },
2736
+ "pinkie-promise": {
2737
+ "version": "2.0.1",
2738
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
2739
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
2740
+ "dev": true,
2741
+ "requires": {
2742
+ "pinkie": "^2.0.0"
2743
+ }
2744
+ },
2745
+ "pkg-up": {
2746
+ "version": "2.0.0",
2747
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
2748
+ "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
2749
+ "dev": true,
2750
+ "requires": {
2751
+ "find-up": "^2.1.0"
2752
+ }
2753
+ },
2754
+ "posix-character-classes": {
2755
+ "version": "0.1.1",
2756
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
2757
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
2758
+ },
2759
+ "postcss": {
2760
+ "version": "7.0.27",
2761
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
2762
+ "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
2763
+ "dev": true,
2764
+ "requires": {
2765
+ "chalk": "^2.4.2",
2766
+ "source-map": "^0.6.1",
2767
+ "supports-color": "^6.1.0"
2768
+ },
2769
+ "dependencies": {
2770
+ "source-map": {
2771
+ "version": "0.6.1",
2772
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2773
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
2774
+ "dev": true
2775
+ },
2776
+ "supports-color": {
2777
+ "version": "6.1.0",
2778
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
2779
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
2780
+ "dev": true,
2781
+ "requires": {
2782
+ "has-flag": "^3.0.0"
2783
+ }
2784
+ }
2785
+ }
2786
+ },
2787
+ "postcss-flexibility": {
2788
+ "version": "2.0.0",
2789
+ "resolved": "https://registry.npmjs.org/postcss-flexibility/-/postcss-flexibility-2.0.0.tgz",
2790
+ "integrity": "sha1-VhLBuF1lle1ICWaDmSikFhemp2g=",
2791
+ "dev": true,
2792
+ "requires": {
2793
+ "postcss": "^6.0.1"
2794
+ },
2795
+ "dependencies": {
2796
+ "postcss": {
2797
+ "version": "6.0.23",
2798
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
2799
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
2800
+ "dev": true,
2801
+ "requires": {
2802
+ "chalk": "^2.4.1",
2803
+ "source-map": "^0.6.1",
2804
+ "supports-color": "^5.4.0"
2805
+ }
2806
+ },
2807
+ "source-map": {
2808
+ "version": "0.6.1",
2809
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2810
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
2811
+ "dev": true
2812
+ }
2813
+ }
2814
+ },
2815
+ "postcss-value-parser": {
2816
+ "version": "4.0.3",
2817
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
2818
+ "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==",
2819
+ "dev": true
2820
+ },
2821
+ "prebuild-install": {
2822
+ "version": "5.3.3",
2823
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
2824
+ "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
2825
+ "dev": true,
2826
+ "optional": true,
2827
+ "requires": {
2828
+ "detect-libc": "^1.0.3",
2829
+ "expand-template": "^2.0.3",
2830
+ "github-from-package": "0.0.0",
2831
+ "minimist": "^1.2.0",
2832
+ "mkdirp": "^0.5.1",
2833
+ "napi-build-utils": "^1.0.1",
2834
+ "node-abi": "^2.7.0",
2835
+ "noop-logger": "^0.1.1",
2836
+ "npmlog": "^4.0.1",
2837
+ "pump": "^3.0.0",
2838
+ "rc": "^1.2.7",
2839
+ "simple-get": "^3.0.3",
2840
+ "tar-fs": "^2.0.0",
2841
+ "tunnel-agent": "^0.6.0",
2842
+ "which-pm-runs": "^1.0.0"
2843
+ },
2844
+ "dependencies": {
2845
+ "mkdirp": {
2846
+ "version": "0.5.5",
2847
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
2848
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
2849
+ "dev": true,
2850
+ "optional": true,
2851
+ "requires": {
2852
+ "minimist": "^1.2.5"
2853
+ }
2854
+ }
2855
+ }
2856
+ },
2857
+ "pretty-bytes": {
2858
+ "version": "4.0.2",
2859
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz",
2860
+ "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=",
2861
+ "dev": true
2862
+ },
2863
+ "process-nextick-args": {
2864
+ "version": "2.0.1",
2865
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
2866
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
2867
+ "dev": true
2868
+ },
2869
+ "pseudomap": {
2870
+ "version": "1.0.2",
2871
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
2872
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
2873
+ "dev": true
2874
+ },
2875
+ "psl": {
2876
+ "version": "1.8.0",
2877
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
2878
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
2879
+ "dev": true
2880
+ },
2881
+ "pump": {
2882
+ "version": "3.0.0",
2883
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
2884
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
2885
+ "dev": true,
2886
+ "optional": true,
2887
+ "requires": {
2888
+ "end-of-stream": "^1.1.0",
2889
+ "once": "^1.3.1"
2890
+ }
2891
+ },
2892
+ "punycode": {
2893
+ "version": "2.1.1",
2894
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
2895
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
2896
+ "dev": true
2897
+ },
2898
+ "qs": {
2899
+ "version": "6.5.2",
2900
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
2901
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
2902
+ "dev": true
2903
+ },
2904
+ "rc": {
2905
+ "version": "1.2.8",
2906
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
2907
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
2908
+ "dev": true,
2909
+ "optional": true,
2910
+ "requires": {
2911
+ "deep-extend": "^0.6.0",
2912
+ "ini": "~1.3.0",
2913
+ "minimist": "^1.2.0",
2914
+ "strip-json-comments": "~2.0.1"
2915
+ }
2916
+ },
2917
+ "read-pkg": {
2918
+ "version": "1.1.0",
2919
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
2920
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
2921
+ "dev": true,
2922
+ "requires": {
2923
+ "load-json-file": "^1.0.0",
2924
+ "normalize-package-data": "^2.3.2",
2925
+ "path-type": "^1.0.0"
2926
+ }
2927
+ },
2928
+ "read-pkg-up": {
2929
+ "version": "1.0.1",
2930
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
2931
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
2932
+ "dev": true,
2933
+ "requires": {
2934
+ "find-up": "^1.0.0",
2935
+ "read-pkg": "^1.0.0"
2936
+ },
2937
+ "dependencies": {
2938
+ "find-up": {
2939
+ "version": "1.1.2",
2940
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
2941
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
2942
+ "dev": true,
2943
+ "requires": {
2944
+ "path-exists": "^2.0.0",
2945
+ "pinkie-promise": "^2.0.0"
2946
+ }
2947
+ },
2948
+ "path-exists": {
2949
+ "version": "2.1.0",
2950
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
2951
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
2952
+ "dev": true,
2953
+ "requires": {
2954
+ "pinkie-promise": "^2.0.0"
2955
+ }
2956
+ }
2957
+ }
2958
+ },
2959
+ "readable-stream": {
2960
+ "version": "2.3.7",
2961
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
2962
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
2963
+ "dev": true,
2964
+ "requires": {
2965
+ "core-util-is": "~1.0.0",
2966
+ "inherits": "~2.0.3",
2967
+ "isarray": "~1.0.0",
2968
+ "process-nextick-args": "~2.0.0",
2969
+ "safe-buffer": "~5.1.1",
2970
+ "string_decoder": "~1.1.1",
2971
+ "util-deprecate": "~1.0.1"
2972
+ }
2973
+ },
2974
+ "rechoir": {
2975
+ "version": "0.6.2",
2976
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
2977
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
2978
+ "requires": {
2979
+ "resolve": "^1.1.6"
2980
+ }
2981
+ },
2982
+ "redent": {
2983
+ "version": "1.0.0",
2984
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
2985
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
2986
+ "dev": true,
2987
+ "requires": {
2988
+ "indent-string": "^2.1.0",
2989
+ "strip-indent": "^1.0.1"
2990
+ }
2991
+ },
2992
+ "regex-not": {
2993
+ "version": "1.0.2",
2994
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
2995
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
2996
+ "requires": {
2997
+ "extend-shallow": "^3.0.2",
2998
+ "safe-regex": "^1.1.0"
2999
+ }
3000
+ },
3001
+ "remove-trailing-separator": {
3002
+ "version": "1.1.0",
3003
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
3004
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
3005
+ "dev": true
3006
+ },
3007
+ "repeat-element": {
3008
+ "version": "1.1.3",
3009
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
3010
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
3011
+ },
3012
+ "repeat-string": {
3013
+ "version": "1.6.1",
3014
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
3015
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
3016
+ },
3017
+ "repeating": {
3018
+ "version": "2.0.1",
3019
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
3020
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
3021
+ "dev": true,
3022
+ "requires": {
3023
+ "is-finite": "^1.0.0"
3024
+ }
3025
+ },
3026
+ "request": {
3027
+ "version": "2.88.2",
3028
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
3029
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
3030
+ "dev": true,
3031
+ "requires": {
3032
+ "aws-sign2": "~0.7.0",
3033
+ "aws4": "^1.8.0",
3034
+ "caseless": "~0.12.0",
3035
+ "combined-stream": "~1.0.6",
3036
+ "extend": "~3.0.2",
3037
+ "forever-agent": "~0.6.1",
3038
+ "form-data": "~2.3.2",
3039
+ "har-validator": "~5.1.3",
3040
+ "http-signature": "~1.2.0",
3041
+ "is-typedarray": "~1.0.0",
3042
+ "isstream": "~0.1.2",
3043
+ "json-stringify-safe": "~5.0.1",
3044
+ "mime-types": "~2.1.19",
3045
+ "oauth-sign": "~0.9.0",
3046
+ "performance-now": "^2.1.0",
3047
+ "qs": "~6.5.2",
3048
+ "safe-buffer": "^5.1.2",
3049
+ "tough-cookie": "~2.5.0",
3050
+ "tunnel-agent": "^0.6.0",
3051
+ "uuid": "^3.3.2"
3052
+ }
3053
+ },
3054
+ "require-directory": {
3055
+ "version": "2.1.1",
3056
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
3057
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
3058
+ "dev": true
3059
+ },
3060
+ "require-main-filename": {
3061
+ "version": "1.0.1",
3062
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
3063
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
3064
+ "dev": true
3065
+ },
3066
+ "resolve": {
3067
+ "version": "1.16.0",
3068
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz",
3069
+ "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==",
3070
+ "requires": {
3071
+ "path-parse": "^1.0.6"
3072
+ }
3073
+ },
3074
+ "resolve-dir": {
3075
+ "version": "1.0.1",
3076
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
3077
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
3078
+ "requires": {
3079
+ "expand-tilde": "^2.0.0",
3080
+ "global-modules": "^1.0.0"
3081
+ }
3082
+ },
3083
+ "resolve-url": {
3084
+ "version": "0.2.1",
3085
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
3086
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
3087
+ },
3088
+ "ret": {
3089
+ "version": "0.1.15",
3090
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
3091
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
3092
+ },
3093
+ "rimraf": {
3094
+ "version": "2.6.3",
3095
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
3096
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
3097
+ "dev": true,
3098
+ "requires": {
3099
+ "glob": "^7.1.3"
3100
+ },
3101
+ "dependencies": {
3102
+ "glob": {
3103
+ "version": "7.1.6",
3104
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
3105
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
3106
+ "dev": true,
3107
+ "requires": {
3108
+ "fs.realpath": "^1.0.0",
3109
+ "inflight": "^1.0.4",
3110
+ "inherits": "2",
3111
+ "minimatch": "^3.0.4",
3112
+ "once": "^1.3.0",
3113
+ "path-is-absolute": "^1.0.0"
3114
+ }
3115
+ }
3116
+ }
3117
+ },
3118
+ "rtlcss": {
3119
+ "version": "2.5.0",
3120
+ "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.5.0.tgz",
3121
+ "integrity": "sha512-NCVdF45w70/3CQeqVvQ84bu2HN8agNn+CDjw+RxXaiWb7mPOmEvltdd1z4qzm9kin4Jnu9ShFBIx28yvWerZ2g==",
3122
+ "dev": true,
3123
+ "requires": {
3124
+ "chalk": "^2.4.2",
3125
+ "findup": "^0.1.5",
3126
+ "mkdirp": "^0.5.1",
3127
+ "postcss": "^6.0.23",
3128
+ "strip-json-comments": "^2.0.0"
3129
+ },
3130
+ "dependencies": {
3131
+ "mkdirp": {
3132
+ "version": "0.5.5",
3133
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
3134
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
3135
+ "dev": true,
3136
+ "requires": {
3137
+ "minimist": "^1.2.5"
3138
+ }
3139
+ },
3140
+ "postcss": {
3141
+ "version": "6.0.23",
3142
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
3143
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
3144
+ "dev": true,
3145
+ "requires": {
3146
+ "chalk": "^2.4.1",
3147
+ "source-map": "^0.6.1",
3148
+ "supports-color": "^5.4.0"
3149
+ }
3150
+ },
3151
+ "source-map": {
3152
+ "version": "0.6.1",
3153
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
3154
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
3155
+ "dev": true
3156
+ }
3157
+ }
3158
+ },
3159
+ "safe-buffer": {
3160
+ "version": "5.1.2",
3161
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
3162
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
3163
+ "dev": true
3164
+ },
3165
+ "safe-regex": {
3166
+ "version": "1.1.0",
3167
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
3168
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
3169
+ "requires": {
3170
+ "ret": "~0.1.10"
3171
+ }
3172
+ },
3173
+ "safer-buffer": {
3174
+ "version": "2.1.2",
3175
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
3176
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
3177
+ "dev": true
3178
+ },
3179
+ "sass-graph": {
3180
+ "version": "2.2.4",
3181
+ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
3182
+ "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
3183
+ "dev": true,
3184
+ "requires": {
3185
+ "glob": "^7.0.0",
3186
+ "lodash": "^4.0.0",
3187
+ "scss-tokenizer": "^0.2.3",
3188
+ "yargs": "^7.0.0"
3189
+ }
3190
+ },
3191
+ "scss-tokenizer": {
3192
+ "version": "0.2.3",
3193
+ "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
3194
+ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
3195
+ "dev": true,
3196
+ "requires": {
3197
+ "js-base64": "^2.1.8",
3198
+ "source-map": "^0.4.2"
3199
+ },
3200
+ "dependencies": {
3201
+ "source-map": {
3202
+ "version": "0.4.4",
3203
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
3204
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
3205
+ "dev": true,
3206
+ "requires": {
3207
+ "amdefine": ">=0.0.4"
3208
+ }
3209
+ }
3210
+ }
3211
+ },
3212
+ "semver": {
3213
+ "version": "5.7.1",
3214
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
3215
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
3216
+ "dev": true
3217
+ },
3218
+ "set-blocking": {
3219
+ "version": "2.0.0",
3220
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
3221
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
3222
+ "dev": true
3223
+ },
3224
+ "set-value": {
3225
+ "version": "2.0.1",
3226
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
3227
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
3228
+ "requires": {
3229
+ "extend-shallow": "^2.0.1",
3230
+ "is-extendable": "^0.1.1",
3231
+ "is-plain-object": "^2.0.3",
3232
+ "split-string": "^3.0.1"
3233
+ },
3234
+ "dependencies": {
3235
+ "extend-shallow": {
3236
+ "version": "2.0.1",
3237
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
3238
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
3239
+ "requires": {
3240
+ "is-extendable": "^0.1.0"
3241
+ }
3242
+ }
3243
+ }
3244
+ },
3245
+ "signal-exit": {
3246
+ "version": "3.0.3",
3247
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
3248
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
3249
+ "dev": true
3250
+ },
3251
+ "simple-concat": {
3252
+ "version": "1.0.0",
3253
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
3254
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
3255
+ "dev": true,
3256
+ "optional": true
3257
+ },
3258
+ "simple-get": {
3259
+ "version": "3.1.0",
3260
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
3261
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
3262
+ "dev": true,
3263
+ "optional": true,
3264
+ "requires": {
3265
+ "decompress-response": "^4.2.0",
3266
+ "once": "^1.3.1",
3267
+ "simple-concat": "^1.0.0"
3268
+ }
3269
+ },
3270
+ "snapdragon": {
3271
+ "version": "0.8.2",
3272
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
3273
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
3274
+ "requires": {
3275
+ "base": "^0.11.1",
3276
+ "debug": "^2.2.0",
3277
+ "define-property": "^0.2.5",
3278
+ "extend-shallow": "^2.0.1",
3279
+ "map-cache": "^0.2.2",
3280
+ "source-map": "^0.5.6",
3281
+ "source-map-resolve": "^0.5.0",
3282
+ "use": "^3.1.0"
3283
+ },
3284
+ "dependencies": {
3285
+ "define-property": {
3286
+ "version": "0.2.5",
3287
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
3288
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
3289
+ "requires": {
3290
+ "is-descriptor": "^0.1.0"
3291
+ }
3292
+ },
3293
+ "extend-shallow": {
3294
+ "version": "2.0.1",
3295
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
3296
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
3297
+ "requires": {
3298
+ "is-extendable": "^0.1.0"
3299
+ }
3300
+ }
3301
+ }
3302
+ },
3303
+ "snapdragon-node": {
3304
+ "version": "2.1.1",
3305
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
3306
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
3307
+ "requires": {
3308
+ "define-property": "^1.0.0",
3309
+ "isobject": "^3.0.0",
3310
+ "snapdragon-util": "^3.0.1"
3311
+ },
3312
+ "dependencies": {
3313
+ "define-property": {
3314
+ "version": "1.0.0",
3315
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
3316
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
3317
+ "requires": {
3318
+ "is-descriptor": "^1.0.0"
3319
+ }
3320
+ },
3321
+ "is-accessor-descriptor": {
3322
+ "version": "1.0.0",
3323
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
3324
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
3325
+ "requires": {
3326
+ "kind-of": "^6.0.0"
3327
+ }
3328
+ },
3329
+ "is-data-descriptor": {
3330
+ "version": "1.0.0",
3331
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
3332
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
3333
+ "requires": {
3334
+ "kind-of": "^6.0.0"
3335
+ }
3336
+ },
3337
+ "is-descriptor": {
3338
+ "version": "1.0.2",
3339
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
3340
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
3341
+ "requires": {
3342
+ "is-accessor-descriptor": "^1.0.0",
3343
+ "is-data-descriptor": "^1.0.0",
3344
+ "kind-of": "^6.0.2"
3345
+ }
3346
+ }
3347
+ }
3348
+ },
3349
+ "snapdragon-util": {
3350
+ "version": "3.0.1",
3351
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
3352
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
3353
+ "requires": {
3354
+ "kind-of": "^3.2.0"
3355
+ },
3356
+ "dependencies": {
3357
+ "kind-of": {
3358
+ "version": "3.2.2",
3359
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
3360
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
3361
+ "requires": {
3362
+ "is-buffer": "^1.1.5"
3363
+ }
3364
+ }
3365
+ }
3366
+ },
3367
+ "source-map": {
3368
+ "version": "0.5.7",
3369
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
3370
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
3371
+ },
3372
+ "source-map-resolve": {
3373
+ "version": "0.5.3",
3374
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
3375
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
3376
+ "requires": {
3377
+ "atob": "^2.1.2",
3378
+ "decode-uri-component": "^0.2.0",
3379
+ "resolve-url": "^0.2.1",
3380
+ "source-map-url": "^0.4.0",
3381
+ "urix": "^0.1.0"
3382
+ }
3383
+ },
3384
+ "source-map-url": {
3385
+ "version": "0.4.0",
3386
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
3387
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
3388
+ },
3389
+ "spdx-correct": {
3390
+ "version": "3.1.0",
3391
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
3392
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
3393
+ "dev": true,
3394
+ "requires": {
3395
+ "spdx-expression-parse": "^3.0.0",
3396
+ "spdx-license-ids": "^3.0.0"
3397
+ }
3398
+ },
3399
+ "spdx-exceptions": {
3400
+ "version": "2.2.0",
3401
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
3402
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
3403
+ "dev": true
3404
+ },
3405
+ "spdx-expression-parse": {
3406
+ "version": "3.0.0",
3407
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
3408
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
3409
+ "dev": true,
3410
+ "requires": {
3411
+ "spdx-exceptions": "^2.1.0",
3412
+ "spdx-license-ids": "^3.0.0"
3413
+ }
3414
+ },
3415
+ "spdx-license-ids": {
3416
+ "version": "3.0.5",
3417
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
3418
+ "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
3419
+ "dev": true
3420
+ },
3421
+ "split-string": {
3422
+ "version": "3.1.0",
3423
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
3424
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
3425
+ "requires": {
3426
+ "extend-shallow": "^3.0.0"
3427
+ }
3428
+ },
3429
+ "sprintf-js": {
3430
+ "version": "1.1.2",
3431
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
3432
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
3433
+ "dev": true
3434
+ },
3435
+ "sshpk": {
3436
+ "version": "1.16.1",
3437
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
3438
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
3439
+ "dev": true,
3440
+ "requires": {
3441
+ "asn1": "~0.2.3",
3442
+ "assert-plus": "^1.0.0",
3443
+ "bcrypt-pbkdf": "^1.0.0",
3444
+ "dashdash": "^1.12.0",
3445
+ "ecc-jsbn": "~0.1.1",
3446
+ "getpass": "^0.1.1",
3447
+ "jsbn": "~0.1.0",
3448
+ "safer-buffer": "^2.0.2",
3449
+ "tweetnacl": "~0.14.0"
3450
+ }
3451
+ },
3452
+ "static-extend": {
3453
+ "version": "0.1.2",
3454
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
3455
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
3456
+ "requires": {
3457
+ "define-property": "^0.2.5",
3458
+ "object-copy": "^0.1.0"
3459
+ },
3460
+ "dependencies": {
3461
+ "define-property": {
3462
+ "version": "0.2.5",
3463
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
3464
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
3465
+ "requires": {
3466
+ "is-descriptor": "^0.1.0"
3467
+ }
3468
+ }
3469
+ }
3470
+ },
3471
+ "stdout-stream": {
3472
+ "version": "1.4.1",
3473
+ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
3474
+ "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
3475
+ "dev": true,
3476
+ "requires": {
3477
+ "readable-stream": "^2.0.1"
3478
+ }
3479
+ },
3480
+ "stream-buffers": {
3481
+ "version": "2.2.0",
3482
+ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
3483
+ "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=",
3484
+ "dev": true
3485
+ },
3486
+ "string-width": {
3487
+ "version": "1.0.2",
3488
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
3489
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
3490
+ "dev": true,
3491
+ "requires": {
3492
+ "code-point-at": "^1.0.0",
3493
+ "is-fullwidth-code-point": "^1.0.0",
3494
+ "strip-ansi": "^3.0.0"
3495
+ }
3496
+ },
3497
+ "string_decoder": {
3498
+ "version": "1.1.1",
3499
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
3500
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
3501
+ "dev": true,
3502
+ "requires": {
3503
+ "safe-buffer": "~5.1.0"
3504
+ }
3505
+ },
3506
+ "strip-ansi": {
3507
+ "version": "3.0.1",
3508
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
3509
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
3510
+ "dev": true,
3511
+ "requires": {
3512
+ "ansi-regex": "^2.0.0"
3513
+ }
3514
+ },
3515
+ "strip-bom": {
3516
+ "version": "2.0.0",
3517
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
3518
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
3519
+ "dev": true,
3520
+ "requires": {
3521
+ "is-utf8": "^0.2.0"
3522
+ }
3523
+ },
3524
+ "strip-indent": {
3525
+ "version": "1.0.1",
3526
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
3527
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
3528
+ "dev": true,
3529
+ "requires": {
3530
+ "get-stdin": "^4.0.1"
3531
+ }
3532
+ },
3533
+ "strip-json-comments": {
3534
+ "version": "2.0.1",
3535
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
3536
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
3537
+ "dev": true
3538
+ },
3539
+ "supports-color": {
3540
+ "version": "5.5.0",
3541
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
3542
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
3543
+ "dev": true,
3544
+ "requires": {
3545
+ "has-flag": "^3.0.0"
3546
+ }
3547
+ },
3548
+ "tar": {
3549
+ "version": "2.2.2",
3550
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
3551
+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
3552
+ "dev": true,
3553
+ "requires": {
3554
+ "block-stream": "*",
3555
+ "fstream": "^1.0.12",
3556
+ "inherits": "2"
3557
+ }
3558
+ },
3559
+ "tar-fs": {
3560
+ "version": "2.0.1",
3561
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
3562
+ "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
3563
+ "dev": true,
3564
+ "optional": true,
3565
+ "requires": {
3566
+ "chownr": "^1.1.1",
3567
+ "mkdirp-classic": "^0.5.2",
3568
+ "pump": "^3.0.0",
3569
+ "tar-stream": "^2.0.0"
3570
+ },
3571
+ "dependencies": {
3572
+ "bl": {
3573
+ "version": "4.0.2",
3574
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
3575
+ "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
3576
+ "dev": true,
3577
+ "optional": true,
3578
+ "requires": {
3579
+ "buffer": "^5.5.0",
3580
+ "inherits": "^2.0.4",
3581
+ "readable-stream": "^3.4.0"
3582
+ }
3583
+ },
3584
+ "readable-stream": {
3585
+ "version": "3.6.0",
3586
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
3587
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
3588
+ "dev": true,
3589
+ "optional": true,
3590
+ "requires": {
3591
+ "inherits": "^2.0.3",
3592
+ "string_decoder": "^1.1.1",
3593
+ "util-deprecate": "^1.0.1"
3594
+ }
3595
+ },
3596
+ "tar-stream": {
3597
+ "version": "2.1.2",
3598
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
3599
+ "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==",
3600
+ "dev": true,
3601
+ "optional": true,
3602
+ "requires": {
3603
+ "bl": "^4.0.1",
3604
+ "end-of-stream": "^1.4.1",
3605
+ "fs-constants": "^1.0.0",
3606
+ "inherits": "^2.0.3",
3607
+ "readable-stream": "^3.1.1"
3608
+ }
3609
+ }
3610
+ }
3611
+ },
3612
+ "tar-stream": {
3613
+ "version": "1.6.2",
3614
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
3615
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
3616
+ "dev": true,
3617
+ "requires": {
3618
+ "bl": "^1.0.0",
3619
+ "buffer-alloc": "^1.2.0",
3620
+ "end-of-stream": "^1.0.0",
3621
+ "fs-constants": "^1.0.0",
3622
+ "readable-stream": "^2.3.0",
3623
+ "to-buffer": "^1.1.1",
3624
+ "xtend": "^4.0.0"
3625
+ }
3626
+ },
3627
+ "to-buffer": {
3628
+ "version": "1.1.1",
3629
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
3630
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
3631
+ "dev": true
3632
+ },
3633
+ "to-object-path": {
3634
+ "version": "0.3.0",
3635
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
3636
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
3637
+ "requires": {
3638
+ "kind-of": "^3.0.2"
3639
+ },
3640
+ "dependencies": {
3641
+ "kind-of": {
3642
+ "version": "3.2.2",
3643
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
3644
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
3645
+ "requires": {
3646
+ "is-buffer": "^1.1.5"
3647
+ }
3648
+ }
3649
+ }
3650
+ },
3651
+ "to-regex": {
3652
+ "version": "3.0.2",
3653
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
3654
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
3655
+ "requires": {
3656
+ "define-property": "^2.0.2",
3657
+ "extend-shallow": "^3.0.2",
3658
+ "regex-not": "^1.0.2",
3659
+ "safe-regex": "^1.1.0"
3660
+ }
3661
+ },
3662
+ "to-regex-range": {
3663
+ "version": "2.1.1",
3664
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
3665
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
3666
+ "requires": {
3667
+ "is-number": "^3.0.0",
3668
+ "repeat-string": "^1.6.1"
3669
+ }
3670
+ },
3671
+ "tough-cookie": {
3672
+ "version": "2.5.0",
3673
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
3674
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
3675
+ "dev": true,
3676
+ "requires": {
3677
+ "psl": "^1.1.28",
3678
+ "punycode": "^2.1.1"
3679
+ }
3680
+ },
3681
+ "trim-newlines": {
3682
+ "version": "1.0.0",
3683
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
3684
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
3685
+ "dev": true
3686
+ },
3687
+ "true-case-path": {
3688
+ "version": "1.0.3",
3689
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
3690
+ "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
3691
+ "dev": true,
3692
+ "requires": {
3693
+ "glob": "^7.1.2"
3694
+ },
3695
+ "dependencies": {
3696
+ "glob": {
3697
+ "version": "7.1.6",
3698
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
3699
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
3700
+ "dev": true,
3701
+ "requires": {
3702
+ "fs.realpath": "^1.0.0",
3703
+ "inflight": "^1.0.4",
3704
+ "inherits": "2",
3705
+ "minimatch": "^3.0.4",
3706
+ "once": "^1.3.0",
3707
+ "path-is-absolute": "^1.0.0"
3708
+ }
3709
+ }
3710
+ }
3711
+ },
3712
+ "tunnel-agent": {
3713
+ "version": "0.6.0",
3714
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
3715
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
3716
+ "dev": true,
3717
+ "requires": {
3718
+ "safe-buffer": "^5.0.1"
3719
+ }
3720
+ },
3721
+ "tweetnacl": {
3722
+ "version": "0.14.5",
3723
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
3724
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
3725
+ "dev": true
3726
+ },
3727
+ "unc-path-regex": {
3728
+ "version": "0.1.2",
3729
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
3730
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
3731
+ },
3732
+ "underscore.string": {
3733
+ "version": "3.3.5",
3734
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
3735
+ "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
3736
+ "dev": true,
3737
+ "requires": {
3738
+ "sprintf-js": "^1.0.3",
3739
+ "util-deprecate": "^1.0.2"
3740
+ }
3741
+ },
3742
+ "union-value": {
3743
+ "version": "1.0.1",
3744
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
3745
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
3746
+ "requires": {
3747
+ "arr-union": "^3.1.0",
3748
+ "get-value": "^2.0.6",
3749
+ "is-extendable": "^0.1.1",
3750
+ "set-value": "^2.0.1"
3751
+ }
3752
+ },
3753
+ "unset-value": {
3754
+ "version": "1.0.0",
3755
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
3756
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
3757
+ "requires": {
3758
+ "has-value": "^0.3.1",
3759
+ "isobject": "^3.0.0"
3760
+ },
3761
+ "dependencies": {
3762
+ "has-value": {
3763
+ "version": "0.3.1",
3764
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
3765
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
3766
+ "requires": {
3767
+ "get-value": "^2.0.3",
3768
+ "has-values": "^0.1.4",
3769
+ "isobject": "^2.0.0"
3770
+ },
3771
+ "dependencies": {
3772
+ "isobject": {
3773
+ "version": "2.1.0",
3774
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
3775
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
3776
+ "requires": {
3777
+ "isarray": "1.0.0"
3778
+ }
3779
+ }
3780
+ }
3781
+ },
3782
+ "has-values": {
3783
+ "version": "0.1.4",
3784
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
3785
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
3786
+ }
3787
+ }
3788
+ },
3789
+ "uri-js": {
3790
+ "version": "4.2.2",
3791
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
3792
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
3793
+ "dev": true,
3794
+ "requires": {
3795
+ "punycode": "^2.1.0"
3796
+ }
3797
+ },
3798
+ "urix": {
3799
+ "version": "0.1.0",
3800
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
3801
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
3802
+ },
3803
+ "use": {
3804
+ "version": "3.1.1",
3805
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
3806
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
3807
+ },
3808
+ "util-deprecate": {
3809
+ "version": "1.0.2",
3810
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
3811
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
3812
+ "dev": true
3813
+ },
3814
+ "uuid": {
3815
+ "version": "3.4.0",
3816
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
3817
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
3818
+ "dev": true
3819
+ },
3820
+ "v8flags": {
3821
+ "version": "3.1.3",
3822
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz",
3823
+ "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==",
3824
+ "requires": {
3825
+ "homedir-polyfill": "^1.0.1"
3826
+ }
3827
+ },
3828
+ "validate-npm-package-license": {
3829
+ "version": "3.0.4",
3830
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
3831
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
3832
+ "dev": true,
3833
+ "requires": {
3834
+ "spdx-correct": "^3.0.0",
3835
+ "spdx-expression-parse": "^3.0.0"
3836
+ }
3837
+ },
3838
+ "verror": {
3839
+ "version": "1.10.0",
3840
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
3841
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
3842
+ "dev": true,
3843
+ "requires": {
3844
+ "assert-plus": "^1.0.0",
3845
+ "core-util-is": "1.0.2",
3846
+ "extsprintf": "^1.2.0"
3847
+ }
3848
+ },
3849
+ "walkdir": {
3850
+ "version": "0.0.11",
3851
+ "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
3852
+ "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
3853
+ "dev": true
3854
+ },
3855
+ "which": {
3856
+ "version": "1.3.1",
3857
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
3858
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
3859
+ "requires": {
3860
+ "isexe": "^2.0.0"
3861
+ }
3862
+ },
3863
+ "which-module": {
3864
+ "version": "1.0.0",
3865
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
3866
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
3867
+ "dev": true
3868
+ },
3869
+ "which-pm-runs": {
3870
+ "version": "1.0.0",
3871
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
3872
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
3873
+ "dev": true,
3874
+ "optional": true
3875
+ },
3876
+ "wide-align": {
3877
+ "version": "1.1.3",
3878
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
3879
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
3880
+ "dev": true,
3881
+ "requires": {
3882
+ "string-width": "^1.0.2 || 2"
3883
+ }
3884
+ },
3885
+ "wrap-ansi": {
3886
+ "version": "2.1.0",
3887
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
3888
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
3889
+ "dev": true,
3890
+ "requires": {
3891
+ "string-width": "^1.0.1",
3892
+ "strip-ansi": "^3.0.1"
3893
+ }
3894
+ },
3895
+ "wrappy": {
3896
+ "version": "1.0.2",
3897
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
3898
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
3899
+ "dev": true
3900
+ },
3901
+ "xtend": {
3902
+ "version": "4.0.2",
3903
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
3904
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
3905
+ "dev": true
3906
+ },
3907
+ "y18n": {
3908
+ "version": "3.2.1",
3909
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
3910
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
3911
+ "dev": true
3912
+ },
3913
+ "yallist": {
3914
+ "version": "2.1.2",
3915
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
3916
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
3917
+ "dev": true
3918
+ },
3919
+ "yargs": {
3920
+ "version": "7.1.0",
3921
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
3922
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
3923
+ "dev": true,
3924
+ "requires": {
3925
+ "camelcase": "^3.0.0",
3926
+ "cliui": "^3.2.0",
3927
+ "decamelize": "^1.1.1",
3928
+ "get-caller-file": "^1.0.1",
3929
+ "os-locale": "^1.4.0",
3930
+ "read-pkg-up": "^1.0.1",
3931
+ "require-directory": "^2.1.1",
3932
+ "require-main-filename": "^1.0.1",
3933
+ "set-blocking": "^2.0.0",
3934
+ "string-width": "^1.0.2",
3935
+ "which-module": "^1.0.0",
3936
+ "y18n": "^3.2.1",
3937
+ "yargs-parser": "^5.0.0"
3938
+ },
3939
+ "dependencies": {
3940
+ "camelcase": {
3941
+ "version": "3.0.0",
3942
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
3943
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
3944
+ "dev": true
3945
+ }
3946
+ }
3947
+ },
3948
+ "yargs-parser": {
3949
+ "version": "5.0.0",
3950
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
3951
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
3952
+ "dev": true,
3953
+ "requires": {
3954
+ "camelcase": "^3.0.0"
3955
+ },
3956
+ "dependencies": {
3957
+ "camelcase": {
3958
+ "version": "3.0.0",
3959
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
3960
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
3961
+ "dev": true
3962
+ }
3963
+ }
3964
+ },
3965
+ "zip-stream": {
3966
+ "version": "1.2.0",
3967
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
3968
+ "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
3969
+ "dev": true,
3970
+ "requires": {
3971
+ "archiver-utils": "^1.3.0",
3972
+ "compress-commons": "^1.2.0",
3973
+ "lodash": "^4.8.0",
3974
+ "readable-stream": "^2.0.0"
3975
+ }
3976
+ }
3977
+ }
3978
+ }
admin/bsf-analytics/package.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "bsf-analytics",
3
+ "version": "1.0.0",
4
+ "description": "BSF Analytics Project.",
5
+ "main": "Gruntfile.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git@git.brainstormforce.com:wp-sharks/bsf-analytics.git"
9
+ },
10
+ "author": "",
11
+ "license": "ISC",
12
+ "devDependencies": {
13
+ "autoprefixer": "^9.6.1",
14
+ "grunt": "^1.0.4",
15
+ "grunt-contrib-clean": "^2.0.0",
16
+ "grunt-contrib-compress": "^1.5.0",
17
+ "grunt-contrib-copy": "^1.0.0",
18
+ "grunt-contrib-cssmin": "^3.0.0",
19
+ "grunt-postcss": "^0.9.0",
20
+ "grunt-rtlcss": "^2.0.2",
21
+ "grunt-text-replace": "^0.4.0",
22
+ "kind-of": ">=6.0.3",
23
+ "minimist": ">=1.2.3",
24
+ "node-sass": "^4.13.1",
25
+ "postcss-flexibility": "^2.0.0"
26
+ },
27
+ "dependencies": {
28
+ "grunt-cli": "^1.3.2"
29
+ }
30
+ }
admin/bsf-analytics/phpcs.xml.dist ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="WordPress Coding Standards for Plugins">
3
+ <description>Generally-applicable sniffs for WordPress plugins</description>
4
+ <config name="testVersion" value="5.3-"/>
5
+
6
+ <rule ref="WordPress-Core" />
7
+ <rule ref="WordPress-Docs" />
8
+ <rule ref="WordPress-Extra" />
9
+
10
+ <!-- Check all PHP files in directory tree by default. -->
11
+ <arg name="extensions" value="php"/>
12
+ <file>.</file>
13
+
14
+ <!-- Show sniff codes in all reports -->
15
+ <arg value="s"/>
16
+
17
+ <exclude-pattern>*/node_modules/*</exclude-pattern>
18
+ <exclude-pattern>*/vendor/*</exclude-pattern>
19
+ </ruleset>
admin/bsf-analytics/version.json ADDED
@@ -0,0 +1 @@
 
1
+ 1.0.1
admin/meta-assets/js/admin-edit.js CHANGED
@@ -228,10 +228,47 @@
228
  var $product_search = $('.wcf-product-search:not(.wc-product-search)');
229
 
230
  if( $product_search.length > 0 ) {
231
-
232
- $product_search.addClass('wc-product-search');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
- $(document.body).trigger('wc-enhanced-select-init');
 
235
  }
236
  };
237
 
@@ -275,47 +312,6 @@
275
  });
276
  };
277
 
278
- var wcf_cartflows_woo_product_search_init = function() {
279
-
280
- $( 'select.wcf-product-search' ).filter( ':not(.enhanced)' ).each( function() {
281
- var select2_args = {
282
- allowClear: $( this ).data( 'allow_clear' ) ? true : false,
283
- placeholder: $( this ).data( 'placeholder' ),
284
- minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3',
285
- escapeMarkup: function( m ) {
286
- return m;
287
- },
288
- ajax: {
289
- url: wc_enhanced_select_params.ajax_url,
290
- dataType: 'json',
291
- quietMillis: 250,
292
- data: function( params, page ) {
293
- return {
294
- term: params.term,
295
- action: $( this ).data( 'action' ) || 'wcf_json_search_products_and_variations',
296
- excluded : $( this ).data( 'excluded_product_types' ) || '',
297
- security: cartflows_admin.wcf_json_search_products_and_variations_nonce
298
- };
299
- },
300
- processResults: function( data, page ) {
301
- var terms = [];
302
- if ( data ) {
303
- $.each( data, function( id, text ) {
304
- terms.push( { id: id, text: text } );
305
- });
306
- }
307
- return { results: terms };
308
- },
309
- cache: true
310
- }
311
- };
312
-
313
- select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
314
-
315
- $( this ).select2( select2_args ).addClass( 'enhanced' );
316
- });
317
- };
318
-
319
  var wcf_pages_search_init = function() {
320
 
321
 
228
  var $product_search = $('.wcf-product-search:not(.wc-product-search)');
229
 
230
  if( $product_search.length > 0 ) {
231
+
232
+ // wcf_cartflows_woo_product_search_init();
233
+ $( 'select.wcf-product-search' ).filter( ':not(.enhanced)' ).each( function() {
234
+ var select2_args = {
235
+ allowClear: $( this ).data( 'allow_clear' ) ? true : false,
236
+ placeholder: $( this ).data( 'placeholder' ),
237
+ minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3',
238
+ escapeMarkup: function( m ) {
239
+ return m;
240
+ },
241
+ ajax: {
242
+ url: wc_enhanced_select_params.ajax_url,
243
+ dataType: 'json',
244
+ quietMillis: 250,
245
+ data: function( params, page ) {
246
+ return {
247
+ term: params.term,
248
+ action: $( this ).data( 'action' ) || 'wcf_json_search_products_and_variations',
249
+ excluded : $( this ).data( 'excluded_product_types' ) || '',
250
+ included : $( this ).data( 'include_product_types' ) || '',
251
+ allowed : $( this ).data( 'allowed_product_types' ) || '',
252
+ security: cartflows_admin.wcf_json_search_products_and_variations_nonce
253
+ };
254
+ },
255
+ processResults: function( data, page ) {
256
+ var terms = [];
257
+ if ( data ) {
258
+ $.each( data, function( id, text ) {
259
+ terms.push( { id: id, text: text } );
260
+ });
261
+ }
262
+ return { results: terms };
263
+ },
264
+ cache: true
265
+ }
266
+ };
267
+
268
+ select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
269
 
270
+ $( this ).select2( select2_args ).addClass( 'enhanced' );
271
+ });
272
  }
273
  };
274
 
312
  });
313
  };
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  var wcf_pages_search_init = function() {
316
 
317
 
assets/js/checkout-template.js CHANGED
@@ -188,7 +188,7 @@
188
 
189
  var wcf_persistent_data = function(){
190
 
191
- if( 'yes' != cartflows.allow_persistance ){
192
  return;
193
  }
194
 
188
 
189
  var wcf_persistent_data = function(){
190
 
191
+ if( 'yes' != cartflows.allow_persistence ){
192
  return;
193
  }
194
 
assets/js/optin-template.js CHANGED
@@ -61,7 +61,7 @@
61
 
62
  var wcf_persistent_data = function(){
63
 
64
- if( 'yes' != cartflows.allow_persistance ){
65
  return;
66
  }
67
 
61
 
62
  var wcf_persistent_data = function(){
63
 
64
+ if( 'yes' != cartflows.allow_persistence ){
65
  return;
66
  }
67
 
assets/min-js/checkout-template.min.js CHANGED
@@ -1 +1 @@
1
- !function(a){function o(){function r(e,o,c,t){""==e||"select"==t&&" "==e?o.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=a("form.woocommerce-checkout #customer_details"),o=e.find("input, textarea"),c=e.find("select");o.blur(function(){var e=a(this),o=e.attr("type"),c=e.closest("p.form-row"),t=e.val();r(t,c,e,o)}),c.blur(function(){var e=a(this).closest("p.form-row"),o=e.find(".select2-container--default"),c=e.find("select").val();r(c,e,o,"select")})}function c(){if("yes"==cartflows.allow_persistance&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",o=function(){var e=[],o=a("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),o.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),a(e+" input, "+e+" select").change(function(){o()})}}a(window).load(function(){});var t={init:function(){a(document.body).on("click",".wcf-submit-coupon",this.submit_coupon),a(document.body).on("click",".wcf-remove-coupon",this.remove_coupon)},submit_coupon:function(e){e.preventDefault();var o=a(".wcf-custom-coupon-field").find(".wcf-coupon-code-input"),c=o.val();if(""==c)return o.addClass("field-required"),!1;o.removeClass("field-required");var t={coupon_code:c,action:"wcf_woo_apply_coupon",security:cartflows.wcf_validate_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:t,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").remove();var c=JSON.parse(e);1==c.status&&a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(c.msg)}})},remove_coupon:function(e){e.preventDefault();var o={coupon_code:a(this).attr("data-coupon"),action:"wcf_woo_remove_coupon",security:cartflows.wcf_validate_remove_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").hide(),e&&(a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(e))}})}};a(document).ready(function(e){c(),o(),function(){a(".cartflows-container").find(".wcf-embed-checkout-form-two-column");var e=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_1_field"),o=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_2_field");e.hasClass("form-row-wide")&&(e.removeClass("form-row-wide"),e.addClass("form-row-first")),o.hasClass("form-row-wide")&&(o.removeClass("form-row-wide"),o.addClass("form-row-last"),o.find("label").hasClass("screen-reader-text")?o.addClass("mt20"):o.removeClass("mt20"));var c=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_1_field"),t=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_2_field");c.hasClass("form-row-wide")&&(c.removeClass("form-row-wide"),c.addClass("form-row-first")),t.hasClass("form-row-wide")&&(t.removeClass("form-row-wide"),t.addClass("form-row-last"),t.find("label").hasClass("screen-reader-text")?t.addClass("mt20"):t.removeClass("mt20")),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_country").on("change",function(e){}),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_country").on("change",function(e){})}(),a(document.body).on("click","#wcf-embed-checkout-form .remove",function(e){e.preventDefault();var c=a(this).attr("data-id"),o={p_key:a(this).attr("data-item-key"),p_id:c,action:"wcf_woo_remove_cart_product",security:cartflows.wcf_validate_remove_cart_product_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=JSON.parse(e);0==o.need_shipping&&a("#wcf-embed-checkout-form").find("#ship-to-different-address-checkbox").attr("checked",!1),a("#wcf-embed-checkout-form").find(".woocommerce-notices-wrapper").first().html(o.msg),a(document).trigger("cartflows_remove_product",[c]),a("#wcf-embed-checkout-form").trigger("update_checkout")}})}),t.init()})}(jQuery);
1
+ !function(a){function o(){function r(e,o,c,t){""==e||"select"==t&&" "==e?o.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=a("form.woocommerce-checkout #customer_details"),o=e.find("input, textarea"),c=e.find("select");o.blur(function(){var e=a(this),o=e.attr("type"),c=e.closest("p.form-row"),t=e.val();r(t,c,e,o)}),c.blur(function(){var e=a(this).closest("p.form-row"),o=e.find(".select2-container--default"),c=e.find("select").val();r(c,e,o,"select")})}function c(){if("yes"==cartflows.allow_persistence&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",o=function(){var e=[],o=a("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),o.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):a("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),a(e+" input, "+e+" select").change(function(){o()})}}a(window).load(function(){});var t={init:function(){a(document.body).on("click",".wcf-submit-coupon",this.submit_coupon),a(document.body).on("click",".wcf-remove-coupon",this.remove_coupon)},submit_coupon:function(e){e.preventDefault();var o=a(".wcf-custom-coupon-field").find(".wcf-coupon-code-input"),c=o.val();if(""==c)return o.addClass("field-required"),!1;o.removeClass("field-required");var t={coupon_code:c,action:"wcf_woo_apply_coupon",security:cartflows.wcf_validate_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:t,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").remove();var c=JSON.parse(e);1==c.status&&a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(c.msg)}})},remove_coupon:function(e){e.preventDefault();var o={coupon_code:a(this).attr("data-coupon"),action:"wcf_woo_remove_coupon",security:cartflows.wcf_validate_remove_coupon_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=a(".wcf-custom-coupon-field");o.find(".woocommerce-error, .woocommerce-message").hide(),e&&(a(document.body).trigger("update_checkout",{update_shipping_method:!1}),o.prepend(e))}})}};a(document).ready(function(e){c(),o(),function(){a(".cartflows-container").find(".wcf-embed-checkout-form-two-column");var e=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_1_field"),o=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_address_2_field");e.hasClass("form-row-wide")&&(e.removeClass("form-row-wide"),e.addClass("form-row-first")),o.hasClass("form-row-wide")&&(o.removeClass("form-row-wide"),o.addClass("form-row-last"),o.find("label").hasClass("screen-reader-text")?o.addClass("mt20"):o.removeClass("mt20"));var c=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_1_field"),t=a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_address_2_field");c.hasClass("form-row-wide")&&(c.removeClass("form-row-wide"),c.addClass("form-row-first")),t.hasClass("form-row-wide")&&(t.removeClass("form-row-wide"),t.addClass("form-row-last"),t.find("label").hasClass("screen-reader-text")?t.addClass("mt20"):t.removeClass("mt20")),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#billing_country").on("change",function(e){}),a(".wcf-embed-checkout-form .woocommerce-checkout").find("#shipping_country").on("change",function(e){})}(),a(document.body).on("click","#wcf-embed-checkout-form .remove",function(e){e.preventDefault();var c=a(this).attr("data-id"),o={p_key:a(this).attr("data-item-key"),p_id:c,action:"wcf_woo_remove_cart_product",security:cartflows.wcf_validate_remove_cart_product_nonce};a.ajax({type:"POST",url:cartflows.ajax_url,data:o,success:function(e){var o=JSON.parse(e);0==o.need_shipping&&a("#wcf-embed-checkout-form").find("#ship-to-different-address-checkbox").attr("checked",!1),a("#wcf-embed-checkout-form").find(".woocommerce-notices-wrapper").first().html(o.msg),a(document).trigger("cartflows_remove_product",[c]),a("#wcf-embed-checkout-form").trigger("update_checkout")}})}),t.init()})}(jQuery);
assets/min-js/optin-template.min.js CHANGED
@@ -1 +1 @@
1
- !function(r){function t(){function a(e,t,c,o){""==e||"select"==o&&" "==e?t.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=r("form.woocommerce-checkout #customer_details"),t=e.find("input, textarea"),c=e.find("select");t.blur(function(){var e=r(this),t=e.attr("type"),c=e.closest("p.form-row"),o=e.val();a(o,c,e,t)}),c.blur(function(){var e=r(this).closest("p.form-row"),t=e.find(".select2-container--default"),c=e.find("select").val();a(c,e,t,"select")})}function c(){if("yes"==cartflows.allow_persistance&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",t=function(){var e=[],t=r("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),t.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),r(e+" input, "+e+" select").change(function(){t()})}}r(document).ready(function(e){c(),t()})}(jQuery);
1
+ !function(r){function t(){function a(e,t,c,o){""==e||"select"==o&&" "==e?t.hasClass("validate-required")&&c.addClass("field-required"):c.removeClass("field-required")}var e=r("form.woocommerce-checkout #customer_details"),t=e.find("input, textarea"),c=e.find("select");t.blur(function(){var e=r(this),t=e.attr("type"),c=e.closest("p.form-row"),o=e.val();a(o,c,e,t)}),c.blur(function(){var e=r(this).closest("p.form-row"),t=e.find(".select2-container--default"),c=e.find("select").val();a(c,e,t,"select")})}function c(){if("yes"==cartflows.allow_persistence&&!1!==function(){var e="test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}()){var e="form.woocommerce-checkout #customer_details",t=function(){var e=[],t=r("form.woocommerce-checkout #customer_details");localStorage.removeItem("cartflows_checkout_form"),t.find("input[type=text], select, input[type=email], input[type=tel]").each(function(){e.push({name:this.name,value:this.value})}),cartflows_checkout_form=JSON.stringify(e),localStorage.setItem("cartflows_checkout_form",cartflows_checkout_form)};(function(){if(null!=localStorage.getItem("cartflows_checkout_form")){checkout_data=JSON.parse(localStorage.getItem("cartflows_checkout_form"));for(var e=0;e<checkout_data.length;e++)r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").hasClass("select2-hidden-accessible")?r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").selectWoo("val",[checkout_data[e].value]):r("form.woocommerce-checkout [name="+checkout_data[e].name+"]").val(checkout_data[e].value)}})(),r(e+" input, "+e+" select").change(function(){t()})}}r(document).ready(function(e){c(),t()})}(jQuery);
cartflows.php CHANGED
@@ -3,12 +3,12 @@
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.5.12
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
10
  * WC requires at least: 3.0
11
- * WC tested up to: 4.2
12
  *
13
  * @package CartFlows
14
  */
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
+ * Version: 1.5.13
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
10
  * WC requires at least: 3.0
11
+ * WC tested up to: 4.3
12
  *
13
  * @package CartFlows
14
  */
changelog.txt CHANGED
@@ -1,3 +1,7 @@
 
 
 
 
1
  Version 1.5.12 - Wednesday, 1st July 2020
2
  - Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
3
  - Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.
1
+ Version 1.5.13 - Tuesday, 21st July 2020
2
+ - Improvement: Improved the product search query of meta options.
3
+ - Improvement: Added compatibility for a future release of CartFlows Pro.
4
+
5
  Version 1.5.12 - Wednesday, 1st July 2020
6
  - Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
7
  - Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.
classes/class-cartflows-default-meta.php CHANGED
@@ -1,871 +1,871 @@
1
- <?php
2
- /**
3
- * Cartflow default options.
4
- *
5
- * @package Cartflows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Default_Meta {
14
-
15
-
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_fields
28
- */
29
- private static $checkout_fields = null;
30
-
31
- /**
32
- * Member Variable
33
- *
34
- * @var checkout_fields
35
- */
36
- private static $thankyou_fields = null;
37
-
38
- /**
39
- * Member Variable
40
- *
41
- * @var flow_fields
42
- */
43
- private static $flow_fields = null;
44
-
45
- /**
46
- * Member Variable
47
- *
48
- * @var landing_fields
49
- */
50
- private static $landing_fields = null;
51
-
52
- /**
53
- * Member Variable
54
- *
55
- * @var optin_fields
56
- */
57
- private static $optin_fields = null;
58
-
59
- /**
60
- * Initiator
61
- */
62
- public static function get_instance() {
63
- if ( ! isset( self::$instance ) ) {
64
- self::$instance = new self();
65
- }
66
- return self::$instance;
67
- }
68
-
69
- /**
70
- * Constructor
71
- */
72
- public function __construct() {
73
- }
74
-
75
- /**
76
- * Checkout Default fields.
77
- *
78
- * @param int $post_id post id.
79
- * @return array
80
- */
81
- public function get_checkout_fields( $post_id ) {
82
-
83
- if ( null === self::$checkout_fields ) {
84
- self::$checkout_fields = array(
85
- 'wcf-field-google-font-url' => array(
86
- 'default' => '',
87
- 'sanitize' => 'FILTER_DEFAULT',
88
- ),
89
- 'wcf-checkout-products' => array(
90
- 'default' => array(),
91
- 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
- ),
93
- 'wcf-checkout-layout' => array(
94
- 'default' => 'two-column',
95
- 'sanitize' => 'FILTER_DEFAULT',
96
- ),
97
- 'wcf-input-font-family' => array(
98
- 'default' => '',
99
- 'sanitize' => 'FILTER_DEFAULT',
100
- ),
101
- 'wcf-input-font-weight' => array(
102
- 'default' => '',
103
- 'sanitize' => 'FILTER_DEFAULT',
104
- ),
105
- 'wcf-heading-font-family' => array(
106
- 'default' => '',
107
- 'sanitize' => 'FILTER_DEFAULT',
108
- ),
109
- 'wcf-heading-font-weight' => array(
110
- 'default' => '',
111
- 'sanitize' => 'FILTER_DEFAULT',
112
- ),
113
- 'wcf-base-font-family' => array(
114
- 'default' => '',
115
- 'sanitize' => 'FILTER_DEFAULT',
116
- ),
117
- 'wcf-advance-options-fields' => array(
118
- 'default' => '',
119
- 'sanitize' => 'FILTER_DEFAULT',
120
- ),
121
- 'wcf-remove-product-field' => array(
122
- 'default' => '',
123
- 'sanitize' => 'FILTER_DEFAULT',
124
- ),
125
- 'wcf-checkout-place-order-button-text' => array(
126
- 'default' => '',
127
- 'sanitize' => 'FILTER_SANITIZE_STRING',
128
- ),
129
- 'wcf-base-font-weight' => array(
130
- 'default' => '',
131
- 'sanitize' => 'FILTER_DEFAULT',
132
- ),
133
- 'wcf-button-font-family' => array(
134
- 'default' => '',
135
- 'sanitize' => 'FILTER_DEFAULT',
136
- ),
137
- 'wcf-button-font-weight' => array(
138
- 'default' => '',
139
- 'sanitize' => 'FILTER_DEFAULT',
140
- ),
141
- 'wcf-primary-color' => array(
142
- 'default' => '',
143
- 'sanitize' => 'FILTER_DEFAULT',
144
- ),
145
- 'wcf-heading-color' => array(
146
- 'default' => '',
147
- 'sanitize' => 'FILTER_DEFAULT',
148
- ),
149
- 'wcf-section-bg-color' => array(
150
- 'default' => '',
151
- 'sanitize' => 'FILTER_DEFAULT',
152
- ),
153
- 'wcf-hl-bg-color' => array(
154
- 'default' => '',
155
- 'sanitize' => 'FILTER_DEFAULT',
156
- ),
157
- 'wcf-field-tb-padding' => array(
158
- 'default' => '',
159
- 'sanitize' => 'FILTER_DEFAULT',
160
- ),
161
- 'wcf-field-lr-padding' => array(
162
- 'default' => '',
163
- 'sanitize' => 'FILTER_DEFAULT',
164
- ),
165
- 'wcf-fields-skins' => array(
166
- 'default' => '',
167
- 'sanitize' => 'FILTER_DEFAULT',
168
- ),
169
- 'wcf-input-field-size' => array(
170
- 'default' => '33px',
171
- 'sanitize' => 'FILTER_DEFAULT',
172
- ),
173
- 'wcf-field-color' => array(
174
- 'default' => '',
175
- 'sanitize' => 'FILTER_DEFAULT',
176
- ),
177
- 'wcf-field-bg-color' => array(
178
- 'default' => '',
179
- 'sanitize' => 'FILTER_DEFAULT',
180
- ),
181
- 'wcf-field-border-color' => array(
182
- 'default' => '',
183
- 'sanitize' => 'FILTER_DEFAULT',
184
- ),
185
- 'wcf-box-border-color' => array(
186
- 'default' => '',
187
- 'sanitize' => 'FILTER_DEFAULT',
188
- ),
189
- 'wcf-field-label-color' => array(
190
- 'default' => '',
191
- 'sanitize' => 'FILTER_DEFAULT',
192
- ),
193
- 'wcf-submit-tb-padding' => array(
194
- 'default' => '',
195
- 'sanitize' => 'FILTER_DEFAULT',
196
- ),
197
- 'wcf-submit-lr-padding' => array(
198
- 'default' => '',
199
- 'sanitize' => 'FILTER_DEFAULT',
200
- ),
201
- 'wcf-input-button-size' => array(
202
- 'default' => '33px',
203
- 'sanitize' => 'FILTER_DEFAULT',
204
- ),
205
- 'wcf-submit-color' => array(
206
- 'default' => '',
207
- 'sanitize' => 'FILTER_DEFAULT',
208
- ),
209
- 'wcf-submit-hover-color' => array(
210
- 'default' => '',
211
- 'sanitize' => 'FILTER_DEFAULT',
212
- ),
213
- 'wcf-submit-bg-color' => array(
214
- 'default' => '',
215
- 'sanitize' => 'FILTER_DEFAULT',
216
- ),
217
- 'wcf-submit-bg-hover-color' => array(
218
- 'default' => '',
219
- 'sanitize' => 'FILTER_DEFAULT',
220
- ),
221
- 'wcf-submit-border-color' => array(
222
- 'default' => '',
223
- 'sanitize' => 'FILTER_DEFAULT',
224
- ),
225
- 'wcf-submit-border-hover-color' => array(
226
- 'default' => '',
227
- 'sanitize' => 'FILTER_DEFAULT',
228
- ),
229
- 'wcf-active-tab' => array(
230
- 'default' => '',
231
- 'sanitize' => 'FILTER_DEFAULT',
232
- ),
233
- 'wcf-header-logo-image' => array(
234
- 'default' => '',
235
- 'sanitize' => 'FILTER_DEFAULT',
236
- ),
237
- 'wcf-header-logo-width' => array(
238
- 'default' => '',
239
- 'sanitize' => 'FILTER_DEFAULT',
240
- ),
241
- 'wcf-custom-script' => array(
242
- 'default' => '',
243
- 'sanitize' => 'FILTER_DEFAULT',
244
- ),
245
- );
246
-
247
- self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
- }
249
-
250
- return self::$checkout_fields;
251
- }
252
-
253
- /**
254
- * Save Checkout Meta fields.
255
- *
256
- * @param int $post_id post id.
257
- * @return void
258
- */
259
- public function save_checkout_fields( $post_id ) {
260
-
261
- $post_meta = $this->get_checkout_fields( $post_id );
262
-
263
- $this->save_meta_fields( $post_id, $post_meta );
264
- }
265
-
266
- /**
267
- * Save Landing Meta fields.
268
- *
269
- * @param int $post_id post id.
270
- * @return void
271
- */
272
- public function save_landing_fields( $post_id ) {
273
-
274
- $post_meta = $this->get_landing_fields( $post_id );
275
-
276
- $this->save_meta_fields( $post_id, $post_meta );
277
- }
278
-
279
- /**
280
- * Save ThankYou Meta fields.
281
- *
282
- * @param int $post_id post id.
283
- * @return void
284
- */
285
- public function save_thankyou_fields( $post_id ) {
286
-
287
- $post_meta = $this->get_thankyou_fields( $post_id );
288
-
289
- $this->save_meta_fields( $post_id, $post_meta );
290
- }
291
-
292
- /**
293
- * Flow Default fields.
294
- *
295
- * @param int $post_id post id.
296
- * @return array
297
- */
298
- public function get_flow_fields( $post_id ) {
299
-
300
- if ( null === self::$flow_fields ) {
301
- self::$flow_fields = array(
302
- 'wcf-steps' => array(
303
- 'default' => array(),
304
- 'sanitize' => 'FILTER_DEFAULT',
305
- ),
306
-
307
- 'wcf-testing' => array(
308
- 'default' => 'no',
309
- 'sanitize' => 'FILTER_DEFAULT',
310
- ),
311
- );
312
- }
313
-
314
- return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
- }
316
-
317
- /**
318
- * Save Flow Meta fields.
319
- *
320
- * @param int $post_id post id.
321
- * @return void
322
- */
323
- public function save_flow_fields( $post_id ) {
324
-
325
- $post_meta = $this->get_flow_fields( $post_id );
326
-
327
- if ( isset( $post_meta['wcf-steps'] ) ) {
328
- unset( $post_meta['wcf-steps'] );
329
- }
330
-
331
- $this->save_meta_fields( $post_id, $post_meta );
332
- }
333
-
334
- /**
335
- * Save Meta fields - Common Function.
336
- *
337
- * @param int $post_id post id.
338
- * @param array $post_meta options to store.
339
- * @return void
340
- */
341
- public function save_meta_fields( $post_id, $post_meta ) {
342
-
343
- if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
- return;
345
- }
346
-
347
- foreach ( $post_meta as $key => $data ) {
348
- $meta_value = false;
349
-
350
- // Sanitize values.
351
- $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
-
353
- switch ( $sanitize_filter ) {
354
- case 'FILTER_SANITIZE_STRING':
355
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
- break;
357
-
358
- case 'FILTER_SANITIZE_URL':
359
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
- break;
361
-
362
- case 'FILTER_SANITIZE_NUMBER_INT':
363
- $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
- break;
365
-
366
- case 'FILTER_CARTFLOWS_ARRAY':
367
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
- $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
- }
370
- break;
371
-
372
- case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
- if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
- $i = 0;
375
- $q = 0;
376
-
377
- foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
- if ( ! array_key_exists( 'product', $p_data ) ) {
379
- continue;
380
- }
381
- foreach ( $p_data as $i_key => $i_value ) {
382
-
383
- if ( is_array( $i_value ) ) {
384
- foreach ( $i_value as $q_key => $q_value ) {
385
- $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
-
387
- $q++;
388
- }
389
- } else {
390
- $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
- }
392
- }
393
-
394
- $i++;
395
- }
396
- }
397
- break;
398
-
399
- case 'FILTER_CARTFLOWS_IMAGES':
400
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
-
402
- if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
-
404
- if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
-
406
- $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
- $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
-
409
- $image_data = array(
410
- 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
- 'url' => array(
412
- 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
- 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
- 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
- ),
416
- );
417
-
418
- $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
- update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
- }
421
- }
422
-
423
- break;
424
-
425
- default:
426
- if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
- $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
- } else {
429
- $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
- }
431
-
432
- break;
433
- }
434
-
435
- if ( false !== $meta_value ) {
436
- update_post_meta( $post_id, $key, $meta_value );
437
- } else {
438
- delete_post_meta( $post_id, $key );
439
- }
440
- }
441
- }
442
-
443
- /**
444
- * Get checkout meta.
445
- *
446
- * @param int $post_id post id.
447
- * @param string $key options key.
448
- * @param mix $default options default value.
449
- * @return string
450
- */
451
- public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
-
453
- $value = $this->get_save_meta( $post_id, $key );
454
-
455
- if ( ! $value ) {
456
- if ( $default ) {
457
- $value = $default;
458
- } else {
459
- $fields = $this->get_flow_fields( $post_id );
460
-
461
- if ( isset( $fields[ $key ]['default'] ) ) {
462
- $value = $fields[ $key ]['default'];
463
- }
464
- }
465
- }
466
-
467
- return $value;
468
- }
469
-
470
- /**
471
- * Get checkout meta.
472
- *
473
- * @param int $post_id post id.
474
- * @param string $key options key.
475
- * @param mix $default options default value.
476
- * @return string
477
- */
478
- public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
-
480
- $value = $this->get_save_meta( $post_id, $key );
481
-
482
- if ( ! $value ) {
483
- if ( false !== $default ) {
484
- $value = $default;
485
- } else {
486
- $fields = $this->get_checkout_fields( $post_id );
487
-
488
- if ( isset( $fields[ $key ]['default'] ) ) {
489
- $value = $fields[ $key ]['default'];
490
- }
491
- }
492
- }
493
-
494
- return $value;
495
- }
496
-
497
- /**
498
- * Get post meta.
499
- *
500
- * @param int $post_id post id.
501
- * @param string $key options key.
502
- * @return string
503
- */
504
- public function get_save_meta( $post_id, $key ) {
505
-
506
- $value = get_post_meta( $post_id, $key, true );
507
-
508
- return $value;
509
- }
510
-
511
- /**
512
- * Thank You Default fields.
513
- *
514
- * @param int $post_id post id.
515
- * @return array
516
- */
517
- public function get_thankyou_fields( $post_id ) {
518
-
519
- if ( null === self::$thankyou_fields ) {
520
- self::$thankyou_fields = array(
521
- 'wcf-field-google-font-url' => array(
522
- 'default' => '',
523
- 'sanitize' => 'FILTER_DEFAULT',
524
- ),
525
- 'wcf-active-tab' => array(
526
- 'default' => '',
527
- 'sanitize' => 'FILTER_DEFAULT',
528
- ),
529
- 'wcf-tq-text-color' => array(
530
- 'default' => '',
531
- 'sanitize' => 'FILTER_DEFAULT',
532
- ),
533
- 'wcf-tq-font-family' => array(
534
- 'default' => '',
535
- 'sanitize' => 'FILTER_DEFAULT',
536
- ),
537
- 'wcf-tq-font-size' => array(
538
- 'default' => '',
539
- 'sanitize' => 'FILTER_DEFAULT',
540
- ),
541
- 'wcf-tq-heading-color' => array(
542
- 'default' => '',
543
- 'sanitize' => 'FILTER_DEFAULT',
544
- ),
545
- 'wcf-tq-heading-font-family' => array(
546
- 'default' => '',
547
- 'sanitize' => 'FILTER_DEFAULT',
548
- ),
549
- 'wcf-tq-heading-font-wt' => array(
550
- 'default' => '',
551
- 'sanitize' => 'FILTER_DEFAULT',
552
- ),
553
- 'wcf-tq-container-width' => array(
554
- 'default' => '',
555
- 'sanitize' => 'FILTER_DEFAULT',
556
- ),
557
- 'wcf-tq-section-bg-color' => array(
558
- 'default' => '',
559
- 'sanitize' => 'FILTER_DEFAULT',
560
- ),
561
- 'wcf-tq-advance-options-fields' => array(
562
- 'default' => '',
563
- 'sanitize' => 'FILTER_DEFAULT',
564
- ),
565
- 'wcf-show-overview-section' => array(
566
- 'default' => 'yes',
567
- 'sanitize' => 'FILTER_DEFAULT',
568
- ),
569
- 'wcf-show-details-section' => array(
570
- 'default' => 'yes',
571
- 'sanitize' => 'FILTER_DEFAULT',
572
- ),
573
- 'wcf-show-billing-section' => array(
574
- 'default' => 'yes',
575
- 'sanitize' => 'FILTER_DEFAULT',
576
- ),
577
- 'wcf-show-shipping-section' => array(
578
- 'default' => 'yes',
579
- 'sanitize' => 'FILTER_DEFAULT',
580
- ),
581
- 'wcf-show-tq-redirect-section' => array(
582
- 'default' => '',
583
- 'sanitize' => 'FILTER_DEFAULT',
584
- ),
585
- 'wcf-tq-redirect-link' => array(
586
- 'default' => '',
587
- 'sanitize' => 'FILTER_SANITIZE_URL',
588
- ),
589
- 'wcf-tq-text' => array(
590
- 'default' => '',
591
- 'sanitize' => 'FILTER_DEFAULT',
592
- ),
593
- 'wcf-custom-script' => array(
594
- 'default' => '',
595
- 'sanitize' => 'FILTER_DEFAULT',
596
- ),
597
- );
598
- }
599
-
600
- return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
- }
602
-
603
- /**
604
- * Get Thank you section meta.
605
- *
606
- * @param int $post_id post id.
607
- * @param string $key options key.
608
- * @param mix $default options default value.
609
- * @return string
610
- */
611
- public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
-
613
- $value = $this->get_save_meta( $post_id, $key );
614
-
615
- if ( ! $value ) {
616
- if ( $default ) {
617
- $value = $default;
618
- } else {
619
- $fields = $this->get_thankyou_fields( $post_id );
620
-
621
- if ( isset( $fields[ $key ]['default'] ) ) {
622
- $value = $fields[ $key ]['default'];
623
- }
624
- }
625
- }
626
-
627
- return $value;
628
- }
629
-
630
- /**
631
- * Get Landing section meta.
632
- *
633
- * @param int $post_id post id.
634
- * @param string $key options key.
635
- * @param mix $default options default value.
636
- * @return string
637
- */
638
- public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
-
640
- $value = $this->get_save_meta( $post_id, $key );
641
- if ( ! $value ) {
642
- if ( $default ) {
643
- $value = $default;
644
- } else {
645
- $fields = $this->get_landing_fields( $post_id );
646
-
647
- if ( isset( $fields[ $key ]['default'] ) ) {
648
- $value = $fields[ $key ]['default'];
649
- }
650
- }
651
- }
652
-
653
- return $value;
654
- }
655
-
656
- /**
657
- * Landing Default fields.
658
- *
659
- * @param int $post_id post id.
660
- * @return array
661
- */
662
- public function get_landing_fields( $post_id ) {
663
-
664
- if ( null === self::$landing_fields ) {
665
- self::$landing_fields = array(
666
- 'wcf-custom-script' => array(
667
- 'default' => '',
668
- 'sanitize' => 'FILTER_DEFAULT',
669
- ),
670
- );
671
- }
672
- return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
- }
674
-
675
- /**
676
- * Optin Default fields.
677
- *
678
- * @param int $post_id post id.
679
- * @return array
680
- */
681
- public function get_optin_fields( $post_id ) {
682
-
683
- if ( null === self::$optin_fields ) {
684
- self::$optin_fields = array(
685
-
686
- 'wcf-optin-product' => array(
687
- 'default' => array(),
688
- 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
- ),
690
-
691
- /* Style */
692
- 'wcf-field-google-font-url' => array(
693
- 'default' => '',
694
- 'sanitize' => 'FILTER_DEFAULT',
695
- ),
696
- 'wcf-primary-color' => array(
697
- 'default' => '',
698
- 'sanitize' => 'FILTER_DEFAULT',
699
- ),
700
- 'wcf-base-font-family' => array(
701
- 'default' => '',
702
- 'sanitize' => 'FILTER_DEFAULT',
703
- ),
704
- 'wcf-input-fields-skins' => array(
705
- 'default' => '',
706
- 'sanitize' => 'FILTER_DEFAULT',
707
- ),
708
- 'wcf-input-font-family' => array(
709
- 'default' => '',
710
- 'sanitize' => 'FILTER_DEFAULT',
711
- ),
712
- 'wcf-input-font-weight' => array(
713
- 'default' => '',
714
- 'sanitize' => 'FILTER_DEFAULT',
715
- ),
716
- 'wcf-input-field-size' => array(
717
- 'default' => '33px',
718
- 'sanitize' => 'FILTER_DEFAULT',
719
- ),
720
- 'wcf-field-tb-padding' => array(
721
- 'default' => '',
722
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
- ),
724
- 'wcf-field-lr-padding' => array(
725
- 'default' => '',
726
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
- ),
728
- 'wcf-field-color' => array(
729
- 'default' => '',
730
- 'sanitize' => 'FILTER_DEFAULT',
731
- ),
732
- 'wcf-field-bg-color' => array(
733
- 'default' => '',
734
- 'sanitize' => 'FILTER_DEFAULT',
735
- ),
736
- 'wcf-field-border-color' => array(
737
- 'default' => '',
738
- 'sanitize' => 'FILTER_DEFAULT',
739
- ),
740
- 'wcf-field-label-color' => array(
741
- 'default' => '',
742
- 'sanitize' => 'FILTER_DEFAULT',
743
- ),
744
- 'wcf-submit-button-text' => array(
745
- 'default' => __( 'Submit', 'cartflows' ),
746
- 'sanitize' => 'FILTER_DEFAULT',
747
- ),
748
- 'wcf-submit-font-size' => array(
749
- 'default' => '',
750
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
- ),
752
- 'wcf-button-font-family' => array(
753
- 'default' => '',
754
- 'sanitize' => 'FILTER_DEFAULT',
755
- ),
756
- 'wcf-button-font-weight' => array(
757
- 'default' => '',
758
- 'sanitize' => 'FILTER_DEFAULT',
759
- ),
760
- 'wcf-submit-button-size' => array(
761
- 'default' => '33px',
762
- 'sanitize' => 'FILTER_DEFAULT',
763
- ),
764
- 'wcf-submit-tb-padding' => array(
765
- 'default' => '',
766
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
- ),
768
- 'wcf-submit-lr-padding' => array(
769
- 'default' => '',
770
- 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
- ),
772
- 'wcf-submit-button-position' => array(
773
- 'default' => 'center',
774
- 'sanitize' => 'FILTER_DEFAULT',
775
- ),
776
- 'wcf-submit-color' => array(
777
- 'default' => '',
778
- 'sanitize' => 'FILTER_DEFAULT',
779
- ),
780
- 'wcf-submit-hover-color' => array(
781
- 'default' => '',
782
- 'sanitize' => 'FILTER_DEFAULT',
783
- ),
784
- 'wcf-submit-bg-color' => array(
785
- 'default' => '',
786
- 'sanitize' => 'FILTER_DEFAULT',
787
- ),
788
- 'wcf-submit-bg-hover-color' => array(
789
- 'default' => '',
790
- 'sanitize' => 'FILTER_DEFAULT',
791
- ),
792
- 'wcf-submit-border-color' => array(
793
- 'default' => '',
794
- 'sanitize' => 'FILTER_DEFAULT',
795
- ),
796
- 'wcf-submit-border-hover-color' => array(
797
- 'default' => '',
798
- 'sanitize' => 'FILTER_DEFAULT',
799
- ),
800
-
801
- /* Settings */
802
- 'wcf-optin-pass-fields' => array(
803
- 'default' => '',
804
- 'sanitize' => 'FILTER_DEFAULT',
805
- ),
806
- 'wcf-optin-pass-specific-fields' => array(
807
- 'default' => 'first_name',
808
- 'sanitize' => 'FILTER_DEFAULT',
809
- ),
810
-
811
- /* Script */
812
- 'wcf-custom-script' => array(
813
- 'default' => '',
814
- 'sanitize' => 'FILTER_DEFAULT',
815
- ),
816
-
817
- /* Hidden */
818
- 'wcf-active-tab' => array(
819
- 'default' => '',
820
- 'sanitize' => 'FILTER_DEFAULT',
821
- ),
822
- );
823
- }
824
- return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
- }
826
-
827
- /**
828
- * Save Optin Meta fields.
829
- *
830
- * @param int $post_id post id.
831
- * @return void
832
- */
833
- public function save_optin_fields( $post_id ) {
834
-
835
- $post_meta = $this->get_optin_fields( $post_id );
836
-
837
- $this->save_meta_fields( $post_id, $post_meta );
838
- }
839
-
840
- /**
841
- * Get optin meta.
842
- *
843
- * @param int $post_id post id.
844
- * @param string $key options key.
845
- * @param mix $default options default value.
846
- * @return string
847
- */
848
- public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
-
850
- $value = $this->get_save_meta( $post_id, $key );
851
-
852
- if ( ! $value ) {
853
- if ( false !== $default ) {
854
- $value = $default;
855
- } else {
856
- $fields = $this->get_optin_fields( $post_id );
857
-
858
- if ( isset( $fields[ $key ]['default'] ) ) {
859
- $value = $fields[ $key ]['default'];
860
- }
861
- }
862
- }
863
-
864
- return $value;
865
- }
866
- }
867
-
868
- /**
869
- * Kicking this off by calling 'get_instance()' method
870
- */
871
- Cartflows_Default_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Cartflow default options.
4
+ *
5
+ * @package Cartflows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Default_Meta {
14
+
15
+
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_fields
28
+ */
29
+ private static $checkout_fields = null;
30
+
31
+ /**
32
+ * Member Variable
33
+ *
34
+ * @var checkout_fields
35
+ */
36
+ private static $thankyou_fields = null;
37
+
38
+ /**
39
+ * Member Variable
40
+ *
41
+ * @var flow_fields
42
+ */
43
+ private static $flow_fields = null;
44
+
45
+ /**
46
+ * Member Variable
47
+ *
48
+ * @var landing_fields
49
+ */
50
+ private static $landing_fields = null;
51
+
52
+ /**
53
+ * Member Variable
54
+ *
55
+ * @var optin_fields
56
+ */
57
+ private static $optin_fields = null;
58
+
59
+ /**
60
+ * Initiator
61
+ */
62
+ public static function get_instance() {
63
+ if ( ! isset( self::$instance ) ) {
64
+ self::$instance = new self();
65
+ }
66
+ return self::$instance;
67
+ }
68
+
69
+ /**
70
+ * Constructor
71
+ */
72
+ public function __construct() {
73
+ }
74
+
75
+ /**
76
+ * Checkout Default fields.
77
+ *
78
+ * @param int $post_id post id.
79
+ * @return array
80
+ */
81
+ public function get_checkout_fields( $post_id ) {
82
+
83
+ if ( null === self::$checkout_fields ) {
84
+ self::$checkout_fields = array(
85
+ 'wcf-field-google-font-url' => array(
86
+ 'default' => '',
87
+ 'sanitize' => 'FILTER_DEFAULT',
88
+ ),
89
+ 'wcf-checkout-products' => array(
90
+ 'default' => array(),
91
+ 'sanitize' => 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS',
92
+ ),
93
+ 'wcf-checkout-layout' => array(
94
+ 'default' => 'two-column',
95
+ 'sanitize' => 'FILTER_DEFAULT',
96
+ ),
97
+ 'wcf-input-font-family' => array(
98
+ 'default' => '',
99
+ 'sanitize' => 'FILTER_DEFAULT',
100
+ ),
101
+ 'wcf-input-font-weight' => array(
102
+ 'default' => '',
103
+ 'sanitize' => 'FILTER_DEFAULT',
104
+ ),
105
+ 'wcf-heading-font-family' => array(
106
+ 'default' => '',
107
+ 'sanitize' => 'FILTER_DEFAULT',
108
+ ),
109
+ 'wcf-heading-font-weight' => array(
110
+ 'default' => '',
111
+ 'sanitize' => 'FILTER_DEFAULT',
112
+ ),
113
+ 'wcf-base-font-family' => array(
114
+ 'default' => '',
115
+ 'sanitize' => 'FILTER_DEFAULT',
116
+ ),
117
+ 'wcf-advance-options-fields' => array(
118
+ 'default' => '',
119
+ 'sanitize' => 'FILTER_DEFAULT',
120
+ ),
121
+ 'wcf-remove-product-field' => array(
122
+ 'default' => '',
123
+ 'sanitize' => 'FILTER_DEFAULT',
124
+ ),
125
+ 'wcf-checkout-place-order-button-text' => array(
126
+ 'default' => '',
127
+ 'sanitize' => 'FILTER_SANITIZE_STRING',
128
+ ),
129
+ 'wcf-base-font-weight' => array(
130
+ 'default' => '',
131
+ 'sanitize' => 'FILTER_DEFAULT',
132
+ ),
133
+ 'wcf-button-font-family' => array(
134
+ 'default' => '',
135
+ 'sanitize' => 'FILTER_DEFAULT',
136
+ ),
137
+ 'wcf-button-font-weight' => array(
138
+ 'default' => '',
139
+ 'sanitize' => 'FILTER_DEFAULT',
140
+ ),
141
+ 'wcf-primary-color' => array(
142
+ 'default' => '',
143
+ 'sanitize' => 'FILTER_DEFAULT',
144
+ ),
145
+ 'wcf-heading-color' => array(
146
+ 'default' => '',
147
+ 'sanitize' => 'FILTER_DEFAULT',
148
+ ),
149
+ 'wcf-section-bg-color' => array(
150
+ 'default' => '',
151
+ 'sanitize' => 'FILTER_DEFAULT',
152
+ ),
153
+ 'wcf-hl-bg-color' => array(
154
+ 'default' => '',
155
+ 'sanitize' => 'FILTER_DEFAULT',
156
+ ),
157
+ 'wcf-field-tb-padding' => array(
158
+ 'default' => '',
159
+ 'sanitize' => 'FILTER_DEFAULT',
160
+ ),
161
+ 'wcf-field-lr-padding' => array(
162
+ 'default' => '',
163
+ 'sanitize' => 'FILTER_DEFAULT',
164
+ ),
165
+ 'wcf-fields-skins' => array(
166
+ 'default' => '',
167
+ 'sanitize' => 'FILTER_DEFAULT',
168
+ ),
169
+ 'wcf-input-field-size' => array(
170
+ 'default' => '33px',
171
+ 'sanitize' => 'FILTER_DEFAULT',
172
+ ),
173
+ 'wcf-field-color' => array(
174
+ 'default' => '',
175
+ 'sanitize' => 'FILTER_DEFAULT',
176
+ ),
177
+ 'wcf-field-bg-color' => array(
178
+ 'default' => '',
179
+ 'sanitize' => 'FILTER_DEFAULT',
180
+ ),
181
+ 'wcf-field-border-color' => array(
182
+ 'default' => '',
183
+ 'sanitize' => 'FILTER_DEFAULT',
184
+ ),
185
+ 'wcf-box-border-color' => array(
186
+ 'default' => '',
187
+ 'sanitize' => 'FILTER_DEFAULT',
188
+ ),
189
+ 'wcf-field-label-color' => array(
190
+ 'default' => '',
191
+ 'sanitize' => 'FILTER_DEFAULT',
192
+ ),
193
+ 'wcf-submit-tb-padding' => array(
194
+ 'default' => '',
195
+ 'sanitize' => 'FILTER_DEFAULT',
196
+ ),
197
+ 'wcf-submit-lr-padding' => array(
198
+ 'default' => '',
199
+ 'sanitize' => 'FILTER_DEFAULT',
200
+ ),
201
+ 'wcf-input-button-size' => array(
202
+ 'default' => '33px',
203
+ 'sanitize' => 'FILTER_DEFAULT',
204
+ ),
205
+ 'wcf-submit-color' => array(
206
+ 'default' => '',
207
+ 'sanitize' => 'FILTER_DEFAULT',
208
+ ),
209
+ 'wcf-submit-hover-color' => array(
210
+ 'default' => '',
211
+ 'sanitize' => 'FILTER_DEFAULT',
212
+ ),
213
+ 'wcf-submit-bg-color' => array(
214
+ 'default' => '',
215
+ 'sanitize' => 'FILTER_DEFAULT',
216
+ ),
217
+ 'wcf-submit-bg-hover-color' => array(
218
+ 'default' => '',
219
+ 'sanitize' => 'FILTER_DEFAULT',
220
+ ),
221
+ 'wcf-submit-border-color' => array(
222
+ 'default' => '',
223
+ 'sanitize' => 'FILTER_DEFAULT',
224
+ ),
225
+ 'wcf-submit-border-hover-color' => array(
226
+ 'default' => '',
227
+ 'sanitize' => 'FILTER_DEFAULT',
228
+ ),
229
+ 'wcf-active-tab' => array(
230
+ 'default' => '',
231
+ 'sanitize' => 'FILTER_DEFAULT',
232
+ ),
233
+ 'wcf-header-logo-image' => array(
234
+ 'default' => '',
235
+ 'sanitize' => 'FILTER_DEFAULT',
236
+ ),
237
+ 'wcf-header-logo-width' => array(
238
+ 'default' => '',
239
+ 'sanitize' => 'FILTER_DEFAULT',
240
+ ),
241
+ 'wcf-custom-script' => array(
242
+ 'default' => '',
243
+ 'sanitize' => 'FILTER_DEFAULT',
244
+ ),
245
+ );
246
+
247
+ self::$checkout_fields = apply_filters( 'cartflows_checkout_meta_options', self::$checkout_fields, $post_id );
248
+ }
249
+
250
+ return self::$checkout_fields;
251
+ }
252
+
253
+ /**
254
+ * Save Checkout Meta fields.
255
+ *
256
+ * @param int $post_id post id.
257
+ * @return void
258
+ */
259
+ public function save_checkout_fields( $post_id ) {
260
+
261
+ $post_meta = $this->get_checkout_fields( $post_id );
262
+
263
+ $this->save_meta_fields( $post_id, $post_meta );
264
+ }
265
+
266
+ /**
267
+ * Save Landing Meta fields.
268
+ *
269
+ * @param int $post_id post id.
270
+ * @return void
271
+ */
272
+ public function save_landing_fields( $post_id ) {
273
+
274
+ $post_meta = $this->get_landing_fields( $post_id );
275
+
276
+ $this->save_meta_fields( $post_id, $post_meta );
277
+ }
278
+
279
+ /**
280
+ * Save ThankYou Meta fields.
281
+ *
282
+ * @param int $post_id post id.
283
+ * @return void
284
+ */
285
+ public function save_thankyou_fields( $post_id ) {
286
+
287
+ $post_meta = $this->get_thankyou_fields( $post_id );
288
+
289
+ $this->save_meta_fields( $post_id, $post_meta );
290
+ }
291
+
292
+ /**
293
+ * Flow Default fields.
294
+ *
295
+ * @param int $post_id post id.
296
+ * @return array
297
+ */
298
+ public function get_flow_fields( $post_id ) {
299
+
300
+ if ( null === self::$flow_fields ) {
301
+ self::$flow_fields = array(
302
+ 'wcf-steps' => array(
303
+ 'default' => array(),
304
+ 'sanitize' => 'FILTER_DEFAULT',
305
+ ),
306
+
307
+ 'wcf-testing' => array(
308
+ 'default' => 'no',
309
+ 'sanitize' => 'FILTER_DEFAULT',
310
+ ),
311
+ );
312
+ }
313
+
314
+ return apply_filters( 'cartflows_flow_meta_options', self::$flow_fields );
315
+ }
316
+
317
+ /**
318
+ * Save Flow Meta fields.
319
+ *
320
+ * @param int $post_id post id.
321
+ * @return void
322
+ */
323
+ public function save_flow_fields( $post_id ) {
324
+
325
+ $post_meta = $this->get_flow_fields( $post_id );
326
+
327
+ if ( isset( $post_meta['wcf-steps'] ) ) {
328
+ unset( $post_meta['wcf-steps'] );
329
+ }
330
+
331
+ $this->save_meta_fields( $post_id, $post_meta );
332
+ }
333
+
334
+ /**
335
+ * Save Meta fields - Common Function.
336
+ *
337
+ * @param int $post_id post id.
338
+ * @param array $post_meta options to store.
339
+ * @return void
340
+ */
341
+ public function save_meta_fields( $post_id, $post_meta ) {
342
+
343
+ if ( ! ( $post_id && is_array( $post_meta ) ) ) {
344
+ return;
345
+ }
346
+
347
+ foreach ( $post_meta as $key => $data ) {
348
+ $meta_value = false;
349
+
350
+ // Sanitize values.
351
+ $sanitize_filter = ( isset( $data['sanitize'] ) ) ? $data['sanitize'] : 'FILTER_DEFAULT';
352
+
353
+ switch ( $sanitize_filter ) {
354
+ case 'FILTER_SANITIZE_STRING':
355
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
356
+ break;
357
+
358
+ case 'FILTER_SANITIZE_URL':
359
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_URL );
360
+ break;
361
+
362
+ case 'FILTER_SANITIZE_NUMBER_INT':
363
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_SANITIZE_NUMBER_INT );
364
+ break;
365
+
366
+ case 'FILTER_CARTFLOWS_ARRAY':
367
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
368
+ $meta_value = array_map( 'sanitize_text_field', wp_unslash( $_POST[ $key ] ) ); //phpcs:ignore
369
+ }
370
+ break;
371
+
372
+ case 'FILTER_CARTFLOWS_CHECKOUT_PRODUCTS':
373
+ if ( isset( $_POST[ $key ] ) && is_array( $_POST[ $key ] ) ) { //phpcs:ignore
374
+ $i = 0;
375
+ $q = 0;
376
+
377
+ foreach ( $_POST[ $key ] as $p_index => $p_data ) { // phpcs:ignore
378
+ if ( ! array_key_exists( 'product', $p_data ) ) {
379
+ continue;
380
+ }
381
+ foreach ( $p_data as $i_key => $i_value ) {
382
+
383
+ if ( is_array( $i_value ) ) {
384
+ foreach ( $i_value as $q_key => $q_value ) {
385
+ $meta_value[ $i ][ $i_key ][ $q ] = array_map( 'sanitize_text_field', $q_value );
386
+
387
+ $q++;
388
+ }
389
+ } else {
390
+ $meta_value[ $i ][ $i_key ] = sanitize_text_field( $i_value );
391
+ }
392
+ }
393
+
394
+ $i++;
395
+ }
396
+ }
397
+ break;
398
+
399
+ case 'FILTER_CARTFLOWS_IMAGES':
400
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
401
+
402
+ if ( isset( $_POST[ $key . '-obj' ] )) { //phpcs:ignore
403
+
404
+ if ( ! is_serialized( $_POST[ $key . '-obj' ] ) ) { //phpcs:ignore
405
+
406
+ $image_obj = json_decode( stripcslashes( wp_unslash( $_POST[ $key . '-obj' ] ) ), true ); //phpcs:ignore
407
+ $image_url = isset( $image_obj['sizes'] ) ? $image_obj['sizes'] : array();
408
+
409
+ $image_data = array(
410
+ 'id' => isset( $image_obj['id'] ) ? intval( $image_obj['id'] ) : 0,
411
+ 'url' => array(
412
+ 'thumbnail' => isset( $image_url['thumbnail']['url'] ) ? esc_url_raw( $image_url['thumbnail']['url'] ) : '',
413
+ 'medium' => isset( $image_url['medium']['url'] ) ? esc_url_raw( $image_url['medium']['url'] ) : '',
414
+ 'full' => isset( $image_url['full']['url'] ) ? esc_url_raw( $image_url['full']['url'] ) : '',
415
+ ),
416
+ );
417
+
418
+ $new_meta_value = 0 !== $image_data['id'] ? $image_data : '';
419
+ update_post_meta( $post_id, $key . '-obj', $new_meta_value );
420
+ }
421
+ }
422
+
423
+ break;
424
+
425
+ default:
426
+ if ( 'FILTER_DEFAULT' === $sanitize_filter ) {
427
+ $meta_value = filter_input( INPUT_POST, $key, FILTER_DEFAULT );
428
+ } else {
429
+ $meta_value = apply_filters( 'cartflows_save_meta_field_values', $meta_value, $post_id, $key, $sanitize_filter );
430
+ }
431
+
432
+ break;
433
+ }
434
+
435
+ if ( false !== $meta_value ) {
436
+ update_post_meta( $post_id, $key, $meta_value );
437
+ } else {
438
+ delete_post_meta( $post_id, $key );
439
+ }
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Get checkout meta.
445
+ *
446
+ * @param int $post_id post id.
447
+ * @param string $key options key.
448
+ * @param mix $default options default value.
449
+ * @return string
450
+ */
451
+ public function get_flow_meta_value( $post_id, $key, $default = false ) {
452
+
453
+ $value = $this->get_save_meta( $post_id, $key );
454
+
455
+ if ( ! $value ) {
456
+ if ( $default ) {
457
+ $value = $default;
458
+ } else {
459
+ $fields = $this->get_flow_fields( $post_id );
460
+
461
+ if ( isset( $fields[ $key ]['default'] ) ) {
462
+ $value = $fields[ $key ]['default'];
463
+ }
464
+ }
465
+ }
466
+
467
+ return $value;
468
+ }
469
+
470
+ /**
471
+ * Get checkout meta.
472
+ *
473
+ * @param int $post_id post id.
474
+ * @param string $key options key.
475
+ * @param mix $default options default value.
476
+ * @return string
477
+ */
478
+ public function get_checkout_meta_value( $post_id = 0, $key = '', $default = false ) {
479
+
480
+ $value = $this->get_save_meta( $post_id, $key );
481
+
482
+ if ( ! $value ) {
483
+ if ( false !== $default ) {
484
+ $value = $default;
485
+ } else {
486
+ $fields = $this->get_checkout_fields( $post_id );
487
+
488
+ if ( isset( $fields[ $key ]['default'] ) ) {
489
+ $value = $fields[ $key ]['default'];
490
+ }
491
+ }
492
+ }
493
+
494
+ return $value;
495
+ }
496
+
497
+ /**
498
+ * Get post meta.
499
+ *
500
+ * @param int $post_id post id.
501
+ * @param string $key options key.
502
+ * @return string
503
+ */
504
+ public function get_save_meta( $post_id, $key ) {
505
+
506
+ $value = get_post_meta( $post_id, $key, true );
507
+
508
+ return $value;
509
+ }
510
+
511
+ /**
512
+ * Thank You Default fields.
513
+ *
514
+ * @param int $post_id post id.
515
+ * @return array
516
+ */
517
+ public function get_thankyou_fields( $post_id ) {
518
+
519
+ if ( null === self::$thankyou_fields ) {
520
+ self::$thankyou_fields = array(
521
+ 'wcf-field-google-font-url' => array(
522
+ 'default' => '',
523
+ 'sanitize' => 'FILTER_DEFAULT',
524
+ ),
525
+ 'wcf-active-tab' => array(
526
+ 'default' => '',
527
+ 'sanitize' => 'FILTER_DEFAULT',
528
+ ),
529
+ 'wcf-tq-text-color' => array(
530
+ 'default' => '',
531
+ 'sanitize' => 'FILTER_DEFAULT',
532
+ ),
533
+ 'wcf-tq-font-family' => array(
534
+ 'default' => '',
535
+ 'sanitize' => 'FILTER_DEFAULT',
536
+ ),
537
+ 'wcf-tq-font-size' => array(
538
+ 'default' => '',
539
+ 'sanitize' => 'FILTER_DEFAULT',
540
+ ),
541
+ 'wcf-tq-heading-color' => array(
542
+ 'default' => '',
543
+ 'sanitize' => 'FILTER_DEFAULT',
544
+ ),
545
+ 'wcf-tq-heading-font-family' => array(
546
+ 'default' => '',
547
+ 'sanitize' => 'FILTER_DEFAULT',
548
+ ),
549
+ 'wcf-tq-heading-font-wt' => array(
550
+ 'default' => '',
551
+ 'sanitize' => 'FILTER_DEFAULT',
552
+ ),
553
+ 'wcf-tq-container-width' => array(
554
+ 'default' => '',
555
+ 'sanitize' => 'FILTER_DEFAULT',
556
+ ),
557
+ 'wcf-tq-section-bg-color' => array(
558
+ 'default' => '',
559
+ 'sanitize' => 'FILTER_DEFAULT',
560
+ ),
561
+ 'wcf-tq-advance-options-fields' => array(
562
+ 'default' => '',
563
+ 'sanitize' => 'FILTER_DEFAULT',
564
+ ),
565
+ 'wcf-show-overview-section' => array(
566
+ 'default' => 'yes',
567
+ 'sanitize' => 'FILTER_DEFAULT',
568
+ ),
569
+ 'wcf-show-details-section' => array(
570
+ 'default' => 'yes',
571
+ 'sanitize' => 'FILTER_DEFAULT',
572
+ ),
573
+ 'wcf-show-billing-section' => array(
574
+ 'default' => 'yes',
575
+ 'sanitize' => 'FILTER_DEFAULT',
576
+ ),
577
+ 'wcf-show-shipping-section' => array(
578
+ 'default' => 'yes',
579
+ 'sanitize' => 'FILTER_DEFAULT',
580
+ ),
581
+ 'wcf-show-tq-redirect-section' => array(
582
+ 'default' => '',
583
+ 'sanitize' => 'FILTER_DEFAULT',
584
+ ),
585
+ 'wcf-tq-redirect-link' => array(
586
+ 'default' => '',
587
+ 'sanitize' => 'FILTER_SANITIZE_URL',
588
+ ),
589
+ 'wcf-tq-text' => array(
590
+ 'default' => '',
591
+ 'sanitize' => 'FILTER_DEFAULT',
592
+ ),
593
+ 'wcf-custom-script' => array(
594
+ 'default' => '',
595
+ 'sanitize' => 'FILTER_DEFAULT',
596
+ ),
597
+ );
598
+ }
599
+
600
+ return apply_filters( 'cartflows_thankyou_meta_options', self::$thankyou_fields, $post_id );
601
+ }
602
+
603
+ /**
604
+ * Get Thank you section meta.
605
+ *
606
+ * @param int $post_id post id.
607
+ * @param string $key options key.
608
+ * @param mix $default options default value.
609
+ * @return string
610
+ */
611
+ public function get_thankyou_meta_value( $post_id, $key, $default = false ) {
612
+
613
+ $value = $this->get_save_meta( $post_id, $key );
614
+
615
+ if ( ! $value ) {
616
+ if ( $default ) {
617
+ $value = $default;
618
+ } else {
619
+ $fields = $this->get_thankyou_fields( $post_id );
620
+
621
+ if ( isset( $fields[ $key ]['default'] ) ) {
622
+ $value = $fields[ $key ]['default'];
623
+ }
624
+ }
625
+ }
626
+
627
+ return $value;
628
+ }
629
+
630
+ /**
631
+ * Get Landing section meta.
632
+ *
633
+ * @param int $post_id post id.
634
+ * @param string $key options key.
635
+ * @param mix $default options default value.
636
+ * @return string
637
+ */
638
+ public function get_landing_meta_value( $post_id, $key, $default = false ) {
639
+
640
+ $value = $this->get_save_meta( $post_id, $key );
641
+ if ( ! $value ) {
642
+ if ( $default ) {
643
+ $value = $default;
644
+ } else {
645
+ $fields = $this->get_landing_fields( $post_id );
646
+
647
+ if ( isset( $fields[ $key ]['default'] ) ) {
648
+ $value = $fields[ $key ]['default'];
649
+ }
650
+ }
651
+ }
652
+
653
+ return $value;
654
+ }
655
+
656
+ /**
657
+ * Landing Default fields.
658
+ *
659
+ * @param int $post_id post id.
660
+ * @return array
661
+ */
662
+ public function get_landing_fields( $post_id ) {
663
+
664
+ if ( null === self::$landing_fields ) {
665
+ self::$landing_fields = array(
666
+ 'wcf-custom-script' => array(
667
+ 'default' => '',
668
+ 'sanitize' => 'FILTER_DEFAULT',
669
+ ),
670
+ );
671
+ }
672
+ return apply_filters( 'cartflows_landing_meta_options', self::$landing_fields, $post_id );
673
+ }
674
+
675
+ /**
676
+ * Optin Default fields.
677
+ *
678
+ * @param int $post_id post id.
679
+ * @return array
680
+ */
681
+ public function get_optin_fields( $post_id ) {
682
+
683
+ if ( null === self::$optin_fields ) {
684
+ self::$optin_fields = array(
685
+
686
+ 'wcf-optin-product' => array(
687
+ 'default' => array(),
688
+ 'sanitize' => 'FILTER_CARTFLOWS_ARRAY',
689
+ ),
690
+
691
+ /* Style */
692
+ 'wcf-field-google-font-url' => array(
693
+ 'default' => '',
694
+ 'sanitize' => 'FILTER_DEFAULT',
695
+ ),
696
+ 'wcf-primary-color' => array(
697
+ 'default' => '',
698
+ 'sanitize' => 'FILTER_DEFAULT',
699
+ ),
700
+ 'wcf-base-font-family' => array(
701
+ 'default' => '',
702
+ 'sanitize' => 'FILTER_DEFAULT',
703
+ ),
704
+ 'wcf-input-fields-skins' => array(
705
+ 'default' => '',
706
+ 'sanitize' => 'FILTER_DEFAULT',
707
+ ),
708
+ 'wcf-input-font-family' => array(
709
+ 'default' => '',
710
+ 'sanitize' => 'FILTER_DEFAULT',
711
+ ),
712
+ 'wcf-input-font-weight' => array(
713
+ 'default' => '',
714
+ 'sanitize' => 'FILTER_DEFAULT',
715
+ ),
716
+ 'wcf-input-field-size' => array(
717
+ 'default' => '33px',
718
+ 'sanitize' => 'FILTER_DEFAULT',
719
+ ),
720
+ 'wcf-field-tb-padding' => array(
721
+ 'default' => '',
722
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
723
+ ),
724
+ 'wcf-field-lr-padding' => array(
725
+ 'default' => '',
726
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
727
+ ),
728
+ 'wcf-field-color' => array(
729
+ 'default' => '',
730
+ 'sanitize' => 'FILTER_DEFAULT',
731
+ ),
732
+ 'wcf-field-bg-color' => array(
733
+ 'default' => '',
734
+ 'sanitize' => 'FILTER_DEFAULT',
735
+ ),
736
+ 'wcf-field-border-color' => array(
737
+ 'default' => '',
738
+ 'sanitize' => 'FILTER_DEFAULT',
739
+ ),
740
+ 'wcf-field-label-color' => array(
741
+ 'default' => '',
742
+ 'sanitize' => 'FILTER_DEFAULT',
743
+ ),
744
+ 'wcf-submit-button-text' => array(
745
+ 'default' => __( 'Submit', 'cartflows' ),
746
+ 'sanitize' => 'FILTER_DEFAULT',
747
+ ),
748
+ 'wcf-submit-font-size' => array(
749
+ 'default' => '',
750
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
751
+ ),
752
+ 'wcf-button-font-family' => array(
753
+ 'default' => '',
754
+ 'sanitize' => 'FILTER_DEFAULT',
755
+ ),
756
+ 'wcf-button-font-weight' => array(
757
+ 'default' => '',
758
+ 'sanitize' => 'FILTER_DEFAULT',
759
+ ),
760
+ 'wcf-submit-button-size' => array(
761
+ 'default' => '33px',
762
+ 'sanitize' => 'FILTER_DEFAULT',
763
+ ),
764
+ 'wcf-submit-tb-padding' => array(
765
+ 'default' => '',
766
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
767
+ ),
768
+ 'wcf-submit-lr-padding' => array(
769
+ 'default' => '',
770
+ 'sanitize' => 'FILTER_SANITIZE_NUMBER_INT',
771
+ ),
772
+ 'wcf-submit-button-position' => array(
773
+ 'default' => 'center',
774
+ 'sanitize' => 'FILTER_DEFAULT',
775
+ ),
776
+ 'wcf-submit-color' => array(
777
+ 'default' => '',
778
+ 'sanitize' => 'FILTER_DEFAULT',
779
+ ),
780
+ 'wcf-submit-hover-color' => array(
781
+ 'default' => '',
782
+ 'sanitize' => 'FILTER_DEFAULT',
783
+ ),
784
+ 'wcf-submit-bg-color' => array(
785
+ 'default' => '',
786
+ 'sanitize' => 'FILTER_DEFAULT',
787
+ ),
788
+ 'wcf-submit-bg-hover-color' => array(
789
+ 'default' => '',
790
+ 'sanitize' => 'FILTER_DEFAULT',
791
+ ),
792
+ 'wcf-submit-border-color' => array(
793
+ 'default' => '',
794
+ 'sanitize' => 'FILTER_DEFAULT',
795
+ ),
796
+ 'wcf-submit-border-hover-color' => array(
797
+ 'default' => '',
798
+ 'sanitize' => 'FILTER_DEFAULT',
799
+ ),
800
+
801
+ /* Settings */
802
+ 'wcf-optin-pass-fields' => array(
803
+ 'default' => '',
804
+ 'sanitize' => 'FILTER_DEFAULT',
805
+ ),
806
+ 'wcf-optin-pass-specific-fields' => array(
807
+ 'default' => 'first_name',
808
+ 'sanitize' => 'FILTER_DEFAULT',
809
+ ),
810
+
811
+ /* Script */
812
+ 'wcf-custom-script' => array(
813
+ 'default' => '',
814
+ 'sanitize' => 'FILTER_DEFAULT',
815
+ ),
816
+
817
+ /* Hidden */
818
+ 'wcf-active-tab' => array(
819
+ 'default' => '',
820
+ 'sanitize' => 'FILTER_DEFAULT',
821
+ ),
822
+ );
823
+ }
824
+ return apply_filters( 'cartflows_optin_meta_options', self::$optin_fields, $post_id );
825
+ }
826
+
827
+ /**
828
+ * Save Optin Meta fields.
829
+ *
830
+ * @param int $post_id post id.
831
+ * @return void
832
+ */
833
+ public function save_optin_fields( $post_id ) {
834
+
835
+ $post_meta = $this->get_optin_fields( $post_id );
836
+
837
+ $this->save_meta_fields( $post_id, $post_meta );
838
+ }
839
+
840
+ /**
841
+ * Get optin meta.
842
+ *
843
+ * @param int $post_id post id.
844
+ * @param string $key options key.
845
+ * @param mix $default options default value.
846
+ * @return string
847
+ */
848
+ public function get_optin_meta_value( $post_id = 0, $key = '', $default = false ) {
849
+
850
+ $value = $this->get_save_meta( $post_id, $key );
851
+
852
+ if ( ! $value ) {
853
+ if ( false !== $default ) {
854
+ $value = $default;
855
+ } else {
856
+ $fields = $this->get_optin_fields( $post_id );
857
+
858
+ if ( isset( $fields[ $key ]['default'] ) ) {
859
+ $value = $fields[ $key ]['default'];
860
+ }
861
+ }
862
+ }
863
+
864
+ return $value;
865
+ }
866
+ }
867
+
868
+ /**
869
+ * Kicking this off by calling 'get_instance()' method
870
+ */
871
+ Cartflows_Default_Meta::get_instance();
classes/class-cartflows-flow-frontend.php CHANGED
@@ -1,247 +1,247 @@
1
- <?php
2
- /**
3
- * Frontend & Markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Frontend {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- /* Analytics */
39
- add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
- }
41
-
42
- /**
43
- * Footer markup
44
- */
45
- public function footer_markup() {
46
-
47
- if ( wcf()->utils->is_step_post_type() ) {
48
- // @codingStandardsIgnoreStart
49
- $flow_id = wcf()->utils->get_flow_id();
50
- ?>
51
- <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
- <div class="wcf-preview-mode">
53
- <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
- <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
- <?php
56
- $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
- ?>
58
- <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
- <?php } ?>
60
- </div>
61
- <?php } ?>
62
- <?php
63
- // @codingStandardsIgnoreEnd
64
- }
65
- }
66
-
67
- /**
68
- * Check if flow test mode is enable.
69
- *
70
- * @since 1.0.0
71
- * @param int $flow_id flow ID.
72
- *
73
- * @return boolean
74
- */
75
- public function is_flow_testmode( $flow_id = '' ) {
76
-
77
- if ( ! $flow_id ) {
78
- $flow_id = wcf()->utils->get_flow_id();
79
- }
80
-
81
- $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
-
83
- if ( 'no' === $test_mode ) {
84
- return false;
85
- }
86
-
87
- return true;
88
- }
89
-
90
- /**
91
- * Get steps data.
92
- *
93
- * @since 1.0.0
94
- * @param int $flow_id flow ID.
95
- *
96
- * @return array
97
- */
98
- public function get_steps( $flow_id ) {
99
-
100
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
-
102
- if ( ! is_array( $steps ) ) {
103
-
104
- $steps = array();
105
- }
106
-
107
- return $steps;
108
- }
109
-
110
- /**
111
- * Check thank you page exists.
112
- *
113
- * @since 1.0.0
114
- * @param array $order order data.
115
- *
116
- * @return bool
117
- */
118
- public function is_thankyou_page_exists( $order ) {
119
-
120
- $thankyou_step_exist = false;
121
-
122
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
-
124
- if ( $flow_id ) {
125
-
126
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
-
129
- if ( is_array( $flow_steps ) ) {
130
-
131
- $current_step_found = false;
132
-
133
- foreach ( $flow_steps as $index => $data ) {
134
-
135
- if ( $current_step_found ) {
136
-
137
- if ( 'thankyou' === $data['type'] ) {
138
-
139
- $thankyou_step_exist = true;
140
- break;
141
- }
142
- } else {
143
-
144
- if ( intval( $data['id'] ) === $step_id ) {
145
-
146
- $current_step_found = true;
147
- }
148
- }
149
- }
150
- }
151
- }
152
-
153
- return $thankyou_step_exist;
154
- }
155
-
156
- /**
157
- * Check thank you page exists.
158
- *
159
- * @since 1.0.0
160
- * @param array $order order data.
161
- *
162
- * @return bool
163
- */
164
- public function get_thankyou_page_id( $order ) {
165
-
166
- $thankyou_step_id = false;
167
-
168
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
-
170
- if ( $flow_id ) {
171
-
172
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
-
175
- if ( is_array( $flow_steps ) ) {
176
-
177
- $current_step_found = false;
178
-
179
- foreach ( $flow_steps as $index => $data ) {
180
-
181
- if ( $current_step_found ) {
182
-
183
- if ( 'thankyou' === $data['type'] ) {
184
-
185
- $thankyou_step_id = intval( $data['id'] );
186
- break;
187
- }
188
- } else {
189
-
190
- if ( intval( $data['id'] ) === $step_id ) {
191
-
192
- $current_step_found = true;
193
- }
194
- }
195
- }
196
- }
197
- }
198
-
199
- return $thankyou_step_id;
200
- }
201
-
202
- /**
203
- * Check thank you page exists.
204
- *
205
- * @since 1.0.0
206
- * @param array $order order data.
207
- *
208
- * @return bool
209
- */
210
- public function get_next_step_id( $order ) {
211
-
212
- $next_step_id = false;
213
-
214
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
-
216
- if ( $flow_id ) {
217
-
218
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
- $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
-
221
- if ( is_array( $flow_steps ) ) {
222
-
223
- foreach ( $flow_steps as $index => $data ) {
224
-
225
- if ( intval( $data['id'] ) === $step_id ) {
226
-
227
- $next_step_index = $index + 1;
228
-
229
- if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
-
231
- $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
- }
233
-
234
- break;
235
- }
236
- }
237
- }
238
- }
239
-
240
- return $next_step_id;
241
- }
242
- }
243
-
244
- /**
245
- * Kicking this off by calling 'get_instance()' method
246
- */
247
- Cartflows_Flow_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * Frontend & Markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Frontend {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ /* Analytics */
39
+ add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
+ }
41
+
42
+ /**
43
+ * Footer markup
44
+ */
45
+ public function footer_markup() {
46
+
47
+ if ( wcf()->utils->is_step_post_type() ) {
48
+ // @codingStandardsIgnoreStart
49
+ $flow_id = wcf()->utils->get_flow_id();
50
+ ?>
51
+ <?php if( $this->is_flow_testmode( $flow_id ) ) { ?>
52
+ <div class="wcf-preview-mode">
53
+ <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
54
+ <?php if ( current_user_can( 'manage_options' ) ) { ?>
55
+ <?php
56
+ $flow_edit_link = add_query_arg( 'edit_test_mode', 'yes', get_edit_post_link( $flow_id ) );
57
+ ?>
58
+ <a href="<?php echo $flow_edit_link; ?>"><?php _e( 'Click here to disable it', 'cartflows'); ?></a>
59
+ <?php } ?>
60
+ </div>
61
+ <?php } ?>
62
+ <?php
63
+ // @codingStandardsIgnoreEnd
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Check if flow test mode is enable.
69
+ *
70
+ * @since 1.0.0
71
+ * @param int $flow_id flow ID.
72
+ *
73
+ * @return boolean
74
+ */
75
+ public function is_flow_testmode( $flow_id = '' ) {
76
+
77
+ if ( ! $flow_id ) {
78
+ $flow_id = wcf()->utils->get_flow_id();
79
+ }
80
+
81
+ $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
82
+
83
+ if ( 'no' === $test_mode ) {
84
+ return false;
85
+ }
86
+
87
+ return true;
88
+ }
89
+
90
+ /**
91
+ * Get steps data.
92
+ *
93
+ * @since 1.0.0
94
+ * @param int $flow_id flow ID.
95
+ *
96
+ * @return array
97
+ */
98
+ public function get_steps( $flow_id ) {
99
+
100
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
101
+
102
+ if ( ! is_array( $steps ) ) {
103
+
104
+ $steps = array();
105
+ }
106
+
107
+ return $steps;
108
+ }
109
+
110
+ /**
111
+ * Check thank you page exists.
112
+ *
113
+ * @since 1.0.0
114
+ * @param array $order order data.
115
+ *
116
+ * @return bool
117
+ */
118
+ public function is_thankyou_page_exists( $order ) {
119
+
120
+ $thankyou_step_exist = false;
121
+
122
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
123
+
124
+ if ( $flow_id ) {
125
+
126
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
127
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
128
+
129
+ if ( is_array( $flow_steps ) ) {
130
+
131
+ $current_step_found = false;
132
+
133
+ foreach ( $flow_steps as $index => $data ) {
134
+
135
+ if ( $current_step_found ) {
136
+
137
+ if ( 'thankyou' === $data['type'] ) {
138
+
139
+ $thankyou_step_exist = true;
140
+ break;
141
+ }
142
+ } else {
143
+
144
+ if ( intval( $data['id'] ) === $step_id ) {
145
+
146
+ $current_step_found = true;
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ return $thankyou_step_exist;
154
+ }
155
+
156
+ /**
157
+ * Check thank you page exists.
158
+ *
159
+ * @since 1.0.0
160
+ * @param array $order order data.
161
+ *
162
+ * @return bool
163
+ */
164
+ public function get_thankyou_page_id( $order ) {
165
+
166
+ $thankyou_step_id = false;
167
+
168
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
169
+
170
+ if ( $flow_id ) {
171
+
172
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
173
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
174
+
175
+ if ( is_array( $flow_steps ) ) {
176
+
177
+ $current_step_found = false;
178
+
179
+ foreach ( $flow_steps as $index => $data ) {
180
+
181
+ if ( $current_step_found ) {
182
+
183
+ if ( 'thankyou' === $data['type'] ) {
184
+
185
+ $thankyou_step_id = intval( $data['id'] );
186
+ break;
187
+ }
188
+ } else {
189
+
190
+ if ( intval( $data['id'] ) === $step_id ) {
191
+
192
+ $current_step_found = true;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+
199
+ return $thankyou_step_id;
200
+ }
201
+
202
+ /**
203
+ * Check thank you page exists.
204
+ *
205
+ * @since 1.0.0
206
+ * @param array $order order data.
207
+ *
208
+ * @return bool
209
+ */
210
+ public function get_next_step_id( $order ) {
211
+
212
+ $next_step_id = false;
213
+
214
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
215
+
216
+ if ( $flow_id ) {
217
+
218
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
219
+ $step_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
220
+
221
+ if ( is_array( $flow_steps ) ) {
222
+
223
+ foreach ( $flow_steps as $index => $data ) {
224
+
225
+ if ( intval( $data['id'] ) === $step_id ) {
226
+
227
+ $next_step_index = $index + 1;
228
+
229
+ if ( isset( $flow_steps[ $next_step_index ] ) ) {
230
+
231
+ $next_step_id = intval( $flow_steps[ $next_step_index ]['id'] );
232
+ }
233
+
234
+ break;
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ return $next_step_id;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Kicking this off by calling 'get_instance()' method
246
+ */
247
+ Cartflows_Flow_Frontend::get_instance();
classes/class-cartflows-frontend.php CHANGED
@@ -1,654 +1,654 @@
1
- <?php
2
- /**
3
- * CartFlows Frontend.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Frontend.
10
- */
11
- class Cartflows_Frontend {
12
-
13
- /**
14
- * Member Variable
15
- *
16
- * @var instance
17
- */
18
- private static $instance;
19
-
20
- /**
21
- * Initiator
22
- */
23
- public static function get_instance() {
24
- if ( ! isset( self::$instance ) ) {
25
- self::$instance = new self();
26
- }
27
- return self::$instance;
28
- }
29
-
30
- /**
31
- * Constructor
32
- */
33
- public function __construct() {
34
-
35
- /* Set / Destroy Flow Sessions. Set data */
36
- add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
-
38
- add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
- add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
- /* Enqueue global required scripts */
41
- add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
-
43
- /* Modify the checkout order received url to go thank you page in our flow */
44
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
-
46
- add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
-
48
- }
49
-
50
- /**
51
- * Redirect to thank page if upsell not exists
52
- *
53
- * @param string $order_recieve_url url.
54
- * @param object $order order object.
55
- * @since 1.0.0
56
- */
57
- public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
-
59
- /* Only for thank you page */
60
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
- wcf()->logger->log( 'Only for thank you page' );
62
-
63
- if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
-
65
- if ( _is_wcf_doing_checkout_ajax() ) {
66
-
67
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
-
69
- if ( ! $checkout_id ) {
70
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
- }
72
- } else {
73
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
- }
75
-
76
- wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
-
78
- if ( $checkout_id ) {
79
-
80
- $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
-
82
- if ( $thankyou_step_id ) {
83
-
84
- $order_recieve_url = get_permalink( $thankyou_step_id );
85
-
86
- $order_recieve_url = add_query_arg(
87
- array(
88
- 'wcf-key' => $order->get_order_key(),
89
- 'wcf-order' => $order->get_id(),
90
- ),
91
- $order_recieve_url
92
- );
93
- }
94
- }
95
- }
96
-
97
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
-
99
- Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
-
101
- Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
-
103
- return $order_recieve_url;
104
- }
105
-
106
- /**
107
- * Cancel and redirect to checkout
108
- *
109
- * @param string $return_url url.
110
- * @since 1.0.0
111
- */
112
- public function redirect_to_checkout_on_cancel( $return_url ) {
113
-
114
- if ( _is_wcf_doing_checkout_ajax() ) {
115
-
116
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
-
118
- if ( ! $checkout_id ) {
119
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
- }
121
- } else {
122
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
- }
124
-
125
- if ( $checkout_id ) {
126
-
127
- $return_url = add_query_arg(
128
- array(
129
- 'cancel_order' => 'true',
130
- '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
- ),
132
- get_permalink( $checkout_id )
133
- );
134
- }
135
-
136
- return $return_url;
137
- }
138
-
139
-
140
- /**
141
- * Remove theme styles.
142
- *
143
- * @since 1.0.0
144
- */
145
- public function remove_theme_styles() {
146
-
147
- if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
- return;
149
- }
150
-
151
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
-
153
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
-
155
- if ( ! _wcf_supported_template( $page_template ) ) {
156
- return;
157
- }
158
-
159
- // get all styles data.
160
- global $wp_styles;
161
- global $wp_scripts;
162
-
163
- $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
- $get_template = 'themes/' . get_template() . '/';
165
-
166
- $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
-
168
- if ( $remove_styles ) {
169
-
170
- // loop over all of the registered scripts..
171
- foreach ( $wp_styles->registered as $handle => $data ) {
172
-
173
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
-
175
- // remove it.
176
- wp_deregister_style( $handle );
177
- wp_dequeue_style( $handle );
178
- }
179
- }
180
- }
181
-
182
- $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
-
184
- if ( $remove_scripts ) {
185
-
186
- // loop over all of the registered scripts.
187
- foreach ( $wp_scripts->registered as $handle => $data ) {
188
-
189
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
-
191
- // remove it.
192
- wp_deregister_script( $handle );
193
- wp_dequeue_script( $handle );
194
- }
195
- }
196
- }
197
-
198
- }
199
-
200
- /**
201
- * Update main order data in transient.
202
- *
203
- * @param array $woo_styles new styles array.
204
- * @since 1.0.0
205
- * @return array.
206
- */
207
- public function woo_default_css( $woo_styles ) {
208
-
209
- $woo_styles = array(
210
- 'woocommerce-layout' => array(
211
- 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
- 'deps' => '',
213
- 'version' => WC_VERSION,
214
- 'media' => 'all',
215
- 'has_rtl' => true,
216
- ),
217
- 'woocommerce-smallscreen' => array(
218
- 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
- 'deps' => 'woocommerce-layout',
220
- 'version' => WC_VERSION,
221
- 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
- 'has_rtl' => true,
223
- ),
224
- 'woocommerce-general' => array(
225
- 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
- 'deps' => '',
227
- 'version' => WC_VERSION,
228
- 'media' => 'all',
229
- 'has_rtl' => true,
230
- ),
231
- );
232
-
233
- return $woo_styles;
234
- }
235
-
236
- /**
237
- * Init Actions.
238
- *
239
- * @since 1.0.0
240
- */
241
- public function init_actions() {
242
-
243
- $this->set_flow_session();
244
- }
245
-
246
- /**
247
- * Set flow session.
248
- *
249
- * @since 1.0.0
250
- */
251
- public function set_flow_session() {
252
-
253
- if ( wcf()->utils->is_step_post_type() ) {
254
- global $wp;
255
- add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
-
257
- wcf()->utils->do_not_cache();
258
-
259
- if ( _is_wcf_thankyou_type() ) {
260
- /* Set key to support pixel */
261
- if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
-
263
- $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
-
265
- $_GET['key'] = $wcf_key;
266
- $_REQUEST['key'] = $wcf_key;
267
- }
268
-
269
- if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
-
271
- $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
-
273
- $_GET['order'] = $wcf_order;
274
- $_REQUEST['order'] = $wcf_order;
275
- $_GET['order-received'] = $wcf_order;
276
- $_REQUEST['order-received'] = $wcf_order;
277
-
278
- $wp->set_query_var( 'order-received', $wcf_order );
279
- }
280
- }
281
- }
282
- }
283
-
284
- /**
285
- * Add noindex, nofollow.
286
- *
287
- * @since 1.0.0
288
- */
289
- public function noindex_flow() {
290
-
291
- $common = Cartflows_Helper::get_common_settings();
292
-
293
- if ( 'enable' === $common['disallow_indexing'] ) {
294
- echo '<meta name="robots" content="noindex,nofollow">';
295
- }
296
- }
297
-
298
- /**
299
- * WP Actions.
300
- *
301
- * @since 1.0.0
302
- */
303
- public function wp_actions() {
304
-
305
- if ( wcf()->utils->is_step_post_type() ) {
306
-
307
- if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
- wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
- }
310
-
311
- /* CSS Compatibility for All theme */
312
- add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
-
314
- add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
- add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
-
317
- /* Load woo templates from plugin */
318
- add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
-
320
- /* Add version class to body in frontend. */
321
- add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
-
323
- /* Custom Script Option */
324
- add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
-
326
- /* Remove the action applied by the Flatsome theme */
327
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
- $this->remove_flatsome_action();
329
- }
330
- }
331
- }
332
-
333
- /**
334
- * Function for facebook pixel.
335
- */
336
- public function facebook_pixel_init() {
337
-
338
- $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
-
341
- $facebook_id = $facebook_settings['facebook_pixel_id'];
342
- echo '<!-- Facebook Pixel Script By CartFlows -->';
343
- $fb_script = "<script type='text/javascript'>
344
- !function(f,b,e,v,n,t,s)
345
- {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
- n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
- if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
- n.queue=[];t=b.createElement(e);t.async=!0;
349
- t.src=v;s=b.getElementsByTagName(e)[0];
350
- s.parentNode.insertBefore(t,s)}(window, document,'script',
351
- 'https://connect.facebook.net/en_US/fbevents.js');
352
- </script>
353
- <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
-
355
- $fb_page_view = "<script type='text/javascript'>
356
- fbq('init', $facebook_id);
357
- fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
- </script>";
359
-
360
- if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
- echo $fb_script;
362
- echo $fb_page_view;
363
- } else {
364
- echo $fb_script;
365
- }
366
- echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
- }
368
-
369
- }
370
-
371
- /**
372
- * Debug Data Setting Actions.
373
- *
374
- * @since 1.1.14
375
- */
376
- public function debug_data_setting_actions() {
377
-
378
- add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
- }
380
-
381
- /**
382
- * Get/Set the allow minify option.
383
- *
384
- * @since 1.1.14
385
- */
386
- public function allow_load_minify() {
387
- $debug_data = Cartflows_Helper::get_debug_settings();
388
- $allow_minified = $debug_data['allow_minified_files'];
389
- $allow_minify = false;
390
-
391
- if ( 'enable' === $allow_minified ) {
392
- $allow_minify = true;
393
- }
394
-
395
- return $allow_minify;
396
- }
397
-
398
- /**
399
- * Global flow scripts.
400
- *
401
- * @since 1.0.0
402
- */
403
- public function global_flow_scripts() {
404
-
405
- global $post;
406
-
407
- $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
- $current_step = $post->ID;
409
- $next_step_link = '';
410
- $compatibility = Cartflows_Compatibility::get_instance();
411
-
412
- if ( _is_wcf_landing_type() ) {
413
-
414
- $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
- $next_step_link = get_permalink( $next_step_id );
416
- }
417
-
418
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
-
420
- $fb_active = Cartflows_Helper::get_facebook_settings();
421
- $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
- $params = array();
423
- $ga_param = array();
424
-
425
- if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
-
427
- $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
- }
429
-
430
- if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
- $ga_param = Cartflows_Tracking::get_ga_items_list();
432
- }
433
-
434
- $localize = array(
435
- 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
- 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
- 'current_theme' => $compatibility->get_current_theme(),
438
- 'current_flow' => $flow,
439
- 'current_step' => $current_step,
440
- 'next_step' => $next_step_link,
441
- 'page_template' => $page_template,
442
- 'is_checkout_page' => _is_wcf_checkout_type(),
443
- 'params' => $params,
444
- 'fb_active' => $fb_active,
445
- 'wcf_ga_active' => $wcf_ga_active,
446
- 'ga_param' => $ga_param,
447
- );
448
-
449
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
-
451
- if ( _wcf_supported_template( $page_template ) ) {
452
-
453
- wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
- }
455
-
456
- wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
-
458
- wp_enqueue_script(
459
- 'wcf-frontend-global',
460
- wcf()->utils->get_js_url( 'frontend' ),
461
- array( 'jquery', 'jquery-cookie' ),
462
- CARTFLOWS_VER,
463
- false
464
- );
465
- }
466
-
467
- /**
468
- * Custom Script in head.
469
- *
470
- * @since 1.0.0
471
- */
472
- public function custom_script_option() {
473
-
474
- /* Add custom script to header in frontend. */
475
- $script = $this->get_custom_script();
476
- if ( '' !== $script ) {
477
- if ( false === strpos( $script, '<script' ) ) {
478
- $script = '<script>' . $script . '</script>';
479
- }
480
- echo '<!-- Custom CartFlows Script -->';
481
- echo $script;
482
- echo '<!-- End Custom CartFlows Script -->';
483
- }
484
- }
485
-
486
- /**
487
- * Override woo templates.
488
- *
489
- * @param string $template new Template full path.
490
- * @param string $template_name Template name.
491
- * @param string $template_path Template Path.
492
- * @since 1.1.5
493
- * @return string.
494
- */
495
- public function override_woo_template( $template, $template_name, $template_path ) {
496
-
497
- global $woocommerce;
498
-
499
- $_template = $template;
500
-
501
- $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
-
503
- if ( file_exists( $plugin_path . $template_name ) ) {
504
- $template = $plugin_path . $template_name;
505
- }
506
-
507
- if ( ! $template ) {
508
- $template = $_template;
509
- }
510
-
511
- return $template;
512
- }
513
-
514
- /**
515
- * Remove the action applied by the Flatsome theme.
516
- *
517
- * @since 1.1.5
518
- * @return void.
519
- */
520
- public function remove_flatsome_action() {
521
-
522
- // Remove action where flatsome dequeued the woocommerce's default styles.
523
- remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
- }
525
-
526
- /**
527
- * Add version class to body in frontend.
528
- *
529
- * @since 1.1.5
530
- * @param array $classes classes.
531
- * @return array $classes classes.
532
- */
533
- public function add_cartflows_lite_version_to_body( $classes ) {
534
-
535
- $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
-
537
- return $classes;
538
-
539
- }
540
-
541
- /**
542
- * Get custom script data.
543
- *
544
- * @since 1.0.0
545
- */
546
- public function get_custom_script() {
547
-
548
- global $post;
549
-
550
- $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
-
552
- return $script;
553
- }
554
-
555
-
556
- /**
557
- * Set appropriate filter sctions.
558
- *
559
- * @since 1.1.14
560
- */
561
- public function setup_optin_checkout_filter() {
562
-
563
- if ( _is_wcf_doing_optin_ajax() ) {
564
- /* Modify the optin order received url to go next step */
565
- remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
- }
568
- }
569
-
570
- /**
571
- * Redirect to thank page if upsell not exists
572
- *
573
- * @param string $order_recieve_url url.
574
- * @param object $order order object.
575
- * @since 1.0.0
576
- */
577
- public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
-
579
- /* Only for optin page */
580
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
- wcf()->logger->log( 'Only for optin page' );
582
-
583
- if ( _is_wcf_doing_optin_ajax() ) {
584
-
585
- $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
-
587
- if ( ! $optin_id ) {
588
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
- }
590
- } else {
591
- $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
- }
593
-
594
- wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
-
596
- if ( $optin_id ) {
597
-
598
- $next_step_id = wcf()->flow->get_next_step_id( $order );
599
-
600
- if ( $next_step_id ) {
601
-
602
- $order_recieve_url = get_permalink( $next_step_id );
603
- $query_param = array(
604
- 'wcf-key' => $order->get_order_key(),
605
- 'wcf-order' => $order->get_id(),
606
- );
607
-
608
- if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
-
610
- $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
-
612
- $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
-
614
- if ( is_array( $fields ) ) {
615
-
616
- $order_id = $order->get_id();
617
-
618
- foreach ( $fields as $in => $key ) {
619
- switch ( $key ) {
620
- case 'first_name':
621
- $query_param[ $key ] = $order->get_billing_first_name();
622
- break;
623
- case 'last_name':
624
- $query_param[ $key ] = $order->get_billing_last_name();
625
- break;
626
- case 'email':
627
- $query_param[ $key ] = $order->get_billing_email();
628
- break;
629
- default:
630
- $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
- break;
632
- }
633
- }
634
- }
635
- }
636
-
637
- $order_recieve_url = add_query_arg(
638
- $query_param,
639
- $order_recieve_url
640
- );
641
- }
642
- }
643
-
644
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
-
646
- return $order_recieve_url;
647
- }
648
- }
649
-
650
- /**
651
- * Prepare if class 'Cartflows_Frontend' exist.
652
- * Kicking this off by calling 'get_instance()' method
653
- */
654
- Cartflows_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * CartFlows Frontend.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Frontend.
10
+ */
11
+ class Cartflows_Frontend {
12
+
13
+ /**
14
+ * Member Variable
15
+ *
16
+ * @var instance
17
+ */
18
+ private static $instance;
19
+
20
+ /**
21
+ * Initiator
22
+ */
23
+ public static function get_instance() {
24
+ if ( ! isset( self::$instance ) ) {
25
+ self::$instance = new self();
26
+ }
27
+ return self::$instance;
28
+ }
29
+
30
+ /**
31
+ * Constructor
32
+ */
33
+ public function __construct() {
34
+
35
+ /* Set / Destroy Flow Sessions. Set data */
36
+ add_action( 'wp', array( $this, 'init_actions' ), 1 );
37
+
38
+ add_action( 'init', array( $this, 'debug_data_setting_actions' ) );
39
+ add_action( 'init', array( $this, 'setup_optin_checkout_filter' ) );
40
+ /* Enqueue global required scripts */
41
+ add_action( 'wp', array( $this, 'wp_actions' ), 55 );
42
+
43
+ /* Modify the checkout order received url to go thank you page in our flow */
44
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
45
+
46
+ add_action( 'wp_head', array( $this, 'facebook_pixel_init' ) );
47
+
48
+ }
49
+
50
+ /**
51
+ * Redirect to thank page if upsell not exists
52
+ *
53
+ * @param string $order_recieve_url url.
54
+ * @param object $order order object.
55
+ * @since 1.0.0
56
+ */
57
+ public function redirect_to_thankyou_page( $order_recieve_url, $order ) {
58
+
59
+ /* Only for thank you page */
60
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
61
+ wcf()->logger->log( 'Only for thank you page' );
62
+
63
+ if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
64
+
65
+ if ( _is_wcf_doing_checkout_ajax() ) {
66
+
67
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
68
+
69
+ if ( ! $checkout_id ) {
70
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
71
+ }
72
+ } else {
73
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
74
+ }
75
+
76
+ wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
77
+
78
+ if ( $checkout_id ) {
79
+
80
+ $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
81
+
82
+ if ( $thankyou_step_id ) {
83
+
84
+ $order_recieve_url = get_permalink( $thankyou_step_id );
85
+
86
+ $order_recieve_url = add_query_arg(
87
+ array(
88
+ 'wcf-key' => $order->get_order_key(),
89
+ 'wcf-order' => $order->get_id(),
90
+ ),
91
+ $order_recieve_url
92
+ );
93
+ }
94
+ }
95
+ }
96
+
97
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
98
+
99
+ Cartflows_Helper::send_fb_response_if_enabled( $order->get_id() );
100
+
101
+ Cartflows_Tracking::send_ga_data_if_enabled( $order->get_id() );
102
+
103
+ return $order_recieve_url;
104
+ }
105
+
106
+ /**
107
+ * Cancel and redirect to checkout
108
+ *
109
+ * @param string $return_url url.
110
+ * @since 1.0.0
111
+ */
112
+ public function redirect_to_checkout_on_cancel( $return_url ) {
113
+
114
+ if ( _is_wcf_doing_checkout_ajax() ) {
115
+
116
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
117
+
118
+ if ( ! $checkout_id ) {
119
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
120
+ }
121
+ } else {
122
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
123
+ }
124
+
125
+ if ( $checkout_id ) {
126
+
127
+ $return_url = add_query_arg(
128
+ array(
129
+ 'cancel_order' => 'true',
130
+ '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
131
+ ),
132
+ get_permalink( $checkout_id )
133
+ );
134
+ }
135
+
136
+ return $return_url;
137
+ }
138
+
139
+
140
+ /**
141
+ * Remove theme styles.
142
+ *
143
+ * @since 1.0.0
144
+ */
145
+ public function remove_theme_styles() {
146
+
147
+ if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
148
+ return;
149
+ }
150
+
151
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
152
+
153
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
154
+
155
+ if ( ! _wcf_supported_template( $page_template ) ) {
156
+ return;
157
+ }
158
+
159
+ // get all styles data.
160
+ global $wp_styles;
161
+ global $wp_scripts;
162
+
163
+ $get_stylesheet = 'themes/' . get_stylesheet() . '/';
164
+ $get_template = 'themes/' . get_template() . '/';
165
+
166
+ $remove_styles = apply_filters( 'cartflows_remove_theme_styles', true );
167
+
168
+ if ( $remove_styles ) {
169
+
170
+ // loop over all of the registered scripts..
171
+ foreach ( $wp_styles->registered as $handle => $data ) {
172
+
173
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
174
+
175
+ // remove it.
176
+ wp_deregister_style( $handle );
177
+ wp_dequeue_style( $handle );
178
+ }
179
+ }
180
+ }
181
+
182
+ $remove_scripts = apply_filters( 'cartflows_remove_theme_scripts', true );
183
+
184
+ if ( $remove_scripts ) {
185
+
186
+ // loop over all of the registered scripts.
187
+ foreach ( $wp_scripts->registered as $handle => $data ) {
188
+
189
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
190
+
191
+ // remove it.
192
+ wp_deregister_script( $handle );
193
+ wp_dequeue_script( $handle );
194
+ }
195
+ }
196
+ }
197
+
198
+ }
199
+
200
+ /**
201
+ * Update main order data in transient.
202
+ *
203
+ * @param array $woo_styles new styles array.
204
+ * @since 1.0.0
205
+ * @return array.
206
+ */
207
+ public function woo_default_css( $woo_styles ) {
208
+
209
+ $woo_styles = array(
210
+ 'woocommerce-layout' => array(
211
+ 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
212
+ 'deps' => '',
213
+ 'version' => WC_VERSION,
214
+ 'media' => 'all',
215
+ 'has_rtl' => true,
216
+ ),
217
+ 'woocommerce-smallscreen' => array(
218
+ 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
219
+ 'deps' => 'woocommerce-layout',
220
+ 'version' => WC_VERSION,
221
+ 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
222
+ 'has_rtl' => true,
223
+ ),
224
+ 'woocommerce-general' => array(
225
+ 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
226
+ 'deps' => '',
227
+ 'version' => WC_VERSION,
228
+ 'media' => 'all',
229
+ 'has_rtl' => true,
230
+ ),
231
+ );
232
+
233
+ return $woo_styles;
234
+ }
235
+
236
+ /**
237
+ * Init Actions.
238
+ *
239
+ * @since 1.0.0
240
+ */
241
+ public function init_actions() {
242
+
243
+ $this->set_flow_session();
244
+ }
245
+
246
+ /**
247
+ * Set flow session.
248
+ *
249
+ * @since 1.0.0
250
+ */
251
+ public function set_flow_session() {
252
+
253
+ if ( wcf()->utils->is_step_post_type() ) {
254
+ global $wp;
255
+ add_action( 'wp_head', array( $this, 'noindex_flow' ) );
256
+
257
+ wcf()->utils->do_not_cache();
258
+
259
+ if ( _is_wcf_thankyou_type() ) {
260
+ /* Set key to support pixel */
261
+ if ( isset( $_GET['wcf-key'] ) ) { //phpcs:ignore
262
+
263
+ $wcf_key = sanitize_text_field( wp_unslash( $_GET['wcf-key'] ) ); //phpcs:ignore
264
+
265
+ $_GET['key'] = $wcf_key;
266
+ $_REQUEST['key'] = $wcf_key;
267
+ }
268
+
269
+ if ( isset( $_GET['wcf-order'] ) ) { //phpcs:ignore
270
+
271
+ $wcf_order = intval( wp_unslash( $_GET['wcf-order'] ) ); //phpcs:ignore
272
+
273
+ $_GET['order'] = $wcf_order;
274
+ $_REQUEST['order'] = $wcf_order;
275
+ $_GET['order-received'] = $wcf_order;
276
+ $_REQUEST['order-received'] = $wcf_order;
277
+
278
+ $wp->set_query_var( 'order-received', $wcf_order );
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Add noindex, nofollow.
286
+ *
287
+ * @since 1.0.0
288
+ */
289
+ public function noindex_flow() {
290
+
291
+ $common = Cartflows_Helper::get_common_settings();
292
+
293
+ if ( 'enable' === $common['disallow_indexing'] ) {
294
+ echo '<meta name="robots" content="noindex,nofollow">';
295
+ }
296
+ }
297
+
298
+ /**
299
+ * WP Actions.
300
+ *
301
+ * @since 1.0.0
302
+ */
303
+ public function wp_actions() {
304
+
305
+ if ( wcf()->utils->is_step_post_type() ) {
306
+
307
+ if ( ! wcf()->is_woo_active && wcf()->utils->check_is_woo_required_page() ) {
308
+ wp_die( ' This page requires WooCommerce plugin installed and activated!', 'WooCommerce Required' );
309
+ }
310
+
311
+ /* CSS Compatibility for All theme */
312
+ add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
313
+
314
+ add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
315
+ add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
316
+
317
+ /* Load woo templates from plugin */
318
+ add_filter( 'woocommerce_locate_template', array( $this, 'override_woo_template' ), 20, 3 );
319
+
320
+ /* Add version class to body in frontend. */
321
+ add_filter( 'body_class', array( $this, 'add_cartflows_lite_version_to_body' ) );
322
+
323
+ /* Custom Script Option */
324
+ add_action( 'wp_head', array( $this, 'custom_script_option' ) );
325
+
326
+ /* Remove the action applied by the Flatsome theme */
327
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
328
+ $this->remove_flatsome_action();
329
+ }
330
+ }
331
+ }
332
+
333
+ /**
334
+ * Function for facebook pixel.
335
+ */
336
+ public function facebook_pixel_init() {
337
+
338
+ $facebook_settings = Cartflows_Helper::get_facebook_settings();
339
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking'] ) {
340
+
341
+ $facebook_id = $facebook_settings['facebook_pixel_id'];
342
+ echo '<!-- Facebook Pixel Script By CartFlows -->';
343
+ $fb_script = "<script type='text/javascript'>
344
+ !function(f,b,e,v,n,t,s)
345
+ {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
346
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};
347
+ if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
348
+ n.queue=[];t=b.createElement(e);t.async=!0;
349
+ t.src=v;s=b.getElementsByTagName(e)[0];
350
+ s.parentNode.insertBefore(t,s)}(window, document,'script',
351
+ 'https://connect.facebook.net/en_US/fbevents.js');
352
+ </script>
353
+ <noscript><img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=" . $facebook_id . "&ev=PageView&noscript=1'/></noscript>";
354
+
355
+ $fb_page_view = "<script type='text/javascript'>
356
+ fbq('init', $facebook_id);
357
+ fbq('track', 'PageView', {'plugin': 'CartFlows'});
358
+ </script>";
359
+
360
+ if ( 'enable' === $facebook_settings['facebook_pixel_tracking_for_site'] && ! wcf()->utils->is_step_post_type() ) {
361
+ echo $fb_script;
362
+ echo $fb_page_view;
363
+ } else {
364
+ echo $fb_script;
365
+ }
366
+ echo '<!-- End Facebook Pixel Script By CartFlows -->';
367
+ }
368
+
369
+ }
370
+
371
+ /**
372
+ * Debug Data Setting Actions.
373
+ *
374
+ * @since 1.1.14
375
+ */
376
+ public function debug_data_setting_actions() {
377
+
378
+ add_filter( 'cartflows_load_min_assets', array( $this, 'allow_load_minify' ) );
379
+ }
380
+
381
+ /**
382
+ * Get/Set the allow minify option.
383
+ *
384
+ * @since 1.1.14
385
+ */
386
+ public function allow_load_minify() {
387
+ $debug_data = Cartflows_Helper::get_debug_settings();
388
+ $allow_minified = $debug_data['allow_minified_files'];
389
+ $allow_minify = false;
390
+
391
+ if ( 'enable' === $allow_minified ) {
392
+ $allow_minify = true;
393
+ }
394
+
395
+ return $allow_minify;
396
+ }
397
+
398
+ /**
399
+ * Global flow scripts.
400
+ *
401
+ * @since 1.0.0
402
+ */
403
+ public function global_flow_scripts() {
404
+
405
+ global $post;
406
+
407
+ $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
408
+ $current_step = $post->ID;
409
+ $next_step_link = '';
410
+ $compatibility = Cartflows_Compatibility::get_instance();
411
+
412
+ if ( _is_wcf_landing_type() ) {
413
+
414
+ $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
415
+ $next_step_link = get_permalink( $next_step_id );
416
+ }
417
+
418
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
419
+
420
+ $fb_active = Cartflows_Helper::get_facebook_settings();
421
+ $wcf_ga_active = Cartflows_Helper::get_google_analytics_settings();
422
+ $params = array();
423
+ $ga_param = array();
424
+
425
+ if ( 'enable' === $fb_active['facebook_pixel_tracking'] && Cartflows_Loader::get_instance()->is_woo_active ) {
426
+
427
+ $params = Cartflows_Helper::prepare_cart_data_fb_response();
428
+ }
429
+
430
+ if ( 'enable' === $wcf_ga_active['enable_google_analytics'] ) {
431
+ $ga_param = Cartflows_Tracking::get_ga_items_list();
432
+ }
433
+
434
+ $localize = array(
435
+ 'ajax_url' => admin_url( 'admin-ajax.php', 'relative' ),
436
+ 'is_pb_preview' => $compatibility->is_page_builder_preview(),
437
+ 'current_theme' => $compatibility->get_current_theme(),
438
+ 'current_flow' => $flow,
439
+ 'current_step' => $current_step,
440
+ 'next_step' => $next_step_link,
441
+ 'page_template' => $page_template,
442
+ 'is_checkout_page' => _is_wcf_checkout_type(),
443
+ 'params' => $params,
444
+ 'fb_active' => $fb_active,
445
+ 'wcf_ga_active' => $wcf_ga_active,
446
+ 'ga_param' => $ga_param,
447
+ );
448
+
449
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
450
+
451
+ if ( _wcf_supported_template( $page_template ) ) {
452
+
453
+ wp_enqueue_style( 'wcf-normalize-frontend-global', wcf()->utils->get_css_url( 'cartflows-normalize' ), array(), CARTFLOWS_VER );
454
+ }
455
+
456
+ wp_enqueue_style( 'wcf-frontend-global', wcf()->utils->get_css_url( 'frontend' ), array(), CARTFLOWS_VER );
457
+
458
+ wp_enqueue_script(
459
+ 'wcf-frontend-global',
460
+ wcf()->utils->get_js_url( 'frontend' ),
461
+ array( 'jquery', 'jquery-cookie' ),
462
+ CARTFLOWS_VER,
463
+ false
464
+ );
465
+ }
466
+
467
+ /**
468
+ * Custom Script in head.
469
+ *
470
+ * @since 1.0.0
471
+ */
472
+ public function custom_script_option() {
473
+
474
+ /* Add custom script to header in frontend. */
475
+ $script = $this->get_custom_script();
476
+ if ( '' !== $script ) {
477
+ if ( false === strpos( $script, '<script' ) ) {
478
+ $script = '<script>' . $script . '</script>';
479
+ }
480
+ echo '<!-- Custom CartFlows Script -->';
481
+ echo $script;
482
+ echo '<!-- End Custom CartFlows Script -->';
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Override woo templates.
488
+ *
489
+ * @param string $template new Template full path.
490
+ * @param string $template_name Template name.
491
+ * @param string $template_path Template Path.
492
+ * @since 1.1.5
493
+ * @return string.
494
+ */
495
+ public function override_woo_template( $template, $template_name, $template_path ) {
496
+
497
+ global $woocommerce;
498
+
499
+ $_template = $template;
500
+
501
+ $plugin_path = CARTFLOWS_DIR . 'woocommerce/template/';
502
+
503
+ if ( file_exists( $plugin_path . $template_name ) ) {
504
+ $template = $plugin_path . $template_name;
505
+ }
506
+
507
+ if ( ! $template ) {
508
+ $template = $_template;
509
+ }
510
+
511
+ return $template;
512
+ }
513
+
514
+ /**
515
+ * Remove the action applied by the Flatsome theme.
516
+ *
517
+ * @since 1.1.5
518
+ * @return void.
519
+ */
520
+ public function remove_flatsome_action() {
521
+
522
+ // Remove action where flatsome dequeued the woocommerce's default styles.
523
+ remove_action( 'wp_enqueue_scripts', 'flatsome_woocommerce_scripts_styles', 98 );
524
+ }
525
+
526
+ /**
527
+ * Add version class to body in frontend.
528
+ *
529
+ * @since 1.1.5
530
+ * @param array $classes classes.
531
+ * @return array $classes classes.
532
+ */
533
+ public function add_cartflows_lite_version_to_body( $classes ) {
534
+
535
+ $classes[] = 'cartflows-' . CARTFLOWS_VER;
536
+
537
+ return $classes;
538
+
539
+ }
540
+
541
+ /**
542
+ * Get custom script data.
543
+ *
544
+ * @since 1.0.0
545
+ */
546
+ public function get_custom_script() {
547
+
548
+ global $post;
549
+
550
+ $script = get_post_meta( $post->ID, 'wcf-custom-script', true );
551
+
552
+ return $script;
553
+ }
554
+
555
+
556
+ /**
557
+ * Set appropriate filter sctions.
558
+ *
559
+ * @since 1.1.14
560
+ */
561
+ public function setup_optin_checkout_filter() {
562
+
563
+ if ( _is_wcf_doing_optin_ajax() ) {
564
+ /* Modify the optin order received url to go next step */
565
+ remove_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
566
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_optin_to_next_step' ), 10, 2 );
567
+ }
568
+ }
569
+
570
+ /**
571
+ * Redirect to thank page if upsell not exists
572
+ *
573
+ * @param string $order_recieve_url url.
574
+ * @param object $order order object.
575
+ * @since 1.0.0
576
+ */
577
+ public function redirect_optin_to_next_step( $order_recieve_url, $order ) {
578
+
579
+ /* Only for optin page */
580
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
581
+ wcf()->logger->log( 'Only for optin page' );
582
+
583
+ if ( _is_wcf_doing_optin_ajax() ) {
584
+
585
+ $optin_id = wcf()->utils->get_optin_id_from_post_data();
586
+
587
+ if ( ! $optin_id ) {
588
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
589
+ }
590
+ } else {
591
+ $optin_id = wcf()->utils->get_optin_id_from_order( $order->get_id() );
592
+ }
593
+
594
+ wcf()->logger->log( 'Optin ID : ' . $optin_id );
595
+
596
+ if ( $optin_id ) {
597
+
598
+ $next_step_id = wcf()->flow->get_next_step_id( $order );
599
+
600
+ if ( $next_step_id ) {
601
+
602
+ $order_recieve_url = get_permalink( $next_step_id );
603
+ $query_param = array(
604
+ 'wcf-key' => $order->get_order_key(),
605
+ 'wcf-order' => $order->get_id(),
606
+ );
607
+
608
+ if ( 'yes' === wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-fields' ) ) {
609
+
610
+ $fields_string = wcf()->options->get_optin_meta_value( $optin_id, 'wcf-optin-pass-specific-fields' );
611
+
612
+ $fields = array_map( 'trim', explode( ',', $fields_string ) );
613
+
614
+ if ( is_array( $fields ) ) {
615
+
616
+ $order_id = $order->get_id();
617
+
618
+ foreach ( $fields as $in => $key ) {
619
+ switch ( $key ) {
620
+ case 'first_name':
621
+ $query_param[ $key ] = $order->get_billing_first_name();
622
+ break;
623
+ case 'last_name':
624
+ $query_param[ $key ] = $order->get_billing_last_name();
625
+ break;
626
+ case 'email':
627
+ $query_param[ $key ] = $order->get_billing_email();
628
+ break;
629
+ default:
630
+ $query_param[ $key ] = get_post_meta( $order_id, '_billing_' . $key, true );
631
+ break;
632
+ }
633
+ }
634
+ }
635
+ }
636
+
637
+ $order_recieve_url = add_query_arg(
638
+ $query_param,
639
+ $order_recieve_url
640
+ );
641
+ }
642
+ }
643
+
644
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
645
+
646
+ return $order_recieve_url;
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Prepare if class 'Cartflows_Frontend' exist.
652
+ * Kicking this off by calling 'get_instance()' method
653
+ */
654
+ Cartflows_Frontend::get_instance();
classes/class-cartflows-functions.php CHANGED
@@ -1,539 +1,539 @@
1
- <?php
2
- /**
3
- * CartFlows Functions.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Fatal error mb_strpos fallback.
14
- *
15
- * @param string $string string where to find.
16
- * @param string $search string to search.
17
- * @since 1.0.0
18
- */
19
- function wcf_mb_strpos( $string, $search ) {
20
-
21
- if ( function_exists( 'mb_strpos' ) ) {
22
- return mb_strpos( $string, $search, 0, 'utf-8' );
23
- } else {
24
- return strpos( $string, $search );
25
- }
26
- }
27
-
28
- /**
29
- * Check if cartflows pro activated.
30
- *
31
- * @since 1.0.0
32
- */
33
- function _is_cartflows_pro() {
34
-
35
- if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
- return true;
37
- }
38
-
39
- return false;
40
-
41
- }
42
-
43
- /**
44
- * Returns pro version number.
45
- *
46
- * @param int $version version number.
47
- * @since 1.0.0
48
- */
49
- function _is_cartflows_pro_ver_less_than( $version ) {
50
-
51
- if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
- return true;
53
- }
54
-
55
- return false;
56
- }
57
-
58
- /**
59
- * Returns step id.
60
- *
61
- * @since 1.0.0
62
- */
63
- function _get_wcf_post_id() {
64
-
65
- global $post;
66
-
67
- if ( isset( $post->ID ) ) {
68
- return $post->ID;
69
- }
70
-
71
- return 0;
72
- }
73
-
74
- /**
75
- * Returns step id.
76
- *
77
- * @since 1.0.0
78
- */
79
- function _get_wcf_step_id() {
80
-
81
- if ( wcf()->utils->is_step_post_type() ) {
82
-
83
- global $post;
84
-
85
- return $post->ID;
86
- }
87
-
88
- return false;
89
- }
90
-
91
- /**
92
- * Check if it is a landing page?
93
- *
94
- * @since 1.0.0
95
- */
96
- function _is_wcf_landing_type() {
97
-
98
- if ( wcf()->utils->is_step_post_type() ) {
99
-
100
- global $post;
101
-
102
- if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
-
104
- return true;
105
- }
106
- }
107
-
108
- return false;
109
- }
110
-
111
- /**
112
- * Returns landing id.
113
- *
114
- * @since 1.0.0
115
- */
116
- function _get_wcf_landing_id() {
117
-
118
- if ( _is_wcf_landing_type() ) {
119
-
120
- global $post;
121
-
122
- return $post->ID;
123
- }
124
-
125
- return false;
126
- }
127
-
128
- /**
129
- * Is custom checkout?
130
- *
131
- * @param int $checkout_id checkout ID.
132
- * @since 1.0.0
133
- */
134
- function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
-
136
- $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
-
138
- if ( 'yes' === $is_custom ) {
139
-
140
- return true;
141
- }
142
-
143
- return false;
144
- }
145
-
146
- /**
147
- * Check if page is cartflow checkout.
148
- *
149
- * @since 1.0.0
150
- * @return bool
151
- */
152
- function _is_wcf_checkout_type() {
153
-
154
- if ( wcf()->utils->is_step_post_type() ) {
155
-
156
- global $post;
157
-
158
- if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
-
160
- return true;
161
- }
162
- }
163
-
164
- return false;
165
- }
166
-
167
- /**
168
- * Check if AJAX call is in progress.
169
- *
170
- * @since 1.0.0
171
- * @return bool
172
- */
173
- function _is_wcf_doing_checkout_ajax() {
174
-
175
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
-
177
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
- isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
- ) {
180
- return true;
181
- }
182
- }
183
-
184
- return false;
185
- }
186
-
187
- /**
188
- * Check if optin AJAX call is in progress.
189
- *
190
- * @since 1.0.0
191
- * @return bool
192
- */
193
- function _is_wcf_doing_optin_ajax() {
194
-
195
- if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
-
197
- if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
- isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
- ) {
200
- return true;
201
- }
202
- }
203
-
204
- return false;
205
- }
206
-
207
- /**
208
- * Returns checkout ID.
209
- *
210
- * @since 1.0.0
211
- * @return int/bool
212
- */
213
- function _get_wcf_checkout_id() {
214
-
215
- if ( _is_wcf_checkout_type() ) {
216
-
217
- global $post;
218
-
219
- return $post->ID;
220
- }
221
-
222
- return false;
223
- }
224
-
225
- /**
226
- * Check if it is checkout shortcode.
227
- *
228
- * @since 1.0.0
229
- * @return bool
230
- */
231
- function _is_wcf_checkout_shortcode() {
232
-
233
- global $post;
234
-
235
- if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
-
237
- return true;
238
- }
239
-
240
- return false;
241
- }
242
-
243
- /**
244
- * Check if it is checkout shortcode.
245
- *
246
- * @since 1.0.0
247
- * @param string $content shortcode content.
248
- * @return bool
249
- */
250
- function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
-
252
- $checkout_id = 0;
253
-
254
- if ( ! empty( $content ) ) {
255
-
256
- $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
-
258
- preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
-
260
- if ( ! empty( $regex_matches ) ) {
261
-
262
- if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
-
264
- $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
- $attribure_str = str_replace( '"', '', $attribure_str );
266
-
267
- $attributes = wp_parse_args( $attribure_str );
268
-
269
- if ( isset( $attributes['id'] ) ) {
270
- $checkout_id = $attributes['id'];
271
- }
272
- }
273
- }
274
- }
275
-
276
- return $checkout_id;
277
- }
278
-
279
- /**
280
- * Check if post type is upsell.
281
- *
282
- * @since 1.0.0
283
- * @return bool
284
- */
285
- function _is_wcf_upsell_type() {
286
-
287
- if ( wcf()->utils->is_step_post_type() ) {
288
-
289
- global $post;
290
-
291
- if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
-
293
- return true;
294
- }
295
- }
296
-
297
- return false;
298
- }
299
-
300
- /**
301
- * Returns upsell ID.
302
- *
303
- * @since 1.0.0
304
- * @return int/bool
305
- */
306
- function _get_wcf_upsell_id() {
307
-
308
- if ( _is_wcf_upsell_type() ) {
309
-
310
- global $post;
311
-
312
- return $post->ID;
313
- }
314
-
315
- return false;
316
- }
317
-
318
- /**
319
- * Check if post is of type downsell.
320
- *
321
- * @since 1.0.0
322
- * @return int/bool
323
- */
324
- function _is_wcf_downsell_type() {
325
-
326
- if ( wcf()->utils->is_step_post_type() ) {
327
-
328
- global $post;
329
-
330
- if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
-
332
- return true;
333
- }
334
- }
335
-
336
- return false;
337
- }
338
-
339
- /**
340
- * Get downsell page ID.
341
- *
342
- * @since 1.0.0
343
- * @return int/bool
344
- */
345
- function _get_wcf_downsell_id() {
346
-
347
- if ( _is_wcf_downsell_type() ) {
348
-
349
- global $post;
350
-
351
- return $post->ID;
352
- }
353
-
354
- return false;
355
- }
356
-
357
- /**
358
- * Check if page is of thank you type.
359
- *
360
- * @since 1.0.0
361
- * @return int/bool
362
- */
363
- function _is_wcf_thankyou_type() {
364
-
365
- if ( wcf()->utils->is_step_post_type() ) {
366
-
367
- global $post;
368
-
369
- if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
-
371
- return true;
372
- }
373
- }
374
-
375
- return false;
376
- }
377
-
378
- /**
379
- * Get thank you page ID.
380
- *
381
- * @since 1.0.0
382
- * @return int/bool
383
- */
384
- function _get_wcf_thankyou_id() {
385
-
386
- if ( _is_wcf_thankyou_type() ) {
387
-
388
- global $post;
389
-
390
- return $post->ID;
391
- }
392
-
393
- return false;
394
- }
395
-
396
-
397
- /**
398
- * Check if post type is upsell.
399
- *
400
- * @since 1.0.0
401
- * @return bool
402
- */
403
- function _is_wcf_base_offer_type() {
404
-
405
- if ( wcf()->utils->is_step_post_type() ) {
406
-
407
- global $post;
408
-
409
- $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
-
411
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
-
413
- return true;
414
- }
415
- }
416
-
417
- return false;
418
- }
419
-
420
- /**
421
- * Returns upsell ID.
422
- *
423
- * @since 1.0.0
424
- * @return int/bool
425
- */
426
- function _get_wcf_base_offer_id() {
427
-
428
- if ( _is_wcf_base_offer_type() ) {
429
-
430
- global $post;
431
-
432
- return $post->ID;
433
- }
434
-
435
- return false;
436
- }
437
-
438
- /**
439
- * Check if page is of optin type.
440
- *
441
- * @since 1.0.0
442
- * @return int/bool
443
- */
444
- function _is_wcf_optin_type() {
445
-
446
- if ( wcf()->utils->is_step_post_type() ) {
447
-
448
- global $post;
449
-
450
- if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
-
452
- return true;
453
- }
454
- }
455
-
456
- return false;
457
- }
458
-
459
- /**
460
- * Get optin page ID.
461
- *
462
- * @since 1.0.0
463
- * @return int/bool
464
- */
465
- function _get_wcf_optin_id() {
466
-
467
- if ( _is_wcf_optin_type() ) {
468
-
469
- global $post;
470
-
471
- return $post->ID;
472
- }
473
-
474
- return false;
475
- }
476
-
477
- /**
478
- * Define a constant if it is not already defined.
479
- *
480
- * @since 3.0.0
481
- * @param string $name Constant name.
482
- * @param mixed $value Value.
483
- */
484
- function wcf_maybe_define_constant( $name, $value ) {
485
- if ( ! defined( $name ) ) {
486
- define( $name, $value );
487
- }
488
- }
489
-
490
-
491
- if ( ! function_exists( 'wp_body_open' ) ) {
492
- /**
493
- * Fire the wp_body_open action.
494
- *
495
- * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
- */
497
- function wp_body_open() {
498
- /**
499
- * Triggered after the opening <body> tag.
500
- */
501
- do_action( 'wp_body_open' );
502
- }
503
- }
504
-
505
- /**
506
- * Check if type is optin by id.
507
- *
508
- * @param int $post_id post id.
509
- *
510
- * @return int/bool
511
- * @since 1.0.0
512
- */
513
- function _wcf_check_is_optin_by_id( $post_id ) {
514
-
515
- if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
-
517
- return true;
518
- }
519
-
520
- return false;
521
- }
522
-
523
- /**
524
- * Supported Page Template
525
- *
526
- * @param string $page_template current page template.
527
- *
528
- * @return int/bool
529
- * @since 1.5.7
530
- */
531
- function _wcf_supported_template( $page_template ) {
532
-
533
- if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
-
535
- return true;
536
- }
537
-
538
- return false;
539
- }
1
+ <?php
2
+ /**
3
+ * CartFlows Functions.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Fatal error mb_strpos fallback.
14
+ *
15
+ * @param string $string string where to find.
16
+ * @param string $search string to search.
17
+ * @since 1.0.0
18
+ */
19
+ function wcf_mb_strpos( $string, $search ) {
20
+
21
+ if ( function_exists( 'mb_strpos' ) ) {
22
+ return mb_strpos( $string, $search, 0, 'utf-8' );
23
+ } else {
24
+ return strpos( $string, $search );
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Check if cartflows pro activated.
30
+ *
31
+ * @since 1.0.0
32
+ */
33
+ function _is_cartflows_pro() {
34
+
35
+ if ( defined( 'CARTFLOWS_PRO_FILE' ) ) {
36
+ return true;
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Returns pro version number.
45
+ *
46
+ * @param int $version version number.
47
+ * @since 1.0.0
48
+ */
49
+ function _is_cartflows_pro_ver_less_than( $version ) {
50
+
51
+ if ( defined( 'CARTFLOWS_PRO_VER' ) && version_compare( CARTFLOWS_PRO_VER, $version, '<' ) ) {
52
+ return true;
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * Returns step id.
60
+ *
61
+ * @since 1.0.0
62
+ */
63
+ function _get_wcf_post_id() {
64
+
65
+ global $post;
66
+
67
+ if ( isset( $post->ID ) ) {
68
+ return $post->ID;
69
+ }
70
+
71
+ return 0;
72
+ }
73
+
74
+ /**
75
+ * Returns step id.
76
+ *
77
+ * @since 1.0.0
78
+ */
79
+ function _get_wcf_step_id() {
80
+
81
+ if ( wcf()->utils->is_step_post_type() ) {
82
+
83
+ global $post;
84
+
85
+ return $post->ID;
86
+ }
87
+
88
+ return false;
89
+ }
90
+
91
+ /**
92
+ * Check if it is a landing page?
93
+ *
94
+ * @since 1.0.0
95
+ */
96
+ function _is_wcf_landing_type() {
97
+
98
+ if ( wcf()->utils->is_step_post_type() ) {
99
+
100
+ global $post;
101
+
102
+ if ( 'landing' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
103
+
104
+ return true;
105
+ }
106
+ }
107
+
108
+ return false;
109
+ }
110
+
111
+ /**
112
+ * Returns landing id.
113
+ *
114
+ * @since 1.0.0
115
+ */
116
+ function _get_wcf_landing_id() {
117
+
118
+ if ( _is_wcf_landing_type() ) {
119
+
120
+ global $post;
121
+
122
+ return $post->ID;
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Is custom checkout?
130
+ *
131
+ * @param int $checkout_id checkout ID.
132
+ * @since 1.0.0
133
+ */
134
+ function _is_wcf_meta_custom_checkout( $checkout_id ) {
135
+
136
+ $is_custom = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-custom-checkout-fields' );
137
+
138
+ if ( 'yes' === $is_custom ) {
139
+
140
+ return true;
141
+ }
142
+
143
+ return false;
144
+ }
145
+
146
+ /**
147
+ * Check if page is cartflow checkout.
148
+ *
149
+ * @since 1.0.0
150
+ * @return bool
151
+ */
152
+ function _is_wcf_checkout_type() {
153
+
154
+ if ( wcf()->utils->is_step_post_type() ) {
155
+
156
+ global $post;
157
+
158
+ if ( 'checkout' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
159
+
160
+ return true;
161
+ }
162
+ }
163
+
164
+ return false;
165
+ }
166
+
167
+ /**
168
+ * Check if AJAX call is in progress.
169
+ *
170
+ * @since 1.0.0
171
+ * @return bool
172
+ */
173
+ function _is_wcf_doing_checkout_ajax() {
174
+
175
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
176
+
177
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
178
+ isset( $_POST['_wcf_checkout_id'] ) //phpcs:ignore
179
+ ) {
180
+ return true;
181
+ }
182
+ }
183
+
184
+ return false;
185
+ }
186
+
187
+ /**
188
+ * Check if optin AJAX call is in progress.
189
+ *
190
+ * @since 1.0.0
191
+ * @return bool
192
+ */
193
+ function _is_wcf_doing_optin_ajax() {
194
+
195
+ if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) { //phpcs:ignore
196
+
197
+ if ( isset( $_GET['wc-ajax'] ) && //phpcs:ignore
198
+ isset( $_POST['_wcf_optin_id'] ) //phpcs:ignore
199
+ ) {
200
+ return true;
201
+ }
202
+ }
203
+
204
+ return false;
205
+ }
206
+
207
+ /**
208
+ * Returns checkout ID.
209
+ *
210
+ * @since 1.0.0
211
+ * @return int/bool
212
+ */
213
+ function _get_wcf_checkout_id() {
214
+
215
+ if ( _is_wcf_checkout_type() ) {
216
+
217
+ global $post;
218
+
219
+ return $post->ID;
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Check if it is checkout shortcode.
227
+ *
228
+ * @since 1.0.0
229
+ * @return bool
230
+ */
231
+ function _is_wcf_checkout_shortcode() {
232
+
233
+ global $post;
234
+
235
+ if ( ! empty( $post ) && has_shortcode( $post->post_content, 'cartflows_checkout' ) ) {
236
+
237
+ return true;
238
+ }
239
+
240
+ return false;
241
+ }
242
+
243
+ /**
244
+ * Check if it is checkout shortcode.
245
+ *
246
+ * @since 1.0.0
247
+ * @param string $content shortcode content.
248
+ * @return bool
249
+ */
250
+ function _get_wcf_checkout_id_from_shortcode( $content = '' ) {
251
+
252
+ $checkout_id = 0;
253
+
254
+ if ( ! empty( $content ) ) {
255
+
256
+ $regex_pattern = get_shortcode_regex( array( 'cartflows_checkout' ) );
257
+
258
+ preg_match( '/' . $regex_pattern . '/s', $content, $regex_matches );
259
+
260
+ if ( ! empty( $regex_matches ) ) {
261
+
262
+ if ( 'cartflows_checkout' == $regex_matches[2] ) {
263
+
264
+ $attribure_str = str_replace( ' ', '&', trim( $regex_matches[3] ) );
265
+ $attribure_str = str_replace( '"', '', $attribure_str );
266
+
267
+ $attributes = wp_parse_args( $attribure_str );
268
+
269
+ if ( isset( $attributes['id'] ) ) {
270
+ $checkout_id = $attributes['id'];
271
+ }
272
+ }
273
+ }
274
+ }
275
+
276
+ return $checkout_id;
277
+ }
278
+
279
+ /**
280
+ * Check if post type is upsell.
281
+ *
282
+ * @since 1.0.0
283
+ * @return bool
284
+ */
285
+ function _is_wcf_upsell_type() {
286
+
287
+ if ( wcf()->utils->is_step_post_type() ) {
288
+
289
+ global $post;
290
+
291
+ if ( 'upsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
292
+
293
+ return true;
294
+ }
295
+ }
296
+
297
+ return false;
298
+ }
299
+
300
+ /**
301
+ * Returns upsell ID.
302
+ *
303
+ * @since 1.0.0
304
+ * @return int/bool
305
+ */
306
+ function _get_wcf_upsell_id() {
307
+
308
+ if ( _is_wcf_upsell_type() ) {
309
+
310
+ global $post;
311
+
312
+ return $post->ID;
313
+ }
314
+
315
+ return false;
316
+ }
317
+
318
+ /**
319
+ * Check if post is of type downsell.
320
+ *
321
+ * @since 1.0.0
322
+ * @return int/bool
323
+ */
324
+ function _is_wcf_downsell_type() {
325
+
326
+ if ( wcf()->utils->is_step_post_type() ) {
327
+
328
+ global $post;
329
+
330
+ if ( 'downsell' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
331
+
332
+ return true;
333
+ }
334
+ }
335
+
336
+ return false;
337
+ }
338
+
339
+ /**
340
+ * Get downsell page ID.
341
+ *
342
+ * @since 1.0.0
343
+ * @return int/bool
344
+ */
345
+ function _get_wcf_downsell_id() {
346
+
347
+ if ( _is_wcf_downsell_type() ) {
348
+
349
+ global $post;
350
+
351
+ return $post->ID;
352
+ }
353
+
354
+ return false;
355
+ }
356
+
357
+ /**
358
+ * Check if page is of thank you type.
359
+ *
360
+ * @since 1.0.0
361
+ * @return int/bool
362
+ */
363
+ function _is_wcf_thankyou_type() {
364
+
365
+ if ( wcf()->utils->is_step_post_type() ) {
366
+
367
+ global $post;
368
+
369
+ if ( 'thankyou' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
370
+
371
+ return true;
372
+ }
373
+ }
374
+
375
+ return false;
376
+ }
377
+
378
+ /**
379
+ * Get thank you page ID.
380
+ *
381
+ * @since 1.0.0
382
+ * @return int/bool
383
+ */
384
+ function _get_wcf_thankyou_id() {
385
+
386
+ if ( _is_wcf_thankyou_type() ) {
387
+
388
+ global $post;
389
+
390
+ return $post->ID;
391
+ }
392
+
393
+ return false;
394
+ }
395
+
396
+
397
+ /**
398
+ * Check if post type is upsell.
399
+ *
400
+ * @since 1.0.0
401
+ * @return bool
402
+ */
403
+ function _is_wcf_base_offer_type() {
404
+
405
+ if ( wcf()->utils->is_step_post_type() ) {
406
+
407
+ global $post;
408
+
409
+ $step_type = get_post_meta( $post->ID, 'wcf-step-type', true );
410
+
411
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
412
+
413
+ return true;
414
+ }
415
+ }
416
+
417
+ return false;
418
+ }
419
+
420
+ /**
421
+ * Returns upsell ID.
422
+ *
423
+ * @since 1.0.0
424
+ * @return int/bool
425
+ */
426
+ function _get_wcf_base_offer_id() {
427
+
428
+ if ( _is_wcf_base_offer_type() ) {
429
+
430
+ global $post;
431
+
432
+ return $post->ID;
433
+ }
434
+
435
+ return false;
436
+ }
437
+
438
+ /**
439
+ * Check if page is of optin type.
440
+ *
441
+ * @since 1.0.0
442
+ * @return int/bool
443
+ */
444
+ function _is_wcf_optin_type() {
445
+
446
+ if ( wcf()->utils->is_step_post_type() ) {
447
+
448
+ global $post;
449
+
450
+ if ( 'optin' === get_post_meta( $post->ID, 'wcf-step-type', true ) ) {
451
+
452
+ return true;
453
+ }
454
+ }
455
+
456
+ return false;
457
+ }
458
+
459
+ /**
460
+ * Get optin page ID.
461
+ *
462
+ * @since 1.0.0
463
+ * @return int/bool
464
+ */
465
+ function _get_wcf_optin_id() {
466
+
467
+ if ( _is_wcf_optin_type() ) {
468
+
469
+ global $post;
470
+
471
+ return $post->ID;
472
+ }
473
+
474
+ return false;
475
+ }
476
+
477
+ /**
478
+ * Define a constant if it is not already defined.
479
+ *
480
+ * @since 3.0.0
481
+ * @param string $name Constant name.
482
+ * @param mixed $value Value.
483
+ */
484
+ function wcf_maybe_define_constant( $name, $value ) {
485
+ if ( ! defined( $name ) ) {
486
+ define( $name, $value );
487
+ }
488
+ }
489
+
490
+
491
+ if ( ! function_exists( 'wp_body_open' ) ) {
492
+ /**
493
+ * Fire the wp_body_open action.
494
+ *
495
+ * Added for backwards compatibility to support WordPress versions prior to 5.2.0.
496
+ */
497
+ function wp_body_open() {
498
+ /**
499
+ * Triggered after the opening <body> tag.
500
+ */
501
+ do_action( 'wp_body_open' );
502
+ }
503
+ }
504
+
505
+ /**
506
+ * Check if type is optin by id.
507
+ *
508
+ * @param int $post_id post id.
509
+ *
510
+ * @return int/bool
511
+ * @since 1.0.0
512
+ */
513
+ function _wcf_check_is_optin_by_id( $post_id ) {
514
+
515
+ if ( 'optin' === get_post_meta( $post_id, 'wcf-step-type', true ) ) {
516
+
517
+ return true;
518
+ }
519
+
520
+ return false;
521
+ }
522
+
523
+ /**
524
+ * Supported Page Template
525
+ *
526
+ * @param string $page_template current page template.
527
+ *
528
+ * @return int/bool
529
+ * @since 1.5.7
530
+ */
531
+ function _wcf_supported_template( $page_template ) {
532
+
533
+ if ( in_array( $page_template, array( 'cartflows-default', 'cartflows-canvas' ), true ) ) {
534
+
535
+ return true;
536
+ }
537
+
538
+ return false;
539
+ }
classes/class-cartflows-importer.php CHANGED
@@ -1,1742 +1,1742 @@
1
- <?php
2
- /**
3
- * CartFlows Admin
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
-
11
- /**
12
- * CartFlows Import
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Importer {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
-
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.0.0
45
- */
46
- public function __construct() {
47
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
-
49
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
-
55
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
-
58
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
-
60
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
-
62
- add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
- add_action( 'admin_init', array( $this, 'export_json' ) );
64
- add_action( 'admin_init', array( $this, 'import_json' ) );
65
- add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
- add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
- }
68
-
69
- /**
70
- * Add the export link to action list for flows row actions
71
- *
72
- * @since 1.1.4
73
- *
74
- * @param array $actions Actions array.
75
- * @param object $post Post object.
76
- *
77
- * @return array
78
- */
79
- public function export_link( $actions, $post ) {
80
- if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
- $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
- }
83
- return $actions;
84
- }
85
-
86
- /**
87
- * Add menus
88
- *
89
- * @since 1.1.4
90
- */
91
- public function add_to_menus() {
92
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
- add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
- }
95
-
96
- /**
97
- * Export flow with steps and its meta
98
- *
99
- * @since 1.1.4
100
- */
101
- public function export_flow() {
102
-
103
- if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
- wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
- }
106
-
107
- if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
- return;
109
- }
110
-
111
- // Get the original post id.
112
- $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
-
114
- $flows = array();
115
- $flows[] = $this->get_flow_export_data( $flow_id );
116
- $flows = apply_filters( 'cartflows_export_data', $flows );
117
-
118
- nocache_headers();
119
- header( 'Content-Type: application/json; charset=utf-8' );
120
- header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
- header( 'Expires: 0' );
122
-
123
- echo wp_json_encode( $flows );
124
- exit;
125
- }
126
-
127
- /**
128
- * Export flow markup
129
- *
130
- * @since 1.1.4
131
- */
132
- public function exporter_markup() {
133
- include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
- }
135
-
136
- /**
137
- * Import flow markup
138
- *
139
- * @since 1.1.4
140
- */
141
- public function importer_markup() {
142
- include_once CARTFLOWS_DIR . 'includes/importer.php';
143
- }
144
-
145
- /**
146
- * Export flow
147
- *
148
- * @since 1.1.4
149
- */
150
- public function export_json() {
151
- if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
- return;
153
- }
154
-
155
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
- return;
157
- }
158
-
159
- if ( ! current_user_can( 'manage_options' ) ) {
160
- return;
161
- }
162
-
163
- $flows = $this->get_all_flow_export_data();
164
- $flows = apply_filters( 'cartflows_export_data', $flows );
165
-
166
- nocache_headers();
167
- header( 'Content-Type: application/json; charset=utf-8' );
168
- header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
- header( 'Expires: 0' );
170
-
171
- echo wp_json_encode( $flows );
172
- exit;
173
- }
174
-
175
- /**
176
- * Get flow export data
177
- *
178
- * @since 1.1.4
179
- *
180
- * @param integer $flow_id Flow ID.
181
- * @return array
182
- */
183
- public function get_flow_export_data( $flow_id ) {
184
-
185
- $export_all = apply_filters( 'cartflows_export_all', true );
186
-
187
- $valid_step_meta_keys = array(
188
- '_wp_page_template',
189
- '_thumbnail_id',
190
- 'classic-editor-remember',
191
- );
192
-
193
- $new_steps = array();
194
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
- if ( $steps ) {
196
- foreach ( $steps as $key => $step ) {
197
-
198
- // Add step post meta.
199
- $new_all_meta = array();
200
- $all_meta = get_post_meta( $step['id'] );
201
-
202
- // Add single step.
203
- $step_data_arr = array(
204
- 'title' => get_the_title( $step['id'] ),
205
- 'type' => $step['type'],
206
- 'meta' => $all_meta,
207
- 'post_content' => '',
208
- );
209
-
210
- if ( $export_all ) {
211
-
212
- $step_post_obj = get_post( $step['id'] );
213
-
214
- $step_data_arr['post_content'] = $step_post_obj->post_content;
215
- }
216
-
217
- $new_steps[] = $step_data_arr;
218
- }
219
- }
220
-
221
- // Add single flow.
222
- return array(
223
- 'title' => get_the_title( $flow_id ),
224
- 'steps' => $new_steps,
225
- );
226
- }
227
-
228
- /**
229
- * Get all flow export data
230
- *
231
- * @since 1.1.4
232
- */
233
- public function get_all_flow_export_data() {
234
-
235
- $query_args = array(
236
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
-
238
- // Query performance optimization.
239
- 'fields' => 'ids',
240
- 'no_found_rows' => true,
241
- 'posts_per_page' => -1,
242
- );
243
-
244
- $query = new WP_Query( $query_args );
245
- $flows = array();
246
- if ( $query->posts ) {
247
- foreach ( $query->posts as $key => $post_id ) {
248
- $flows[] = $this->get_flow_export_data( $post_id );
249
- }
250
- }
251
-
252
- return $flows;
253
- }
254
-
255
- /**
256
- * Import our exported file
257
- *
258
- * @since 1.1.4
259
- */
260
- public function import_json() {
261
- if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
- return;
263
- }
264
-
265
- if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
- return;
267
- }
268
-
269
- if ( ! current_user_can( 'manage_options' ) ) {
270
- return;
271
- }
272
-
273
- $filename = $_FILES['file']['name']; //phpcs:ignore
274
- $file_info = explode( '.', $filename );
275
- $extension = end( $file_info );
276
-
277
- if ( 'json' != $extension ) {
278
- wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
- }
280
-
281
- $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
-
283
- if ( empty( $file ) ) {
284
- wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
- }
286
-
287
- // Retrieve the settings from the file and convert the JSON object to an array.
288
- $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
-
290
- $this->import_from_json_data( $flows );
291
-
292
- add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
- }
294
-
295
- /**
296
- * Import flow from the JSON data
297
- *
298
- * @since x.x.x
299
- * @param array $flows JSON array.
300
- * @return void
301
- */
302
- public function import_from_json_data( $flows ) {
303
- if ( $flows ) {
304
-
305
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
-
307
- foreach ( $flows as $key => $flow ) {
308
-
309
- $flow_title = $flow['title'];
310
- if ( post_exists( $flow['title'] ) ) {
311
- $flow_title = $flow['title'] . ' Copy';
312
- }
313
-
314
- // Create post object.
315
- $new_flow_args = apply_filters(
316
- 'cartflows_flow_importer_args',
317
- array(
318
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
- 'post_title' => $flow_title,
320
- 'post_status' => 'publish',
321
- )
322
- );
323
-
324
- // Insert the post into the database.
325
- $flow_id = wp_insert_post( $new_flow_args );
326
-
327
- /**
328
- * Fire after flow import
329
- *
330
- * @since x.x.x
331
- * @param int $flow_id Flow ID.
332
- * @param array $new_flow_args Flow post args.
333
- * @param array $flows Flow JSON data.
334
- */
335
- do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
-
337
- if ( $flow['steps'] ) {
338
- foreach ( $flow['steps'] as $key => $step ) {
339
-
340
- $new_all_meta = array();
341
- if ( is_array( $step['meta'] ) ) {
342
- foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
- $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
- }
345
- }
346
- $new_step_args = apply_filters(
347
- 'cartflows_step_importer_args',
348
- array(
349
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
- 'post_title' => $step['title'],
351
- 'post_status' => 'publish',
352
- 'meta_input' => $new_all_meta,
353
- 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
- )
355
- );
356
-
357
- $new_step_id = wp_insert_post( $new_step_args );
358
-
359
- /**
360
- * Fire after step import
361
- *
362
- * @since x.x.x
363
- * @param int $new_step_id step ID.
364
- * @param int $flow_id flow ID.
365
- * @param array $new_step_args Step post args.
366
- * @param array $flow_steps Flow steps.
367
- * @param array $flows All flows JSON data.
368
- */
369
- do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
-
371
- // Insert post meta.
372
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
-
374
- $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
- $current_term = term_exists( $step['type'], $step_taxonomy );
376
-
377
- // // Set type object.
378
- $data = get_term( $current_term['term_id'], $step_taxonomy );
379
- $step_slug = $data->slug;
380
- wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
-
382
- // Set type.
383
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
-
385
- // Set flow.
386
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
-
388
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
-
390
- if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
-
392
- // Download and replace images.
393
- $content = $this->get_content( $step['post_content'] );
394
-
395
- // Update post content.
396
- wp_update_post(
397
- array(
398
- 'ID' => $new_step_id,
399
- 'post_content' => $content,
400
- )
401
- );
402
- }
403
-
404
- // Elementor Data.
405
- if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
- // Add "elementor" in import [queue].
407
- // @todo Remove required `allow_url_fopen` support.
408
- if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
- $obj->import_single_template( $new_step_id );
411
- }
412
- }
413
-
414
- // Beaver Builder.
415
- if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
- if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
- CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
- }
419
- }
420
- }
421
- }
422
- }
423
- }
424
- }
425
-
426
- /**
427
- * Download and Replace hotlink images
428
- *
429
- * @since x.x.x
430
- *
431
- * @param string $content Mixed post content.
432
- * @return array Hotlink image array.
433
- */
434
- public function get_content( $content = '' ) {
435
-
436
- $content = stripslashes( $content );
437
-
438
- // Extract all links.
439
- $all_links = wp_extract_urls( $content );
440
-
441
- // Not have any link.
442
- if ( empty( $all_links ) ) {
443
- return $content;
444
- }
445
-
446
- $link_mapping = array();
447
- $image_links = array();
448
- $other_links = array();
449
-
450
- // Extract normal and image links.
451
- foreach ( $all_links as $key => $link ) {
452
- if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
-
454
- // Get all image links.
455
- // Avoid *-150x, *-300x and *-1024x images.
456
- if (
457
- false === strpos( $link, '-150x' ) &&
458
- false === strpos( $link, '-300x' ) &&
459
- false === strpos( $link, '-1024x' )
460
- ) {
461
- $image_links[] = $link;
462
- }
463
- } else {
464
-
465
- // Collect other links.
466
- $other_links[] = $link;
467
- }
468
- }
469
-
470
- // Step 1: Download images.
471
- if ( ! empty( $image_links ) ) {
472
- foreach ( $image_links as $key => $image_url ) {
473
- // Download remote image.
474
- $image = array(
475
- 'url' => $image_url,
476
- 'id' => 0,
477
- );
478
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
-
480
- // Old and New image mapping links.
481
- $link_mapping[ $image_url ] = $downloaded_image['url'];
482
- }
483
- }
484
-
485
- // Step 3: Replace mapping links.
486
- foreach ( $link_mapping as $old_url => $new_url ) {
487
- $content = str_replace( $old_url, $new_url, $content );
488
-
489
- // Replace the slashed URLs if any exist.
490
- $old_url = str_replace( '/', '/\\', $old_url );
491
- $new_url = str_replace( '/', '/\\', $new_url );
492
- $content = str_replace( $old_url, $new_url, $content );
493
- }
494
-
495
- return $content;
496
- }
497
-
498
- /**
499
- * Imported notice
500
- *
501
- * @since 1.1.4
502
- */
503
- public function imported_successfully() {
504
- ?>
505
- <div class="notice notice-success">
506
- <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
- </div>
508
- <?php
509
- }
510
-
511
- /**
512
- * Clear Cache.
513
- *
514
- * @since 1.0.0
515
- */
516
- public function clear_cache() {
517
- // Clear 'Elementor' file cache.
518
- if ( class_exists( '\Elementor\Plugin' ) ) {
519
- \Elementor\Plugin::$instance->files_manager->clear_cache();
520
- }
521
- }
522
-
523
- /**
524
- * JS Templates
525
- *
526
- * @since 1.0.0
527
- *
528
- * @return void
529
- */
530
- public function js_templates() {
531
-
532
- // Loading Templates.
533
- ?>
534
- <script type="text/template" id="tmpl-cartflows-step-loading">
535
- <div class="template-message-block cartflows-step-loading">
536
- <h2>
537
- <span class="spinner"></span>
538
- <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
- </h2>
540
- <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
- </div>
542
- </script>
543
-
544
- <?php
545
- // Search Templates.
546
- ?>
547
- <script type="text/template" id="tmpl-cartflows-searching-templates">
548
- <div class="template-message-block cartflows-searching-templates">
549
- <h2>
550
- <span class="spinner"></span>
551
- <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
- </h2>
553
- <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
- </div>
555
- </script>
556
-
557
- <?php
558
- // CartFlows Importing Template.
559
- ?>
560
- <script type="text/template" id="tmpl-cartflows-step-importing">
561
- <div class="template-message-block cartflows-step-importing">
562
- <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
- </div>
564
- </script>
565
-
566
- <?php
567
- // CartFlows Imported.
568
- ?>
569
- <script type="text/template" id="tmpl-cartflows-step-imported">
570
- <div class="template-message-block cartflows-step-imported">
571
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
- </script>
574
-
575
- <?php
576
- // No templates.
577
- ?>
578
- <script type="text/template" id="tmpl-cartflows-no-steps">
579
- <div class="cartflows-no-steps">
580
- <div class="template-message-block">
581
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
- <p class="description"></p>
583
- </div>
584
- </div>
585
- </script>
586
-
587
- <?php
588
- // No templates.
589
- ?>
590
- <script type="text/template" id="tmpl-cartflows-no-flows">
591
- <div class="cartflows-no-flows">
592
- <div class="template-message-block">
593
- <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
- <p class="description"></p>
595
- </div>
596
- </div>
597
- </script>
598
-
599
- <?php
600
- // Error handling.
601
- ?>
602
- <script type="text/template" id="tmpl-templator-error">
603
- <div class="notice notice-error"><p>{{ data }}</p></div>
604
- </script>
605
-
606
- <?php
607
- // Redirect to Elementor.
608
- ?>
609
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
- <div class="template-message-block templator-redirect-to-elementor">
611
- <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
- <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
- </script>
614
-
615
- <?php
616
- /**
617
- * Responsive Buttons
618
- */
619
- ?>
620
- <script type="text/template" id="tmpl-cartflows-responsive-view">
621
- <span class="responsive-view">
622
- <span class="actions">
623
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
- </span>
627
- </span>
628
- </script>
629
-
630
- <?php
631
- // Templates data.
632
- ?>
633
- <script type="text/template" id="tmpl-cartflows-flows-list">
634
-
635
- <# console.log( data.items.length ) #>
636
- <# console.log( data.items ) #>
637
- <# if ( data.items.length ) { #>
638
- <# for ( key in data.items ) { #>
639
- <#
640
- var flow_steps = [];
641
- if( data.items[ key ].flow_steps ) {
642
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
- return value['id'];
644
- });
645
- }
646
- #>
647
- <div class="inner">
648
- <div class="template">
649
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
650
- <div class="template-screenshot">
651
- <# if( data.items[ key ].featured_image_url ) { #>
652
- <img src="{{ data.items[ key ].featured_image_url }}" />
653
- <# } else { #>
654
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
- <# } #>
656
- </div>
657
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
- <# } #>
660
- <# if( data.items[ key ].woo_required ) { #>
661
- <div class="notice notice-info" style="width: auto;">
662
- <p class="wcf-learn-how">
663
- Install/Activate WooCommerce to use this template.
664
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
- <i class="dashicons dashicons-external"></i>
667
- </a>
668
- </p>
669
- </div>
670
- <# } else { #>
671
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
672
- <# } #>
673
-
674
- </span>
675
- <div class="template-id-container">
676
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
- <div class="template-actions">
678
-
679
- <#
680
- if( data.items[ key ].page_builder.slug ) {
681
- required_plugin_group = data.items[ key ].page_builder.slug;
682
- } else {
683
- required_plugin_group = '';
684
- }
685
-
686
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
687
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
- } else {
689
- import_btn_title = 'Import';
690
- } #>
691
-
692
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
- <# if( ! data.items[ key ].woo_required ) { #>
694
- <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
695
- <# } else { #>
696
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
- <# } #>
698
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
- <# } else { #>
701
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
- <# } #>
703
- </div>
704
- </div>
705
- </div>
706
- </div>
707
- <# } #>
708
- <# } #>
709
- </script>
710
-
711
- <?php
712
- // Empty Step.
713
- ?>
714
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
- <div class="inner">
716
- <div class="template">
717
- <span class="thumbnail site-preview cartflows-flow-preview">
718
- <div class="template-screenshot">
719
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
- </div>
721
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
- </span>
723
- <div class="template-id-container">
724
- <h3 class="template-name"> Blank </h3>
725
- <div class="template-actions">
726
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
- </div>
728
- </div>
729
- </div>
730
- </div>
731
- </script>
732
-
733
- <?php
734
- // Templates data.
735
- ?>
736
- <script type="text/template" id="tmpl-cartflows-steps-list">
737
- <# if ( data.items.length ) { #>
738
- <# for ( key in data.items ) { #>
739
- <#
740
- var flow_steps = [];
741
- if( data.items[ key ].flow_steps ) {
742
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
- return value['id'];
744
- });
745
- }
746
- #>
747
- <div class="inner">
748
- <div class="template">
749
- <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
750
- <div class="template-screenshot">
751
- <# if( data.items[ key ].featured_image_url ) { #>
752
- <img src="{{ data.items[ key ].featured_image_url }}" />
753
- <# } else { #>
754
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
- <# } #>
756
- </div>
757
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
-
759
- <# if( data.items[ key ].woo_required ) { #>
760
- <div class="notice notice-info" style="width: auto;">
761
- <p class="wcf-learn-how">
762
- Install/Activate WooCommerce to use this template.
763
- <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
- <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
- <i class="dashicons dashicons-external"></i>
766
- </a>
767
- </p>
768
- </div>
769
- <# } else { #>
770
- <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
771
- <# } #>
772
-
773
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
- <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
- <# } #>
776
- </span>
777
- <div class="template-id-container">
778
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
- <div class="template-actions">
780
-
781
- <#
782
-
783
- var step_slug = data.items[ key ].step_type.slug || '';
784
- var step_title = data.items[ key ].step_type.name || '';
785
- var import_btn_title = 'Import';
786
-
787
- var required_plugin_group = '';
788
- if( data.items[ key ].page_builder ) {
789
- required_plugin_group = data.items[ key ].page_builder.slug;
790
-
791
- if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
792
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
- }
794
- }
795
- #>
796
-
797
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
-
799
- <# if( ! data.items[ key ].woo_required ) { #>
800
- <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
801
- <# } else { #>
802
- <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
- <# } #>
804
-
805
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
- <# } else { #>
808
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
- <# } #>
810
- </div>
811
- </div>
812
- </div>
813
- </div>
814
- <# } #>
815
- <# } #>
816
- </script>
817
-
818
- <?php
819
- /**
820
- * TMPL - Website Unreachable
821
- */
822
- ?>
823
- <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
- <div class="postbox cartflows-website-unreachable">
825
- <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
- <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
- <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
- </div>
829
- </script>
830
-
831
- <?php
832
- /**
833
- * TMPL - Filters
834
- */
835
- ?>
836
- <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
- <?php
838
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
- $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
- $title = $page_builder['title'];
841
-
842
- $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
- $theme_status = '';
844
- if ( 'divi' === $default_page_builder ) {
845
-
846
- $theme_status = $page_builder['theme-status'];
847
- $plugin_status = $page_builder['plugin-status'];
848
-
849
- if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
- $plugin_string = 'Please activate ' . esc_html( $title );
851
- } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
- $plugin_string = 'Please install and activate ' . esc_html( $title );
853
- }
854
- }
855
- ?>
856
- <div class="wcf-page-builder-message">
857
- <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
- <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
- <p>We plan to add design templates made with more page builder shortly!</p>
860
- </div>
861
- </script>
862
-
863
- <?php
864
- /**
865
- * TMPL - Filters
866
- */
867
- ?>
868
- <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
- <# if ( data ) { #>
870
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
- <# if ( data.args.show_all ) { #>
872
- <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
- <# } #>
874
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
- <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
- <# } #>
877
- <# var step_slug_data = []; #>
878
- <# for ( key in data.items ) { #>
879
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
880
-
881
- <# step_slug_data.push( data.items[ key ].slug ); #>
882
-
883
- <# } #>
884
- <# if( step_slug_data.indexOf("optin") === -1){ #>
885
- <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
- <# } #>
887
- </select>
888
- <# } #>
889
- </script>
890
-
891
- <script type="text/template" id="tmpl-cartflows-term-filters">
892
-
893
- <# if ( data ) { #>
894
-
895
- <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
-
898
- <# if ( data.args.show_all ) { #>
899
- <li>
900
- <a href="#" data-group="all"> All </a>
901
- </li>
902
- <# } #>
903
-
904
- <# for ( key in data.items ) { #>
905
- <li>
906
- <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
907
- </li>
908
- <# } #>
909
-
910
- </ul>
911
-
912
- <?php
913
-
914
- /**
915
- <# } else { #>
916
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
-
918
- <# if ( data.args.show_all ) { #>
919
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
- <# } #>
921
-
922
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
- <# } #>
925
-
926
- <# for ( key in data.items ) { #>
927
- <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
928
- <# } #>
929
-
930
- </select>
931
- */
932
- ?>
933
-
934
- <?php /* <# } #> */ ?>
935
-
936
- <# } #>
937
- </script>
938
-
939
- <?php
940
- // Step Type.
941
- ?>
942
- <script type="text/template" id="tmpl-cartflows-step-types">
943
- <ul class="wcf-tab nav-tabs">
944
- <# if( data.items_count ) { #>
945
- <# for( key in data.items ) { #>
946
- <# console.log( data.items[ key ].id ) #>
947
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
- </li>
950
- <# } #>
951
- <# } #>
952
- </ul>
953
- </script>
954
-
955
- <?php
956
- // Add to library button.
957
- ?>
958
- <script type="text/template" id="tmpl-templator-add-to-library">
959
- <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
960
- </script>
961
- <?php
962
- }
963
-
964
- /**
965
- * Enqueue scripts
966
- *
967
- * @since 1.0.0
968
- *
969
- * @hook admin_enqueue_scripts
970
- * @param string $hook Current page hook.
971
- */
972
- public function scripts( $hook = '' ) {
973
-
974
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
- return;
976
- }
977
-
978
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
-
983
- $installed_plugins = get_plugins();
984
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
- $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
-
987
- $localize_vars = array(
988
- '_is_pro_active' => _is_cartflows_pro(),
989
- 'is_wc_installed' => $is_wc_installed,
990
- 'is_wc_activated' => $is_wc_activated,
991
-
992
- // Set API headers for the CartFlows API Calls only.
993
- 'headers' => array(),
994
-
995
- // Flow and its rest fields.
996
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
997
- 'flow_fields' => array(
998
- 'id',
999
- 'title',
1000
- 'flow_type',
1001
- 'page_builder',
1002
- 'flow_steps',
1003
- 'licence_status',
1004
- 'featured_image_url',
1005
- 'featured_media', // @required for field `featured_image_url`.
1006
- ),
1007
-
1008
- // Flow type and rest fields.
1009
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1010
- 'flow_type_fields' => array(
1011
- 'id',
1012
- 'name',
1013
- 'slug',
1014
- ),
1015
-
1016
- // Flow page builder and rest fields.
1017
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1018
- 'flow_page_builder_fields' => array(
1019
- 'id',
1020
- 'name',
1021
- 'slug',
1022
- ),
1023
-
1024
- // Step page builder and rest fields.
1025
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1026
- 'step_page_builder_fields' => array(
1027
- 'id',
1028
- 'name',
1029
- 'slug',
1030
- ),
1031
-
1032
- // Step and its rest fields.
1033
- 'step' => CARTFLOWS_STEP_POST_TYPE,
1034
- 'step_fields' => array(
1035
- 'title',
1036
- 'featured_image_url',
1037
- 'featured_media', // @required for field `featured_image_url`.
1038
- 'id',
1039
- 'flow_type',
1040
- 'step_type',
1041
- 'page_builder',
1042
- 'licence_status',
1043
- ),
1044
-
1045
- // Step type and its rest fields.
1046
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1047
- 'step_type_fields' => array(
1048
- 'id',
1049
- 'name',
1050
- 'slug',
1051
- ),
1052
-
1053
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
1054
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
1055
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1056
- 'site_url' => site_url(),
1057
- 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1058
- 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1059
- 'admin_url' => admin_url(),
1060
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1061
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1062
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1063
-
1064
- 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1065
-
1066
- 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1067
- );
1068
-
1069
- $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1070
-
1071
- // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1072
- // wp_die( );
1073
- // Add thickbox.
1074
- add_thickbox();
1075
-
1076
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1077
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1078
- }
1079
-
1080
- /**
1081
- * Import.
1082
- *
1083
- * @since 1.0.0
1084
- *
1085
- * @hook wp_ajax_cartflows_import_flow_step
1086
- * @return void
1087
- */
1088
- public function import_flow() {
1089
-
1090
- if ( ! current_user_can( 'manage_options' ) ) {
1091
- return;
1092
- }
1093
-
1094
- check_ajax_referer( 'cf-import-flow-step', 'security' );
1095
-
1096
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1097
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1098
-
1099
- wcf()->logger->import_log( '------------------------------------' );
1100
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1101
- wcf()->logger->import_log( '------------------------------------' );
1102
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1103
-
1104
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1105
-
1106
- $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1107
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1108
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1109
- $post_content = $response['data']['divi_content'];
1110
- }
1111
- }
1112
-
1113
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1114
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1115
- $post_content = $response['data']['divi_content'];
1116
- }
1117
- }
1118
-
1119
- if ( false === $response['success'] ) {
1120
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1121
- wp_send_json_error( $response );
1122
- }
1123
-
1124
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1125
-
1126
- $new_step_id = wp_insert_post(
1127
- array(
1128
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1129
- 'post_title' => $response['title'],
1130
- 'post_content' => $post_content,
1131
- 'post_status' => 'publish',
1132
- )
1133
- );
1134
-
1135
- if ( is_wp_error( $new_step_id ) ) {
1136
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1137
- wp_send_json_error( $new_step_id );
1138
- }
1139
-
1140
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1141
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1142
- update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1143
- }
1144
- }
1145
-
1146
- /* Imported Step */
1147
- update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1148
-
1149
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1150
- // insert post meta.
1151
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1152
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1153
-
1154
- /**
1155
- * Import & Set type.
1156
- */
1157
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1158
-
1159
- $term_slug = '';
1160
- if ( $term ) {
1161
-
1162
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1163
- $term_exist = term_exists( $term->slug, $taxonomy );
1164
-
1165
- if ( empty( $term_exist ) ) {
1166
- $terms = array(
1167
- array(
1168
- 'name' => $term->name,
1169
- 'slug' => $term->slug,
1170
- ),
1171
- );
1172
-
1173
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1174
- wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1175
- }
1176
-
1177
- $current_term = term_exists( $term->slug, $taxonomy );
1178
-
1179
- // Set type object.
1180
- $data = get_term( $current_term['term_id'], $taxonomy );
1181
- $term_slug = $data->slug;
1182
- $term_name = $data->name;
1183
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1184
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1185
-
1186
- // Set type.
1187
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1188
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1189
- }
1190
-
1191
- // Set flow.
1192
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1193
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1194
-
1195
- /**
1196
- * Update steps for the current flow.
1197
- */
1198
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1199
-
1200
- if ( ! is_array( $flow_steps ) ) {
1201
- $flow_steps = array();
1202
- }
1203
-
1204
- $flow_steps[] = array(
1205
- 'id' => $new_step_id,
1206
- 'title' => $response['title'],
1207
- 'type' => $term_slug,
1208
- );
1209
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1210
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1211
-
1212
- // Import Post Meta.
1213
- self::import_post_meta( $new_step_id, $response );
1214
-
1215
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1216
- wcf()->logger->import_log( '------------------------------------' );
1217
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1218
- wcf()->logger->import_log( '------------------------------------' );
1219
-
1220
- do_action( 'cartflows_import_complete' );
1221
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1222
-
1223
- // Batch Process.
1224
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
1225
-
1226
- /**
1227
- * End
1228
- */
1229
- wp_send_json_success( $new_step_id );
1230
- }
1231
-
1232
- /**
1233
- * Import Step.
1234
- *
1235
- * @since 1.0.0
1236
- * @hook wp_ajax_cartflows_step_import
1237
- *
1238
- * @return void
1239
- */
1240
- public function create_default_flow() {
1241
-
1242
- if ( ! current_user_can( 'manage_options' ) ) {
1243
- return;
1244
- }
1245
-
1246
- check_ajax_referer( 'cf-default-flow', 'security' );
1247
-
1248
- // Create post object.
1249
- $new_flow_post = array(
1250
- 'post_content' => '',
1251
- 'post_status' => 'publish',
1252
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1253
- );
1254
-
1255
- // Insert the post into the database.
1256
- $flow_id = wp_insert_post( $new_flow_post );
1257
-
1258
- if ( is_wp_error( $flow_id ) ) {
1259
- wp_send_json_error( $flow_id->get_error_message() );
1260
- }
1261
-
1262
- $flow_steps = array();
1263
-
1264
- if ( wcf()->is_woo_active ) {
1265
- $steps_data = array(
1266
- 'sales' => array(
1267
- 'title' => __( 'Sales Landing', 'cartflows' ),
1268
- 'type' => 'landing',
1269
- ),
1270
- 'order-form' => array(
1271
- 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1272
- 'type' => 'checkout',
1273
- ),
1274
- 'order-confirmation' => array(
1275
- 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1276
- 'type' => 'thankyou',
1277
- ),
1278
- );
1279
-
1280
- } else {
1281
- $steps_data = array(
1282
- 'landing' => array(
1283
- 'title' => __( 'Landing', 'cartflows' ),
1284
- 'type' => 'landing',
1285
- ),
1286
- 'thankyou' => array(
1287
- 'title' => __( 'Thank You', 'cartflows' ),
1288
- 'type' => 'landing',
1289
- ),
1290
- );
1291
- }
1292
-
1293
- foreach ( $steps_data as $slug => $data ) {
1294
-
1295
- $post_content = '';
1296
- $step_type = trim( $data['type'] );
1297
-
1298
- $step_id = wp_insert_post(
1299
- array(
1300
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1301
- 'post_title' => $data['title'],
1302
- 'post_content' => $post_content,
1303
- 'post_status' => 'publish',
1304
- )
1305
- );
1306
-
1307
- if ( is_wp_error( $step_id ) ) {
1308
- wp_send_json_error( $step_id->get_error_message() );
1309
- }
1310
-
1311
- if ( $step_id ) {
1312
-
1313
- $flow_steps[] = array(
1314
- 'id' => $step_id,
1315
- 'title' => $data['title'],
1316
- 'type' => $step_type,
1317
- );
1318
-
1319
- // insert post meta.
1320
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1321
- update_post_meta( $step_id, 'wcf-step-type', $step_type );
1322
-
1323
- wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1324
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1325
-
1326
- update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1327
- }
1328
- }
1329
-
1330
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1331
-
1332
- wp_send_json_success( $flow_id );
1333
- }
1334
-
1335
- /**
1336
- * Create Flow
1337
- *
1338
- * @return void
1339
- */
1340
- public function create_flow() {
1341
-
1342
- if ( ! current_user_can( 'manage_options' ) ) {
1343
- return;
1344
- }
1345
-
1346
- check_ajax_referer( 'cf-create-flow', 'security' );
1347
-
1348
- // Create post object.
1349
- $new_flow_post = array(
1350
- 'post_content' => '',
1351
- 'post_status' => 'publish',
1352
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1353
- );
1354
-
1355
- // Insert the post into the database.
1356
- $flow_id = wp_insert_post( $new_flow_post );
1357
-
1358
- if ( is_wp_error( $flow_id ) ) {
1359
- wp_send_json_error( $flow_id->get_error_message() );
1360
- }
1361
-
1362
- /* Imported Flow */
1363
- update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1364
-
1365
- wp_send_json_success( $flow_id );
1366
- }
1367
-
1368
- /**
1369
- * Create Step
1370
- *
1371
- * @return void
1372
- */
1373
- public function import_step() {
1374
-
1375
- if ( ! current_user_can( 'manage_options' ) ) {
1376
- return;
1377
- }
1378
-
1379
- check_ajax_referer( 'cf-step-import', 'security' );
1380
-
1381
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1382
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1383
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1384
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1385
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1386
-
1387
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1388
-
1389
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1390
-
1391
- wcf()->logger->import_log( '------------------------------------' );
1392
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
1393
- wcf()->logger->import_log( '------------------------------------' );
1394
-
1395
- if ( empty( $template_id ) || empty( $post_id ) ) {
1396
- /* translators: %s: template ID */
1397
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1398
- wcf()->logger->import_log( $data );
1399
- wp_send_json_error( $data );
1400
- }
1401
-
1402
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1403
-
1404
- $response = CartFlows_API::get_instance()->get_template( $template_id );
1405
-
1406
- if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1407
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1408
-
1409
- update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1410
-
1411
- wp_update_post(
1412
- array(
1413
- 'ID' => $post_id,
1414
- 'post_content' => $response['data']['divi_content'],
1415
- )
1416
- );
1417
- }
1418
- }
1419
-
1420
- if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1421
- if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1422
-
1423
- wp_update_post(
1424
- array(
1425
- 'ID' => $post_id,
1426
- 'post_content' => $response['data']['divi_content'],
1427
- )
1428
- );
1429
- }
1430
- }
1431
-
1432
- /* Imported Step */
1433
- update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1434
-
1435
- // Import Post Meta.
1436
- self::import_post_meta( $post_id, $response );
1437
-
1438
- do_action( 'cartflows_import_complete' );
1439
-
1440
- // Batch Process.
1441
- do_action( 'cartflows_after_template_import', $post_id, $response );
1442
-
1443
- wcf()->logger->import_log( '------------------------------------' );
1444
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1445
- wcf()->logger->import_log( '------------------------------------' );
1446
-
1447
- wp_send_json_success( $post_id );
1448
- }
1449
-
1450
- /**
1451
- * Import Step.
1452
- *
1453
- * @since 1.0.0
1454
- * @hook wp_ajax_cartflows_step_create_blank
1455
- *
1456
- * @return void
1457
- */
1458
- public function step_create_blank() {
1459
-
1460
- if ( ! current_user_can( 'manage_options' ) ) {
1461
- return;
1462
- }
1463
-
1464
- check_ajax_referer( 'cf-step-create-blank', 'security' );
1465
-
1466
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1467
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1468
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1469
-
1470
- if ( empty( $flow_id ) || empty( $step_type ) ) {
1471
- /* translators: %s: flow ID */
1472
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1473
- wcf()->logger->import_log( $data );
1474
- wp_send_json_error( $data );
1475
- }
1476
-
1477
- wcf()->logger->import_log( '------------------------------------' );
1478
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1479
-
1480
- $step_type_title = str_replace( '-', ' ', $step_type );
1481
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1482
-
1483
- $new_step_id = wp_insert_post(
1484
- array(
1485
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1486
- 'post_title' => $step_title,
1487
- 'post_content' => '',
1488
- 'post_status' => 'publish',
1489
- )
1490
- );
1491
-
1492
- // insert post meta.
1493
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1494
-
1495
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1496
- $term_exist = term_exists( $step_type_slug, $taxonomy );
1497
-
1498
- if ( empty( $term_exist ) ) {
1499
- $terms = array(
1500
- array(
1501
- 'name' => $step_type_title,
1502
- 'slug' => $step_type_slug,
1503
- ),
1504
- );
1505
-
1506
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1507
- wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1508
- }
1509
-
1510
- $current_term = term_exists( $step_type_slug, $taxonomy );
1511
-
1512
- // Set type object.
1513
- $data = get_term( $current_term['term_id'], $taxonomy );
1514
- $step_slug = $data->slug;
1515
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1516
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1517
-
1518
- // Set Default page Layout.
1519
- update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1520
-
1521
- // Set type.
1522
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1523
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1524
-
1525
- // Set flow.
1526
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1527
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1528
-
1529
- self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1530
-
1531
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1532
- wcf()->logger->import_log( '------------------------------------' );
1533
-
1534
- wp_send_json_success( $new_step_id );
1535
- }
1536
-
1537
- /**
1538
- * Import Post Meta
1539
- *
1540
- * @since 1.0.0
1541
- *
1542
- * @param integer $post_id Post ID.
1543
- * @param array $response Post meta.
1544
- * @return void
1545
- */
1546
- public static function import_post_meta( $post_id, $response ) {
1547
-
1548
- $metadata = (array) $response['post_meta'];
1549
-
1550
- foreach ( $metadata as $meta_key => $meta_value ) {
1551
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1552
-
1553
- if ( $meta_value ) {
1554
-
1555
- if ( is_serialized( $meta_value, true ) ) {
1556
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1557
- } elseif ( is_array( $meta_value ) ) {
1558
- $raw_data = json_decode( stripslashes( $meta_value ), true );
1559
- } else {
1560
- $raw_data = $meta_value;
1561
- }
1562
-
1563
- if ( '_elementor_data' === $meta_key ) {
1564
- if ( is_array( $raw_data ) ) {
1565
- $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1566
- } else {
1567
- $raw_data = wp_slash( $raw_data );
1568
- }
1569
- }
1570
- if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1571
- if ( is_array( $raw_data ) ) {
1572
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1573
- } else {
1574
- if ( ! is_object( $raw_data ) ) {
1575
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1576
- }
1577
- }
1578
- }
1579
-
1580
- update_post_meta( $post_id, $meta_key, $raw_data );
1581
- }
1582
- }
1583
- }
1584
-
1585
- /**
1586
- * Import Template for Elementor
1587
- *
1588
- * @since 1.0.0
1589
- *
1590
- * @param integer $post_id Post ID.
1591
- * @param array $response Post meta.
1592
- * @param array $page_build_data Page build data.
1593
- * @return void
1594
- */
1595
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1596
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1597
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1598
- wcf()->logger->import_log( $data );
1599
- wp_send_json_error( $data );
1600
- }
1601
-
1602
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1603
-
1604
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1605
-
1606
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1607
- $obj->import_single_template( $post_id );
1608
-
1609
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1610
- }
1611
-
1612
- /**
1613
- * Supported post types
1614
- *
1615
- * @since 1.0.0
1616
- *
1617
- * @return array Supported post types.
1618
- */
1619
- public static function supported_post_types() {
1620
- return apply_filters(
1621
- 'cartflows_supported_post_types',
1622
- array(
1623
- CARTFLOWS_FLOW_POST_TYPE,
1624
- )
1625
- );
1626
- }
1627
-
1628
- /**
1629
- * Check supported post type
1630
- *
1631
- * @since 1.0.0
1632
- *
1633
- * @param string $post_type Post type.
1634
- * @return boolean Supported post type status.
1635
- */
1636
- public static function is_supported_post( $post_type = '' ) {
1637
-
1638
- if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1639
- return true;
1640
- }
1641
-
1642
- return false;
1643
- }
1644
-
1645
- /**
1646
- * Set steps to the flow
1647
- *
1648
- * @param integer $flow_id Flow ID.
1649
- * @param integer $new_step_id New step ID.
1650
- * @param string $step_title Flow Type.
1651
- * @param string $step_slug Flow Type.
1652
- */
1653
- public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1654
- // Update steps for the current flow.
1655
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1656
-
1657
- if ( ! is_array( $flow_steps ) ) {
1658
- $flow_steps = array();
1659
- }
1660
-
1661
- $flow_steps[] = array(
1662
- 'id' => $new_step_id,
1663
- 'title' => $step_title,
1664
- 'type' => $step_slug,
1665
- );
1666
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1667
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1668
- }
1669
-
1670
- /**
1671
- * Localize variables in admin
1672
- *
1673
- * @param array $vars variables.
1674
- */
1675
- public function localize_vars( $vars ) {
1676
-
1677
- $ajax_actions = array(
1678
- 'cf_step_import',
1679
- 'cf_load_steps',
1680
- 'cf_create_flow',
1681
- 'cf_default_flow',
1682
- 'cf_step_create_blank',
1683
- 'cf_import_flow_step',
1684
- );
1685
-
1686
- foreach ( $ajax_actions as $action ) {
1687
-
1688
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1689
- }
1690
-
1691
- return $vars;
1692
- }
1693
-
1694
- /**
1695
- * Ajax action to activate plugin
1696
- */
1697
- public function activate_plugin() {
1698
-
1699
- if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1700
- wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1701
- }
1702
-
1703
- if ( ! current_user_can( 'activate_plugins' ) ) {
1704
- wp_send_json_error(
1705
- array(
1706
- 'success' => false,
1707
- 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1708
- )
1709
- );
1710
- }
1711
-
1712
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1713
-
1714
- $activate = activate_plugin( $plugin_init, '', false, true );
1715
-
1716
- if ( is_wp_error( $activate ) ) {
1717
- wp_send_json_error(
1718
- array(
1719
- 'success' => false,
1720
- 'message' => $activate->get_error_message(),
1721
- 'init' => $plugin_init,
1722
- )
1723
- );
1724
- }
1725
-
1726
- wp_send_json_success(
1727
- array(
1728
- 'success' => true,
1729
- 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1730
- 'init' => $plugin_init,
1731
- )
1732
- );
1733
- }
1734
-
1735
- }
1736
-
1737
- /**
1738
- * Initialize class object with 'get_instance()' method
1739
- */
1740
- CartFlows_Importer::get_instance();
1741
-
1742
- endif;
1
+ <?php
2
+ /**
3
+ * CartFlows Admin
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Importer {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.0.0
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since 1.0.0
45
+ */
46
+ public function __construct() {
47
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
+
49
+ add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
+ add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
+ add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
52
+ add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
53
+ add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
54
+
55
+ add_action( 'admin_footer', array( $this, 'js_templates' ) );
56
+ add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
57
+
58
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
59
+
60
+ add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
61
+
62
+ add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
63
+ add_action( 'admin_init', array( $this, 'export_json' ) );
64
+ add_action( 'admin_init', array( $this, 'import_json' ) );
65
+ add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
66
+ add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
67
+ }
68
+
69
+ /**
70
+ * Add the export link to action list for flows row actions
71
+ *
72
+ * @since 1.1.4
73
+ *
74
+ * @param array $actions Actions array.
75
+ * @param object $post Post object.
76
+ *
77
+ * @return array
78
+ */
79
+ public function export_link( $actions, $post ) {
80
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
81
+ $actions['export'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_export_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_export_nonce' ) . '" title="' . __( 'Export this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Export', 'cartflows' ) . '</a>';
82
+ }
83
+ return $actions;
84
+ }
85
+
86
+ /**
87
+ * Add menus
88
+ *
89
+ * @since 1.1.4
90
+ */
91
+ public function add_to_menus() {
92
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
93
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
94
+ }
95
+
96
+ /**
97
+ * Export flow with steps and its meta
98
+ *
99
+ * @since 1.1.4
100
+ */
101
+ public function export_flow() {
102
+
103
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
104
+ wp_die( esc_html__( 'No post to export has been supplied!', 'cartflows' ) );
105
+ }
106
+
107
+ if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['flow_export_nonce'] ) ), basename( __FILE__ ) ) ) {
108
+ return;
109
+ }
110
+
111
+ // Get the original post id.
112
+ $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
113
+
114
+ $flows = array();
115
+ $flows[] = $this->get_flow_export_data( $flow_id );
116
+ $flows = apply_filters( 'cartflows_export_data', $flows );
117
+
118
+ nocache_headers();
119
+ header( 'Content-Type: application/json; charset=utf-8' );
120
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-' . $flow_id . '-' . gmdate( 'm-d-Y' ) . '.json' );
121
+ header( 'Expires: 0' );
122
+
123
+ echo wp_json_encode( $flows );
124
+ exit;
125
+ }
126
+
127
+ /**
128
+ * Export flow markup
129
+ *
130
+ * @since 1.1.4
131
+ */
132
+ public function exporter_markup() {
133
+ include_once CARTFLOWS_DIR . 'includes/exporter.php';
134
+ }
135
+
136
+ /**
137
+ * Import flow markup
138
+ *
139
+ * @since 1.1.4
140
+ */
141
+ public function importer_markup() {
142
+ include_once CARTFLOWS_DIR . 'includes/importer.php';
143
+ }
144
+
145
+ /**
146
+ * Export flow
147
+ *
148
+ * @since 1.1.4
149
+ */
150
+ public function export_json() {
151
+ if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
152
+ return;
153
+ }
154
+
155
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
156
+ return;
157
+ }
158
+
159
+ if ( ! current_user_can( 'manage_options' ) ) {
160
+ return;
161
+ }
162
+
163
+ $flows = $this->get_all_flow_export_data();
164
+ $flows = apply_filters( 'cartflows_export_data', $flows );
165
+
166
+ nocache_headers();
167
+ header( 'Content-Type: application/json; charset=utf-8' );
168
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . gmdate( 'm-d-Y' ) . '.json' );
169
+ header( 'Expires: 0' );
170
+
171
+ echo wp_json_encode( $flows );
172
+ exit;
173
+ }
174
+
175
+ /**
176
+ * Get flow export data
177
+ *
178
+ * @since 1.1.4
179
+ *
180
+ * @param integer $flow_id Flow ID.
181
+ * @return array
182
+ */
183
+ public function get_flow_export_data( $flow_id ) {
184
+
185
+ $export_all = apply_filters( 'cartflows_export_all', true );
186
+
187
+ $valid_step_meta_keys = array(
188
+ '_wp_page_template',
189
+ '_thumbnail_id',
190
+ 'classic-editor-remember',
191
+ );
192
+
193
+ $new_steps = array();
194
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
195
+ if ( $steps ) {
196
+ foreach ( $steps as $key => $step ) {
197
+
198
+ // Add step post meta.
199
+ $new_all_meta = array();
200
+ $all_meta = get_post_meta( $step['id'] );
201
+
202
+ // Add single step.
203
+ $step_data_arr = array(
204
+ 'title' => get_the_title( $step['id'] ),
205
+ 'type' => $step['type'],
206
+ 'meta' => $all_meta,
207
+ 'post_content' => '',
208
+ );
209
+
210
+ if ( $export_all ) {
211
+
212
+ $step_post_obj = get_post( $step['id'] );
213
+
214
+ $step_data_arr['post_content'] = $step_post_obj->post_content;
215
+ }
216
+
217
+ $new_steps[] = $step_data_arr;
218
+ }
219
+ }
220
+
221
+ // Add single flow.
222
+ return array(
223
+ 'title' => get_the_title( $flow_id ),
224
+ 'steps' => $new_steps,
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Get all flow export data
230
+ *
231
+ * @since 1.1.4
232
+ */
233
+ public function get_all_flow_export_data() {
234
+
235
+ $query_args = array(
236
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
237
+
238
+ // Query performance optimization.
239
+ 'fields' => 'ids',
240
+ 'no_found_rows' => true,
241
+ 'posts_per_page' => -1,
242
+ );
243
+
244
+ $query = new WP_Query( $query_args );
245
+ $flows = array();
246
+ if ( $query->posts ) {
247
+ foreach ( $query->posts as $key => $post_id ) {
248
+ $flows[] = $this->get_flow_export_data( $post_id );
249
+ }
250
+ }
251
+
252
+ return $flows;
253
+ }
254
+
255
+ /**
256
+ * Import our exported file
257
+ *
258
+ * @since 1.1.4
259
+ */
260
+ public function import_json() {
261
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
262
+ return;
263
+ }
264
+
265
+ if ( isset( $_POST['cartflows-action-nonce'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['cartflows-action-nonce'] ) ), 'cartflows-action-nonce' ) ) {
266
+ return;
267
+ }
268
+
269
+ if ( ! current_user_can( 'manage_options' ) ) {
270
+ return;
271
+ }
272
+
273
+ $filename = $_FILES['file']['name']; //phpcs:ignore
274
+ $file_info = explode( '.', $filename );
275
+ $extension = end( $file_info );
276
+
277
+ if ( 'json' != $extension ) {
278
+ wp_die( esc_html__( 'Please upload a valid .json file', 'cartflows' ) );
279
+ }
280
+
281
+ $file = $_FILES['file']['tmp_name']; //phpcs:ignore
282
+
283
+ if ( empty( $file ) ) {
284
+ wp_die( esc_html__( 'Please upload a file to import', 'cartflows' ) );
285
+ }
286
+
287
+ // Retrieve the settings from the file and convert the JSON object to an array.
288
+ $flows = json_decode( file_get_contents( $file ), true );//phpcs:ignore
289
+
290
+ $this->import_from_json_data( $flows );
291
+
292
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
293
+ }
294
+
295
+ /**
296
+ * Import flow from the JSON data
297
+ *
298
+ * @since x.x.x
299
+ * @param array $flows JSON array.
300
+ * @return void
301
+ */
302
+ public function import_from_json_data( $flows ) {
303
+ if ( $flows ) {
304
+
305
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
306
+
307
+ foreach ( $flows as $key => $flow ) {
308
+
309
+ $flow_title = $flow['title'];
310
+ if ( post_exists( $flow['title'] ) ) {
311
+ $flow_title = $flow['title'] . ' Copy';
312
+ }
313
+
314
+ // Create post object.
315
+ $new_flow_args = apply_filters(
316
+ 'cartflows_flow_importer_args',
317
+ array(
318
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
319
+ 'post_title' => $flow_title,
320
+ 'post_status' => 'publish',
321
+ )
322
+ );
323
+
324
+ // Insert the post into the database.
325
+ $flow_id = wp_insert_post( $new_flow_args );
326
+
327
+ /**
328
+ * Fire after flow import
329
+ *
330
+ * @since x.x.x
331
+ * @param int $flow_id Flow ID.
332
+ * @param array $new_flow_args Flow post args.
333
+ * @param array $flows Flow JSON data.
334
+ */
335
+ do_action( 'cartflows_flow_imported', $flow_id, $new_flow_args, $flows );
336
+
337
+ if ( $flow['steps'] ) {
338
+ foreach ( $flow['steps'] as $key => $step ) {
339
+
340
+ $new_all_meta = array();
341
+ if ( is_array( $step['meta'] ) ) {
342
+ foreach ( $step['meta'] as $meta_key => $mvalue ) {
343
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $mvalue[0] );
344
+ }
345
+ }
346
+ $new_step_args = apply_filters(
347
+ 'cartflows_step_importer_args',
348
+ array(
349
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
350
+ 'post_title' => $step['title'],
351
+ 'post_status' => 'publish',
352
+ 'meta_input' => $new_all_meta,
353
+ 'post_content' => isset( $step['post_content'] ) ? $step['post_content'] : '',
354
+ )
355
+ );
356
+
357
+ $new_step_id = wp_insert_post( $new_step_args );
358
+
359
+ /**
360
+ * Fire after step import
361
+ *
362
+ * @since x.x.x
363
+ * @param int $new_step_id step ID.
364
+ * @param int $flow_id flow ID.
365
+ * @param array $new_step_args Step post args.
366
+ * @param array $flow_steps Flow steps.
367
+ * @param array $flows All flows JSON data.
368
+ */
369
+ do_action( 'cartflows_step_imported', $new_step_id, $flow_id, $new_step_args, $flow['steps'], $flows );
370
+
371
+ // Insert post meta.
372
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
373
+
374
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
375
+ $current_term = term_exists( $step['type'], $step_taxonomy );
376
+
377
+ // // Set type object.
378
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
379
+ $step_slug = $data->slug;
380
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
381
+
382
+ // Set type.
383
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
384
+
385
+ // Set flow.
386
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
387
+
388
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
389
+
390
+ if ( isset( $step['post_content'] ) && ! empty( $step['post_content'] ) ) {
391
+
392
+ // Download and replace images.
393
+ $content = $this->get_content( $step['post_content'] );
394
+
395
+ // Update post content.
396
+ wp_update_post(
397
+ array(
398
+ 'ID' => $new_step_id,
399
+ 'post_content' => $content,
400
+ )
401
+ );
402
+ }
403
+
404
+ // Elementor Data.
405
+ if ( ( 'elementor' === $default_page_builder ) && class_exists( '\Elementor\Plugin' ) ) {
406
+ // Add "elementor" in import [queue].
407
+ // @todo Remove required `allow_url_fopen` support.
408
+ if ( ini_get( 'allow_url_fopen' ) && isset( $step['meta']['_elementor_data'] ) ) {
409
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
410
+ $obj->import_single_template( $new_step_id );
411
+ }
412
+ }
413
+
414
+ // Beaver Builder.
415
+ if ( ( 'beaver-builder' === $default_page_builder ) && class_exists( 'FLBuilder' ) ) {
416
+ if ( isset( $step['meta']['_fl_builder_data'] ) ) {
417
+ CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $new_step_id );
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Download and Replace hotlink images
428
+ *
429
+ * @since x.x.x
430
+ *
431
+ * @param string $content Mixed post content.
432
+ * @return array Hotlink image array.
433
+ */
434
+ public function get_content( $content = '' ) {
435
+
436
+ $content = stripslashes( $content );
437
+
438
+ // Extract all links.
439
+ $all_links = wp_extract_urls( $content );
440
+
441
+ // Not have any link.
442
+ if ( empty( $all_links ) ) {
443
+ return $content;
444
+ }
445
+
446
+ $link_mapping = array();
447
+ $image_links = array();
448
+ $other_links = array();
449
+
450
+ // Extract normal and image links.
451
+ foreach ( $all_links as $key => $link ) {
452
+ if ( preg_match( '/^((https?:\/\/)|(www\.))([a-z0-9-].?)+(:[0-9]+)?\/[\w\-]+\.(jpg|png|gif|jpeg)\/?$/i', $link ) ) {
453
+
454
+ // Get all image links.
455
+ // Avoid *-150x, *-300x and *-1024x images.
456
+ if (
457
+ false === strpos( $link, '-150x' ) &&
458
+ false === strpos( $link, '-300x' ) &&
459
+ false === strpos( $link, '-1024x' )
460
+ ) {
461
+ $image_links[] = $link;
462
+ }
463
+ } else {
464
+
465
+ // Collect other links.
466
+ $other_links[] = $link;
467
+ }
468
+ }
469
+
470
+ // Step 1: Download images.
471
+ if ( ! empty( $image_links ) ) {
472
+ foreach ( $image_links as $key => $image_url ) {
473
+ // Download remote image.
474
+ $image = array(
475
+ 'url' => $image_url,
476
+ 'id' => 0,
477
+ );
478
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
479
+
480
+ // Old and New image mapping links.
481
+ $link_mapping[ $image_url ] = $downloaded_image['url'];
482
+ }
483
+ }
484
+
485
+ // Step 3: Replace mapping links.
486
+ foreach ( $link_mapping as $old_url => $new_url ) {
487
+ $content = str_replace( $old_url, $new_url, $content );
488
+
489
+ // Replace the slashed URLs if any exist.
490
+ $old_url = str_replace( '/', '/\\', $old_url );
491
+ $new_url = str_replace( '/', '/\\', $new_url );
492
+ $content = str_replace( $old_url, $new_url, $content );
493
+ }
494
+
495
+ return $content;
496
+ }
497
+
498
+ /**
499
+ * Imported notice
500
+ *
501
+ * @since 1.1.4
502
+ */
503
+ public function imported_successfully() {
504
+ ?>
505
+ <div class="notice notice-success">
506
+ <p><?php esc_html_e( 'Successfully imported flows.', 'cartflows' ); ?></p>
507
+ </div>
508
+ <?php
509
+ }
510
+
511
+ /**
512
+ * Clear Cache.
513
+ *
514
+ * @since 1.0.0
515
+ */
516
+ public function clear_cache() {
517
+ // Clear 'Elementor' file cache.
518
+ if ( class_exists( '\Elementor\Plugin' ) ) {
519
+ \Elementor\Plugin::$instance->files_manager->clear_cache();
520
+ }
521
+ }
522
+
523
+ /**
524
+ * JS Templates
525
+ *
526
+ * @since 1.0.0
527
+ *
528
+ * @return void
529
+ */
530
+ public function js_templates() {
531
+
532
+ // Loading Templates.
533
+ ?>
534
+ <script type="text/template" id="tmpl-cartflows-step-loading">
535
+ <div class="template-message-block cartflows-step-loading">
536
+ <h2>
537
+ <span class="spinner"></span>
538
+ <?php esc_html_e( 'Loading Steps', 'cartflows' ); ?>
539
+ </h2>
540
+ <p class="description"><?php esc_html_e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
541
+ </div>
542
+ </script>
543
+
544
+ <?php
545
+ // Search Templates.
546
+ ?>
547
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
548
+ <div class="template-message-block cartflows-searching-templates">
549
+ <h2>
550
+ <span class="spinner"></span>
551
+ <?php esc_html_e( 'Searching Template..', 'cartflows' ); ?>
552
+ </h2>
553
+ <p class="description"><?php esc_html_e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
554
+ </div>
555
+ </script>
556
+
557
+ <?php
558
+ // CartFlows Importing Template.
559
+ ?>
560
+ <script type="text/template" id="tmpl-cartflows-step-importing">
561
+ <div class="template-message-block cartflows-step-importing">
562
+ <h2><span class="spinner"></span> <?php esc_html_e( 'Importing..', 'cartflows' ); ?></h2>
563
+ </div>
564
+ </script>
565
+
566
+ <?php
567
+ // CartFlows Imported.
568
+ ?>
569
+ <script type="text/template" id="tmpl-cartflows-step-imported">
570
+ <div class="template-message-block cartflows-step-imported">
571
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
572
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
573
+ </script>
574
+
575
+ <?php
576
+ // No templates.
577
+ ?>
578
+ <script type="text/template" id="tmpl-cartflows-no-steps">
579
+ <div class="cartflows-no-steps">
580
+ <div class="template-message-block">
581
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
582
+ <p class="description"></p>
583
+ </div>
584
+ </div>
585
+ </script>
586
+
587
+ <?php
588
+ // No templates.
589
+ ?>
590
+ <script type="text/template" id="tmpl-cartflows-no-flows">
591
+ <div class="cartflows-no-flows">
592
+ <div class="template-message-block">
593
+ <h2><?php esc_html_e( 'Coming Soon!', 'cartflows' ); ?></h2>
594
+ <p class="description"></p>
595
+ </div>
596
+ </div>
597
+ </script>
598
+
599
+ <?php
600
+ // Error handling.
601
+ ?>
602
+ <script type="text/template" id="tmpl-templator-error">
603
+ <div class="notice notice-error"><p>{{ data }}</p></div>
604
+ </script>
605
+
606
+ <?php
607
+ // Redirect to Elementor.
608
+ ?>
609
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
610
+ <div class="template-message-block templator-redirect-to-elementor">
611
+ <h2><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Imported', 'cartflows' ); ?></h2>
612
+ <p class="description"><?php esc_html_e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php esc_html_e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
613
+ </script>
614
+
615
+ <?php
616
+ /**
617
+ * Responsive Buttons
618
+ */
619
+ ?>
620
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
621
+ <span class="responsive-view">
622
+ <span class="actions">
623
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
624
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
625
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
626
+ </span>
627
+ </span>
628
+ </script>
629
+
630
+ <?php
631
+ // Templates data.
632
+ ?>
633
+ <script type="text/template" id="tmpl-cartflows-flows-list">
634
+
635
+ <# console.log( data.items.length ) #>
636
+ <# console.log( data.items ) #>
637
+ <# if ( data.items.length ) { #>
638
+ <# for ( key in data.items ) { #>
639
+ <#
640
+ var flow_steps = [];
641
+ if( data.items[ key ].flow_steps ) {
642
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
643
+ return value['id'];
644
+ });
645
+ }
646
+ #>
647
+ <div class="inner">
648
+ <div class="template">
649
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
650
+ <div class="template-screenshot">
651
+ <# if( data.items[ key ].featured_image_url ) { #>
652
+ <img src="{{ data.items[ key ].featured_image_url }}" />
653
+ <# } else { #>
654
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
655
+ <# } #>
656
+ </div>
657
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
658
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
659
+ <# } #>
660
+ <# if( data.items[ key ].woo_required ) { #>
661
+ <div class="notice notice-info" style="width: auto;">
662
+ <p class="wcf-learn-how">
663
+ Install/Activate WooCommerce to use this template.
664
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
665
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
666
+ <i class="dashicons dashicons-external"></i>
667
+ </a>
668
+ </p>
669
+ </div>
670
+ <# } else { #>
671
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>flow={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
672
+ <# } #>
673
+
674
+ </span>
675
+ <div class="template-id-container">
676
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
677
+ <div class="template-actions">
678
+
679
+ <#
680
+ if( data.items[ key ].page_builder.slug ) {
681
+ required_plugin_group = data.items[ key ].page_builder.slug;
682
+ } else {
683
+ required_plugin_group = '';
684
+ }
685
+
686
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
687
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
688
+ } else {
689
+ import_btn_title = 'Import';
690
+ } #>
691
+
692
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
693
+ <# if( ! data.items[ key ].woo_required ) { #>
694
+ <a data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
695
+ <# } else { #>
696
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
697
+ <# } #>
698
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
699
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
700
+ <# } else { #>
701
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
702
+ <# } #>
703
+ </div>
704
+ </div>
705
+ </div>
706
+ </div>
707
+ <# } #>
708
+ <# } #>
709
+ </script>
710
+
711
+ <?php
712
+ // Empty Step.
713
+ ?>
714
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
715
+ <div class="inner">
716
+ <div class="template">
717
+ <span class="thumbnail site-preview cartflows-flow-preview">
718
+ <div class="template-screenshot">
719
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
720
+ </div>
721
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
722
+ </span>
723
+ <div class="template-id-container">
724
+ <h3 class="template-name"> Blank </h3>
725
+ <div class="template-actions">
726
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create', 'cartflows' ); ?></a>
727
+ </div>
728
+ </div>
729
+ </div>
730
+ </div>
731
+ </script>
732
+
733
+ <?php
734
+ // Templates data.
735
+ ?>
736
+ <script type="text/template" id="tmpl-cartflows-steps-list">
737
+ <# if ( data.items.length ) { #>
738
+ <# for ( key in data.items ) { #>
739
+ <#
740
+ var flow_steps = [];
741
+ if( data.items[ key ].flow_steps ) {
742
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
743
+ return value['id'];
744
+ });
745
+ }
746
+ #>
747
+ <div class="inner">
748
+ <div class="template">
749
+ <span class="thumbnail site-preview cartflows-preview-flow-steps" data-flow-steps="{{ JSON.stringify( data.items[ key ].flow_steps ) }}" data-title="{{ data.items[ key ].title.rendered }}">
750
+ <div class="template-screenshot">
751
+ <# if( data.items[ key ].featured_image_url ) { #>
752
+ <img src="{{ data.items[ key ].featured_image_url }}" />
753
+ <# } else { #>
754
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
755
+ <# } #>
756
+ </div>
757
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
758
+
759
+ <# if( data.items[ key ].woo_required ) { #>
760
+ <div class="notice notice-info" style="width: auto;">
761
+ <p class="wcf-learn-how">
762
+ Install/Activate WooCommerce to use this template.
763
+ <a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank">
764
+ <strong><?php esc_html_e( 'Learn How', 'cartflows' ); ?></strong>
765
+ <i class="dashicons dashicons-external"></i>
766
+ </a>
767
+ </p>
768
+ </div>
769
+ <# } else { #>
770
+ <a href="<?php echo CARTFLOWS_TEMPLATES_URL . 'preview/?'; ?>step={{ data.items[ key ].id }}&title={{{ data.items[ key ].title.rendered }}}" class="preview" target="_blank">Preview <i class="dashicons dashicons-external"></i></a>
771
+ <# } #>
772
+
773
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
774
+ <span class="wcf-flow-type pro"><?php esc_html_e( 'Pro', 'cartflows' ); ?></span>
775
+ <# } #>
776
+ </span>
777
+ <div class="template-id-container">
778
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
779
+ <div class="template-actions">
780
+
781
+ <#
782
+
783
+ var step_slug = data.items[ key ].step_type.slug || '';
784
+ var step_title = data.items[ key ].step_type.name || '';
785
+ var import_btn_title = 'Import';
786
+
787
+ var required_plugin_group = '';
788
+ if( data.items[ key ].page_builder ) {
789
+ required_plugin_group = data.items[ key ].page_builder.slug;
790
+
791
+ if( data.items[ key ].page_builder.slug && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug] && CartFlowsImportVars.required_plugins[data.items[ key ].page_builder.slug].button_title ) {
792
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
793
+ }
794
+ }
795
+ #>
796
+
797
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
798
+
799
+ <# if( ! data.items[ key ].woo_required ) { #>
800
+ <a data-slug="{{step_slug}}" data-title="{{step_title}}" data-flow-steps="{{ flow_steps }}" data-required-plugin-group="{{required_plugin_group}}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}">{{ import_btn_title }}</a>
801
+ <# } else { #>
802
+ <a href='#' class='wcf-activate-wc button-primary'>Install & activate Woo</a>
803
+ <# } #>
804
+
805
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
806
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php esc_html_e( 'Activate License', 'cartflows' ); ?></a>
807
+ <# } else { #>
808
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php esc_html_e( 'Get Pro', 'cartflows' ); ?></a>
809
+ <# } #>
810
+ </div>
811
+ </div>
812
+ </div>
813
+ </div>
814
+ <# } #>
815
+ <# } #>
816
+ </script>
817
+
818
+ <?php
819
+ /**
820
+ * TMPL - Website Unreachable
821
+ */
822
+ ?>
823
+ <script type="text/template" id="tmpl-cartflows-website-unreachable">
824
+ <div class="postbox cartflows-website-unreachable">
825
+ <h2><?php esc_html_e( 'Under Maintenance..', 'cartflows' ); ?></h2>
826
+ <p><?php esc_html_e( 'If you are seeing this message, most likely our servers are under routine maintenance and we will be back shortly.', 'cartflows' ); ?></p>
827
+ <p><?php esc_html_e( 'In rare case, it is possible your website is having trouble connecting with ours. If you need help, please feel free to get in touch with us from our website..', 'cartflows' ); ?></p>
828
+ </div>
829
+ </script>
830
+
831
+ <?php
832
+ /**
833
+ * TMPL - Filters
834
+ */
835
+ ?>
836
+ <script type="text/template" id="tmpl-cartflows-page-builder-notice">
837
+ <?php
838
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
839
+ $page_builder = Cartflows_Helper::get_required_plugins_for_page_builder( Cartflows_Helper::get_common_setting( 'default_page_builder' ) );
840
+ $title = $page_builder['title'];
841
+
842
+ $plugin_string = '<a href="#" data-slug="' . esc_html( $default_page_builder ) . '" class="wcf-install-plugin">Please click here and activate ' . esc_html( $title ) . '</a>';
843
+ $theme_status = '';
844
+ if ( 'divi' === $default_page_builder ) {
845
+
846
+ $theme_status = $page_builder['theme-status'];
847
+ $plugin_status = $page_builder['plugin-status'];
848
+
849
+ if ( 'deactivate' === $theme_status || 'install' === $plugin_status ) {
850
+ $plugin_string = 'Please activate ' . esc_html( $title );
851
+ } elseif ( ( 'deactivate' === $theme_status || 'not-installed' === $theme_status ) && 'install' === $plugin_status ) {
852
+ $plugin_string = 'Please install and activate ' . esc_html( $title );
853
+ }
854
+ }
855
+ ?>
856
+ <div class="wcf-page-builder-message">
857
+ <p><?php /* translators: %s: Plugin string */ printf( __( '%1$s to see CartFlows templates. If you prefer another page builder tool, you can <a href="%2$s" target="blank">select it here</a>.', 'cartflows' ), $plugin_string, admin_url( 'admin.php?page=' . CARTFLOWS_SETTINGS . '&action=common-settings#form-field-wcf_default_page_builder' ) ); ?></p>
858
+ <p>If your preferred page builder is not available, feel free to <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own</a> pages using page builder of your choice as CartFlows works with all major page builders.</p>
859
+ <p>We plan to add design templates made with more page builder shortly!</p>
860
+ </div>
861
+ </script>
862
+
863
+ <?php
864
+ /**
865
+ * TMPL - Filters
866
+ */
867
+ ?>
868
+ <script type="text/template" id="tmpl-cartflows-term-filters-dropdown">
869
+ <# if ( data ) { #>
870
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
871
+ <# if ( data.args.show_all ) { #>
872
+ <option value="all"> <?php esc_html_e( 'All', 'cartflows' ); ?> </option>
873
+ <# } #>
874
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
875
+ <option value=""> <?php esc_html_e( 'Select Step Type', 'cartflows' ); ?> </option>
876
+ <# } #>
877
+ <# var step_slug_data = []; #>
878
+ <# for ( key in data.items ) { #>
879
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
880
+
881
+ <# step_slug_data.push( data.items[ key ].slug ); #>
882
+
883
+ <# } #>
884
+ <# if( step_slug_data.indexOf("optin") === -1){ #>
885
+ <option value='0' data-group='0' class="Optin (Woo)" data-slug="optin" data-title="Optin (Woo)">Optin (Woo)</option>
886
+ <# } #>
887
+ </select>
888
+ <# } #>
889
+ </script>
890
+
891
+ <script type="text/template" id="tmpl-cartflows-term-filters">
892
+
893
+ <# if ( data ) { #>
894
+
895
+ <?php /* <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #> */ ?>
896
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
897
+
898
+ <# if ( data.args.show_all ) { #>
899
+ <li>
900
+ <a href="#" data-group="all"> All </a>
901
+ </li>
902
+ <# } #>
903
+
904
+ <# for ( key in data.items ) { #>
905
+ <li>
906
+ <a href="#" data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</a>
907
+ </li>
908
+ <# } #>
909
+
910
+ </ul>
911
+
912
+ <?php
913
+
914
+ /**
915
+ <# } else { #>
916
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
917
+
918
+ <# if ( data.args.show_all ) { #>
919
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
920
+ <# } #>
921
+
922
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
923
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
924
+ <# } #>
925
+
926
+ <# for ( key in data.items ) { #>
927
+ <option value='{{ data.items[ key ].id }}' data-group='{{ data.items[ key ].id }}' class="{{ data.items[ key ].name }}" data-slug="{{ data.items[ key ].slug }}" data-title="{{ data.items[ key ].name }}">{{ data.items[ key ].name }}</option>
928
+ <# } #>
929
+
930
+ </select>
931
+ */
932
+ ?>
933
+
934
+ <?php /* <# } #> */ ?>
935
+
936
+ <# } #>
937
+ </script>
938
+
939
+ <?php
940
+ // Step Type.
941
+ ?>
942
+ <script type="text/template" id="tmpl-cartflows-step-types">
943
+ <ul class="wcf-tab nav-tabs">
944
+ <# if( data.items_count ) { #>
945
+ <# for( key in data.items ) { #>
946
+ <# console.log( data.items[ key ].id ) #>
947
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
948
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
949
+ </li>
950
+ <# } #>
951
+ <# } #>
952
+ </ul>
953
+ </script>
954
+
955
+ <?php
956
+ // Add to library button.
957
+ ?>
958
+ <script type="text/template" id="tmpl-templator-add-to-library">
959
+ <a class="templator-add-to-library page-title-action cartflows-load-steps-library"><i class="dashicons dashicons-cloud"></i><?php esc_attr_e( 'Import from Cloud', 'cartflows' ); ?></a>
960
+ </script>
961
+ <?php
962
+ }
963
+
964
+ /**
965
+ * Enqueue scripts
966
+ *
967
+ * @since 1.0.0
968
+ *
969
+ * @hook admin_enqueue_scripts
970
+ * @param string $hook Current page hook.
971
+ */
972
+ public function scripts( $hook = '' ) {
973
+
974
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
975
+ return;
976
+ }
977
+
978
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
979
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
980
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
981
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
982
+
983
+ $installed_plugins = get_plugins();
984
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
985
+ $is_wc_activated = wcf()->is_woo_active ? 'yes' : 'no';
986
+
987
+ $localize_vars = array(
988
+ '_is_pro_active' => _is_cartflows_pro(),
989
+ 'is_wc_installed' => $is_wc_installed,
990
+ 'is_wc_activated' => $is_wc_activated,
991
+
992
+ // Set API headers for the CartFlows API Calls only.
993
+ 'headers' => array(),
994
+
995
+ // Flow and its rest fields.
996
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
997
+ 'flow_fields' => array(
998
+ 'id',
999
+ 'title',
1000
+ 'flow_type',
1001
+ 'page_builder',
1002
+ 'flow_steps',
1003
+ 'licence_status',
1004
+ 'featured_image_url',
1005
+ 'featured_media', // @required for field `featured_image_url`.
1006
+ ),
1007
+
1008
+ // Flow type and rest fields.
1009
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
1010
+ 'flow_type_fields' => array(
1011
+ 'id',
1012
+ 'name',
1013
+ 'slug',
1014
+ ),
1015
+
1016
+ // Flow page builder and rest fields.
1017
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
1018
+ 'flow_page_builder_fields' => array(
1019
+ 'id',
1020
+ 'name',
1021
+ 'slug',
1022
+ ),
1023
+
1024
+ // Step page builder and rest fields.
1025
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
1026
+ 'step_page_builder_fields' => array(
1027
+ 'id',
1028
+ 'name',
1029
+ 'slug',
1030
+ ),
1031
+
1032
+ // Step and its rest fields.
1033
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
1034
+ 'step_fields' => array(
1035
+ 'title',
1036
+ 'featured_image_url',
1037
+ 'featured_media', // @required for field `featured_image_url`.
1038
+ 'id',
1039
+ 'flow_type',
1040
+ 'step_type',
1041
+ 'page_builder',
1042
+ 'licence_status',
1043
+ ),
1044
+
1045
+ // Step type and its rest fields.
1046
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
1047
+ 'step_type_fields' => array(
1048
+ 'id',
1049
+ 'name',
1050
+ 'slug',
1051
+ ),
1052
+
1053
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
1054
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
1055
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
1056
+ 'site_url' => site_url(),
1057
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
1058
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
1059
+ 'admin_url' => admin_url(),
1060
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
1061
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1062
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false, //phpcs:ignore
1063
+
1064
+ 'required_plugins' => Cartflows_Helper::get_plugins_groupby_page_builders(),
1065
+
1066
+ 'default_page_builder' => Cartflows_Helper::get_common_setting( 'default_page_builder' ),
1067
+ );
1068
+
1069
+ $localize_vars['cartflows_activate_plugin_nonce'] = wp_create_nonce( 'cartflows_activate_plugin' );
1070
+
1071
+ // var_dump(Cartflows_Helper::get_common_setting( 'default_page_builder' ));
1072
+ // wp_die( );
1073
+ // Add thickbox.
1074
+ add_thickbox();
1075
+
1076
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
1077
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
1078
+ }
1079
+
1080
+ /**
1081
+ * Import.
1082
+ *
1083
+ * @since 1.0.0
1084
+ *
1085
+ * @hook wp_ajax_cartflows_import_flow_step
1086
+ * @return void
1087
+ */
1088
+ public function import_flow() {
1089
+
1090
+ if ( ! current_user_can( 'manage_options' ) ) {
1091
+ return;
1092
+ }
1093
+
1094
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
1095
+
1096
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1097
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1098
+
1099
+ wcf()->logger->import_log( '------------------------------------' );
1100
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
1101
+ wcf()->logger->import_log( '------------------------------------' );
1102
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
1103
+
1104
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1105
+
1106
+ $post_content = isset( $response['data']['content']->rendered ) ? $response['data']['content']->rendered : '';
1107
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1108
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1109
+ $post_content = $response['data']['divi_content'];
1110
+ }
1111
+ }
1112
+
1113
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1114
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1115
+ $post_content = $response['data']['divi_content'];
1116
+ }
1117
+ }
1118
+
1119
+ if ( false === $response['success'] ) {
1120
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
1121
+ wp_send_json_error( $response );
1122
+ }
1123
+
1124
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . wp_json_encode( $response ) );
1125
+
1126
+ $new_step_id = wp_insert_post(
1127
+ array(
1128
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1129
+ 'post_title' => $response['title'],
1130
+ 'post_content' => $post_content,
1131
+ 'post_status' => 'publish',
1132
+ )
1133
+ );
1134
+
1135
+ if ( is_wp_error( $new_step_id ) ) {
1136
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
1137
+ wp_send_json_error( $new_step_id );
1138
+ }
1139
+
1140
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1141
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1142
+ update_post_meta( $new_step_id, 'divi_content', $response['data']['divi_content'] );
1143
+ }
1144
+ }
1145
+
1146
+ /* Imported Step */
1147
+ update_post_meta( $new_step_id, 'cartflows_imported_step', 'yes' );
1148
+
1149
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );//phpcs:ignore
1150
+ // insert post meta.
1151
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1152
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
1153
+
1154
+ /**
1155
+ * Import & Set type.
1156
+ */
1157
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
1158
+
1159
+ $term_slug = '';
1160
+ if ( $term ) {
1161
+
1162
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1163
+ $term_exist = term_exists( $term->slug, $taxonomy );
1164
+
1165
+ if ( empty( $term_exist ) ) {
1166
+ $terms = array(
1167
+ array(
1168
+ 'name' => $term->name,
1169
+ 'slug' => $term->slug,
1170
+ ),
1171
+ );
1172
+
1173
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1174
+ wcf()->logger->import_log( '(✓) Created new term name ' . $term->name . ' | term slug ' . $term->slug );
1175
+ }
1176
+
1177
+ $current_term = term_exists( $term->slug, $taxonomy );
1178
+
1179
+ // Set type object.
1180
+ $data = get_term( $current_term['term_id'], $taxonomy );
1181
+ $term_slug = $data->slug;
1182
+ $term_name = $data->name;
1183
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1184
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
1185
+
1186
+ // Set type.
1187
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
1188
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
1189
+ }
1190
+
1191
+ // Set flow.
1192
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1193
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1194
+
1195
+ /**
1196
+ * Update steps for the current flow.
1197
+ */
1198
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1199
+
1200
+ if ( ! is_array( $flow_steps ) ) {
1201
+ $flow_steps = array();
1202
+ }
1203
+
1204
+ $flow_steps[] = array(
1205
+ 'id' => $new_step_id,
1206
+ 'title' => $response['title'],
1207
+ 'type' => $term_slug,
1208
+ );
1209
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1210
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1211
+
1212
+ // Import Post Meta.
1213
+ self::import_post_meta( $new_step_id, $response );
1214
+
1215
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
1216
+ wcf()->logger->import_log( '------------------------------------' );
1217
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
1218
+ wcf()->logger->import_log( '------------------------------------' );
1219
+
1220
+ do_action( 'cartflows_import_complete' );
1221
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
1222
+
1223
+ // Batch Process.
1224
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
1225
+
1226
+ /**
1227
+ * End
1228
+ */
1229
+ wp_send_json_success( $new_step_id );
1230
+ }
1231
+
1232
+ /**
1233
+ * Import Step.
1234
+ *
1235
+ * @since 1.0.0
1236
+ * @hook wp_ajax_cartflows_step_import
1237
+ *
1238
+ * @return void
1239
+ */
1240
+ public function create_default_flow() {
1241
+
1242
+ if ( ! current_user_can( 'manage_options' ) ) {
1243
+ return;
1244
+ }
1245
+
1246
+ check_ajax_referer( 'cf-default-flow', 'security' );
1247
+
1248
+ // Create post object.
1249
+ $new_flow_post = array(
1250
+ 'post_content' => '',
1251
+ 'post_status' => 'publish',
1252
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1253
+ );
1254
+
1255
+ // Insert the post into the database.
1256
+ $flow_id = wp_insert_post( $new_flow_post );
1257
+
1258
+ if ( is_wp_error( $flow_id ) ) {
1259
+ wp_send_json_error( $flow_id->get_error_message() );
1260
+ }
1261
+
1262
+ $flow_steps = array();
1263
+
1264
+ if ( wcf()->is_woo_active ) {
1265
+ $steps_data = array(
1266
+ 'sales' => array(
1267
+ 'title' => __( 'Sales Landing', 'cartflows' ),
1268
+ 'type' => 'landing',
1269
+ ),
1270
+ 'order-form' => array(
1271
+ 'title' => __( 'Checkout (Woo)', 'cartflows' ),
1272
+ 'type' => 'checkout',
1273
+ ),
1274
+ 'order-confirmation' => array(
1275
+ 'title' => __( 'Thank You (Woo)', 'cartflows' ),
1276
+ 'type' => 'thankyou',
1277
+ ),
1278
+ );
1279
+
1280
+ } else {
1281
+ $steps_data = array(
1282
+ 'landing' => array(
1283
+ 'title' => __( 'Landing', 'cartflows' ),
1284
+ 'type' => 'landing',
1285
+ ),
1286
+ 'thankyou' => array(
1287
+ 'title' => __( 'Thank You', 'cartflows' ),
1288
+ 'type' => 'landing',
1289
+ ),
1290
+ );
1291
+ }
1292
+
1293
+ foreach ( $steps_data as $slug => $data ) {
1294
+
1295
+ $post_content = '';
1296
+ $step_type = trim( $data['type'] );
1297
+
1298
+ $step_id = wp_insert_post(
1299
+ array(
1300
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1301
+ 'post_title' => $data['title'],
1302
+ 'post_content' => $post_content,
1303
+ 'post_status' => 'publish',
1304
+ )
1305
+ );
1306
+
1307
+ if ( is_wp_error( $step_id ) ) {
1308
+ wp_send_json_error( $step_id->get_error_message() );
1309
+ }
1310
+
1311
+ if ( $step_id ) {
1312
+
1313
+ $flow_steps[] = array(
1314
+ 'id' => $step_id,
1315
+ 'title' => $data['title'],
1316
+ 'type' => $step_type,
1317
+ );
1318
+
1319
+ // insert post meta.
1320
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1321
+ update_post_meta( $step_id, 'wcf-step-type', $step_type );
1322
+
1323
+ wp_set_object_terms( $step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
1324
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1325
+
1326
+ update_post_meta( $step_id, '_wp_page_template', 'cartflows-default' );
1327
+ }
1328
+ }
1329
+
1330
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1331
+
1332
+ wp_send_json_success( $flow_id );
1333
+ }
1334
+
1335
+ /**
1336
+ * Create Flow
1337
+ *
1338
+ * @return void
1339
+ */
1340
+ public function create_flow() {
1341
+
1342
+ if ( ! current_user_can( 'manage_options' ) ) {
1343
+ return;
1344
+ }
1345
+
1346
+ check_ajax_referer( 'cf-create-flow', 'security' );
1347
+
1348
+ // Create post object.
1349
+ $new_flow_post = array(
1350
+ 'post_content' => '',
1351
+ 'post_status' => 'publish',
1352
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1353
+ );
1354
+
1355
+ // Insert the post into the database.
1356
+ $flow_id = wp_insert_post( $new_flow_post );
1357
+
1358
+ if ( is_wp_error( $flow_id ) ) {
1359
+ wp_send_json_error( $flow_id->get_error_message() );
1360
+ }
1361
+
1362
+ /* Imported Flow */
1363
+ update_post_meta( $flow_id, 'cartflows_imported_flow', 'yes' );
1364
+
1365
+ wp_send_json_success( $flow_id );
1366
+ }
1367
+
1368
+ /**
1369
+ * Create Step
1370
+ *
1371
+ * @return void
1372
+ */
1373
+ public function import_step() {
1374
+
1375
+ if ( ! current_user_can( 'manage_options' ) ) {
1376
+ return;
1377
+ }
1378
+
1379
+ check_ajax_referer( 'cf-step-import', 'security' );
1380
+
1381
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1382
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1383
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1384
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( wp_unslash( $_POST['step_type'] ) ) : '';
1385
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( wp_unslash( $_POST['step_custom_title'] ) ) : $step_title;
1386
+
1387
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1388
+
1389
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1390
+
1391
+ wcf()->logger->import_log( '------------------------------------' );
1392
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1393
+ wcf()->logger->import_log( '------------------------------------' );
1394
+
1395
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1396
+ /* translators: %s: template ID */
1397
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1398
+ wcf()->logger->import_log( $data );
1399
+ wp_send_json_error( $data );
1400
+ }
1401
+
1402
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1403
+
1404
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1405
+
1406
+ if ( 'divi' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1407
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1408
+
1409
+ update_post_meta( $post_id, 'divi_content', $response['data']['divi_content'] );
1410
+
1411
+ wp_update_post(
1412
+ array(
1413
+ 'ID' => $post_id,
1414
+ 'post_content' => $response['data']['divi_content'],
1415
+ )
1416
+ );
1417
+ }
1418
+ }
1419
+
1420
+ if ( 'gutenberg' === Cartflows_Helper::get_common_setting( 'default_page_builder' ) ) {
1421
+ if ( isset( $response['data']['divi_content'] ) && ! empty( $response['data']['divi_content'] ) ) {
1422
+
1423
+ wp_update_post(
1424
+ array(
1425
+ 'ID' => $post_id,
1426
+ 'post_content' => $response['data']['divi_content'],
1427
+ )
1428
+ );
1429
+ }
1430
+ }
1431
+
1432
+ /* Imported Step */
1433
+ update_post_meta( $post_id, 'cartflows_imported_step', 'yes' );
1434
+
1435
+ // Import Post Meta.
1436
+ self::import_post_meta( $post_id, $response );
1437
+
1438
+ do_action( 'cartflows_import_complete' );
1439
+
1440
+ // Batch Process.
1441
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1442
+
1443
+ wcf()->logger->import_log( '------------------------------------' );
1444
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1445
+ wcf()->logger->import_log( '------------------------------------' );
1446
+
1447
+ wp_send_json_success( $post_id );
1448
+ }
1449
+
1450
+ /**
1451
+ * Import Step.
1452
+ *
1453
+ * @since 1.0.0
1454
+ * @hook wp_ajax_cartflows_step_create_blank
1455
+ *
1456
+ * @return void
1457
+ */
1458
+ public function step_create_blank() {
1459
+
1460
+ if ( ! current_user_can( 'manage_options' ) ) {
1461
+ return;
1462
+ }
1463
+
1464
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1465
+
1466
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1467
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( wp_unslash( $_POST['step_type'] ) ) : '';
1468
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( wp_unslash( $_POST['step_title'] ) ) : '';
1469
+
1470
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1471
+ /* translators: %s: flow ID */
1472
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1473
+ wcf()->logger->import_log( $data );
1474
+ wp_send_json_error( $data );
1475
+ }
1476
+
1477
+ wcf()->logger->import_log( '------------------------------------' );
1478
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1479
+
1480
+ $step_type_title = str_replace( '-', ' ', $step_type );
1481
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1482
+
1483
+ $new_step_id = wp_insert_post(
1484
+ array(
1485
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1486
+ 'post_title' => $step_title,
1487
+ 'post_content' => '',
1488
+ 'post_status' => 'publish',
1489
+ )
1490
+ );
1491
+
1492
+ // insert post meta.
1493
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1494
+
1495
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1496
+ $term_exist = term_exists( $step_type_slug, $taxonomy );
1497
+
1498
+ if ( empty( $term_exist ) ) {
1499
+ $terms = array(
1500
+ array(
1501
+ 'name' => $step_type_title,
1502
+ 'slug' => $step_type_slug,
1503
+ ),
1504
+ );
1505
+
1506
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1507
+ wcf()->logger->import_log( '(✓) Created new term name ' . $step_type_title . ' | term slug ' . $step_type_slug );
1508
+ }
1509
+
1510
+ $current_term = term_exists( $step_type_slug, $taxonomy );
1511
+
1512
+ // Set type object.
1513
+ $data = get_term( $current_term['term_id'], $taxonomy );
1514
+ $step_slug = $data->slug;
1515
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1516
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1517
+
1518
+ // Set Default page Layout.
1519
+ update_post_meta( $new_step_id, '_wp_page_template', 'cartflows-default' );
1520
+
1521
+ // Set type.
1522
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1523
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1524
+
1525
+ // Set flow.
1526
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1527
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1528
+
1529
+ self::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1530
+
1531
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1532
+ wcf()->logger->import_log( '------------------------------------' );
1533
+
1534
+ wp_send_json_success( $new_step_id );
1535
+ }
1536
+
1537
+ /**
1538
+ * Import Post Meta
1539
+ *
1540
+ * @since 1.0.0
1541
+ *
1542
+ * @param integer $post_id Post ID.
1543
+ * @param array $response Post meta.
1544
+ * @return void
1545
+ */
1546
+ public static function import_post_meta( $post_id, $response ) {
1547
+
1548
+ $metadata = (array) $response['post_meta'];
1549
+
1550
+ foreach ( $metadata as $meta_key => $meta_value ) {
1551
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1552
+
1553
+ if ( $meta_value ) {
1554
+
1555
+ if ( is_serialized( $meta_value, true ) ) {
1556
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1557
+ } elseif ( is_array( $meta_value ) ) {
1558
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1559
+ } else {
1560
+ $raw_data = $meta_value;
1561
+ }
1562
+
1563
+ if ( '_elementor_data' === $meta_key ) {
1564
+ if ( is_array( $raw_data ) ) {
1565
+ $raw_data = wp_slash( wp_json_encode( $raw_data ) );
1566
+ } else {
1567
+ $raw_data = wp_slash( $raw_data );
1568
+ }
1569
+ }
1570
+ if ( '_elementor_data' !== $meta_key && '_elementor_draft' !== $meta_key && '_fl_builder_data' !== $meta_key && '_fl_builder_draft' !== $meta_key ) {
1571
+ if ( is_array( $raw_data ) ) {
1572
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . wp_json_encode( $raw_data ) );
1573
+ } else {
1574
+ if ( ! is_object( $raw_data ) ) {
1575
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1576
+ }
1577
+ }
1578
+ }
1579
+
1580
+ update_post_meta( $post_id, $meta_key, $raw_data );
1581
+ }
1582
+ }
1583
+ }
1584
+
1585
+ /**
1586
+ * Import Template for Elementor
1587
+ *
1588
+ * @since 1.0.0
1589
+ *
1590
+ * @param integer $post_id Post ID.
1591
+ * @param array $response Post meta.
1592
+ * @param array $page_build_data Page build data.
1593
+ * @return void
1594
+ */
1595
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1596
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1597
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1598
+ wcf()->logger->import_log( $data );
1599
+ wp_send_json_error( $data );
1600
+ }
1601
+
1602
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1603
+
1604
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1605
+
1606
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1607
+ $obj->import_single_template( $post_id );
1608
+
1609
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1610
+ }
1611
+
1612
+ /**
1613
+ * Supported post types
1614
+ *
1615
+ * @since 1.0.0
1616
+ *
1617
+ * @return array Supported post types.
1618
+ */
1619
+ public static function supported_post_types() {
1620
+ return apply_filters(
1621
+ 'cartflows_supported_post_types',
1622
+ array(
1623
+ CARTFLOWS_FLOW_POST_TYPE,
1624
+ )
1625
+ );
1626
+ }
1627
+
1628
+ /**
1629
+ * Check supported post type
1630
+ *
1631
+ * @since 1.0.0
1632
+ *
1633
+ * @param string $post_type Post type.
1634
+ * @return boolean Supported post type status.
1635
+ */
1636
+ public static function is_supported_post( $post_type = '' ) {
1637
+
1638
+ if ( in_array( $post_type, self::supported_post_types(), true ) ) {
1639
+ return true;
1640
+ }
1641
+
1642
+ return false;
1643
+ }
1644
+
1645
+ /**
1646
+ * Set steps to the flow
1647
+ *
1648
+ * @param integer $flow_id Flow ID.
1649
+ * @param integer $new_step_id New step ID.
1650
+ * @param string $step_title Flow Type.
1651
+ * @param string $step_slug Flow Type.
1652
+ */
1653
+ public function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1654
+ // Update steps for the current flow.
1655
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1656
+
1657
+ if ( ! is_array( $flow_steps ) ) {
1658
+ $flow_steps = array();
1659
+ }
1660
+
1661
+ $flow_steps[] = array(
1662
+ 'id' => $new_step_id,
1663
+ 'title' => $step_title,
1664
+ 'type' => $step_slug,
1665
+ );
1666
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1667
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . wp_json_encode( $flow_steps ) );
1668
+ }
1669
+
1670
+ /**
1671
+ * Localize variables in admin
1672
+ *
1673
+ * @param array $vars variables.
1674
+ */
1675
+ public function localize_vars( $vars ) {
1676
+
1677
+ $ajax_actions = array(
1678
+ 'cf_step_import',
1679
+ 'cf_load_steps',
1680
+ 'cf_create_flow',
1681
+ 'cf_default_flow',
1682
+ 'cf_step_create_blank',
1683
+ 'cf_import_flow_step',
1684
+ );
1685
+
1686
+ foreach ( $ajax_actions as $action ) {
1687
+
1688
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1689
+ }
1690
+
1691
+ return $vars;
1692
+ }
1693
+
1694
+ /**
1695
+ * Ajax action to activate plugin
1696
+ */
1697
+ public function activate_plugin() {
1698
+
1699
+ if ( ! check_ajax_referer( 'cartflows_activate_plugin', 'security', false ) ) {
1700
+ wp_send_json_error( esc_html__( 'Action failed. Invalid Security Nonce.', 'cartflows' ) );
1701
+ }
1702
+
1703
+ if ( ! current_user_can( 'activate_plugins' ) ) {
1704
+ wp_send_json_error(
1705
+ array(
1706
+ 'success' => false,
1707
+ 'message' => __( 'User have not plugin install permissions.', 'cartflows' ),
1708
+ )
1709
+ );
1710
+ }
1711
+
1712
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
1713
+
1714
+ $activate = activate_plugin( $plugin_init, '', false, true );
1715
+
1716
+ if ( is_wp_error( $activate ) ) {
1717
+ wp_send_json_error(
1718
+ array(
1719
+ 'success' => false,
1720
+ 'message' => $activate->get_error_message(),
1721
+ 'init' => $plugin_init,
1722
+ )
1723
+ );
1724
+ }
1725
+
1726
+ wp_send_json_success(
1727
+ array(
1728
+ 'success' => true,
1729
+ 'message' => __( 'Plugin Successfully Activated', 'cartflows' ),
1730
+ 'init' => $plugin_init,
1731
+ )
1732
+ );
1733
+ }
1734
+
1735
+ }
1736
+
1737
+ /**
1738
+ * Initialize class object with 'get_instance()' method
1739
+ */
1740
+ CartFlows_Importer::get_instance();
1741
+
1742
+ endif;
classes/class-cartflows-loader.php CHANGED
@@ -125,7 +125,7 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
- define( 'CARTFLOWS_VER', '1.5.12' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
@@ -253,8 +253,22 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
253
  require_once CARTFLOWS_DIR . 'classes/lib/notices/class-astra-notices.php';
254
  }
255
 
256
- /* Load BSF Analytics */
257
- require_once CARTFLOWS_DIR . 'admin/bsf-analytics/class-bsf-analytics.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
  $this->utils = Cartflows_Utils::get_instance();
260
  $this->options = Cartflows_Default_Meta::get_instance();
125
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
126
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
127
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
128
+ define( 'CARTFLOWS_VER', '1.5.13' );
129
  define( 'CARTFLOWS_SLUG', 'cartflows' );
130
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
131
 
253
  require_once CARTFLOWS_DIR . 'classes/lib/notices/class-astra-notices.php';
254
  }
255
 
256
+ if ( ! class_exists( 'BSF_Analytics_Loader' ) ) {
257
+ require_once CARTFLOWS_DIR . '/admin/bsf-analytics/class-bsf-analytics-loader.php';
258
+ }
259
+
260
+ $bsf_analytics = BSF_Analytics_Loader::get_instance();
261
+
262
+ $bsf_analytics->set_entity(
263
+ array(
264
+ 'cf' => array(
265
+ 'product_name' => 'CartFlows',
266
+ 'usage_doc_link' => 'https://my.cartflows.com/usage-tracking/',
267
+ 'path' => CARTFLOWS_DIR . 'admin/bsf-analytics',
268
+ 'author' => 'CartFlows Inc',
269
+ ),
270
+ )
271
+ );
272
 
273
  $this->utils = Cartflows_Utils::get_instance();
274
  $this->options = Cartflows_Default_Meta::get_instance();
classes/class-cartflows-meta-fields.php CHANGED
@@ -100,7 +100,7 @@ class Cartflows_Meta_Fields {
100
  }
101
 
102
  /**
103
- * Function to search products
104
  */
105
  public function json_search_products() {
106
 
@@ -108,8 +108,6 @@ class Cartflows_Meta_Fields {
108
 
109
  global $wpdb;
110
 
111
- $allowed_products_type = array( 'simple', 'variation', 'variable', 'subscription', 'variable-subscription', 'grouped' );
112
-
113
  // get search term.
114
  $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
115
 
@@ -117,54 +115,89 @@ class Cartflows_Meta_Fields {
117
  die();
118
  }
119
 
120
- // get excluded product types.
121
- if ( isset( $_GET['excluded'] ) || ! empty( $_GET['excluded'] ) ) {
122
 
123
- $excluded_types = sanitize_text_field( ( wp_unslash( $_GET['excluded'] ) ) );
 
124
 
125
- if ( ! is_array( $excluded_types ) ) {
126
- $excluded_types = explode( ',', $excluded_types );
127
- }
128
 
129
- // Sanitize the excluded types against valid product types.
130
- foreach ( $excluded_types as $index => $value ) {
131
- $excluded_types[ $index ] = strtolower( trim( $value ) );
132
- }
133
 
134
- $allowed_products_type = array_diff( $allowed_products_type, $excluded_types );
135
  }
136
 
137
- $posts = wp_cache_get( 'wcf_search_products', 'wcf_funnel_Cart' );
 
138
 
139
- if ( false === $posts ) {
140
- $posts = $wpdb->get_results( // phpcs:ignore
141
- $wpdb->prepare(
142
- "SELECT *
143
- FROM {$wpdb->prefix}posts
144
- WHERE post_type = %s
145
- AND post_title LIKE %s
146
- AND post_status = %s",
147
- 'product',
148
- $wpdb->esc_like( $term ) . '%',
149
- 'publish'
150
- )
151
- );
152
- wp_cache_set( 'wcf_search_products', $posts, 'wcf_funnel_Cart' );
153
  }
154
 
155
- $product_found = array();
 
156
 
157
- if ( $posts ) {
158
- foreach ( $posts as $post ) {
159
- $product = wc_get_product( $post->ID );
160
- $type = $product->get_type();
161
- if ( in_array( $type, $allowed_products_type, true ) ) {
162
- $product_found[ $post->ID ] = get_the_title( $post->ID ) . ' (#' . $post->ID . ')';
163
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
 
 
 
165
  }
166
 
167
- wp_send_json( $product_found );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
 
170
  /**
@@ -694,10 +727,18 @@ class Cartflows_Meta_Fields {
694
 
695
  $value = $field_data['value'];
696
  $excluded = '';
 
 
697
 
698
- if ( isset( $field_data['excluded_product_types'] ) && is_array( $field_data['excluded_product_types'] ) ) {
699
  $excluded = html_entity_decode( implode( ',', $field_data['excluded_product_types'] ), ENT_COMPAT, 'UTF-8' );
700
  }
 
 
 
 
 
 
701
 
702
  $multiple = '';
703
 
@@ -715,8 +756,10 @@ class Cartflows_Meta_Fields {
715
  name="' . $field_data['name'] . '[]"
716
  class="wcf-product-search" ' . $multiple . $allow_clear . '
717
  data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
718
- data-action="woocommerce_json_search_products_and_variations"
719
- data-excluded_product_types =" ' . $excluded . '">';
 
 
720
 
721
  if ( is_array( $value ) && ! empty( $value ) ) {
722
 
100
  }
101
 
102
  /**
103
+ * Function to search products.
104
  */
105
  public function json_search_products() {
106
 
108
 
109
  global $wpdb;
110
 
 
 
111
  // get search term.
112
  $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
113
 
115
  die();
116
  }
117
 
118
+ // CartFlows supported product types.
119
+ $supported_product_types = array( 'simple', 'variable', 'variation', 'subscription', 'variable-subscription', 'subscription_variation' );
120
 
121
+ // Allowed product types.
122
+ if ( isset( $_GET['allowed'] ) && ! empty( $_GET['allowed'] ) ) {
123
 
124
+ $allowed_product_types = sanitize_text_field( ( wp_unslash( $_GET['allowed'] ) ) );
 
 
125
 
126
+ $allowed_product_types = $this->sanitize_data_attributes( $allowed_product_types );
 
 
 
127
 
128
+ $supported_product_types = $allowed_product_types;
129
  }
130
 
131
+ // Include product types.
132
+ if ( isset( $_GET['included'] ) && ! empty( $_GET['included'] ) ) {
133
 
134
+ $include_product_types = sanitize_text_field( ( wp_unslash( $_GET['included'] ) ) );
135
+
136
+ $include_product_types = $this->sanitize_data_attributes( $include_product_types );
137
+
138
+ $supported_product_types = array_merge( $supported_product_types, $include_product_types );
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
+ // Exclude product types.
142
+ if ( isset( $_GET['excluded'] ) && ! empty( $_GET['excluded'] ) ) {
143
 
144
+ $excluded_product_types = sanitize_text_field( ( wp_unslash( $_GET['excluded'] ) ) );
145
+
146
+ $excluded_product_types = $this->sanitize_data_attributes( $excluded_product_types );
147
+
148
+ $supported_product_types = array_diff( $supported_product_types, $excluded_product_types );
149
+ }
150
+
151
+ // Get all products data.
152
+ $data = WC_Data_Store::load( 'product' );
153
+ $ids = $data->search_products( $term, '', true, false, 11 );
154
+
155
+ // Get all product objects.
156
+ $product_objects = array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_readable' );
157
+
158
+ // Remove the product objects whose product type are not in supported array.
159
+ $product_objects = array_filter(
160
+ $product_objects,
161
+ function ( $arr ) use ( $supported_product_types ) {
162
+ return $arr && is_a( $arr, 'WC_Product' ) && in_array( $arr->get_type(), $supported_product_types, true );
163
+ }
164
+ );
165
+
166
+ $products_found = array();
167
+
168
+ foreach ( $product_objects as $product_object ) {
169
+ $formatted_name = $product_object->get_formatted_name();
170
+ $managing_stock = $product_object->managing_stock();
171
+
172
+ if ( $managing_stock && ! empty( $_GET['display_stock'] ) ) {
173
+ $stock_amount = $product_object->get_stock_quantity();
174
+ /* Translators: %d stock amount */
175
+ $formatted_name .= ' &ndash; ' . sprintf( __( 'Stock: %d', 'cartflows' ), wc_format_stock_quantity_for_display( $stock_amount, $product_object ) );
176
  }
177
+
178
+ $products_found[ $product_object->get_id() ] = rawurldecode( $formatted_name );
179
+
180
  }
181
 
182
+ wp_send_json( $products_found );
183
+ }
184
+
185
+ /**
186
+ * Function to sanitize the product type data attribute.
187
+ *
188
+ * @param array $product_types product types.
189
+ */
190
+ public function sanitize_data_attributes( $product_types = array() ) {
191
+
192
+ if ( ! is_array( $product_types ) ) {
193
+ $product_types = explode( ',', $product_types );
194
+ }
195
+
196
+ // Sanitize the excluded types against valid product types.
197
+ foreach ( $product_types as $index => $value ) {
198
+ $product_types[ $index ] = strtolower( trim( $value ) );
199
+ }
200
+ return $product_types;
201
  }
202
 
203
  /**
727
 
728
  $value = $field_data['value'];
729
  $excluded = '';
730
+ $allowed = '';
731
+ $included = '';
732
 
733
+ if ( isset( $field_data['excluded_product_types'] ) && is_array( $field_data['excluded_product_types'] ) && ! empty( $field_data['excluded_product_types'] ) ) {
734
  $excluded = html_entity_decode( implode( ',', $field_data['excluded_product_types'] ), ENT_COMPAT, 'UTF-8' );
735
  }
736
+ if ( isset( $field_data['allowed_product_types'] ) && is_array( $field_data['allowed_product_types'] ) && ! empty( $field_data['allowed_product_types'] ) ) {
737
+ $allowed = html_entity_decode( implode( ',', $field_data['allowed_product_types'] ), ENT_COMPAT, 'UTF-8' );
738
+ }
739
+ if ( isset( $field_data['include_product_types'] ) && is_array( $field_data['include_product_types'] ) && ! empty( $field_data['allowed_product_types'] ) ) {
740
+ $included = html_entity_decode( implode( ',', $field_data['include_product_types'] ), ENT_COMPAT, 'UTF-8' );
741
+ }
742
 
743
  $multiple = '';
744
 
756
  name="' . $field_data['name'] . '[]"
757
  class="wcf-product-search" ' . $multiple . $allow_clear . '
758
  data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
759
+ data-action="wcf_json_search_products_and_variations"
760
+ data-excluded_product_types ="' . $excluded . '"
761
+ data-allowed_product_types ="' . $allowed . '"
762
+ data-include_product_types ="' . $included . '">';
763
 
764
  if ( is_array( $value ) && ! empty( $value ) ) {
765
 
classes/class-cartflows-tracking.php CHANGED
@@ -1,287 +1,287 @@
1
- <?php
2
- /**
3
- * Cartflows_Tracking
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Tracking {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var object instance
27
- */
28
- public static $google_analytics_settings = array();
29
-
30
- /**
31
- * Initiator
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self();
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- */
43
- public function __construct() {
44
-
45
- add_action( 'wp_head', array( $this, 'wcf_render_gtag' ) );
46
-
47
- // Set Google analytics values.
48
- $this->get_google_analytics_settings( self::$google_analytics_settings );
49
- }
50
-
51
- /**
52
- * Get ga settings.
53
- *
54
- * @param array $google_analytics_settings ga settings.
55
- */
56
- public function get_google_analytics_settings( $google_analytics_settings ) {
57
- self::$google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
58
- }
59
-
60
-
61
- /**
62
- * Render google tag framework.
63
- */
64
- public function wcf_render_gtag() {
65
- $get_tracking_code = $this->wcf_ga_id();
66
-
67
- if ( self::is_wcf_ga_tracking_on() ) {
68
- ?>
69
- <!-- Google Analytics Script By CartFlows -->
70
- <script type="text/javascript">
71
- var tracking_id = '<?php echo $get_tracking_code; ?>';
72
- </script>
73
- <!-- Global site tag (gtag.js) - Google Analytics -->
74
- <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript ?>
75
- <script async src=https://www.googletagmanager.com/gtag/js?id=<?php echo $get_tracking_code; ?>></script>
76
- <script>
77
- window.dataLayer = window.dataLayer || [];
78
- function gtag(){dataLayer.push(arguments);}
79
- gtag('js', new Date());
80
- </script>
81
-
82
- <!-- Google Analytics Script By CartFlows -->
83
- <?php
84
- if ( 'enable' === self::$google_analytics_settings['enable_google_analytics_for_site'] ) {
85
- ?>
86
- <script>
87
- gtag('config', tracking_id);
88
- </script>
89
- <?php
90
- }
91
- }
92
- }
93
-
94
- /**
95
- * Set cookies to send ga data.
96
- *
97
- * @param int $order_id order id.
98
- * @param array $offer_data offer product data.
99
- */
100
- public static function send_ga_data_if_enabled( $order_id, $offer_data = array() ) {
101
-
102
- // Stop Execution if WooCommerce is not installed & don't set the cookie.
103
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
104
- return;
105
- }
106
-
107
- if ( self::is_wcf_ga_tracking_on() && self::wcf_track_ga_purchase() ) {
108
-
109
- setcookie( 'wcf_ga_trans_data', wp_json_encode( self::get_ga_purchase_transactions_data( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
110
- }
111
- }
112
-
113
-
114
- /**
115
- * Prepare cart data for GA response.
116
- *
117
- * @param int $order_id order id.
118
- * @param array $offer_data offer product data.
119
- * @return array
120
- */
121
- public static function get_ga_purchase_transactions_data( $order_id, $offer_data ) {
122
-
123
- $response = array();
124
-
125
- // Stop Execution if WooCommerce is not installed & don't set the cookie.
126
- if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
127
- return;
128
- }
129
-
130
- $order = wc_get_order( $order_id );
131
- $cart_total = WC()->cart->get_cart_contents_total();
132
- $cart_items_count = WC()->cart->get_cart_contents_count();
133
- $items = $order->get_items();
134
- $cart_tax = $order->get_cart_tax();
135
- $response['items'] = array();
136
- $cart_contents = array();
137
-
138
- $response = array(
139
- 'transaction_id' => $order_id,
140
- 'affiliation' => get_bloginfo( 'name' ),
141
- 'value' => $order->get_total(),
142
- 'currency' => $order->get_currency(),
143
- 'tax' => $order->get_cart_tax(),
144
- 'shipping' => $order->get_shipping_total(),
145
- 'coupon' => WC()->cart->get_coupons(),
146
- );
147
- if ( empty( $offer_data ) ) {
148
- // Iterating through each WC_Order_Item_Product objects.
149
- foreach ( $items as $item => $value ) {
150
-
151
- $_product = wc_get_product( $value['product_id'] );
152
-
153
- if ( ! $_product->is_type( 'variable' ) ) {
154
- $product_data = self::get_required_data( $_product );
155
- } else {
156
- $variable_product = wc_get_product( $value['variation_id'] );
157
- $product_data = self::get_required_data( $variable_product );
158
- }
159
- array_push(
160
- $cart_contents,
161
- array(
162
- 'id' => $product_data['id'],
163
- 'name' => $product_data['name'],
164
- 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
165
- 'price' => $product_data['price'],
166
- 'quantity' => $value['quantity'],
167
- )
168
- );
169
- }
170
- } else {
171
- array_push(
172
- $cart_contents,
173
- array(
174
- 'id' => $offer_data['id'],
175
- 'name' => $offer_data['name'],
176
- 'quantity' => $offer_data['qty'],
177
- 'price' => $offer_data['price'],
178
- )
179
- );
180
- }
181
-
182
- $response['items'] = $cart_contents;
183
-
184
- // Prepare the json data to send it to google.
185
- return $response;
186
- }
187
-
188
- /**
189
- * Prepare Ecommerce data for GA response.
190
- *
191
- * @return array
192
- */
193
- public static function get_ga_items_list() {
194
-
195
- $items = WC()->cart->get_cart();
196
- $items_data = array();
197
-
198
- foreach ( $items as $item => $value ) {
199
-
200
- $_product = wc_get_product( $value['product_id'] );
201
-
202
- if ( ! $_product->is_type( 'variable' ) ) {
203
- $product_data = self::get_required_data( $_product );
204
- } else {
205
- $variable_product = wc_get_product( $value['variation_id'] );
206
- $product_data = self::get_required_data( $variable_product );
207
- }
208
-
209
- array_push(
210
- $items_data,
211
- array(
212
- 'id' => $product_data['id'],
213
- 'name' => $product_data['name'],
214
- 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
215
- 'price' => $product_data['price'],
216
- 'quantity' => $value['quantity'],
217
- )
218
- );
219
- }
220
- return $items_data;
221
- }
222
-
223
-
224
-
225
- /**
226
- * Check tracking on.
227
- */
228
- public static function is_wcf_ga_tracking_on() {
229
-
230
- $is_enabled = false;
231
-
232
- if ( 'disable' === self::$google_analytics_settings['enable_google_analytics'] ) {
233
- $is_enabled = false;
234
- } else {
235
- $is_enabled = true;
236
- }
237
-
238
- return apply_filters( 'cartflows_google_analytics_tracking_enabled', $is_enabled );
239
- }
240
-
241
-
242
-
243
- /**
244
- * Check purchase event enable.
245
- */
246
- public static function wcf_track_ga_purchase() {
247
-
248
- $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
249
- $wcf_track_ga_purchase = $google_analytics_settings['enable_purchase_event'];
250
-
251
- if ( is_array( $google_analytics_settings ) && ! empty( $google_analytics_settings ) && 'enable' === $wcf_track_ga_purchase ) {
252
- return true;
253
- }
254
-
255
- return false;
256
- }
257
-
258
- /**
259
- * Get product data.
260
- *
261
- * @param object $_product product data.
262
- */
263
- public static function get_required_data( $_product ) {
264
-
265
- $data = array(
266
- 'id' => $_product->get_id(),
267
- 'name' => $_product->get_name(),
268
- 'price' => $_product->get_price(),
269
- );
270
- return $data;
271
- }
272
-
273
- /**
274
- * Retreive google anlytics ID.
275
- */
276
- public function wcf_ga_id() {
277
-
278
- $get_ga_id = self::$google_analytics_settings['google_analytics_id'];
279
-
280
- return empty( $get_ga_id ) ? false : $get_ga_id;
281
- }
282
- }
283
-
284
- /**
285
- * Kicking this off by calling 'get_instance()' method
286
- */
287
- Cartflows_Tracking::get_instance();
1
+ <?php
2
+ /**
3
+ * Cartflows_Tracking
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Tracking {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var object instance
27
+ */
28
+ public static $google_analytics_settings = array();
29
+
30
+ /**
31
+ * Initiator
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self();
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+
45
+ add_action( 'wp_head', array( $this, 'wcf_render_gtag' ) );
46
+
47
+ // Set Google analytics values.
48
+ $this->get_google_analytics_settings( self::$google_analytics_settings );
49
+ }
50
+
51
+ /**
52
+ * Get ga settings.
53
+ *
54
+ * @param array $google_analytics_settings ga settings.
55
+ */
56
+ public function get_google_analytics_settings( $google_analytics_settings ) {
57
+ self::$google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
58
+ }
59
+
60
+
61
+ /**
62
+ * Render google tag framework.
63
+ */
64
+ public function wcf_render_gtag() {
65
+ $get_tracking_code = $this->wcf_ga_id();
66
+
67
+ if ( self::is_wcf_ga_tracking_on() ) {
68
+ ?>
69
+ <!-- Google Analytics Script By CartFlows -->
70
+ <script type="text/javascript">
71
+ var tracking_id = '<?php echo $get_tracking_code; ?>';
72
+ </script>
73
+ <!-- Global site tag (gtag.js) - Google Analytics -->
74
+ <?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript ?>
75
+ <script async src=https://www.googletagmanager.com/gtag/js?id=<?php echo $get_tracking_code; ?>></script>
76
+ <script>
77
+ window.dataLayer = window.dataLayer || [];
78
+ function gtag(){dataLayer.push(arguments);}
79
+ gtag('js', new Date());
80
+ </script>
81
+
82
+ <!-- Google Analytics Script By CartFlows -->
83
+ <?php
84
+ if ( 'enable' === self::$google_analytics_settings['enable_google_analytics_for_site'] ) {
85
+ ?>
86
+ <script>
87
+ gtag('config', tracking_id);
88
+ </script>
89
+ <?php
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Set cookies to send ga data.
96
+ *
97
+ * @param int $order_id order id.
98
+ * @param array $offer_data offer product data.
99
+ */
100
+ public static function send_ga_data_if_enabled( $order_id, $offer_data = array() ) {
101
+
102
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
103
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
104
+ return;
105
+ }
106
+
107
+ if ( self::is_wcf_ga_tracking_on() && self::wcf_track_ga_purchase() ) {
108
+
109
+ setcookie( 'wcf_ga_trans_data', wp_json_encode( self::get_ga_purchase_transactions_data( $order_id, $offer_data ) ), strtotime( '+1 year' ), '/' );
110
+ }
111
+ }
112
+
113
+
114
+ /**
115
+ * Prepare cart data for GA response.
116
+ *
117
+ * @param int $order_id order id.
118
+ * @param array $offer_data offer product data.
119
+ * @return array
120
+ */
121
+ public static function get_ga_purchase_transactions_data( $order_id, $offer_data ) {
122
+
123
+ $response = array();
124
+
125
+ // Stop Execution if WooCommerce is not installed & don't set the cookie.
126
+ if ( ! Cartflows_Loader::get_instance()->is_woo_active ) {
127
+ return;
128
+ }
129
+
130
+ $order = wc_get_order( $order_id );
131
+ $cart_total = WC()->cart->get_cart_contents_total();
132
+ $cart_items_count = WC()->cart->get_cart_contents_count();
133
+ $items = $order->get_items();
134
+ $cart_tax = $order->get_cart_tax();
135
+ $response['items'] = array();
136
+ $cart_contents = array();
137
+
138
+ $response = array(
139
+ 'transaction_id' => $order_id,
140
+ 'affiliation' => get_bloginfo( 'name' ),
141
+ 'value' => $order->get_total(),
142
+ 'currency' => $order->get_currency(),
143
+ 'tax' => $order->get_cart_tax(),
144
+ 'shipping' => $order->get_shipping_total(),
145
+ 'coupon' => WC()->cart->get_coupons(),
146
+ );
147
+ if ( empty( $offer_data ) ) {
148
+ // Iterating through each WC_Order_Item_Product objects.
149
+ foreach ( $items as $item => $value ) {
150
+
151
+ $_product = wc_get_product( $value['product_id'] );
152
+
153
+ if ( ! $_product->is_type( 'variable' ) ) {
154
+ $product_data = self::get_required_data( $_product );
155
+ } else {
156
+ $variable_product = wc_get_product( $value['variation_id'] );
157
+ $product_data = self::get_required_data( $variable_product );
158
+ }
159
+ array_push(
160
+ $cart_contents,
161
+ array(
162
+ 'id' => $product_data['id'],
163
+ 'name' => $product_data['name'],
164
+ 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
165
+ 'price' => $product_data['price'],
166
+ 'quantity' => $value['quantity'],
167
+ )
168
+ );
169
+ }
170
+ } else {
171
+ array_push(
172
+ $cart_contents,
173
+ array(
174
+ 'id' => $offer_data['id'],
175
+ 'name' => $offer_data['name'],
176
+ 'quantity' => $offer_data['qty'],
177
+ 'price' => $offer_data['price'],
178
+ )
179
+ );
180
+ }
181
+
182
+ $response['items'] = $cart_contents;
183
+
184
+ // Prepare the json data to send it to google.
185
+ return $response;
186
+ }
187
+
188
+ /**
189
+ * Prepare Ecommerce data for GA response.
190
+ *
191
+ * @return array
192
+ */
193
+ public static function get_ga_items_list() {
194
+
195
+ $items = WC()->cart->get_cart();
196
+ $items_data = array();
197
+
198
+ foreach ( $items as $item => $value ) {
199
+
200
+ $_product = wc_get_product( $value['product_id'] );
201
+
202
+ if ( ! $_product->is_type( 'variable' ) ) {
203
+ $product_data = self::get_required_data( $_product );
204
+ } else {
205
+ $variable_product = wc_get_product( $value['variation_id'] );
206
+ $product_data = self::get_required_data( $variable_product );
207
+ }
208
+
209
+ array_push(
210
+ $items_data,
211
+ array(
212
+ 'id' => $product_data['id'],
213
+ 'name' => $product_data['name'],
214
+ 'category' => wp_strip_all_tags( wc_get_product_category_list( $_product->get_id() ) ),
215
+ 'price' => $product_data['price'],
216
+ 'quantity' => $value['quantity'],
217
+ )
218
+ );
219
+ }
220
+ return $items_data;
221
+ }
222
+
223
+
224
+
225
+ /**
226
+ * Check tracking on.
227
+ */
228
+ public static function is_wcf_ga_tracking_on() {
229
+
230
+ $is_enabled = false;
231
+
232
+ if ( 'disable' === self::$google_analytics_settings['enable_google_analytics'] ) {
233
+ $is_enabled = false;
234
+ } else {
235
+ $is_enabled = true;
236
+ }
237
+
238
+ return apply_filters( 'cartflows_google_analytics_tracking_enabled', $is_enabled );
239
+ }
240
+
241
+
242
+
243
+ /**
244
+ * Check purchase event enable.
245
+ */
246
+ public static function wcf_track_ga_purchase() {
247
+
248
+ $google_analytics_settings = Cartflows_Helper::get_google_analytics_settings();
249
+ $wcf_track_ga_purchase = $google_analytics_settings['enable_purchase_event'];
250
+
251
+ if ( is_array( $google_analytics_settings ) && ! empty( $google_analytics_settings ) && 'enable' === $wcf_track_ga_purchase ) {
252
+ return true;
253
+ }
254
+
255
+ return false;
256
+ }
257
+
258
+ /**
259
+ * Get product data.
260
+ *
261
+ * @param object $_product product data.
262
+ */
263
+ public static function get_required_data( $_product ) {
264
+
265
+ $data = array(
266
+ 'id' => $_product->get_id(),
267
+ 'name' => $_product->get_name(),
268
+ 'price' => $_product->get_price(),
269
+ );
270
+ return $data;
271
+ }
272
+
273
+ /**
274
+ * Retreive google anlytics ID.
275
+ */
276
+ public function wcf_ga_id() {
277
+
278
+ $get_ga_id = self::$google_analytics_settings['google_analytics_id'];
279
+
280
+ return empty( $get_ga_id ) ? false : $get_ga_id;
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Kicking this off by calling 'get_instance()' method
286
+ */
287
+ Cartflows_Tracking::get_instance();
classes/class-cartflows-update.php CHANGED
@@ -1,146 +1,168 @@
1
- <?php
2
- /**
3
- * Update Compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- if ( ! class_exists( 'Cartflows_Update' ) ) :
9
-
10
- /**
11
- * CartFlows Update initial setup
12
- *
13
- * @since 1.0.0
14
- */
15
- class Cartflows_Update {
16
-
17
- /**
18
- * Class instance.
19
- *
20
- * @access private
21
- * @var $instance Class instance.
22
- */
23
- private static $instance;
24
-
25
- /**
26
- * Initiator
27
- */
28
- public static function get_instance() {
29
- if ( ! isset( self::$instance ) ) {
30
- self::$instance = new self();
31
- }
32
- return self::$instance;
33
- }
34
-
35
- /**
36
- * Constructor
37
- */
38
- public function __construct() {
39
- add_action( 'admin_init', array( $this, 'init' ) );
40
- }
41
-
42
- /**
43
- * Init
44
- *
45
- * @since 1.0.0
46
- * @return void
47
- */
48
- public function init() {
49
-
50
- do_action( 'cartflows_update_before' );
51
-
52
- // Get auto saved version number.
53
- $saved_version = get_option( 'cartflows-version', false );
54
-
55
- // Update auto saved version number.
56
- if ( ! $saved_version ) {
57
- update_option( 'cartflows-version', CARTFLOWS_VER );
58
- return;
59
- }
60
-
61
- // If equals then return.
62
- if ( version_compare( $saved_version, CARTFLOWS_VER, '=' ) ) {
63
- return;
64
- }
65
-
66
- $this->logger_files();
67
-
68
- if ( version_compare( $saved_version, '1.1.22', '<' ) ) {
69
- update_option( 'wcf_setup_skipped', true );
70
- }
71
-
72
- if ( version_compare( $saved_version, '1.2.0', '<' ) ) {
73
-
74
- $this->changed_wp_templates();
75
- }
76
-
77
- // Update auto saved version number.
78
- update_option( 'cartflows-version', CARTFLOWS_VER );
79
-
80
- do_action( 'cartflows_update_after' );
81
- }
82
-
83
-
84
- /**
85
- * Loading logger files.
86
- *
87
- * @since 1.0.0
88
- * @return void
89
- */
90
- public function logger_files() {
91
-
92
- if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
93
-
94
- $upload_dir = wp_upload_dir( null, false );
95
-
96
- define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
97
- }
98
-
99
- wcf()->create_files();
100
- }
101
-
102
- /**
103
- * Init
104
- *
105
- * @since 1.0.0
106
- * @return void
107
- */
108
- public function changed_wp_templates() {
109
-
110
- global $wpdb;
111
-
112
- $query_results = $wpdb->get_results(
113
- $wpdb->prepare(
114
- "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )
115
- where {$wpdb->posts}.post_type = %s AND {$wpdb->postmeta}.meta_key = %s AND {$wpdb->postmeta}.meta_value != %s AND {$wpdb->postmeta}.meta_value != %s",
116
- 'cartflows_step',
117
- '_wp_page_template',
118
- 'cartflows-canvas',
119
- 'cartflows-default'
120
- )
121
- ); // db call ok; no-cache ok.
122
-
123
- if ( is_array( $query_results ) && ! empty( $query_results ) ) {
124
-
125
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-change-template-batch.php';
126
-
127
- wcf()->logger->log( '(✓) Update Templates BATCH Started!' );
128
-
129
- $change_template_batch = new Cartflows_Change_Template_Batch();
130
-
131
- foreach ( $query_results as $query_result ) {
132
-
133
- wcf()->logger->log( '(✓) POST ID ' . $query_result->ID );
134
- $change_template_batch->push_to_queue( $query_result->ID );
135
- }
136
-
137
- $change_template_batch->save()->dispatch();
138
- }
139
- }
140
- }
141
- /**
142
- * Kicking this off by calling 'get_instance()' method
143
- */
144
- Cartflows_Update::get_instance();
145
-
146
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Update Compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ if ( ! class_exists( 'Cartflows_Update' ) ) :
9
+
10
+ /**
11
+ * CartFlows Update initial setup
12
+ *
13
+ * @since 1.0.0
14
+ */
15
+ class Cartflows_Update {
16
+
17
+ /**
18
+ * Class instance.
19
+ *
20
+ * @access private
21
+ * @var $instance Class instance.
22
+ */
23
+ private static $instance;
24
+
25
+ /**
26
+ * Initiator
27
+ */
28
+ public static function get_instance() {
29
+ if ( ! isset( self::$instance ) ) {
30
+ self::$instance = new self();
31
+ }
32
+ return self::$instance;
33
+ }
34
+
35
+ /**
36
+ * Constructor
37
+ */
38
+ public function __construct() {
39
+ add_action( 'admin_init', array( $this, 'init' ) );
40
+ }
41
+
42
+ /**
43
+ * Init
44
+ *
45
+ * @since 1.0.0
46
+ * @return void
47
+ */
48
+ public function init() {
49
+
50
+ do_action( 'cartflows_update_before' );
51
+
52
+ // Get auto saved version number.
53
+ $saved_version = get_option( 'cartflows-version', false );
54
+
55
+ // Update auto saved version number.
56
+ if ( ! $saved_version ) {
57
+ update_option( 'cartflows-version', CARTFLOWS_VER );
58
+ return;
59
+ }
60
+
61
+ // If equals then return.
62
+ if ( version_compare( $saved_version, CARTFLOWS_VER, '=' ) ) {
63
+ return;
64
+ }
65
+
66
+ $this->logger_files();
67
+
68
+ if ( version_compare( $saved_version, '1.1.22', '<' ) ) {
69
+ update_option( 'wcf_setup_skipped', true );
70
+ }
71
+
72
+ if ( version_compare( $saved_version, '1.2.0', '<' ) ) {
73
+
74
+ $this->changed_wp_templates();
75
+ }
76
+
77
+ if ( version_compare( $saved_version, '1.5.13', '<' ) ) {
78
+ $this->update_usage_tracking_option();
79
+ }
80
+
81
+ // Update auto saved version number.
82
+ update_option( 'cartflows-version', CARTFLOWS_VER );
83
+
84
+ do_action( 'cartflows_update_after' );
85
+ }
86
+
87
+
88
+ /**
89
+ * Loading logger files.
90
+ *
91
+ * @since 1.0.0
92
+ * @return void
93
+ */
94
+ public function logger_files() {
95
+
96
+ if ( ! defined( 'CARTFLOWS_LOG_DIR' ) ) {
97
+
98
+ $upload_dir = wp_upload_dir( null, false );
99
+
100
+ define( 'CARTFLOWS_LOG_DIR', $upload_dir['basedir'] . '/cartflows-logs/' );
101
+ }
102
+
103
+ wcf()->create_files();
104
+ }
105
+
106
+ /**
107
+ * Update usage tracking option.
108
+ *
109
+ * @since 1.0.0
110
+ * @return void
111
+ */
112
+ public function update_usage_tracking_option() {
113
+
114
+ $bsf_usage_tracking = get_site_option( 'bsf_analytics_optin' );
115
+
116
+ $cf_usage_tracking = get_site_option( 'cf_analytics_optin' );
117
+
118
+ if ( isset( $bsf_usage_tracking ) && 'yes' === $bsf_usage_tracking && false === $cf_usage_tracking ) {
119
+ update_site_option( 'cf_analytics_optin', 'yes' );
120
+ }
121
+
122
+ }
123
+
124
+ /**
125
+ * Init
126
+ *
127
+ * @since 1.0.0
128
+ * @return void
129
+ */
130
+ public function changed_wp_templates() {
131
+
132
+ global $wpdb;
133
+
134
+ $query_results = $wpdb->get_results(
135
+ $wpdb->prepare(
136
+ "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )
137
+ where {$wpdb->posts}.post_type = %s AND {$wpdb->postmeta}.meta_key = %s AND {$wpdb->postmeta}.meta_value != %s AND {$wpdb->postmeta}.meta_value != %s",
138
+ 'cartflows_step',
139
+ '_wp_page_template',
140
+ 'cartflows-canvas',
141
+ 'cartflows-default'
142
+ )
143
+ ); // db call ok; no-cache ok.
144
+
145
+ if ( is_array( $query_results ) && ! empty( $query_results ) ) {
146
+
147
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-change-template-batch.php';
148
+
149
+ wcf()->logger->log( '(✓) Update Templates BATCH Started!' );
150
+
151
+ $change_template_batch = new Cartflows_Change_Template_Batch();
152
+
153
+ foreach ( $query_results as $query_result ) {
154
+
155
+ wcf()->logger->log( '(✓) POST ID ' . $query_result->ID );
156
+ $change_template_batch->push_to_queue( $query_result->ID );
157
+ }
158
+
159
+ $change_template_batch->save()->dispatch();
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * Kicking this off by calling 'get_instance()' method
165
+ */
166
+ Cartflows_Update::get_instance();
167
+
168
+ endif;
classes/class-cartflows-utils.php CHANGED
@@ -1,591 +1,591 @@
1
- <?php
2
- /**
3
- * Utils.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Utils.
14
- */
15
- class Cartflows_Utils {
16
-
17
- /**
18
- * Member Variable
19
- *
20
- * @var instance
21
- */
22
- private static $instance;
23
-
24
- /**
25
- * Member Variable
26
- *
27
- * @var checkout_products
28
- */
29
- public $checkout_products = array();
30
-
31
-
32
- /**
33
- * Initiator
34
- */
35
- public static function get_instance() {
36
- if ( ! isset( self::$instance ) ) {
37
- self::$instance = new self();
38
- }
39
- return self::$instance;
40
- }
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct() {
46
- }
47
-
48
- /**
49
- * Get current post type
50
- *
51
- * @param string $post_type post type.
52
- * @return string
53
- */
54
- public function current_post_type( $post_type = '' ) {
55
-
56
- if ( '' === $post_type ) {
57
- $post_type = get_post_type();
58
- }
59
-
60
- return $post_type;
61
- }
62
-
63
- /**
64
- * Check if post type is of step.
65
- *
66
- * @param string $post_type post type.
67
- * @return bool
68
- */
69
- public function is_step_post_type( $post_type = '' ) {
70
-
71
- if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
-
73
- return true;
74
- }
75
-
76
- return false;
77
- }
78
-
79
- /**
80
- * Check if post type is of flow.
81
- *
82
- * @param string $post_type post type.
83
- * @return bool
84
- */
85
- public function is_flow_post_type( $post_type = '' ) {
86
-
87
- if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
-
89
- return true;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Get post type of step.
97
- *
98
- * @return string
99
- */
100
- public function get_step_post_type() {
101
-
102
- return CARTFLOWS_STEP_POST_TYPE;
103
- }
104
-
105
- /**
106
- * Get post type of flow.
107
- *
108
- * @return string
109
- */
110
- public function get_flow_post_type() {
111
-
112
- return CARTFLOWS_FLOW_POST_TYPE;
113
- }
114
-
115
- /**
116
- * Get flow id
117
- *
118
- * @return int
119
- */
120
- public function get_flow_id() {
121
-
122
- global $post;
123
-
124
- return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
- }
126
-
127
- /**
128
- * Get flow id by step
129
- *
130
- * @param int $step_id step ID.
131
- * @return int
132
- */
133
- public function get_flow_id_from_step_id( $step_id ) {
134
-
135
- return get_post_meta( $step_id, 'wcf-flow-id', true );
136
- }
137
-
138
- /**
139
- * Get flow steps by id
140
- *
141
- * @param int $flow_id flow ID.
142
- * @return int
143
- */
144
- public function get_flow_steps( $flow_id ) {
145
-
146
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
-
148
- if ( is_array( $steps ) && ! empty( $steps ) ) {
149
- return $steps;
150
- }
151
-
152
- return false;
153
- }
154
-
155
- /**
156
- * Get template type of step
157
- *
158
- * @param int $step_id step ID.
159
- * @return int
160
- */
161
- public function get_step_type( $step_id ) {
162
-
163
- return get_post_meta( $step_id, 'wcf-step-type', true );
164
- }
165
-
166
- /**
167
- * Get next id for step
168
- *
169
- * @param int $flow_id flow ID.
170
- * @param int $step_id step ID.
171
- * @return bool
172
- */
173
- public function get_next_step_id( $flow_id, $step_id ) {
174
-
175
- $steps = $this->get_flow_steps( $flow_id );
176
- $step_id = intval( $step_id );
177
-
178
- if ( ! $steps ) {
179
- return false;
180
- }
181
-
182
- foreach ( $steps as $i => $step ) {
183
-
184
- if ( intval( $step['id'] ) === $step_id ) {
185
-
186
- $next_i = $i + 1;
187
-
188
- if ( isset( $steps[ $next_i ] ) ) {
189
-
190
- $navigation = $steps[ $next_i ];
191
-
192
- return intval( $navigation['id'] );
193
- }
194
-
195
- break;
196
- }
197
- }
198
-
199
- return false;
200
- }
201
-
202
- /**
203
- * Get next id for step
204
- *
205
- * @param int $order_id order ID.
206
- * @return int
207
- */
208
- public function get_flow_id_from_order( $order_id ) {
209
-
210
- $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
-
212
- return intval( $flow_id );
213
- }
214
-
215
- /**
216
- * Get checkout id for order
217
- *
218
- * @param int $order_id order ID.
219
- * @return int
220
- */
221
- public function get_checkout_id_from_order( $order_id ) {
222
-
223
- $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
-
225
- return intval( $checkout_id );
226
- }
227
-
228
- /**
229
- * We are using this function mostly in ajax on checkout page
230
- *
231
- * @return bool
232
- */
233
- public function get_checkout_id_from_post_data() {
234
-
235
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
-
237
- $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
-
239
- return intval( $checkout_id );
240
- }
241
-
242
- return false;
243
- }
244
-
245
- /**
246
- * We are using this function mostly in ajax on checkout page
247
- *
248
- * @return bool
249
- */
250
- public function get_flow_id_from_post_data() {
251
-
252
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
-
254
- $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
-
256
- return intval( $flow_id );
257
- }
258
-
259
- return false;
260
- }
261
-
262
- /**
263
- * Get optin id for order
264
- *
265
- * @param int $order_id order ID.
266
- * @return int
267
- */
268
- public function get_optin_id_from_order( $order_id ) {
269
-
270
- $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
-
272
- return intval( $optin_id );
273
- }
274
-
275
- /**
276
- * We are using this function mostly in ajax on checkout page
277
- *
278
- * @return bool
279
- */
280
- public function get_optin_id_from_post_data() {
281
-
282
- if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
-
284
- $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
-
286
- return intval( $optin_id );
287
- }
288
-
289
- return false;
290
- }
291
-
292
- /**
293
- * Check for thank you page
294
- *
295
- * @param int $step_id step ID.
296
- * @return bool
297
- */
298
- public function check_is_thankyou_page( $step_id ) {
299
-
300
- $step_type = $this->get_step_type( $step_id );
301
-
302
- if ( 'thankyou' === $step_type ) {
303
-
304
- return true;
305
- }
306
-
307
- return false;
308
- }
309
-
310
- /**
311
- * Check for offer page
312
- *
313
- * @param int $step_id step ID.
314
- * @return bool
315
- */
316
- public function check_is_offer_page( $step_id ) {
317
-
318
- $step_type = $this->get_step_type( $step_id );
319
-
320
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
-
322
- return true;
323
- }
324
-
325
- return false;
326
- }
327
-
328
- /**
329
- * Check if loaded page requires woo.
330
- *
331
- * @return bool
332
- */
333
- public function check_is_woo_required_page() {
334
-
335
- global $post;
336
- $step_id = $post->ID;
337
- $woo_not_required_type = array( 'landing' );
338
- $step_type = $this->get_step_type( $step_id );
339
- return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
- }
341
-
342
- /**
343
- * Define constant for cache
344
- *
345
- * @return void
346
- */
347
- public function do_not_cache() {
348
-
349
- global $post;
350
-
351
- if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
- return;
353
- }
354
-
355
- wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
- wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
- wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
-
359
- nocache_headers();
360
- }
361
-
362
- /**
363
- * Get linking url
364
- *
365
- * @param array $args query args.
366
- * @return string
367
- */
368
- public function get_linking_url( $args = array() ) {
369
-
370
- $url = get_home_url();
371
-
372
- $url = add_query_arg( $args, $url );
373
-
374
- return $url;
375
- }
376
-
377
- /**
378
- * Get assets urls
379
- *
380
- * @return array
381
- * @since 1.1.6
382
- */
383
- public function get_assets_path() {
384
-
385
- $rtl = '';
386
-
387
- if ( is_rtl() ) {
388
- $rtl = '-rtl';
389
- }
390
-
391
- $file_prefix = '';
392
- $dir_name = '';
393
-
394
- $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
-
396
- if ( $is_min ) {
397
- $file_prefix = '.min';
398
- $dir_name = 'min-';
399
- }
400
-
401
- $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
- $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
-
404
- return array(
405
- 'css' => $css_gen_path,
406
- 'js' => $js_gen_path,
407
- 'file_prefix' => $file_prefix,
408
- 'rtl' => $rtl,
409
- );
410
- }
411
-
412
- /**
413
- * Get assets css url
414
- *
415
- * @param string $file file name.
416
- * @return string
417
- * @since 1.1.6
418
- */
419
- public function get_css_url( $file ) {
420
-
421
- $assets_vars = wcf()->assets_vars;
422
-
423
- $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
-
425
- return $url;
426
- }
427
-
428
- /**
429
- * Get assets js url
430
- *
431
- * @param string $file file name.
432
- * @return string
433
- * @since 1.1.6
434
- */
435
- public function get_js_url( $file ) {
436
-
437
- $assets_vars = wcf()->assets_vars;
438
-
439
- $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
-
441
- return $url;
442
- }
443
-
444
- /**
445
- * Get unique id.
446
- *
447
- * @param int $length Length.
448
- *
449
- * @return string
450
- */
451
- public function get_unique_id( $length = 8 ) {
452
-
453
- return substr( md5( microtime() ), 0, $length );
454
- }
455
-
456
- /**
457
- * Get selected checkout products and data
458
- *
459
- * @param int $checkout_id Checkout id..
460
- * @param array $saved_products Saved product.
461
- *
462
- * @return array
463
- */
464
- public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
-
466
- if ( empty( $checkout_id ) ) {
467
-
468
- global $post;
469
-
470
- $checkout_id = $post->ID;
471
- }
472
-
473
- if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
-
475
- if ( ! empty( $saved_products ) ) {
476
-
477
- $products = $saved_products;
478
- } else {
479
-
480
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
- }
482
-
483
- $verify_url_data = false;
484
- $default_add_to_cart = false;
485
- $default_ids = array();
486
- $default_add_to_cart = true;
487
-
488
- if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
- //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
- $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
- $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
- $verify_url_data = true;
493
- }
494
-
495
- if ( is_array( $products ) ) {
496
-
497
- foreach ( $products as $in => $data ) {
498
-
499
- if ( $verify_url_data ) {
500
-
501
- $default_add_to_cart = false;
502
- $sequence = $in + 1;
503
-
504
- if ( in_array( $sequence, $default_ids, true ) ) {
505
- $default_add_to_cart = true;
506
- }
507
- }
508
-
509
- $default_data = array(
510
- 'quantity' => 1,
511
- 'discount_type' => '',
512
- 'discount_value' => '',
513
- 'unique_id' => $this->get_unique_id(),
514
- 'add_to_cart' => $default_add_to_cart,
515
- );
516
-
517
- $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
- }
519
- }
520
-
521
- $this->checkout_products[ $checkout_id ] = $products;
522
- }
523
-
524
- return $this->checkout_products[ $checkout_id ];
525
- }
526
-
527
- /**
528
- * Get selected checkout products and data
529
- *
530
- * @param int $checkout_id Checkout id..
531
- * @param array $products_data Saved product.
532
- *
533
- * @return array
534
- */
535
- public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
-
537
- if ( empty( $checkout_id ) ) {
538
-
539
- global $post;
540
-
541
- $checkout_id = $post->ID;
542
- }
543
-
544
- if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
-
546
- $products = $this->checkout_products[ $checkout_id ];
547
- } else {
548
- $products = $this->get_selected_checkout_products( $checkout_id );
549
- }
550
-
551
- if ( is_array( $products ) && ! empty( $products_data ) ) {
552
-
553
- foreach ( $products as $in => $data ) {
554
-
555
- if ( isset( $products_data[ $in ] ) ) {
556
- $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
- }
558
- }
559
- }
560
-
561
- $this->checkout_products[ $checkout_id ] = $products;
562
-
563
- return $this->checkout_products[ $checkout_id ];
564
- }
565
- }
566
-
567
- /**
568
- * Get a specific property of an array without needing to check if that property exists.
569
- *
570
- * Provide a default value if you want to return a specific value if the property is not set.
571
- *
572
- * @param array $array Array from which the property's value should be retrieved.
573
- * @param string $prop Name of the property to be retrieved.
574
- * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
- *
576
- * @return null|string|mixed The value
577
- */
578
- function wcf_get_prop( $array, $prop, $default = null ) {
579
-
580
- if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
- return $default;
582
- }
583
-
584
- if ( isset( $array[ $prop ] ) ) {
585
- $value = $array[ $prop ];
586
- } else {
587
- $value = '';
588
- }
589
-
590
- return empty( $value ) && null !== $default ? $default : $value;
591
- }
1
+ <?php
2
+ /**
3
+ * Utils.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Utils.
14
+ */
15
+ class Cartflows_Utils {
16
+
17
+ /**
18
+ * Member Variable
19
+ *
20
+ * @var instance
21
+ */
22
+ private static $instance;
23
+
24
+ /**
25
+ * Member Variable
26
+ *
27
+ * @var checkout_products
28
+ */
29
+ public $checkout_products = array();
30
+
31
+
32
+ /**
33
+ * Initiator
34
+ */
35
+ public static function get_instance() {
36
+ if ( ! isset( self::$instance ) ) {
37
+ self::$instance = new self();
38
+ }
39
+ return self::$instance;
40
+ }
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct() {
46
+ }
47
+
48
+ /**
49
+ * Get current post type
50
+ *
51
+ * @param string $post_type post type.
52
+ * @return string
53
+ */
54
+ public function current_post_type( $post_type = '' ) {
55
+
56
+ if ( '' === $post_type ) {
57
+ $post_type = get_post_type();
58
+ }
59
+
60
+ return $post_type;
61
+ }
62
+
63
+ /**
64
+ * Check if post type is of step.
65
+ *
66
+ * @param string $post_type post type.
67
+ * @return bool
68
+ */
69
+ public function is_step_post_type( $post_type = '' ) {
70
+
71
+ if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
72
+
73
+ return true;
74
+ }
75
+
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * Check if post type is of flow.
81
+ *
82
+ * @param string $post_type post type.
83
+ * @return bool
84
+ */
85
+ public function is_flow_post_type( $post_type = '' ) {
86
+
87
+ if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
88
+
89
+ return true;
90
+ }
91
+
92
+ return false;
93
+ }
94
+
95
+ /**
96
+ * Get post type of step.
97
+ *
98
+ * @return string
99
+ */
100
+ public function get_step_post_type() {
101
+
102
+ return CARTFLOWS_STEP_POST_TYPE;
103
+ }
104
+
105
+ /**
106
+ * Get post type of flow.
107
+ *
108
+ * @return string
109
+ */
110
+ public function get_flow_post_type() {
111
+
112
+ return CARTFLOWS_FLOW_POST_TYPE;
113
+ }
114
+
115
+ /**
116
+ * Get flow id
117
+ *
118
+ * @return int
119
+ */
120
+ public function get_flow_id() {
121
+
122
+ global $post;
123
+
124
+ return get_post_meta( $post->ID, 'wcf-flow-id', true );
125
+ }
126
+
127
+ /**
128
+ * Get flow id by step
129
+ *
130
+ * @param int $step_id step ID.
131
+ * @return int
132
+ */
133
+ public function get_flow_id_from_step_id( $step_id ) {
134
+
135
+ return get_post_meta( $step_id, 'wcf-flow-id', true );
136
+ }
137
+
138
+ /**
139
+ * Get flow steps by id
140
+ *
141
+ * @param int $flow_id flow ID.
142
+ * @return int
143
+ */
144
+ public function get_flow_steps( $flow_id ) {
145
+
146
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
147
+
148
+ if ( is_array( $steps ) && ! empty( $steps ) ) {
149
+ return $steps;
150
+ }
151
+
152
+ return false;
153
+ }
154
+
155
+ /**
156
+ * Get template type of step
157
+ *
158
+ * @param int $step_id step ID.
159
+ * @return int
160
+ */
161
+ public function get_step_type( $step_id ) {
162
+
163
+ return get_post_meta( $step_id, 'wcf-step-type', true );
164
+ }
165
+
166
+ /**
167
+ * Get next id for step
168
+ *
169
+ * @param int $flow_id flow ID.
170
+ * @param int $step_id step ID.
171
+ * @return bool
172
+ */
173
+ public function get_next_step_id( $flow_id, $step_id ) {
174
+
175
+ $steps = $this->get_flow_steps( $flow_id );
176
+ $step_id = intval( $step_id );
177
+
178
+ if ( ! $steps ) {
179
+ return false;
180
+ }
181
+
182
+ foreach ( $steps as $i => $step ) {
183
+
184
+ if ( intval( $step['id'] ) === $step_id ) {
185
+
186
+ $next_i = $i + 1;
187
+
188
+ if ( isset( $steps[ $next_i ] ) ) {
189
+
190
+ $navigation = $steps[ $next_i ];
191
+
192
+ return intval( $navigation['id'] );
193
+ }
194
+
195
+ break;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Get next id for step
204
+ *
205
+ * @param int $order_id order ID.
206
+ * @return int
207
+ */
208
+ public function get_flow_id_from_order( $order_id ) {
209
+
210
+ $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
211
+
212
+ return intval( $flow_id );
213
+ }
214
+
215
+ /**
216
+ * Get checkout id for order
217
+ *
218
+ * @param int $order_id order ID.
219
+ * @return int
220
+ */
221
+ public function get_checkout_id_from_order( $order_id ) {
222
+
223
+ $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
224
+
225
+ return intval( $checkout_id );
226
+ }
227
+
228
+ /**
229
+ * We are using this function mostly in ajax on checkout page
230
+ *
231
+ * @return bool
232
+ */
233
+ public function get_checkout_id_from_post_data() {
234
+
235
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
236
+
237
+ $checkout_id = filter_var( wp_unslash( $_POST['_wcf_checkout_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
238
+
239
+ return intval( $checkout_id );
240
+ }
241
+
242
+ return false;
243
+ }
244
+
245
+ /**
246
+ * We are using this function mostly in ajax on checkout page
247
+ *
248
+ * @return bool
249
+ */
250
+ public function get_flow_id_from_post_data() {
251
+
252
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
253
+
254
+ $flow_id = filter_var( wp_unslash( $_POST['_wcf_flow_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
255
+
256
+ return intval( $flow_id );
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Get optin id for order
264
+ *
265
+ * @param int $order_id order ID.
266
+ * @return int
267
+ */
268
+ public function get_optin_id_from_order( $order_id ) {
269
+
270
+ $optin_id = get_post_meta( $order_id, '_wcf_optin_id', true );
271
+
272
+ return intval( $optin_id );
273
+ }
274
+
275
+ /**
276
+ * We are using this function mostly in ajax on checkout page
277
+ *
278
+ * @return bool
279
+ */
280
+ public function get_optin_id_from_post_data() {
281
+
282
+ if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore
283
+
284
+ $optin_id = filter_var( wp_unslash( $_POST['_wcf_optin_id'] ), FILTER_SANITIZE_NUMBER_INT ); //phpcs:ignore
285
+
286
+ return intval( $optin_id );
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ /**
293
+ * Check for thank you page
294
+ *
295
+ * @param int $step_id step ID.
296
+ * @return bool
297
+ */
298
+ public function check_is_thankyou_page( $step_id ) {
299
+
300
+ $step_type = $this->get_step_type( $step_id );
301
+
302
+ if ( 'thankyou' === $step_type ) {
303
+
304
+ return true;
305
+ }
306
+
307
+ return false;
308
+ }
309
+
310
+ /**
311
+ * Check for offer page
312
+ *
313
+ * @param int $step_id step ID.
314
+ * @return bool
315
+ */
316
+ public function check_is_offer_page( $step_id ) {
317
+
318
+ $step_type = $this->get_step_type( $step_id );
319
+
320
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
321
+
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * Check if loaded page requires woo.
330
+ *
331
+ * @return bool
332
+ */
333
+ public function check_is_woo_required_page() {
334
+
335
+ global $post;
336
+ $step_id = $post->ID;
337
+ $woo_not_required_type = array( 'landing' );
338
+ $step_type = $this->get_step_type( $step_id );
339
+ return ( ! in_array( $step_type, $woo_not_required_type, true ) );
340
+ }
341
+
342
+ /**
343
+ * Define constant for cache
344
+ *
345
+ * @return void
346
+ */
347
+ public function do_not_cache() {
348
+
349
+ global $post;
350
+
351
+ if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
352
+ return;
353
+ }
354
+
355
+ wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
356
+ wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
357
+ wcf_maybe_define_constant( 'DONOTCACHEDB', true );
358
+
359
+ nocache_headers();
360
+ }
361
+
362
+ /**
363
+ * Get linking url
364
+ *
365
+ * @param array $args query args.
366
+ * @return string
367
+ */
368
+ public function get_linking_url( $args = array() ) {
369
+
370
+ $url = get_home_url();
371
+
372
+ $url = add_query_arg( $args, $url );
373
+
374
+ return $url;
375
+ }
376
+
377
+ /**
378
+ * Get assets urls
379
+ *
380
+ * @return array
381
+ * @since 1.1.6
382
+ */
383
+ public function get_assets_path() {
384
+
385
+ $rtl = '';
386
+
387
+ if ( is_rtl() ) {
388
+ $rtl = '-rtl';
389
+ }
390
+
391
+ $file_prefix = '';
392
+ $dir_name = '';
393
+
394
+ $is_min = apply_filters( 'cartflows_load_min_assets', false );
395
+
396
+ if ( $is_min ) {
397
+ $file_prefix = '.min';
398
+ $dir_name = 'min-';
399
+ }
400
+
401
+ $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
402
+ $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
403
+
404
+ return array(
405
+ 'css' => $css_gen_path,
406
+ 'js' => $js_gen_path,
407
+ 'file_prefix' => $file_prefix,
408
+ 'rtl' => $rtl,
409
+ );
410
+ }
411
+
412
+ /**
413
+ * Get assets css url
414
+ *
415
+ * @param string $file file name.
416
+ * @return string
417
+ * @since 1.1.6
418
+ */
419
+ public function get_css_url( $file ) {
420
+
421
+ $assets_vars = wcf()->assets_vars;
422
+
423
+ $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
424
+
425
+ return $url;
426
+ }
427
+
428
+ /**
429
+ * Get assets js url
430
+ *
431
+ * @param string $file file name.
432
+ * @return string
433
+ * @since 1.1.6
434
+ */
435
+ public function get_js_url( $file ) {
436
+
437
+ $assets_vars = wcf()->assets_vars;
438
+
439
+ $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
440
+
441
+ return $url;
442
+ }
443
+
444
+ /**
445
+ * Get unique id.
446
+ *
447
+ * @param int $length Length.
448
+ *
449
+ * @return string
450
+ */
451
+ public function get_unique_id( $length = 8 ) {
452
+
453
+ return substr( md5( microtime() ), 0, $length );
454
+ }
455
+
456
+ /**
457
+ * Get selected checkout products and data
458
+ *
459
+ * @param int $checkout_id Checkout id..
460
+ * @param array $saved_products Saved product.
461
+ *
462
+ * @return array
463
+ */
464
+ public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
465
+
466
+ if ( empty( $checkout_id ) ) {
467
+
468
+ global $post;
469
+
470
+ $checkout_id = $post->ID;
471
+ }
472
+
473
+ if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
474
+
475
+ if ( ! empty( $saved_products ) ) {
476
+
477
+ $products = $saved_products;
478
+ } else {
479
+
480
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
481
+ }
482
+
483
+ $verify_url_data = false;
484
+ $default_add_to_cart = false;
485
+ $default_ids = array();
486
+ $default_add_to_cart = true;
487
+
488
+ if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore
489
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended
490
+ $default_sequence = sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) );
491
+ $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
492
+ $verify_url_data = true;
493
+ }
494
+
495
+ if ( is_array( $products ) ) {
496
+
497
+ foreach ( $products as $in => $data ) {
498
+
499
+ if ( $verify_url_data ) {
500
+
501
+ $default_add_to_cart = false;
502
+ $sequence = $in + 1;
503
+
504
+ if ( in_array( $sequence, $default_ids, true ) ) {
505
+ $default_add_to_cart = true;
506
+ }
507
+ }
508
+
509
+ $default_data = array(
510
+ 'quantity' => 1,
511
+ 'discount_type' => '',
512
+ 'discount_value' => '',
513
+ 'unique_id' => $this->get_unique_id(),
514
+ 'add_to_cart' => $default_add_to_cart,
515
+ );
516
+
517
+ $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
518
+ }
519
+ }
520
+
521
+ $this->checkout_products[ $checkout_id ] = $products;
522
+ }
523
+
524
+ return $this->checkout_products[ $checkout_id ];
525
+ }
526
+
527
+ /**
528
+ * Get selected checkout products and data
529
+ *
530
+ * @param int $checkout_id Checkout id..
531
+ * @param array $products_data Saved product.
532
+ *
533
+ * @return array
534
+ */
535
+ public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
536
+
537
+ if ( empty( $checkout_id ) ) {
538
+
539
+ global $post;
540
+
541
+ $checkout_id = $post->ID;
542
+ }
543
+
544
+ if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
545
+
546
+ $products = $this->checkout_products[ $checkout_id ];
547
+ } else {
548
+ $products = $this->get_selected_checkout_products( $checkout_id );
549
+ }
550
+
551
+ if ( is_array( $products ) && ! empty( $products_data ) ) {
552
+
553
+ foreach ( $products as $in => $data ) {
554
+
555
+ if ( isset( $products_data[ $in ] ) ) {
556
+ $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
557
+ }
558
+ }
559
+ }
560
+
561
+ $this->checkout_products[ $checkout_id ] = $products;
562
+
563
+ return $this->checkout_products[ $checkout_id ];
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Get a specific property of an array without needing to check if that property exists.
569
+ *
570
+ * Provide a default value if you want to return a specific value if the property is not set.
571
+ *
572
+ * @param array $array Array from which the property's value should be retrieved.
573
+ * @param string $prop Name of the property to be retrieved.
574
+ * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
575
+ *
576
+ * @return null|string|mixed The value
577
+ */
578
+ function wcf_get_prop( $array, $prop, $default = null ) {
579
+
580
+ if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
581
+ return $default;
582
+ }
583
+
584
+ if ( isset( $array[ $prop ] ) ) {
585
+ $value = $array[ $prop ];
586
+ } else {
587
+ $value = '';
588
+ }
589
+
590
+ return empty( $value ) && null !== $default ? $default : $value;
591
+ }
classes/class-cartflows-wizard.php CHANGED
@@ -1,706 +1,745 @@
1
- <?php
2
- /**
3
- * CartFlows- Onboarding Wizard
4
- *
5
- * @package cartflows
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit;
10
- }
11
-
12
- if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
-
14
- /**
15
- * CartFlows_Wizard class.
16
- */
17
- class CartFlows_Wizard {
18
-
19
- /**
20
- * Hook in tabs.
21
- */
22
- public function __construct() {
23
-
24
- if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
- add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
- add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
- add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
- add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
- add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
31
- add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
32
-
33
- add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
34
-
35
- add_action( 'admin_init', array( $this, 'hide_notices' ) );
36
-
37
- }
38
- }
39
-
40
-
41
- /**
42
- * Hide a notice if the GET variable is set.
43
- */
44
- public function hide_notices() {
45
-
46
- if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
47
- return;
48
- }
49
-
50
- $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
51
- $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
52
-
53
- if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
54
- update_option( 'wcf_setup_skipped', true );
55
- }
56
- }
57
-
58
- /**
59
- * Disable the woo redirect for new setup.
60
- */
61
- public function disable_woo_setup_redirect() {
62
-
63
- delete_transient( '_wc_activation_redirect' );
64
- }
65
-
66
- /**
67
- * Show action links on the plugin screen.
68
- *
69
- * @since 1.0.0
70
- * @return void
71
- */
72
- public function show_setup_wizard() {
73
-
74
- $screen = get_current_screen();
75
- $screen_id = $screen ? $screen->id : '';
76
- $allowed_screens = array(
77
- 'cartflows_page_cartflows_settings',
78
- 'edit-cartflows_flow',
79
- 'dashboard',
80
- 'plugins',
81
- );
82
-
83
- if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
84
- return;
85
- }
86
-
87
- $status = get_option( 'wcf_setup_complete', false );
88
- $skip_setup = get_option( 'wcf_setup_skipped', false );
89
- if ( false === $status && ! $skip_setup ) { ?>
90
- <div class="notice notice-info wcf-notice">
91
- <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
92
- <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
93
- <p>
94
- <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
95
- <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
96
- </p>
97
- </div>
98
- <?php
99
- }
100
- }
101
-
102
- /**
103
- * Add admin menus/screens.
104
- */
105
- public function admin_menus() {
106
-
107
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
108
- return;
109
- }
110
-
111
- add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
112
- }
113
-
114
- /**
115
- * Show the setup wizard.
116
- */
117
- public function setup_wizard() {
118
-
119
- if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
120
- return;
121
- }
122
-
123
- $this->steps = array(
124
- 'basic-config' => array(
125
- 'name' => __( 'Welcome', 'cartflows' ),
126
- 'view' => array( $this, 'welcome_step' ),
127
- 'handler' => array( $this, 'welcome_step_save' ),
128
- ),
129
- 'page-builder' => array(
130
- 'name' => __( 'Page Builder', 'cartflows' ),
131
- 'view' => array( $this, 'page_builder_step' ),
132
- ),
133
- 'checkout' => array(
134
- 'name' => __( 'Checkout', 'cartflows' ),
135
- 'view' => array( $this, 'checkout_step' ),
136
- ),
137
- 'training' => array(
138
- 'name' => __( 'Training', 'cartflows' ),
139
- 'view' => array( $this, 'training_step' ),
140
- ),
141
- 'setup-ready' => array(
142
- 'name' => __( 'Ready!', 'cartflows' ),
143
- 'view' => array( $this, 'ready_step' ),
144
- 'handler' => '',
145
- ),
146
- );
147
-
148
- $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
149
-
150
- wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
151
- wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
152
-
153
- wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
154
-
155
- wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
156
-
157
- wp_enqueue_media();
158
-
159
- if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
160
- call_user_func( $this->steps[ $this->step ]['handler'] );
161
- }
162
-
163
- ob_start();
164
- $this->setup_wizard_header();
165
- $this->setup_wizard_steps();
166
- $this->setup_wizard_content();
167
- $this->setup_wizard_footer();
168
- exit;
169
- }
170
-
171
- /**
172
- * Get current step slug
173
- */
174
- public function get_current_step_slug() {
175
- $keys = array_keys( $this->steps );
176
- return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
177
- }
178
-
179
- /**
180
- * Get previous step link
181
- */
182
- public function get_prev_step_link() {
183
- $keys = array_keys( $this->steps );
184
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
185
- }
186
-
187
- /**
188
- * Get next step link
189
- */
190
- public function get_next_step_link() {
191
- $keys = array_keys( $this->steps );
192
- return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
193
- }
194
-
195
- /**
196
- * Get next step link
197
- */
198
- public function get_next_step_plain_link() {
199
- $keys = array_keys( $this->steps );
200
- $step_index = array_search( $this->step, $keys, true );
201
- $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
202
- $step = $keys[ $step_index ];
203
- return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
204
- }
205
-
206
- /**
207
- * Setup Wizard Header.
208
- */
209
- public function setup_wizard_header() {
210
- set_current_screen();
211
- ?>
212
- <html <?php language_attributes(); ?>>
213
- <html>
214
- <head>
215
- <meta name="viewport" content="width=device-width" />
216
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
217
- <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
218
-
219
- <script type="text/javascript">
220
- addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
221
- var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
222
- var pagenow = '';
223
- </script>
224
- <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
225
- <?php do_action( 'admin_print_styles' ); ?>
226
- <?php do_action( 'admin_head' ); ?>
227
- </head>
228
- <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
229
- <div id="cartflows-logo">
230
- <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
231
- </div>
232
- <?php
233
- }
234
-
235
- /**
236
- * Setup Wizard Footer.
237
- */
238
- public function setup_wizard_footer() {
239
-
240
- $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
241
- ?>
242
- <div class="close-button-wrapper">
243
- <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
244
- </div>
245
- </body>
246
- </html>
247
- <?php
248
- }
249
-
250
- /**
251
- * Output the steps.
252
- */
253
- public function setup_wizard_steps() {
254
-
255
- $ouput_steps = $this->steps;
256
- ?>
257
- <ol class="cartflows-setup-steps">
258
- <?php
259
- foreach ( $ouput_steps as $step_key => $step ) :
260
- $classes = '';
261
- $activated = false;
262
- if ( $step_key === $this->step ) {
263
- $classes = 'active';
264
- $activated = true;
265
- } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
266
- $classes = 'done';
267
- $activated = true;
268
- }
269
- ?>
270
- <li class="<?php echo esc_attr( $classes ); ?>">
271
- <span><?php echo esc_html( $step['name'] ); ?></span>
272
- </li>
273
- <?php endforeach; ?>
274
- </ol>
275
- <?php
276
- }
277
-
278
- /**
279
- * Output the content for the current step.
280
- */
281
- public function setup_wizard_content() {
282
- ?>
283
- <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
284
- <?php
285
-
286
- echo '<div class="cartflows-setup-content">';
287
- call_user_func( $this->steps[ $this->step ]['view'] );
288
- echo '</div>';
289
- }
290
-
291
- /**
292
- * Introduction step.
293
- */
294
- public function welcome_step() {
295
- ?>
296
- <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
297
- <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
298
- <form method="post">
299
- <div class="cartflows-setup-actions step">
300
- <div class="button-prev-wrap">
301
- </div>
302
- <div class="button-next-wrap">
303
- <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
304
- </div>
305
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
306
- </div>
307
- </form>
308
- <?php
309
- }
310
-
311
- /**
312
- * Save Locale Settings.
313
- */
314
- public function welcome_step_save() {
315
- check_admin_referer( 'cartflow-setup' );
316
-
317
- // Update site title & tagline.
318
- $redirect_url = $this->get_next_step_link();
319
-
320
- wp_safe_redirect( esc_url_raw( $redirect_url ) );
321
- exit;
322
- }
323
-
324
- /**
325
- * Locale settings
326
- */
327
- public function page_builder_step() {
328
- ?>
329
-
330
- <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
331
- <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
332
- <form method="post">
333
- <table class="cartflows-table widefat">
334
- <tr class="cartflows-row">
335
- <td class="cartflows-row-heading">
336
- <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
337
- </td>
338
- <td class="cartflows-row-content">
339
- <?php
340
- $installed_plugins = get_plugins();
341
- $plugins = array(
342
- array(
343
- 'title' => __( 'Elementor', 'cartflows' ),
344
- 'value' => 'elementor',
345
- 'data' => array(
346
- 'slug' => 'elementor',
347
- 'init' => 'elementor/elementor.php',
348
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
349
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
350
- ),
351
- ),
352
- array(
353
- 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
354
- 'value' => 'beaver-builder',
355
- 'data' => array(
356
- 'slug' => 'beaver-builder-lite-version',
357
- 'init' => 'beaver-builder-lite-version/fl-builder.php',
358
- 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
359
- 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
360
- ),
361
- ),
362
- array(
363
- 'title' => __( 'Divi', 'cartflows' ),
364
- 'value' => 'divi',
365
- 'data' => array(
366
- 'slug' => 'divi',
367
- 'init' => 'divi',
368
- 'active' => 'yes',
369
- 'install' => 'NA',
370
- ),
371
- ),
372
- array(
373
- 'title' => __( 'Gutenberg', 'cartflows' ),
374
- 'value' => 'gutenberg',
375
- 'data' => array(
376
- 'slug' => 'ultimate-addons-for-gutenberg',
377
- 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
378
- 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
379
- 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
380
- ),
381
- ),
382
- array(
383
- 'title' => __( 'Other', 'cartflows' ),
384
- 'value' => 'other',
385
- 'data' => array(
386
- 'slug' => 'other',
387
- 'init' => false,
388
- 'active' => 'yes',
389
- 'install' => 'NA',
390
- ),
391
- ),
392
- );
393
- ?>
394
- <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
395
- <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
396
- <?php
397
- foreach ( $plugins as $key => $plugin ) {
398
- echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
399
- }
400
- ?>
401
- </select>
402
- </td>
403
- </tr>
404
- </table>
405
- <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
406
- <div class="cartflows-setup-actions step">
407
- <div class="button-prev-wrap">
408
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
409
- </div>
410
- <div class="button-next-wrap">
411
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
412
- <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
413
- </div>
414
- <?php wp_nonce_field( 'cartflow-setup' ); ?>
415
- </div>
416
- </form>
417
- <?php
418
- }
419
-
420
- /**
421
- * Render checkout step.
422
- */
423
- public function checkout_step() {
424
-
425
- $installed_plugins = get_plugins();
426
- $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
427
- $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
428
- $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
429
- $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
430
- ?>
431
- <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
432
- <div class="cartflows-setup-message">
433
- <p>
434
- <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
435
- </p>
436
- <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
437
- <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
438
- </div>
439
-
440
- <div class="cartflows-setup-extra-notice">
441
-
442
- <span>
443
- <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
444
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
445
- <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
446
-
447
- </span>
448
-
449
- </div>
450
-
451
- <div class="cartflows-setup-actions step">
452
- <div class="button-prev-wrap">
453
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
454
- </div>
455
- <div class="button-next-wrap">
456
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
457
- <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
458
- </div>
459
- </div>
460
-
461
- <?php
462
- }
463
-
464
- /**
465
- * Save Locale Settings.
466
- */
467
- public function activate_wc_plugins() {
468
-
469
- check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
470
-
471
- $plugin_slug_arr = array(
472
- 'woocommerce/woocommerce.php' => true,
473
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
474
- );
475
-
476
- $activate = array(
477
- 'woocommerce/woocommerce.php' => false,
478
- 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
479
- );
480
-
481
- foreach ( $plugin_slug_arr as $slug => $do_silently ) {
482
-
483
- $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
484
- }
485
-
486
- foreach ( $activate as $slug => $data ) {
487
-
488
- if ( is_wp_error( $data ) ) {
489
- wp_send_json_error(
490
- array(
491
- 'success' => false,
492
- 'message' => $data->get_error_message(),
493
- )
494
- );
495
- }
496
- }
497
-
498
- wp_send_json_success();
499
- }
500
-
501
- /**
502
- * Save Locale Settings.
503
- */
504
- public function page_builder_step_save() {
505
-
506
- if ( ! current_user_can( 'manage_options' ) ) {
507
- return;
508
- }
509
-
510
- check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
511
-
512
- $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
513
- $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
514
- $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
515
-
516
- $do_sliently = true;
517
- if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
518
- $do_sliently = false;
519
- }
520
-
521
- $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
522
-
523
- if ( $save_option ) {
524
- $this->save_page_builder_option();
525
- }
526
-
527
- if ( is_wp_error( $activate ) ) {
528
- wp_send_json_error(
529
- array(
530
- 'success' => false,
531
- 'message' => $activate->get_error_message(),
532
- )
533
- );
534
- }
535
-
536
- wp_send_json_success(
537
- array( 'plugin' => $plugin_slug )
538
- );
539
- }
540
-
541
- /**
542
- * Save selected page builder in options database.
543
- */
544
- public function save_page_builder_option() {
545
-
546
- if ( ! current_user_can( 'manage_options' ) ) {
547
- return;
548
- }
549
-
550
- $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
551
-
552
- $wcf_settings = get_option( '_cartflows_common', array() );
553
-
554
- if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
555
- $page_builder = 'beaver-builder';
556
- }
557
-
558
- $wcf_settings['default_page_builder'] = $page_builder;
559
-
560
- update_option( '_cartflows_common', $wcf_settings );
561
-
562
- wp_send_json_success(
563
- array( 'plugin' => $page_builder )
564
- );
565
-
566
- }
567
-
568
- /**
569
- * Final step.
570
- */
571
- public function ready_step() {
572
-
573
- // Set setup wizard status to complete.
574
- update_option( 'wcf_setup_complete', true );
575
- ?>
576
- <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
577
-
578
- <div class="cartflows-setup-next-steps">
579
- <div class="cartflows-setup-next-steps-last">
580
-
581
- <p class="success">
582
- <?php
583
- esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
584
- ?>
585
- </p>
586
-
587
-
588
- <ul class="wcf-wizard-next-steps">
589
- <li class="wcf-wizard-next-step-item">
590
- <div class="wcf-wizard-next-step-description">
591
- <p class="next-step-heading">Next step</p>
592
- <h3 class="next-step-description">Create First Flow</h3>
593
- <p class="next-step-extra-info">You're ready to add flows to your website.</p>
594
- </div>
595
- <div class="wcf-wizard-next-step-action">
596
- <p class="wc-setup-actions step">
597
- <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
598
- </p>
599
- </div>
600
- </li>
601
- </ul>
602
-
603
- </div>
604
- </div>
605
- <?php
606
- }
607
-
608
- /**
609
- * Training course step.
610
- */
611
- public function training_step() {
612
- $current_user = wp_get_current_user();
613
- ?>
614
- <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
615
-
616
- <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
617
- <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
618
- <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
619
- <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
620
- <div class="mauticform-innerform">
621
- <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
622
- <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
623
- <div class="cartflows-setup-message">
624
- <p>
625
- <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
626
- <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
627
- </p>
628
- <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
629
- </div>
630
- <span class="mauticform-errormsg" style="display: none;"></span>
631
- </div>
632
- </div>
633
- </div>
634
-
635
- <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
636
- <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
637
- <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
638
- <div class="cartflows-setup-actions step">
639
- <div class="button-prev-wrap">
640
- <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
641
- </div>
642
- <div class="button-next-wrap">
643
- <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
644
- <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
645
- </div>
646
- </div>
647
- </form>
648
- </div>
649
- <?php
650
- }
651
-
652
- /**
653
- * Localize variables in admin
654
- */
655
- public function localize_vars() {
656
-
657
- $vars = array();
658
-
659
- $ajax_actions = array(
660
- 'wcf_page_builder_step_save',
661
- 'wcf_wc_plugins_activate',
662
- );
663
-
664
- foreach ( $ajax_actions as $action ) {
665
-
666
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
667
- }
668
-
669
- return $vars;
670
- }
671
-
672
- /**
673
- * Add JS script for mautic form
674
- */
675
- public function add_mautic_form_script() {
676
-
677
- if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
678
- return;
679
- }
680
- ?>
681
-
682
- <script type="text/javascript">
683
- /** This section is only needed once per page if manually copying **/
684
- if (typeof MauticSDKLoaded == 'undefined') {
685
- var MauticSDKLoaded = true;
686
- var head = document.getElementsByTagName('head')[0];
687
- var script = document.createElement('script');
688
- script.type = 'text/javascript';
689
- script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
690
- script.onload = function() {
691
- MauticSDK.onLoad();
692
- };
693
- head.appendChild(script);
694
- var MauticDomain = 'https://go.cartflows.com';
695
- var MauticLang = {
696
- 'submittingMessage': "Please wait..."
697
- };
698
- }
699
- </script>
700
- <?php
701
- }
702
- }
703
-
704
- new CartFlows_Wizard();
705
-
706
- endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows- Onboarding Wizard
4
+ *
5
+ * @package cartflows
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit;
10
+ }
11
+
12
+ if ( ! class_exists( 'CartFlows_Wizard' ) ) :
13
+
14
+ /**
15
+ * CartFlows_Wizard class.
16
+ */
17
+ class CartFlows_Wizard {
18
+
19
+ /**
20
+ * Hook in tabs.
21
+ */
22
+ public function __construct() {
23
+
24
+ if ( apply_filters( 'cartflows_enable_setup_wizard', true ) && current_user_can( 'manage_options' ) ) {
25
+ add_action( 'admin_menu', array( $this, 'admin_menus' ) );
26
+ add_action( 'admin_init', array( $this, 'setup_wizard' ) );
27
+ add_action( 'admin_notices', array( $this, 'show_setup_wizard' ) );
28
+ add_action( 'wp_ajax_page_builder_step_save', array( $this, 'page_builder_step_save' ) );
29
+ add_action( 'wp_ajax_page_builder_save_option', array( $this, 'save_page_builder_option' ) );
30
+
31
+ add_action( 'wp_ajax_usage_tracking_option', array( $this, 'save_usage_tracking_option' ) );
32
+
33
+ add_action( 'admin_head', array( $this, 'add_mautic_form_script' ) );
34
+ add_action( 'woocommerce_installed', array( $this, 'disable_woo_setup_redirect' ) );
35
+
36
+ add_action( 'wp_ajax_wcf_activate_wc_plugins', array( $this, 'activate_wc_plugins' ) );
37
+
38
+ add_action( 'admin_init', array( $this, 'hide_notices' ) );
39
+
40
+ }
41
+ }
42
+
43
+
44
+ /**
45
+ * Hide a notice if the GET variable is set.
46
+ */
47
+ public function hide_notices() {
48
+
49
+ if ( ! isset( $_GET['wcf-hide-notice'] ) ) {
50
+ return;
51
+ }
52
+
53
+ $wcf_hide_notice = filter_input( INPUT_GET, 'wcf-hide-notice', FILTER_SANITIZE_STRING );
54
+ $_wcf_notice_nonce = filter_input( INPUT_GET, '_wcf_notice_nonce', FILTER_SANITIZE_STRING );
55
+
56
+ if ( $wcf_hide_notice && $_wcf_notice_nonce && wp_verify_nonce( sanitize_text_field( wp_unslash( $_wcf_notice_nonce ) ), 'wcf_hide_notices_nonce' ) ) {
57
+ update_option( 'wcf_setup_skipped', true );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Disable the woo redirect for new setup.
63
+ */
64
+ public function disable_woo_setup_redirect() {
65
+
66
+ delete_transient( '_wc_activation_redirect' );
67
+ }
68
+
69
+ /**
70
+ * Show action links on the plugin screen.
71
+ *
72
+ * @since 1.0.0
73
+ * @return void
74
+ */
75
+ public function show_setup_wizard() {
76
+
77
+ $screen = get_current_screen();
78
+ $screen_id = $screen ? $screen->id : '';
79
+ $allowed_screens = array(
80
+ 'cartflows_page_cartflows_settings',
81
+ 'edit-cartflows_flow',
82
+ 'dashboard',
83
+ 'plugins',
84
+ );
85
+
86
+ if ( ! in_array( $screen_id, $allowed_screens, true ) ) {
87
+ return;
88
+ }
89
+
90
+ $status = get_option( 'wcf_setup_complete', false );
91
+ $skip_setup = get_option( 'wcf_setup_skipped', false );
92
+ if ( false === $status && ! $skip_setup ) { ?>
93
+ <div class="notice notice-info wcf-notice">
94
+ <p><b><?php esc_html_e( 'Thanks for installing and using CartFlows!', 'cartflows' ); ?></b></p>
95
+ <p><?php esc_html_e( 'It is easy to use the CartFlows. Please use the setup wizard to quick start setup.', 'cartflows' ); ?></p>
96
+ <p>
97
+ <a href="<?php echo esc_url( admin_url( 'index.php?page=cartflow-setup' ) ); ?>" class="button button-primary"> <?php esc_html_e( 'Start Wizard', 'cartflows' ); ?></a>
98
+ <a class="button-secondary" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcf-hide-notice', 'install' ), 'wcf_hide_notices_nonce', '_wcf_notice_nonce' ) ); ?>"><?php esc_html_e( 'Skip Setup', 'cartflows' ); ?></a>
99
+ </p>
100
+ </div>
101
+ <?php
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Add admin menus/screens.
107
+ */
108
+ public function admin_menus() {
109
+
110
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
111
+ return;
112
+ }
113
+
114
+ add_dashboard_page( '', '', 'manage_options', 'cartflow-setup', '' );
115
+ }
116
+
117
+ /**
118
+ * Show the setup wizard.
119
+ */
120
+ public function setup_wizard() {
121
+
122
+ if ( empty( $_GET['page'] ) || 'cartflow-setup' !== $_GET['page'] ) { //phpcs:ignore
123
+ return;
124
+ }
125
+
126
+ $this->steps = array(
127
+ 'basic-config' => array(
128
+ 'name' => __( 'Welcome', 'cartflows' ),
129
+ 'view' => array( $this, 'welcome_step' ),
130
+ 'handler' => array( $this, 'welcome_step_save' ),
131
+ ),
132
+ 'page-builder' => array(
133
+ 'name' => __( 'Page Builder', 'cartflows' ),
134
+ 'view' => array( $this, 'page_builder_step' ),
135
+ ),
136
+ 'checkout' => array(
137
+ 'name' => __( 'Checkout', 'cartflows' ),
138
+ 'view' => array( $this, 'checkout_step' ),
139
+ ),
140
+ 'training' => array(
141
+ 'name' => __( 'Training', 'cartflows' ),
142
+ 'view' => array( $this, 'training_step' ),
143
+ ),
144
+ 'setup-ready' => array(
145
+ 'name' => __( 'Ready!', 'cartflows' ),
146
+ 'view' => array( $this, 'ready_step' ),
147
+ 'handler' => '',
148
+ ),
149
+ );
150
+
151
+ $this->step = isset( $_GET['step'] ) ? sanitize_text_field( $_GET['step'] ) : current( array_keys( $this->steps ) ); //phpcs:ignore
152
+
153
+ wp_enqueue_style( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/css/setup-wizard.css', array( 'dashicons' ), CARTFLOWS_VER );
154
+ wp_style_add_data( 'cartflows-setup', 'rtl', 'replace' );
155
+
156
+ wp_enqueue_script( 'cartflows-setup', CARTFLOWS_URL . 'admin/assets/js/setup-wizard.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER, false );
157
+
158
+ wp_localize_script( 'cartflows-setup', 'cartflows_setup_vars', self::localize_vars() );
159
+
160
+ wp_enqueue_media();
161
+
162
+ if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { //phpcs:ignore
163
+ call_user_func( $this->steps[ $this->step ]['handler'] );
164
+ }
165
+
166
+ ob_start();
167
+ $this->setup_wizard_header();
168
+ $this->setup_wizard_steps();
169
+ $this->setup_wizard_content();
170
+ $this->setup_wizard_footer();
171
+ exit;
172
+ }
173
+
174
+ /**
175
+ * Get current step slug
176
+ */
177
+ public function get_current_step_slug() {
178
+ $keys = array_keys( $this->steps );
179
+ return $keys[ array_search( $this->step, array_keys( $this->steps ), true ) ];
180
+ }
181
+
182
+ /**
183
+ * Get previous step link
184
+ */
185
+ public function get_prev_step_link() {
186
+ $keys = array_keys( $this->steps );
187
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) - 1 ] );
188
+ }
189
+
190
+ /**
191
+ * Get next step link
192
+ */
193
+ public function get_next_step_link() {
194
+ $keys = array_keys( $this->steps );
195
+ return add_query_arg( 'step', $keys[ array_search( $this->step, array_keys( $this->steps ), true ) + 1 ] );
196
+ }
197
+
198
+ /**
199
+ * Get next step link
200
+ */
201
+ public function get_next_step_plain_link() {
202
+ $keys = array_keys( $this->steps );
203
+ $step_index = array_search( $this->step, $keys, true );
204
+ $step_index = ( count( $keys ) == $step_index + 1 ) ? $step_index : $step_index + 1;
205
+ $step = $keys[ $step_index ];
206
+ return admin_url( 'index.php?page=cartflow-setup&step=' . $step );
207
+ }
208
+
209
+ /**
210
+ * Setup Wizard Header.
211
+ */
212
+ public function setup_wizard_header() {
213
+ set_current_screen();
214
+ ?>
215
+ <html <?php language_attributes(); ?>>
216
+ <html>
217
+ <head>
218
+ <meta name="viewport" content="width=device-width" />
219
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
220
+ <title><?php esc_html_e( 'CartFlows Setup', 'cartflows' ); ?></title>
221
+
222
+ <script type="text/javascript">
223
+ addLoadEvent = function(func){if(typeof jQuery!="undefined")jQuery(document).ready(func);else if(typeof wpOnload!='function'){wpOnload=func;}else{var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}};
224
+ var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
225
+ var pagenow = '';
226
+ </script>
227
+ <?php wp_print_scripts( array( 'cartflows-setup' ) ); ?>
228
+ <?php do_action( 'admin_print_styles' ); ?>
229
+ <?php do_action( 'admin_head' ); ?>
230
+ </head>
231
+ <body class="cartflows-setup wp-core-ui cartflows-step-<?php echo esc_attr( $this->get_current_step_slug() ); ?>">
232
+ <div id="cartflows-logo">
233
+ <img height="40" class="wcf-logo" src="<?php echo CARTFLOWS_URL . 'assets/images/cartflows-logo.svg'; ?>" />
234
+ </div>
235
+ <?php
236
+ }
237
+
238
+ /**
239
+ * Setup Wizard Footer.
240
+ */
241
+ public function setup_wizard_footer() {
242
+
243
+ $admin_url = admin_url( 'admin.php?page=cartflows_settings' );
244
+ ?>
245
+ <div class="close-button-wrapper">
246
+ <a href="<?php echo esc_url( $admin_url ); ?>" class="wizard-close-link" ><?php esc_html_e( 'Exit Setup Wizard', 'cartflows' ); ?></a>
247
+ </div>
248
+ </body>
249
+ </html>
250
+ <?php
251
+ }
252
+
253
+ /**
254
+ * Output the steps.
255
+ */
256
+ public function setup_wizard_steps() {
257
+
258
+ $ouput_steps = $this->steps;
259
+ ?>
260
+ <ol class="cartflows-setup-steps">
261
+ <?php
262
+ foreach ( $ouput_steps as $step_key => $step ) :
263
+ $classes = '';
264
+ $activated = false;
265
+ if ( $step_key === $this->step ) {
266
+ $classes = 'active';
267
+ $activated = true;
268
+ } elseif ( array_search( $this->step, array_keys( $this->steps ), true ) > array_search( $step_key, array_keys( $this->steps ), true ) ) {
269
+ $classes = 'done';
270
+ $activated = true;
271
+ }
272
+ ?>
273
+ <li class="<?php echo esc_attr( $classes ); ?>">
274
+ <span><?php echo esc_html( $step['name'] ); ?></span>
275
+ </li>
276
+ <?php endforeach; ?>
277
+ </ol>
278
+ <?php
279
+ }
280
+
281
+ /**
282
+ * Output the content for the current step.
283
+ */
284
+ public function setup_wizard_content() {
285
+ ?>
286
+ <input type="hidden" class="wcf-redirect-link" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" >
287
+ <?php
288
+
289
+ echo '<div class="cartflows-setup-content">';
290
+ call_user_func( $this->steps[ $this->step ]['view'] );
291
+ echo '</div>';
292
+ }
293
+
294
+ /**
295
+ * Introduction step.
296
+ */
297
+ public function welcome_step() {
298
+ ?>
299
+ <h1><?php esc_html_e( 'Welcome to CartFlows!', 'cartflows' ); ?></h1>
300
+ <p><?php esc_html_e( 'Thank you for choosing CartFlows to get more leads, increase conversions, & maximize profits. This short setup wizard will guide you though configuring CartFlows and creating your first funnel.', 'cartflows' ); ?></p>
301
+ <form method="post">
302
+ <div class="cartflows-usage-tracking cartflows-setup-message">
303
+ <div class="usage-tracking-wrap">
304
+ <h4><?php esc_html_e( 'Let&#x27;s Build it better!', 'cartflows' ); ?> </h4>
305
+ <p><?php esc_html_e( 'Get improved features and faster fixes by sharing non-sensitive data via usage tracking that shows us how CartFlows is used. No personal data is tracked or stored.', 'cartflows' ); ?>
306
+ <a href="https://my.cartflows.com/usage-tracking/"> <?php esc_html_e( 'Learn More', 'cartflows' ); ?></a></p>
307
+ <input type="hidden" name="cartflows-usage-tracking-option" value="no">
308
+ <input type="checkbox" name="cartflows-usage-tracking-option" id="cartflows-usage-tracking-option" value="Yes" checked>
309
+ <label><?php esc_html_e( 'Yes, I am in.', 'cartflows' ); ?></label>
310
+ </div>
311
+ </div>
312
+ <div class="cartflows-setup-actions step">
313
+ <div class="button-prev-wrap">
314
+ </div>
315
+ <div class="button-next-wrap">
316
+ <input type="submit" class="uct-activate button-primary button button-large " value="<?php esc_html_e( 'Lets Go »', 'cartflows' ); ?>" name="save_step" />
317
+ </div>
318
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
319
+ </div>
320
+
321
+ </form>
322
+ <?php
323
+ }
324
+
325
+ /**
326
+ * Save Locale Settings.
327
+ */
328
+ public function welcome_step_save() {
329
+ check_admin_referer( 'cartflow-setup' );
330
+
331
+ // Update site title & tagline.
332
+ $redirect_url = $this->get_next_step_link();
333
+
334
+ wp_safe_redirect( esc_url_raw( $redirect_url ) );
335
+ exit;
336
+ }
337
+
338
+ /**
339
+ * Locale settings
340
+ */
341
+ public function page_builder_step() {
342
+ ?>
343
+
344
+ <h1><?php esc_html_e( 'Page Builder Setup', 'cartflows' ); ?></h1>
345
+ <p class="description"><?php esc_html_e( 'Please select a page builder you would like to use with CartFlows.', 'cartflows' ); ?></p>
346
+ <form method="post">
347
+ <table class="cartflows-table widefat">
348
+ <tr class="cartflows-row">
349
+ <td class="cartflows-row-heading">
350
+ <label><?php esc_html_e( 'Select Page Builder', 'cartflows' ); ?></label>
351
+ </td>
352
+ <td class="cartflows-row-content">
353
+ <?php
354
+ $installed_plugins = get_plugins();
355
+ $plugins = array(
356
+ array(
357
+ 'title' => __( 'Elementor', 'cartflows' ),
358
+ 'value' => 'elementor',
359
+ 'data' => array(
360
+ 'slug' => 'elementor',
361
+ 'init' => 'elementor/elementor.php',
362
+ 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
363
+ 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
364
+ ),
365
+ ),
366
+ array(
367
+ 'title' => __( 'Beaver Builder Plugin (Lite Version)', 'cartflows' ),
368
+ 'value' => 'beaver-builder',
369
+ 'data' => array(
370
+ 'slug' => 'beaver-builder-lite-version',
371
+ 'init' => 'beaver-builder-lite-version/fl-builder.php',
372
+ 'active' => is_plugin_active( 'beaver-builder-lite-version/fl-builder.php' ) ? 'yes' : 'no',
373
+ 'install' => isset( $installed_plugins['beaver-builder-lite-version/fl-builder.php'] ) ? 'yes' : 'no',
374
+ ),
375
+ ),
376
+ array(
377
+ 'title' => __( 'Divi', 'cartflows' ),
378
+ 'value' => 'divi',
379
+ 'data' => array(
380
+ 'slug' => 'divi',
381
+ 'init' => 'divi',
382
+ 'active' => 'yes',
383
+ 'install' => 'NA',
384
+ ),
385
+ ),
386
+ array(
387
+ 'title' => __( 'Gutenberg', 'cartflows' ),
388
+ 'value' => 'gutenberg',
389
+ 'data' => array(
390
+ 'slug' => 'ultimate-addons-for-gutenberg',
391
+ 'init' => 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php',
392
+ 'active' => is_plugin_active( 'ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php' ) ? 'yes' : 'no',
393
+ 'install' => isset( $installed_plugins['ultimate-addons-for-gutenberg/ultimate-addons-for-gutenberg.php'] ) ? 'yes' : 'no',
394
+ ),
395
+ ),
396
+ array(
397
+ 'title' => __( 'Other', 'cartflows' ),
398
+ 'value' => 'other',
399
+ 'data' => array(
400
+ 'slug' => 'other',
401
+ 'init' => false,
402
+ 'active' => 'yes',
403
+ 'install' => 'NA',
404
+ ),
405
+ ),
406
+ );
407
+ ?>
408
+ <input type="hidden" name="save-pb-input" id="save-pb-option" value="1" />
409
+ <select name="page-builder" class="page-builder-list" data-redirect-link="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>">
410
+ <?php
411
+ foreach ( $plugins as $key => $plugin ) {
412
+ echo '<option value="' . esc_attr( $plugin['value'] ) . '" data-install="' . esc_attr( $plugin['data']['install'] ) . '" data-active="' . esc_attr( $plugin['data']['active'] ) . '" data-slug="' . esc_attr( $plugin['data']['slug'] ) . '" data-init="' . esc_attr( $plugin['data']['init'] ) . '">' . esc_html( $plugin['title'] ) . '</option>';
413
+ }
414
+ ?>
415
+ </select>
416
+ </td>
417
+ </tr>
418
+ </table>
419
+ <p><?php esc_html_e( 'While CartFlows Should work with most page builders, we offer templates for the above page builders.', 'cartflows' ); ?></p>
420
+
421
+ <div class="cartflows-setup-actions step">
422
+ <div class="button-prev-wrap">
423
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
424
+ </div>
425
+ <div class="button-next-wrap">
426
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next" ><?php esc_html_e( 'Skip this step', 'cartflows' ); ?></a>
427
+ <a href="#" class="button button-primary wcf-install-plugins"><?php esc_html_e( 'Next »', 'cartflows' ); ?></a>
428
+ </div>
429
+ <?php wp_nonce_field( 'cartflow-setup' ); ?>
430
+ </div>
431
+ </form>
432
+ <?php
433
+ }
434
+
435
+ /**
436
+ * Render checkout step.
437
+ */
438
+ public function checkout_step() {
439
+
440
+ $installed_plugins = get_plugins();
441
+ $is_wc_installed = isset( $installed_plugins['woocommerce/woocommerce.php'] ) ? 'yes' : 'no';
442
+ $is_wcf_ca_installed = isset( $installed_plugins['woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php'] ) ? 'yes' : 'no';
443
+ $is_active = class_exists( 'WooCommerce' ) ? 'yes' : 'no';
444
+ $is_wcf_ca_active = class_exists( 'CARTFLOWS_CA_Loader' ) ? 'yes' : 'no';
445
+ ?>
446
+ <h1><?php esc_html_e( 'Choose a checkout', 'cartflows' ); ?></h1>
447
+ <div class="cartflows-setup-message">
448
+ <p>
449
+ <?php esc_html_e( 'While CartFlows is designed to use WooCommerce sell digital and physical products, not all funnels need a checkout system.', 'cartflows' ); ?>
450
+ </p>
451
+ <h4 class="cartflows-setup-message-title"><?php esc_html_e( 'Would you like to install WooCommerce to sell digital and physical products in your funnels?', 'cartflows' ); ?></h4>
452
+ <span><input data-wcf-ca-active="<?php echo esc_attr( $is_wcf_ca_active ); ?>" data-wcf-ca-install="<?php echo esc_attr( $is_wcf_ca_installed ); ?>" data-woo-active="<?php echo esc_attr( $is_active ); ?>" data-woo-install="<?php echo esc_attr( $is_wc_installed ); ?>" type="hidden" class="wcf-install-wc-input" name="installl-woocommerce" value="" checked></span>
453
+ </div>
454
+
455
+ <div class="cartflows-setup-extra-notice">
456
+
457
+ <span>
458
+ <?php esc_html_e( 'The following plugin will be installed and activated for you:', 'cartflows' ); ?>
459
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce', 'cartflows' ); ?></a>,
460
+ <a target="_blank" href="https://wordpress.org/plugins/woo-cart-abandonment-recovery/"> <?php esc_html_e( 'WooCommerce Cart Abandonment Recovery', 'cartflows' ); ?></a>
461
+
462
+ </span>
463
+
464
+ </div>
465
+
466
+ <div class="cartflows-setup-actions step">
467
+ <div class="button-prev-wrap">
468
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
469
+ </div>
470
+ <div class="button-next-wrap">
471
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
472
+ <a class="wcf-install-wc button-primary button button-large" name="save_step" > <?php esc_html_e( 'Yes', 'cartflows' ); ?> </a>
473
+ </div>
474
+ </div>
475
+
476
+ <?php
477
+ }
478
+
479
+ /**
480
+ * Save Locale Settings.
481
+ */
482
+ public function activate_wc_plugins() {
483
+
484
+ check_ajax_referer( 'wcf-wc-plugins-activate', 'security' );
485
+
486
+ $plugin_slug_arr = array(
487
+ 'woocommerce/woocommerce.php' => true,
488
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
489
+ );
490
+
491
+ $activate = array(
492
+ 'woocommerce/woocommerce.php' => false,
493
+ 'woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php' => false,
494
+ );
495
+
496
+ foreach ( $plugin_slug_arr as $slug => $do_silently ) {
497
+
498
+ $activate[ $slug ] = activate_plugin( $slug, '', false, $do_silently );
499
+ }
500
+
501
+ foreach ( $activate as $slug => $data ) {
502
+
503
+ if ( is_wp_error( $data ) ) {
504
+ wp_send_json_error(
505
+ array(
506
+ 'success' => false,
507
+ 'message' => $data->get_error_message(),
508
+ )
509
+ );
510
+ }
511
+ }
512
+
513
+ wp_send_json_success();
514
+ }
515
+
516
+ /**
517
+ * Save usage tracking Settings.
518
+ */
519
+ public function save_usage_tracking_option() {
520
+
521
+ if ( ! current_user_can( 'manage_options' ) ) {
522
+ return;
523
+ }
524
+
525
+ check_ajax_referer( 'wcf-usage-tracking-option', 'security' );
526
+
527
+ $allow_usage_tracking = isset( $_POST['allow_usage_tracking'] ) && 'true' == $_POST['allow_usage_tracking'] ? 'yes' : 'no';
528
+
529
+ $usage_tracking = get_site_option( 'cf_analytics_optin' );
530
+
531
+ if ( ( false === $usage_tracking ) || $allow_usage_tracking !== $usage_tracking ) {
532
+ update_site_option( 'cf_analytics_optin', $allow_usage_tracking );
533
+ }
534
+
535
+ wp_send_json_success( get_site_option( 'cf_analytics_optin' ) );
536
+ }
537
+
538
+
539
+ /**
540
+ * Save Locale Settings.
541
+ */
542
+ public function page_builder_step_save() {
543
+
544
+ if ( ! current_user_can( 'manage_options' ) ) {
545
+ return;
546
+ }
547
+
548
+ check_ajax_referer( 'wcf-page-builder-step-save', 'security' );
549
+
550
+ $plugin_init = isset( $_POST['plugin_init'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin_init'] ) ) : '';
551
+ $save_option = ( isset( $_POST['save_builder_option'] ) && 'true' == $_POST['save_builder_option'] ) ? true : false;
552
+ $plugin_slug = filter_input( INPUT_POST, 'page_builder', FILTER_SANITIZE_STRING );
553
+
554
+ $do_sliently = true;
555
+ if ( 'woo-cart-abandonment-recovery' === $plugin_slug ) {
556
+ $do_sliently = false;
557
+ }
558
+
559
+ $activate = activate_plugin( $plugin_init, '', false, $do_sliently );
560
+
561
+ if ( $save_option ) {
562
+ $this->save_page_builder_option();
563
+ }
564
+
565
+ if ( is_wp_error( $activate ) ) {
566
+ wp_send_json_error(
567
+ array(
568
+ 'success' => false,
569
+ 'message' => $activate->get_error_message(),
570
+ )
571
+ );
572
+ }
573
+
574
+ wp_send_json_success(
575
+ array( 'plugin' => $plugin_slug )
576
+ );
577
+ }
578
+
579
+ /**
580
+ * Save selected page builder in options database.
581
+ */
582
+ public function save_page_builder_option() {
583
+
584
+ if ( ! current_user_can( 'manage_options' ) ) {
585
+ return;
586
+ }
587
+
588
+ $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : ''; //phpcs:ignore
589
+
590
+ $wcf_settings = get_option( '_cartflows_common', array() );
591
+
592
+ if ( false !== strpos( $page_builder, 'beaver-builder' ) ) {
593
+ $page_builder = 'beaver-builder';
594
+ }
595
+
596
+ $wcf_settings['default_page_builder'] = $page_builder;
597
+
598
+ update_option( '_cartflows_common', $wcf_settings );
599
+
600
+ wp_send_json_success(
601
+ array( 'plugin' => $page_builder )
602
+ );
603
+
604
+ }
605
+
606
+ /**
607
+ * Final step.
608
+ */
609
+ public function ready_step() {
610
+
611
+ // Set setup wizard status to complete.
612
+ update_option( 'wcf_setup_complete', true );
613
+ ?>
614
+ <h1><?php esc_html_e( 'Congratulations, You Did It!', 'cartflows' ); ?></h1>
615
+
616
+ <div class="cartflows-setup-next-steps">
617
+ <div class="cartflows-setup-next-steps-last">
618
+
619
+ <p class="success">
620
+ <?php
621
+ esc_html_e( 'CartFlows is ready to use on your website. You\'ve successfully completed the setup process and all that is left for you to do is create your first flow.', 'cartflows' )
622
+ ?>
623
+ </p>
624
+
625
+
626
+ <ul class="wcf-wizard-next-steps">
627
+ <li class="wcf-wizard-next-step-item">
628
+ <div class="wcf-wizard-next-step-description">
629
+ <p class="next-step-heading">Next step</p>
630
+ <h3 class="next-step-description">Create First Flow</h3>
631
+ <p class="next-step-extra-info">You're ready to add flows to your website.</p>
632
+ </div>
633
+ <div class="wcf-wizard-next-step-action">
634
+ <p class="wc-setup-actions step">
635
+ <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=cartflows_flow&add-new-flow' ) ); ?>" type="button" class="button button-primary button-hero" ><?php esc_html_e( 'Create a flow', 'cartflows' ); ?></a>
636
+ </p>
637
+ </div>
638
+ </li>
639
+ </ul>
640
+
641
+ </div>
642
+ </div>
643
+ <?php
644
+ }
645
+
646
+ /**
647
+ * Training course step.
648
+ */
649
+ public function training_step() {
650
+ $current_user = wp_get_current_user();
651
+ ?>
652
+ <h1><?php esc_html_e( 'Exclusive CartFlows Training Course Offer', 'cartflows' ); ?></h1>
653
+
654
+ <div id="mauticform_wrapper_cartflowsonboarding" class="mauticform_wrapper">
655
+ <form autocomplete="false" role="form" method="post" action="https://go.cartflows.com/form/submit?formId=2" id="mauticform_cartflowsonboarding" data-mautic-form="cartflowsonboarding" enctype="multipart/form-data">
656
+ <div class="mauticform-error" id="mauticform_cartflowsonboarding_error"></div>
657
+ <div class="mauticform-message" id="mauticform_cartflowsonboarding_message"></div>
658
+ <div class="mauticform-innerform">
659
+ <div class="mauticform-page-wrapper mauticform-page-1" data-mautic-form-page="1">
660
+ <div id="mauticform_cartflowsonboarding_enter_your_email" class="mauticform-row mauticform-email mauticform-field-1">
661
+ <div class="cartflows-setup-message">
662
+ <p>
663
+ <?php esc_html_e( 'We want you to get off to a great start using CartFlows, so we would like to give access to our exclusive training course.', 'cartflows' ); ?>
664
+ <?php esc_html_e( 'Get access to this couse, for free, by entering your email below.', 'cartflows' ); ?>
665
+ </p>
666
+ <input id="mauticform_input_cartflowsonboarding_enter_your_email" name="mauticform[enter_your_email]" placeholder="<?php esc_html_e( 'Enter Email address', 'cartflows' ); ?>" value="<?php echo $current_user->user_email; ?>" class="mauticform-input" type="email">
667
+ </div>
668
+ <span class="mauticform-errormsg" style="display: none;"></span>
669
+ </div>
670
+ </div>
671
+ </div>
672
+
673
+ <input type="hidden" name="mauticform[formId]" id="mauticform_cartflowsonboarding_id" value="2">
674
+ <input type="hidden" name="mauticform[return]" id="mauticform_cartflowsonboarding_return" value="">
675
+ <input type="hidden" name="mauticform[formName]" id="mauticform_cartflowsonboarding_name" value="cartflowsonboarding">
676
+ <div class="cartflows-setup-actions step">
677
+ <div class="button-prev-wrap">
678
+ <a href="<?php echo esc_url( $this->get_prev_step_link() ); ?>" class="button-primary button button-large button-prev" ><?php esc_html_e( '« Previous', 'cartflows' ); ?></a>
679
+ </div>
680
+ <div class="button-next-wrap">
681
+ <a href="<?php echo esc_url_raw( $this->get_next_step_plain_link() ); ?>" class="button button-large button-next"><?php esc_html_e( 'No thanks', 'cartflows' ); ?></a>
682
+ <button type="submit" name="mauticform[submit]" id="mauticform_input_cartflowsonboarding_submit" value="<?php esc_html_e( 'Allow', 'cartflows' ); ?>" class="mautic-form-submit btn btn-default button-primary button button-large button-next" name="save_step"><?php esc_html_e( 'Allow', 'cartflows' ); ?></button>
683
+ </div>
684
+ </div>
685
+ </form>
686
+ </div>
687
+ <?php
688
+ }
689
+
690
+ /**
691
+ * Localize variables in admin
692
+ */
693
+ public function localize_vars() {
694
+
695
+ $vars = array();
696
+
697
+ $ajax_actions = array(
698
+ 'wcf_page_builder_step_save',
699
+ 'wcf_wc_plugins_activate',
700
+ 'wcf_usage_tracking_option',
701
+ );
702
+
703
+ foreach ( $ajax_actions as $action ) {
704
+
705
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
706
+ }
707
+
708
+ return $vars;
709
+ }
710
+
711
+ /**
712
+ * Add JS script for mautic form
713
+ */
714
+ public function add_mautic_form_script() {
715
+
716
+ if ( ! isset( $_REQUEST['page'] ) || ( isset( $_REQUEST['page'] ) && 'cartflow-setup' !== $_REQUEST['page'] ) ) { //phpcs:ignore
717
+ return;
718
+ }
719
+ ?>
720
+
721
+ <script type="text/javascript">
722
+ /** This section is only needed once per page if manually copying **/
723
+ if (typeof MauticSDKLoaded == 'undefined') {
724
+ var MauticSDKLoaded = true;
725
+ var head = document.getElementsByTagName('head')[0];
726
+ var script = document.createElement('script');
727
+ script.type = 'text/javascript';
728
+ script.src = 'https://go.cartflows.com/media/js/mautic-form.js';
729
+ script.onload = function() {
730
+ MauticSDK.onLoad();
731
+ };
732
+ head.appendChild(script);
733
+ var MauticDomain = 'https://go.cartflows.com';
734
+ var MauticLang = {
735
+ 'submittingMessage': "Please wait..."
736
+ };
737
+ }
738
+ </script>
739
+ <?php
740
+ }
741
+ }
742
+
743
+ new CartFlows_Wizard();
744
+
745
+ endif;
classes/deprecated/deprecated-hooks.php CHANGED
@@ -1,31 +1,51 @@
1
- <?php
2
- /**
3
- * Deprecated Hooks of CartFlows Plugin.
4
- *
5
- * @package CartFlows
6
- * @author CartFlows
7
- */
8
-
9
- if ( ! defined( 'ABSPATH' ) ) {
10
- exit;
11
- }
12
-
13
- if ( ! function_exists( 'wcf_do_action_deprecated' ) ) {
14
- /**
15
- * Cartlows Action Deprecated
16
- *
17
- * @since 1.1.1
18
- * @param string $tag The name of the Action hook.
19
- * @param array $args Array of additional function arguments to be passed to apply_filters().
20
- * @param string $version The version of WordPress that deprecated the hook.
21
- * @param string $replacement Optional. The hook that should have been used. Default false.
22
- * @param string $message Optional. A message regarding the change. Default null.
23
- */
24
- function wcf_do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
25
- if ( function_exists( 'do_action_deprecated' ) ) { /* WP >= 4.6 */
26
- do_action_deprecated( $tag, $args, $version, $replacement, $message );
27
- } else {
28
- do_action_ref_array( $tag, $args );
29
- }
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deprecated Hooks of CartFlows Plugin.
4
+ *
5
+ * @package CartFlows
6
+ * @author CartFlows
7
+ */
8
+
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
+ exit;
11
+ }
12
+
13
+ if ( ! function_exists( 'wcf_do_action_deprecated' ) ) {
14
+ /**
15
+ * Cartlows Action Deprecated
16
+ *
17
+ * @since 1.1.1
18
+ * @param string $tag The name of the Action hook.
19
+ * @param array $args Array of additional function arguments to be passed to apply_filters().
20
+ * @param string $version The version of WordPress that deprecated the hook.
21
+ * @param string $replacement Optional. The hook that should have been used. Default false.
22
+ * @param string $message Optional. A message regarding the change. Default null.
23
+ */
24
+ function wcf_do_action_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
25
+ if ( function_exists( 'do_action_deprecated' ) ) { /* WP >= 4.6 */
26
+ do_action_deprecated( $tag, $args, $version, $replacement, $message );
27
+ } else {
28
+ do_action_ref_array( $tag, $args );
29
+ }
30
+ }
31
+ }
32
+
33
+ if ( ! function_exists( 'wcf_apply_filters_deprecated' ) ) {
34
+ /**
35
+ * Cartlows Apply Filters Deprecated
36
+ *
37
+ * @since 1.6.0
38
+ * @param string $tag The name of the Action hook.
39
+ * @param array $args Array of additional function arguments to be passed to apply_filters().
40
+ * @param string $version The version of WordPress that deprecated the hook.
41
+ * @param string $replacement Optional. The hook that should have been used. Default false.
42
+ * @param string $message Optional. A message regarding the change. Default null.
43
+ */
44
+ function wcf_apply_filters_deprecated( $tag, $args, $version, $replacement = false, $message = null ) {
45
+ if ( function_exists( 'apply_filters_deprecated' ) ) { /* WP >= 4.6 */
46
+ return apply_filters_deprecated( $tag, $args, $version, $replacement, $message );
47
+ } else {
48
+ return apply_filters_ref_array( $tag, $args );
49
+ }
50
+ }
51
+ }
includes/meta-fields/generate-product-repeater.php CHANGED
@@ -27,7 +27,7 @@ if ( empty( $selected_data ) ) {
27
  <!-- Product Name -->
28
  <div class="wcf-repeatable-fields wcf-sel-product">
29
  <span class="wcf-repeatable-row-setting-field">
30
- <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-excluded_product_types = "grouped" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="woocommerce_json_search_products_and_variations"><?php echo $options; ?></select>
31
  </span>
32
 
33
  <span class="wcf-repeatable-row-actions">
27
  <!-- Product Name -->
28
  <div class="wcf-repeatable-fields wcf-sel-product">
29
  <span class="wcf-repeatable-row-setting-field">
30
+ <select name="wcf-checkout-products[<?php echo $id; ?>][product]" class="wcf-product-search" data-allow_clear="allow_clear" data-excluded_product_types = "grouped" data-placeholder="<?php echo __( 'Search for a product&hellip;', 'cartflows' ); ?>" data-action="wcf_json_search_products_and_variations"><?php echo $options; ?></select>
31
  </span>
32
 
33
  <span class="wcf-repeatable-row-actions">
languages/cartflows.pot CHANGED
@@ -1,2099 +1,2119 @@
1
- # Copyright (C) 2020 CartFlows Inc
2
- # This file is distributed under the same license as the CartFlows package.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: CartFlows 1.5.12\n"
6
- "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2020-07-01 06:22:56+00:00\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=utf-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
- "Language-Team: LANGUAGE <LL@li.org>\n"
14
- "Language: en\n"
15
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "X-Poedit-Country: United States\n"
17
- "X-Poedit-SourceCharset: UTF-8\n"
18
- "X-Poedit-KeywordsList: "
19
- "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
- "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
- "X-Poedit-Basepath: ../\n"
22
- "X-Poedit-SearchPath-0: .\n"
23
- "X-Poedit-Bookmarks: \n"
24
- "X-Textdomain-Support: yes\n"
25
- "X-Generator: grunt-wp-i18n 1.0.3\n"
26
-
27
- #: admin/bsf-analytics/class-bsf-analytics.php:183
28
- #. translators: %s product name
29
- msgid ""
30
- "Want to help make <strong>%1s</strong> even more awesome? Allow us to "
31
- "collect non-sensitive diagnostic data and usage information. "
32
- msgstr ""
33
-
34
- #: admin/bsf-analytics/class-bsf-analytics.php:186
35
- msgid "This will be applicable for all sites from the network."
36
- msgstr ""
37
-
38
- #: admin/bsf-analytics/class-bsf-analytics.php:210
39
- #. translators: %s usage doc link
40
- msgid " Know More."
41
- msgstr ""
42
-
43
- #: admin/bsf-analytics/class-bsf-analytics.php:217
44
- msgid "Yes! Allow it"
45
- msgstr ""
46
-
47
- #: admin/bsf-analytics/class-bsf-analytics.php:225
48
- msgid "No Thanks"
49
- msgstr ""
50
-
51
- #: admin/bsf-analytics/class-bsf-analytics.php:294
52
- msgid "Every two days"
53
- msgstr ""
54
-
55
- #: admin/bsf-analytics/class-bsf-analytics.php:348
56
- msgid "Usage Tracking"
57
- msgstr ""
58
-
59
- #: admin/bsf-analytics/class-bsf-analytics.php:380
60
- msgid "Allow Brainstorm Force products to track non-sensitive usage tracking data."
61
- msgstr ""
62
-
63
- #: admin/bsf-analytics/class-bsf-analytics.php:383
64
- msgid " This will be applicable for all sites from the network."
65
- msgstr ""
66
-
67
- #: admin/bsf-analytics/class-bsf-analytics.php:388
68
- msgid "Learn More."
69
- msgstr ""
70
-
71
- #: classes/batch-process/class-cartflows-importer-elementor.php:44
72
- msgid "Invalid content."
73
- msgstr ""
74
-
75
- #: classes/batch-process/class-cartflows-importer-elementor.php:56
76
- msgid "Invalid content. Expected an array."
77
- msgstr ""
78
-
79
- #: classes/batch-process/helpers/class-wp-background-process.php:435
80
- msgid "Every %d Minutes"
81
- msgstr ""
82
-
83
- #: classes/class-cartflows-admin-fields.php:235
84
- msgid "Select"
85
- msgstr ""
86
-
87
- #: classes/class-cartflows-admin-fields.php:238
88
- msgid "No Checkout Steps"
89
- msgstr ""
90
-
91
- #: classes/class-cartflows-admin-fields.php:264
92
- #. translators: %s: link
93
- msgid ""
94
- "Be sure not to add any product in above selected Global Checkout step. "
95
- "Please read information about how to set up Global Checkout %1$shere%2$s."
96
- msgstr ""
97
-
98
- #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
99
- #: includes/admin/cartflows-general-bck.php:34
100
- #: modules/optin/classes/class-cartflows-optin-meta.php:150
101
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
102
- msgid "Settings"
103
- msgstr ""
104
-
105
- #: classes/class-cartflows-admin.php:440
106
- msgid "Installing and activating.."
107
- msgstr ""
108
-
109
- #: classes/class-cartflows-admin.php:441
110
- msgid "There was an error with the installation of plugin."
111
- msgstr ""
112
-
113
- #: classes/class-cartflows-admin.php:495
114
- msgid "Flows Library"
115
- msgstr ""
116
-
117
- #: classes/class-cartflows-admin.php:502
118
- #: modules/flow/view/meta-flow-steps.php:156
119
- msgid "Ready Templates"
120
- msgstr ""
121
-
122
- #: classes/class-cartflows-admin.php:505
123
- #: modules/flow/view/meta-flow-steps.php:159
124
- msgid "Create Your Own"
125
- msgstr ""
126
-
127
- #: classes/class-cartflows-admin.php:516
128
- #: modules/flow/view/meta-flow-steps.php:171
129
- msgid "Search Sites"
130
- msgstr ""
131
-
132
- #: classes/class-cartflows-admin.php:517
133
- #: modules/flow/view/meta-flow-steps.php:172
134
- msgid "Search Flow..."
135
- msgstr ""
136
-
137
- #: classes/class-cartflows-admin.php:534
138
- msgid "Design Your Flow"
139
- msgstr ""
140
-
141
- #: classes/class-cartflows-admin.php:535
142
- #: classes/class-cartflows-importer.php:665
143
- #: classes/class-cartflows-importer.php:764
144
- #: modules/flow/view/meta-flow-steps.php:202
145
- msgid "Learn How"
146
- msgstr ""
147
-
148
- #: classes/class-cartflows-api.php:369
149
- msgid "Request successfully processed!"
150
- msgstr ""
151
-
152
- #: classes/class-cartflows-cloning.php:423
153
- msgid "Clone this flow"
154
- msgstr ""
155
-
156
- #: classes/class-cartflows-cloning.php:423
157
- #: modules/flow/view/meta-flow-steps.php:115
158
- msgid "Clone"
159
- msgstr ""
160
-
161
- #: classes/class-cartflows-default-meta.php:745
162
- #: modules/optin/classes/class-cartflows-optin-meta.php:488
163
- msgid "Submit"
164
- msgstr ""
165
-
166
- #: classes/class-cartflows-flow-frontend.php:53
167
- msgid ""
168
- "Test mode is active — which displays random products for previewing. It can "
169
- "be deactivated from the flow settings in the admin dashboard."
170
- msgstr ""
171
-
172
- #: classes/class-cartflows-flow-frontend.php:58
173
- msgid "Click here to disable it"
174
- msgstr ""
175
-
176
- #: classes/class-cartflows-importer.php:81
177
- msgid "Export this flow"
178
- msgstr ""
179
-
180
- #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
181
- msgid "Export"
182
- msgstr ""
183
-
184
- #: classes/class-cartflows-importer.php:92
185
- msgid "Flow Export"
186
- msgstr ""
187
-
188
- #: classes/class-cartflows-importer.php:93
189
- msgid "Flow Import"
190
- msgstr ""
191
-
192
- #: classes/class-cartflows-importer.php:104
193
- msgid "No post to export has been supplied!"
194
- msgstr ""
195
-
196
- #: classes/class-cartflows-importer.php:278
197
- msgid "Please upload a valid .json file"
198
- msgstr ""
199
-
200
- #: classes/class-cartflows-importer.php:284
201
- msgid "Please upload a file to import"
202
- msgstr ""
203
-
204
- #: classes/class-cartflows-importer.php:506
205
- msgid "Successfully imported flows."
206
- msgstr ""
207
-
208
- #: classes/class-cartflows-importer.php:538
209
- msgid "Loading Steps"
210
- msgstr ""
211
-
212
- #: classes/class-cartflows-importer.php:540
213
- msgid "Getting steps from the cloud. Please wait for the moment."
214
- msgstr ""
215
-
216
- #: classes/class-cartflows-importer.php:551
217
- msgid "Searching Template.."
218
- msgstr ""
219
-
220
- #: classes/class-cartflows-importer.php:553
221
- msgid "Getting templates from the cloud. Please wait for the moment."
222
- msgstr ""
223
-
224
- #: classes/class-cartflows-importer.php:562
225
- msgid "Importing.."
226
- msgstr ""
227
-
228
- #: classes/class-cartflows-importer.php:571
229
- #: classes/class-cartflows-importer.php:611
230
- msgid "Imported"
231
- msgstr ""
232
-
233
- #: classes/class-cartflows-importer.php:572
234
- #: classes/class-cartflows-importer.php:612
235
- msgid "Thanks for patience"
236
- msgstr ""
237
-
238
- #: classes/class-cartflows-importer.php:581
239
- #: classes/class-cartflows-importer.php:593
240
- msgid "Coming Soon!"
241
- msgstr ""
242
-
243
- #: classes/class-cartflows-importer.php:612
244
- msgid "Redirecting to the Elementor edit window."
245
- msgstr ""
246
-
247
- #: classes/class-cartflows-importer.php:658
248
- #: classes/class-cartflows-importer.php:774
249
- msgid "Pro"
250
- msgstr ""
251
-
252
- #: classes/class-cartflows-importer.php:699
253
- #: classes/class-cartflows-importer.php:806
254
- msgid "Activate License"
255
- msgstr ""
256
-
257
- #: classes/class-cartflows-importer.php:701
258
- #: classes/class-cartflows-importer.php:808
259
- #: modules/flow/classes/class-cartflows-flow-meta.php:474
260
- msgid "Get Pro"
261
- msgstr ""
262
-
263
- #: classes/class-cartflows-importer.php:726
264
- msgid "Create"
265
- msgstr ""
266
-
267
- #: classes/class-cartflows-importer.php:825
268
- msgid "Under Maintenance.."
269
- msgstr ""
270
-
271
- #: classes/class-cartflows-importer.php:826
272
- msgid ""
273
- "If you are seeing this message, most likely our servers are under routine "
274
- "maintenance and we will be back shortly."
275
- msgstr ""
276
-
277
- #: classes/class-cartflows-importer.php:827
278
- msgid ""
279
- "In rare case, it is possible your website is having trouble connecting with "
280
- "ours. If you need help, please feel free to get in touch with us from our "
281
- "website.."
282
- msgstr ""
283
-
284
- #: classes/class-cartflows-importer.php:857
285
- #. translators: %s: Plugin string
286
- msgid ""
287
- "%1$s to see CartFlows templates. If you prefer another page builder tool, "
288
- "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
289
- msgstr ""
290
-
291
- #: classes/class-cartflows-importer.php:872
292
- msgid "All"
293
- msgstr ""
294
-
295
- #: classes/class-cartflows-importer.php:875
296
- msgid "Select Step Type"
297
- msgstr ""
298
-
299
- #: classes/class-cartflows-importer.php:959
300
- msgid "Import from Cloud"
301
- msgstr ""
302
-
303
- #: classes/class-cartflows-importer.php:1267
304
- msgid "Sales Landing"
305
- msgstr ""
306
-
307
- #: classes/class-cartflows-importer.php:1271
308
- #: modules/flow/classes/class-cartflows-step-post-type.php:253
309
- #: modules/flow/view/meta-flow-steps.php:12
310
- msgid "Checkout (Woo)"
311
- msgstr ""
312
-
313
- #: classes/class-cartflows-importer.php:1275
314
- #: modules/flow/classes/class-cartflows-step-post-type.php:260
315
- #: modules/flow/view/meta-flow-steps.php:13
316
- msgid "Thank You (Woo)"
317
- msgstr ""
318
-
319
- #: classes/class-cartflows-importer.php:1283
320
- #: modules/flow/classes/class-cartflows-step-post-type.php:239
321
- #: modules/flow/view/meta-flow-steps.php:11
322
- msgid "Landing"
323
- msgstr ""
324
-
325
- #: classes/class-cartflows-importer.php:1287
326
- msgid "Thank You"
327
- msgstr ""
328
-
329
- #: classes/class-cartflows-importer.php:1397
330
- #. translators: %s: template ID
331
- msgid "Invalid template id %1$s or post id %2$s."
332
- msgstr ""
333
-
334
- #: classes/class-cartflows-importer.php:1472
335
- #. translators: %s: flow ID
336
- msgid "Invalid flow id %1$s OR step type %2$s."
337
- msgstr ""
338
-
339
- #: classes/class-cartflows-importer.php:1597
340
- msgid ""
341
- "Elementor is not activated. Please activate plugin Elementor Page Builder "
342
- "to import the step."
343
- msgstr ""
344
-
345
- #: classes/class-cartflows-importer.php:1700
346
- msgid "Action failed. Invalid Security Nonce."
347
- msgstr ""
348
-
349
- #: classes/class-cartflows-importer.php:1707
350
- msgid "User have not plugin install permissions."
351
- msgstr ""
352
-
353
- #: classes/class-cartflows-importer.php:1729
354
- msgid "Plugin Successfully Activated"
355
- msgstr ""
356
-
357
- #: classes/class-cartflows-learndash-compatibility.php:86
358
- msgid "None"
359
- msgstr ""
360
-
361
- #: classes/class-cartflows-learndash-compatibility.php:113
362
- #. translators: 1: anchor start, 2: anchor close
363
- msgid ""
364
- "Non-enrolled students will redirect to the selected CartFlows template. If "
365
- "you have not created any Flow already, add new Flow from %1$shere%2$s."
366
- msgstr ""
367
-
368
- #: classes/class-cartflows-learndash-compatibility.php:119
369
- msgid "Select CartFlows Template for this Course"
370
- msgstr ""
371
-
372
- #: classes/class-cartflows-loader.php:222
373
- #. translators: %s: html tags
374
- msgid ""
375
- "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
376
- "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
377
- msgstr ""
378
-
379
- #: classes/class-cartflows-loader.php:471
380
- #. translators: %s: html tags
381
- msgid ""
382
- "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
383
- "activated."
384
- msgstr ""
385
-
386
- #: classes/class-cartflows-loader.php:481
387
- msgid "Activate WooCommerce"
388
- msgstr ""
389
-
390
- #: classes/class-cartflows-loader.php:489
391
- msgid "Install WooCommerce"
392
- msgstr ""
393
-
394
- #: classes/class-cartflows-logger.php:161
395
- msgid "Action failed. Please refresh the page and retry."
396
- msgstr ""
397
-
398
- #: classes/class-cartflows-meta-fields.php:84
399
- msgid "Thin 100"
400
- msgstr ""
401
-
402
- #: classes/class-cartflows-meta-fields.php:85
403
- msgid "Extra-Light 200"
404
- msgstr ""
405
-
406
- #: classes/class-cartflows-meta-fields.php:86
407
- msgid "Light 300"
408
- msgstr ""
409
-
410
- #: classes/class-cartflows-meta-fields.php:87
411
- msgid "Normal 400"
412
- msgstr ""
413
-
414
- #: classes/class-cartflows-meta-fields.php:88
415
- msgid "Medium 500"
416
- msgstr ""
417
-
418
- #: classes/class-cartflows-meta-fields.php:89
419
- msgid "Semi-Bold 600"
420
- msgstr ""
421
-
422
- #: classes/class-cartflows-meta-fields.php:90
423
- msgid "Bold 700"
424
- msgstr ""
425
-
426
- #: classes/class-cartflows-meta-fields.php:91
427
- msgid "Extra-Bold 800"
428
- msgstr ""
429
-
430
- #: classes/class-cartflows-meta-fields.php:92
431
- msgid "Ultra-Bold 900"
432
- msgstr ""
433
-
434
- #: classes/class-cartflows-meta-fields.php:717
435
- #: includes/meta-fields/generate-product-repeater.php:30
436
- msgid "Search for a product&hellip;"
437
- msgstr ""
438
-
439
- #: classes/class-cartflows-meta-fields.php:766
440
- msgid "Search for a coupon&hellip;"
441
- msgstr ""
442
-
443
- #: classes/class-cartflows-meta.php:34
444
- msgid "Update"
445
- msgstr ""
446
-
447
- #: classes/class-cartflows-meta.php:42
448
- #: modules/flow/classes/class-cartflows-flow-meta.php:95
449
- #: modules/flow/classes/class-cartflows-flow-meta.php:733
450
- msgid "Back to edit Flow"
451
- msgstr ""
452
-
453
- #: classes/class-cartflows-meta.php:63
454
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
455
- #: modules/landing/classes/class-cartflows-landing-meta.php:136
456
- #: modules/optin/classes/class-cartflows-optin-meta.php:156
457
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
458
- msgid "Custom Script"
459
- msgstr ""
460
-
461
- #: classes/class-cartflows-meta.php:66
462
- msgid ""
463
- "Custom script lets you add your own custom script on front end of this flow "
464
- "page."
465
- msgstr ""
466
-
467
- #: classes/class-cartflows-metabox.php:59
468
- msgid "Flow Details"
469
- msgstr ""
470
-
471
- #: classes/class-cartflows-wizard.php:91
472
- msgid "Thanks for installing and using CartFlows!"
473
- msgstr ""
474
-
475
- #: classes/class-cartflows-wizard.php:92
476
- msgid ""
477
- "It is easy to use the CartFlows. Please use the setup wizard to quick start "
478
- "setup."
479
- msgstr ""
480
-
481
- #: classes/class-cartflows-wizard.php:94
482
- msgid "Start Wizard"
483
- msgstr ""
484
-
485
- #: classes/class-cartflows-wizard.php:95
486
- msgid "Skip Setup"
487
- msgstr ""
488
-
489
- #: classes/class-cartflows-wizard.php:125
490
- #: includes/admin/cartflows-general-bck.php:24
491
- msgid "Welcome"
492
- msgstr ""
493
-
494
- #: classes/class-cartflows-wizard.php:130
495
- msgid "Page Builder"
496
- msgstr ""
497
-
498
- #: classes/class-cartflows-wizard.php:134
499
- msgid "Checkout"
500
- msgstr ""
501
-
502
- #: classes/class-cartflows-wizard.php:138
503
- msgid "Training"
504
- msgstr ""
505
-
506
- #: classes/class-cartflows-wizard.php:142
507
- msgid "Ready!"
508
- msgstr ""
509
-
510
- #: classes/class-cartflows-wizard.php:217
511
- msgid "CartFlows Setup"
512
- msgstr ""
513
-
514
- #: classes/class-cartflows-wizard.php:243
515
- msgid "Exit Setup Wizard"
516
- msgstr ""
517
-
518
- #: classes/class-cartflows-wizard.php:296
519
- msgid "Welcome to CartFlows!"
520
- msgstr ""
521
-
522
- #: classes/class-cartflows-wizard.php:297
523
- msgid ""
524
- "Thank you for choosing CartFlows to get more leads, increase conversions, & "
525
- "maximize profits. This short setup wizard will guide you though configuring "
526
- "CartFlows and creating your first funnel."
527
- msgstr ""
528
-
529
- #: classes/class-cartflows-wizard.php:303
530
- msgid "Lets Go »"
531
- msgstr ""
532
-
533
- #: classes/class-cartflows-wizard.php:330
534
- msgid "Page Builder Setup"
535
- msgstr ""
536
-
537
- #: classes/class-cartflows-wizard.php:331
538
- msgid "Please select a page builder you would like to use with CartFlows."
539
- msgstr ""
540
-
541
- #: classes/class-cartflows-wizard.php:336
542
- msgid "Select Page Builder"
543
- msgstr ""
544
-
545
- #: classes/class-cartflows-wizard.php:343
546
- #: includes/admin/cartflows-general.php:94
547
- msgid "Elementor"
548
- msgstr ""
549
-
550
- #: classes/class-cartflows-wizard.php:353
551
- msgid "Beaver Builder Plugin (Lite Version)"
552
- msgstr ""
553
-
554
- #: classes/class-cartflows-wizard.php:363
555
- #: includes/admin/cartflows-general.php:96
556
- msgid "Divi"
557
- msgstr ""
558
-
559
- #: classes/class-cartflows-wizard.php:373
560
- #: includes/admin/cartflows-general.php:97
561
- msgid "Gutenberg"
562
- msgstr ""
563
-
564
- #: classes/class-cartflows-wizard.php:383
565
- #: includes/admin/cartflows-general.php:98
566
- msgid "Other"
567
- msgstr ""
568
-
569
- #: classes/class-cartflows-wizard.php:405
570
- msgid ""
571
- "While CartFlows Should work with most page builders, we offer templates for "
572
- "the above page builders."
573
- msgstr ""
574
-
575
- #: classes/class-cartflows-wizard.php:408
576
- #: classes/class-cartflows-wizard.php:453
577
- #: classes/class-cartflows-wizard.php:640
578
- msgid "« Previous"
579
- msgstr ""
580
-
581
- #: classes/class-cartflows-wizard.php:411
582
- msgid "Skip this step"
583
- msgstr ""
584
-
585
- #: classes/class-cartflows-wizard.php:412
586
- msgid "Next »"
587
- msgstr ""
588
-
589
- #: classes/class-cartflows-wizard.php:431
590
- msgid "Choose a checkout"
591
- msgstr ""
592
-
593
- #: classes/class-cartflows-wizard.php:434
594
- msgid ""
595
- "While CartFlows is designed to use WooCommerce sell digital and physical "
596
- "products, not all funnels need a checkout system."
597
- msgstr ""
598
-
599
- #: classes/class-cartflows-wizard.php:436
600
- msgid ""
601
- "Would you like to install WooCommerce to sell digital and physical products "
602
- "in your funnels?"
603
- msgstr ""
604
-
605
- #: classes/class-cartflows-wizard.php:443
606
- msgid "The following plugin will be installed and activated for you:"
607
- msgstr ""
608
-
609
- #: classes/class-cartflows-wizard.php:444
610
- msgid "WooCommerce"
611
- msgstr ""
612
-
613
- #: classes/class-cartflows-wizard.php:445
614
- msgid "WooCommerce Cart Abandonment Recovery"
615
- msgstr ""
616
-
617
- #: classes/class-cartflows-wizard.php:456
618
- #: classes/class-cartflows-wizard.php:643
619
- msgid "No thanks"
620
- msgstr ""
621
-
622
- #: classes/class-cartflows-wizard.php:457
623
- msgid "Yes"
624
- msgstr ""
625
-
626
- #: classes/class-cartflows-wizard.php:576
627
- msgid "Congratulations, You Did It!"
628
- msgstr ""
629
-
630
- #: classes/class-cartflows-wizard.php:583
631
- msgid ""
632
- "CartFlows is ready to use on your website. You've successfully completed "
633
- "the setup process and all that is left for you to do is create your first "
634
- "flow."
635
- msgstr ""
636
-
637
- #: classes/class-cartflows-wizard.php:597
638
- msgid "Create a flow"
639
- msgstr ""
640
-
641
- #: classes/class-cartflows-wizard.php:614
642
- msgid "Exclusive CartFlows Training Course Offer"
643
- msgstr ""
644
-
645
- #: classes/class-cartflows-wizard.php:625
646
- msgid ""
647
- "We want you to get off to a great start using CartFlows, so we would like "
648
- "to give access to our exclusive training course."
649
- msgstr ""
650
-
651
- #: classes/class-cartflows-wizard.php:626
652
- msgid "Get access to this couse, for free, by entering your email below."
653
- msgstr ""
654
-
655
- #: classes/class-cartflows-wizard.php:628
656
- msgid "Enter Email address"
657
- msgstr ""
658
-
659
- #: classes/class-cartflows-wizard.php:644
660
- msgid "Allow"
661
- msgstr ""
662
-
663
- #: classes/lib/notices/class-astra-notices.php:125
664
- msgid "WordPress Nonce not validated."
665
- msgstr ""
666
-
667
- #: classes/logger/class-cartflows-log-handler-file.php:351
668
- #: classes/logger/class-cartflows-log-handler-file.php:371
669
- msgid "This method should not be called before plugins_loaded."
670
- msgstr ""
671
-
672
- #: classes/logger/class-cartflows-wc-logger.php:58
673
- #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
674
- msgid "The provided handler %1$s does not implement %2$s."
675
- msgstr ""
676
-
677
- #: classes/logger/class-cartflows-wc-logger.php:136
678
- #. translators: 1: Cartflows_WC_Logger::log 2: level
679
- msgid "%1$s was called with an invalid level \"%2$s\"."
680
- msgstr ""
681
-
682
- #: includes/admin/cartflows-admin.php:19
683
- #: includes/admin/cartflows-general.php:48
684
- msgid "Modernizing WordPress eCommerce!"
685
- msgstr ""
686
-
687
- #: includes/admin/cartflows-admin.php:29
688
- msgid "Settings saved successfully."
689
- msgstr ""
690
-
691
- #: includes/admin/cartflows-error-log.php:36
692
- msgid "%1$s at %2$s"
693
- msgstr ""
694
-
695
- #: includes/admin/cartflows-error-log.php:41
696
- #: modules/flow/classes/class-cartflows-flow-post-type.php:225
697
- #: modules/flow/view/meta-flow-steps.php:104
698
- msgid "View"
699
- msgstr ""
700
-
701
- #: includes/admin/cartflows-error-log.php:65
702
- msgid "Delete log"
703
- msgstr ""
704
-
705
- #: includes/admin/cartflows-error-log.php:70
706
- msgid "There are currently no logs to view."
707
- msgstr ""
708
-
709
- #: includes/admin/cartflows-general-bck.php:10
710
- msgid "Selec"
711
- msgstr ""
712
-
713
- #: includes/admin/cartflows-general-bck.php:22
714
- msgid "General"
715
- msgstr ""
716
-
717
- #: includes/admin/cartflows-general.php:31
718
- #: includes/admin/cartflows-general.php:58
719
- msgid "General Settings"
720
- msgstr ""
721
-
722
- #: includes/admin/cartflows-general.php:40
723
- msgid "Getting Started"
724
- msgstr ""
725
-
726
- #: includes/admin/cartflows-general.php:71
727
- msgid "Disallow search engines from indexing flows"
728
- msgstr ""
729
-
730
- #: includes/admin/cartflows-general.php:81
731
- #: modules/flow/view/meta-flow-steps.php:93
732
- msgid "Global Checkout"
733
- msgstr ""
734
-
735
- #: includes/admin/cartflows-general.php:90
736
- msgid "Show Templates designed with"
737
- msgstr ""
738
-
739
- #: includes/admin/cartflows-general.php:91
740
- msgid ""
741
- "CartFlows offers flow templates that can be imported in one click. These "
742
- "templates are available in few different page builders. Please choose your "
743
- "preferred page builder from the list so you will only see templates that "
744
- "are made using that page builder.."
745
- msgstr ""
746
-
747
- #: includes/admin/cartflows-general.php:95
748
- msgid "Beaver Builder"
749
- msgstr ""
750
-
751
- #: includes/admin/cartflows-general.php:107
752
- #: includes/admin/cartflows-general.php:193
753
- #: includes/admin/cartflows-general.php:299
754
- #: includes/admin/cartflows-general.php:416
755
- msgid "Save Changes"
756
- msgstr ""
757
-
758
- #: includes/admin/cartflows-general.php:119
759
- msgid "Permalink Settings"
760
- msgstr ""
761
-
762
- #: includes/admin/cartflows-general.php:134
763
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
764
- #: modules/optin/classes/class-cartflows-optin-meta.php:381
765
- msgid "Default"
766
- msgstr ""
767
-
768
- #: includes/admin/cartflows-general.php:140
769
- msgid "Flow and Step Slug"
770
- msgstr ""
771
-
772
- #: includes/admin/cartflows-general.php:146
773
- msgid "Flow Slug"
774
- msgstr ""
775
-
776
- #: includes/admin/cartflows-general.php:152
777
- msgid "Step Slug"
778
- msgstr ""
779
-
780
- #: includes/admin/cartflows-general.php:164
781
- msgid "Post Type Permalink Base"
782
- msgstr ""
783
-
784
- #: includes/admin/cartflows-general.php:172
785
- msgid "Step Base"
786
- msgstr ""
787
-
788
- #: includes/admin/cartflows-general.php:182
789
- msgid "Flow Base"
790
- msgstr ""
791
-
792
- #: includes/admin/cartflows-general.php:194
793
- msgid "Set Default"
794
- msgstr ""
795
-
796
- #: includes/admin/cartflows-general.php:208
797
- msgid "Facebook Pixel Settings"
798
- msgstr ""
799
-
800
- #: includes/admin/cartflows-general.php:223
801
- msgid "Enable Facebook Pixel Tracking"
802
- msgstr ""
803
-
804
- #: includes/admin/cartflows-general.php:236
805
- msgid "Enable for the whole site"
806
- msgstr ""
807
-
808
- #: includes/admin/cartflows-general.php:244
809
- #: includes/admin/cartflows-general.php:343
810
- msgid "If this option is unchecked, it will only apply to CartFlows steps."
811
- msgstr ""
812
-
813
- #: includes/admin/cartflows-general.php:254
814
- msgid "Enter Facebook pixel ID"
815
- msgstr ""
816
-
817
- #: includes/admin/cartflows-general.php:262
818
- #: includes/admin/cartflows-general.php:361
819
- msgid "Enable Events:"
820
- msgstr ""
821
-
822
- #: includes/admin/cartflows-general.php:271
823
- msgid "Initiate Checkout"
824
- msgstr ""
825
-
826
- #: includes/admin/cartflows-general.php:280
827
- #: includes/admin/cartflows-general.php:387
828
- msgid "Add Payment Info"
829
- msgstr ""
830
-
831
- #: includes/admin/cartflows-general.php:289
832
- msgid "Purchase Complete"
833
- msgstr ""
834
-
835
- #: includes/admin/cartflows-general.php:311
836
- msgid "Google Analytics Settings"
837
- msgstr ""
838
-
839
- #: includes/admin/cartflows-general.php:322
840
- msgid "Enable Google Analytics Tracking"
841
- msgstr ""
842
-
843
- #: includes/admin/cartflows-general.php:335
844
- msgid "Enable for the whole website"
845
- msgstr ""
846
-
847
- #: includes/admin/cartflows-general.php:353
848
- msgid "Google Analytics ID"
849
- msgstr ""
850
-
851
- #: includes/admin/cartflows-general.php:355
852
- msgid ""
853
- "Log into your <a href=\"https://analytics.google.com/\" "
854
- "target=\"_blank\">google analytics account</a> to find your ID. eg: "
855
- "UA-XXXXXX-X&period;"
856
- msgstr ""
857
-
858
- #: includes/admin/cartflows-general.php:369
859
- msgid "Begin Checkout"
860
- msgstr ""
861
-
862
- #: includes/admin/cartflows-general.php:378
863
- msgid "Add To Cart"
864
- msgstr ""
865
-
866
- #: includes/admin/cartflows-general.php:396
867
- msgid "Purchase"
868
- msgstr ""
869
-
870
- #: includes/admin/cartflows-general.php:404
871
- msgid ""
872
- "Google Analytics not working correctly? <a "
873
- "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
874
- "issues/\" > Click here </a> to know more. "
875
- msgstr ""
876
-
877
- #: includes/admin/cartflows-general.php:437
878
- msgid "Knowledge Base"
879
- msgstr ""
880
-
881
- #: includes/admin/cartflows-general.php:441
882
- msgid "Not sure how something works? Take a peek at the knowledge base and learn."
883
- msgstr ""
884
-
885
- #: includes/admin/cartflows-general.php:444
886
- msgid "Visit Knowledge Base »"
887
- msgstr ""
888
-
889
- #: includes/admin/cartflows-general.php:452
890
- msgid "Community"
891
- msgstr ""
892
-
893
- #: includes/admin/cartflows-general.php:456
894
- msgid ""
895
- "Join the community of super helpful CartFlows users. Say hello, ask "
896
- "questions, give feedback and help each other!"
897
- msgstr ""
898
-
899
- #: includes/admin/cartflows-general.php:459
900
- msgid "Join Our Facebook Group »"
901
- msgstr ""
902
-
903
- #: includes/admin/cartflows-general.php:467
904
- msgid "Five Star Support"
905
- msgstr ""
906
-
907
- #: includes/admin/cartflows-general.php:471
908
- msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
909
- msgstr ""
910
-
911
- #: includes/admin/cartflows-general.php:474
912
- msgid "Submit a Ticket »"
913
- msgstr ""
914
-
915
- #: includes/admin/cartflows-general.php:484
916
- msgid "Load Minified CSS"
917
- msgstr ""
918
-
919
- #: includes/admin/cartflows-general.php:489
920
- msgid ""
921
- "Load the Minified CSS from here. Just Enable it by checking the below given "
922
- "checkbox."
923
- msgstr ""
924
-
925
- #: includes/admin/cartflows-general.php:496
926
- msgid "Load minified CSS & JS Files"
927
- msgstr ""
928
-
929
- #: includes/admin/cartflows-general.php:501
930
- msgid "Save"
931
- msgstr ""
932
-
933
- #: includes/exporter.php:12
934
- msgid "Export Flows to a JSON file"
935
- msgstr ""
936
-
937
- #: includes/exporter.php:13
938
- msgid ""
939
- "This tool allows you to generate and download a JSON file containing a list "
940
- "of all flows."
941
- msgstr ""
942
-
943
- #: includes/importer.php:12
944
- msgid "Import Flows to a JSON file"
945
- msgstr ""
946
-
947
- #: includes/importer.php:13
948
- msgid "This tool allows you to import the flows from the JSON file."
949
- msgstr ""
950
-
951
- #: includes/importer.php:21
952
- msgid "Import"
953
- msgstr ""
954
-
955
- #: includes/meta-fields/generate-product-repeater.php:36
956
- msgid "Remove"
957
- msgstr ""
958
-
959
- #: includes/meta-fields/generate-product-repeater.php:51
960
- msgid "Product Quantity"
961
- msgstr ""
962
-
963
- #: includes/meta-fields/generate-product-repeater.php:65
964
- msgid "Discount Type"
965
- msgstr ""
966
-
967
- #: includes/meta-fields/generate-product-repeater.php:69
968
- msgid "Select Discount Type"
969
- msgstr ""
970
-
971
- #: includes/meta-fields/generate-product-repeater.php:70
972
- msgid "Original"
973
- msgstr ""
974
-
975
- #: includes/meta-fields/generate-product-repeater.php:71
976
- msgid "Percentage"
977
- msgstr ""
978
-
979
- #: includes/meta-fields/generate-product-repeater.php:72
980
- msgid "Price"
981
- msgstr ""
982
-
983
- #: includes/meta-fields/generate-product-repeater.php:83
984
- msgid "Discount Value"
985
- msgstr ""
986
-
987
- #: includes/meta-fields/generate-product-repeater.php:85
988
- msgid "Discount value will apply for each quantity of product."
989
- msgstr ""
990
-
991
- #: includes/meta-fields/get-product-selection-repeater.php:112
992
- msgid "Add New Product"
993
- msgstr ""
994
-
995
- #: includes/meta-fields/get-product-selection-repeater.php:113
996
- msgid "Create Product"
997
- msgstr ""
998
-
999
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:284
1000
- #: modules/optin/classes/class-cartflows-optin-markup.php:146
1001
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
1002
- msgid ""
1003
- "WooCommerce functions do not exist. If you are in an IFrame, please reload "
1004
- "it."
1005
- msgstr ""
1006
-
1007
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:285
1008
- #: modules/optin/classes/class-cartflows-optin-markup.php:147
1009
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
1010
- msgid "Click Here to Reload"
1011
- msgstr ""
1012
-
1013
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:303
1014
- msgid "Checkout ID not found"
1015
- msgstr ""
1016
-
1017
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:366
1018
- #: modules/checkout/templates/embed/checkout-template-simple.php:25
1019
- #: modules/checkout/templates/wcf-template.php:36
1020
- #: modules/optin/templates/optin-template-simple.php:25
1021
- msgid "Your cart is currently empty."
1022
- msgstr ""
1023
-
1024
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:432
1025
- msgid ""
1026
- "No product is selected. Please select products from the checkout meta "
1027
- "settings to continue."
1028
- msgstr ""
1029
-
1030
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:521
1031
- msgid "Variations Not set"
1032
- msgstr ""
1033
-
1034
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:529
1035
- msgid "This product can't be purchased"
1036
- msgstr ""
1037
-
1038
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:974
1039
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1017
1040
- msgid "Coupon Code"
1041
- msgstr ""
1042
-
1043
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:975
1044
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1026
1045
- msgid "Apply"
1046
- msgstr ""
1047
-
1048
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1182
1049
- msgid "Sorry there was a problem removing this coupon."
1050
- msgstr ""
1051
-
1052
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1185
1053
- msgid "Coupon has been removed."
1054
- msgstr ""
1055
-
1056
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1204
1057
- msgid "Sorry there was a problem removing "
1058
- msgstr ""
1059
-
1060
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:1207
1061
- msgid " has been removed."
1062
- msgstr ""
1063
-
1064
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1065
- msgid "Checkout Layout"
1066
- msgstr ""
1067
-
1068
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1069
- #: modules/landing/classes/class-cartflows-landing-meta.php:130
1070
- #: modules/optin/classes/class-cartflows-optin-meta.php:126
1071
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1072
- msgid "Shortcodes"
1073
- msgstr ""
1074
-
1075
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1076
- #: modules/optin/classes/class-cartflows-optin-meta.php:132
1077
- msgid "Select Product"
1078
- msgstr ""
1079
-
1080
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1081
- msgid "Product Options"
1082
- msgstr ""
1083
-
1084
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1085
- msgid "Order Bump"
1086
- msgstr ""
1087
-
1088
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1089
- msgid "Checkout Offer"
1090
- msgstr ""
1091
-
1092
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1093
- msgid "Checkout Design"
1094
- msgstr ""
1095
-
1096
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1097
- msgid "Checkout Fields"
1098
- msgstr ""
1099
-
1100
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1101
- msgid "Checkout Settings"
1102
- msgstr ""
1103
-
1104
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1105
- msgid "Logo (Optional)"
1106
- msgstr ""
1107
-
1108
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1109
- #. translators: %s: link
1110
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1111
- msgstr ""
1112
-
1113
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1114
- #. translators: %s: link.
1115
- msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1116
- msgstr ""
1117
-
1118
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1119
- msgid "Add this shortcode to your checkout page"
1120
- msgstr ""
1121
-
1122
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1123
- #. translators: %s: link
1124
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1125
- msgstr ""
1126
-
1127
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1128
- #. translators: %s: link
1129
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1130
- msgstr ""
1131
-
1132
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1133
- #. translators: %s: link
1134
- msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1135
- msgstr ""
1136
-
1137
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1138
- #. translators: %s: link
1139
- msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1140
- msgstr ""
1141
-
1142
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1143
- #. translators: %s: link
1144
- msgid ""
1145
- "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1146
- "feature"
1147
- msgstr ""
1148
-
1149
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1150
- #. translators: %s: link
1151
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1152
- msgstr ""
1153
-
1154
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1155
- #: modules/optin/classes/class-cartflows-optin-meta.php:268
1156
- #. translators: %s: link
1157
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1158
- msgstr ""
1159
-
1160
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1161
- msgid "Place Order Button Text"
1162
- msgstr ""
1163
-
1164
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1165
- msgid "Place order"
1166
- msgstr ""
1167
-
1168
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1169
- msgid "It will change the Place Order Button text on checkout page."
1170
- msgstr ""
1171
-
1172
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1173
- msgid "Enable cart editing on checkout"
1174
- msgstr ""
1175
-
1176
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1177
- #. translators: %s: link
1178
- msgid "Users will able to remove products from the checkout page."
1179
- msgstr ""
1180
-
1181
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1182
- msgid "One Column (Available in CartFlows Pro) "
1183
- msgstr ""
1184
-
1185
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1186
- msgid "Two Step (Available in CartFlows Pro) "
1187
- msgstr ""
1188
-
1189
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1190
- msgid "Checkout Skin"
1191
- msgstr ""
1192
-
1193
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1194
- msgid "One Column"
1195
- msgstr ""
1196
-
1197
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1198
- msgid "Two Column"
1199
- msgstr ""
1200
-
1201
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1202
- msgid "Two Step"
1203
- msgstr ""
1204
-
1205
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1206
- #: modules/optin/classes/class-cartflows-optin-meta.php:344
1207
- msgid "Primary Color"
1208
- msgstr ""
1209
-
1210
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1211
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1212
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1213
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1214
- #: modules/optin/classes/class-cartflows-optin-meta.php:353
1215
- #: modules/optin/classes/class-cartflows-optin-meta.php:392
1216
- #: modules/optin/classes/class-cartflows-optin-meta.php:504
1217
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1218
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1219
- msgid "Font Family"
1220
- msgstr ""
1221
-
1222
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1223
- msgid "Advance Options"
1224
- msgstr ""
1225
-
1226
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1227
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1228
- msgid "Heading"
1229
- msgstr ""
1230
-
1231
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1232
- msgid "Heading Color"
1233
- msgstr ""
1234
-
1235
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1236
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1237
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1238
- #: modules/optin/classes/class-cartflows-optin-meta.php:401
1239
- #: modules/optin/classes/class-cartflows-optin-meta.php:513
1240
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1241
- msgid "Font Weight"
1242
- msgstr ""
1243
-
1244
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1245
- #: modules/optin/classes/class-cartflows-optin-meta.php:364
1246
- msgid "Input Fields"
1247
- msgstr ""
1248
-
1249
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1250
- #: modules/optin/classes/class-cartflows-optin-meta.php:371
1251
- msgid "Floating Labels (Available in CartFlows Pro)"
1252
- msgstr ""
1253
-
1254
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1255
- #: modules/optin/classes/class-cartflows-optin-meta.php:377
1256
- msgid "Style"
1257
- msgstr ""
1258
-
1259
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1260
- #: modules/optin/classes/class-cartflows-optin-meta.php:382
1261
- msgid "Floating Labels"
1262
- msgstr ""
1263
-
1264
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1265
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1266
- #: modules/optin/classes/class-cartflows-optin-meta.php:409
1267
- #: modules/optin/classes/class-cartflows-optin-meta.php:521
1268
- msgid "Size"
1269
- msgstr ""
1270
-
1271
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1272
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1273
- #: modules/optin/classes/class-cartflows-optin-meta.php:413
1274
- #: modules/optin/classes/class-cartflows-optin-meta.php:525
1275
- msgid "Extra Small"
1276
- msgstr ""
1277
-
1278
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1279
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1280
- #: modules/optin/classes/class-cartflows-optin-meta.php:414
1281
- #: modules/optin/classes/class-cartflows-optin-meta.php:526
1282
- msgid "Small"
1283
- msgstr ""
1284
-
1285
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1286
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1287
- #: modules/optin/classes/class-cartflows-optin-meta.php:415
1288
- #: modules/optin/classes/class-cartflows-optin-meta.php:527
1289
- msgid "Medium"
1290
- msgstr ""
1291
-
1292
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1293
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1294
- #: modules/optin/classes/class-cartflows-optin-meta.php:416
1295
- #: modules/optin/classes/class-cartflows-optin-meta.php:528
1296
- msgid "Large"
1297
- msgstr ""
1298
-
1299
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1300
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1301
- #: modules/optin/classes/class-cartflows-optin-meta.php:417
1302
- #: modules/optin/classes/class-cartflows-optin-meta.php:529
1303
- msgid "Extra Large"
1304
- msgstr ""
1305
-
1306
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1307
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1308
- #: modules/optin/classes/class-cartflows-optin-meta.php:418
1309
- #: modules/optin/classes/class-cartflows-optin-meta.php:530
1310
- msgid "Custom"
1311
- msgstr ""
1312
-
1313
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1314
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1315
- #: modules/optin/classes/class-cartflows-optin-meta.php:425
1316
- #: modules/optin/classes/class-cartflows-optin-meta.php:537
1317
- msgid "Top Bottom Spacing"
1318
- msgstr ""
1319
-
1320
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1321
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1322
- #: modules/optin/classes/class-cartflows-optin-meta.php:433
1323
- #: modules/optin/classes/class-cartflows-optin-meta.php:545
1324
- msgid "Left Right Spacing"
1325
- msgstr ""
1326
-
1327
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1328
- #: modules/optin/classes/class-cartflows-optin-meta.php:449
1329
- msgid "Text / Placeholder Color"
1330
- msgstr ""
1331
-
1332
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1333
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1334
- #: modules/optin/classes/class-cartflows-optin-meta.php:457
1335
- #: modules/optin/classes/class-cartflows-optin-meta.php:582
1336
- msgid "Background Color"
1337
- msgstr ""
1338
-
1339
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1340
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1341
- #: modules/optin/classes/class-cartflows-optin-meta.php:465
1342
- #: modules/optin/classes/class-cartflows-optin-meta.php:598
1343
- msgid "Border Color"
1344
- msgstr ""
1345
-
1346
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1347
- #: modules/optin/classes/class-cartflows-optin-meta.php:441
1348
- msgid "Label Color"
1349
- msgstr ""
1350
-
1351
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1352
- msgid "Buttons"
1353
- msgstr ""
1354
-
1355
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1356
- #: modules/optin/classes/class-cartflows-optin-meta.php:566
1357
- msgid "Text Color"
1358
- msgstr ""
1359
-
1360
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1361
- #: modules/optin/classes/class-cartflows-optin-meta.php:574
1362
- msgid "Text Hover Color"
1363
- msgstr ""
1364
-
1365
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1366
- #: modules/optin/classes/class-cartflows-optin-meta.php:590
1367
- msgid "Background Hover Color"
1368
- msgstr ""
1369
-
1370
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1371
- #: modules/optin/classes/class-cartflows-optin-meta.php:606
1372
- msgid "Border Hover Color"
1373
- msgstr ""
1374
-
1375
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1376
- msgid "Sections"
1377
- msgstr ""
1378
-
1379
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1380
- msgid "Highlight Area Background Color"
1381
- msgstr ""
1382
-
1383
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1384
- msgid "Header Logo"
1385
- msgstr ""
1386
-
1387
- #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1388
- msgid "Logo Width (In px)"
1389
- msgstr ""
1390
-
1391
- #: modules/checkout/templates/wcf-template.php:46
1392
- msgid "Copyright &copy;"
1393
- msgstr ""
1394
-
1395
- #: modules/checkout/templates/wcf-template.php:50
1396
- msgid "All Rights Reserved"
1397
- msgstr ""
1398
-
1399
- #: modules/flow/classes/class-cartflows-flow-meta.php:263
1400
- #. translators: %s flow id
1401
- msgid "Step not deleted for flow - %s"
1402
- msgstr ""
1403
-
1404
- #: modules/flow/classes/class-cartflows-flow-meta.php:294
1405
- #. translators: %s flow id
1406
- msgid "Step deleted for flow - %s"
1407
- msgstr ""
1408
-
1409
- #: modules/flow/classes/class-cartflows-flow-meta.php:322
1410
- #. translators: %s flow id
1411
- msgid "Steps not sorted for flow - %s"
1412
- msgstr ""
1413
-
1414
- #: modules/flow/classes/class-cartflows-flow-meta.php:345
1415
- #. translators: %s flow id
1416
- msgid "Steps sorted for flow - %s"
1417
- msgstr ""
1418
-
1419
- #: modules/flow/classes/class-cartflows-flow-meta.php:456
1420
- msgid "Analytics"
1421
- msgstr ""
1422
-
1423
- #: modules/flow/classes/class-cartflows-flow-meta.php:473
1424
- #. translators: %s: link
1425
- msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1426
- msgstr ""
1427
-
1428
- #: modules/flow/classes/class-cartflows-flow-meta.php:491
1429
- msgid "Flow Settings"
1430
- msgstr ""
1431
-
1432
- #: modules/flow/classes/class-cartflows-flow-meta.php:576
1433
- msgid "Enable Test Mode"
1434
- msgstr ""
1435
-
1436
- #: modules/flow/classes/class-cartflows-flow-meta.php:583
1437
- msgid ""
1438
- "If you are using WooCommerce plugin then test mode will add random products "
1439
- "in your flow, so you can preview it easily while testing."
1440
- msgstr ""
1441
-
1442
- #: modules/flow/classes/class-cartflows-flow-meta.php:702
1443
- #: modules/flow/view/meta-flow-steps.php:133
1444
- msgid "Add New Step"
1445
- msgstr ""
1446
-
1447
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1448
- msgid "Flow: "
1449
- msgstr ""
1450
-
1451
- #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1452
- msgid "Name: "
1453
- msgstr ""
1454
-
1455
- #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1456
- msgid "Search Flows"
1457
- msgstr ""
1458
-
1459
- #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1460
- msgid "All Flows"
1461
- msgstr ""
1462
-
1463
- #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1464
- msgid "Edit Flow"
1465
- msgstr ""
1466
-
1467
- #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1468
- msgid "View Flow"
1469
- msgstr ""
1470
-
1471
- #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1472
- #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1473
- #: modules/flow/classes/class-cartflows-step-post-type.php:167
1474
- #: modules/flow/classes/class-cartflows-step-post-type.php:169
1475
- msgid "Add New"
1476
- msgstr ""
1477
-
1478
- #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1479
- msgid "Update Flow"
1480
- msgstr ""
1481
-
1482
- #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1483
- msgid "New Flow Name"
1484
- msgstr ""
1485
-
1486
- #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1487
- msgid "Upgrade to CartFlows Pro"
1488
- msgstr ""
1489
-
1490
- #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1491
- msgid "Slug"
1492
- msgstr ""
1493
-
1494
- #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1495
- msgid "Flows"
1496
- msgstr ""
1497
-
1498
- #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1499
- #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1500
- #: modules/flow/classes/class-cartflows-step-post-type.php:401
1501
- #: modules/flow/classes/class-cartflows-step-post-type.php:407
1502
- #. translators: %s: singular custom post type name
1503
- msgid "%s updated."
1504
- msgstr ""
1505
-
1506
- #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1507
- #: modules/flow/classes/class-cartflows-step-post-type.php:403
1508
- #. translators: %s: singular custom post type name
1509
- msgid "Custom %s updated."
1510
- msgstr ""
1511
-
1512
- #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1513
- #: modules/flow/classes/class-cartflows-step-post-type.php:405
1514
- #. translators: %s: singular custom post type name
1515
- msgid "Custom %s deleted."
1516
- msgstr ""
1517
-
1518
- #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1519
- #: modules/flow/classes/class-cartflows-step-post-type.php:409
1520
- #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1521
- #. the revision
1522
- msgid "%1$s restored to revision from %2$s"
1523
- msgstr ""
1524
-
1525
- #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1526
- #: modules/flow/classes/class-cartflows-step-post-type.php:411
1527
- #. translators: %s: singular custom post type name
1528
- msgid "%s published."
1529
- msgstr ""
1530
-
1531
- #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1532
- #: modules/flow/classes/class-cartflows-step-post-type.php:413
1533
- #. translators: %s: singular custom post type name
1534
- msgid "%s saved."
1535
- msgstr ""
1536
-
1537
- #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1538
- #: modules/flow/classes/class-cartflows-step-post-type.php:415
1539
- #. translators: %s: singular custom post type name
1540
- msgid "%s submitted."
1541
- msgstr ""
1542
-
1543
- #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1544
- #: modules/flow/classes/class-cartflows-step-post-type.php:417
1545
- #. translators: %s: singular custom post type name
1546
- msgid "%s scheduled for."
1547
- msgstr ""
1548
-
1549
- #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1550
- #: modules/flow/classes/class-cartflows-step-post-type.php:419
1551
- #. translators: %s: singular custom post type name
1552
- msgid "%s draft updated."
1553
- msgstr ""
1554
-
1555
- #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1556
- #: modules/widgets/class-cartflows-next-step.php:78
1557
- msgid "Next Step"
1558
- msgstr ""
1559
-
1560
- #: modules/flow/classes/class-cartflows-step-post-type.php:163
1561
- msgid "Search Steps"
1562
- msgstr ""
1563
-
1564
- #: modules/flow/classes/class-cartflows-step-post-type.php:164
1565
- msgid "All Steps"
1566
- msgstr ""
1567
-
1568
- #: modules/flow/classes/class-cartflows-step-post-type.php:165
1569
- #: modules/flow/view/meta-flow-steps.php:106
1570
- msgid "Edit Step"
1571
- msgstr ""
1572
-
1573
- #: modules/flow/classes/class-cartflows-step-post-type.php:166
1574
- #: modules/flow/view/meta-flow-steps.php:102
1575
- msgid "View Step"
1576
- msgstr ""
1577
-
1578
- #: modules/flow/classes/class-cartflows-step-post-type.php:168
1579
- msgid "Update Step"
1580
- msgstr ""
1581
-
1582
- #: modules/flow/classes/class-cartflows-step-post-type.php:170
1583
- msgid "New Step Name"
1584
- msgstr ""
1585
-
1586
- #: modules/flow/classes/class-cartflows-step-post-type.php:211
1587
- msgid "Step Type"
1588
- msgstr ""
1589
-
1590
- #: modules/flow/classes/class-cartflows-step-post-type.php:221
1591
- msgid "Step Flow"
1592
- msgstr ""
1593
-
1594
- #: modules/flow/classes/class-cartflows-step-post-type.php:246
1595
- #: modules/flow/view/meta-flow-steps.php:16
1596
- msgid "Optin (Woo)"
1597
- msgstr ""
1598
-
1599
- #: modules/flow/classes/class-cartflows-step-post-type.php:267
1600
- #: modules/flow/view/meta-flow-steps.php:14
1601
- msgid "Upsell (Woo)"
1602
- msgstr ""
1603
-
1604
- #: modules/flow/classes/class-cartflows-step-post-type.php:274
1605
- #: modules/flow/view/meta-flow-steps.php:15
1606
- msgid "Downsell (Woo)"
1607
- msgstr ""
1608
-
1609
- #: modules/flow/view/meta-flow-steps.php:85
1610
- msgid "No Product Assigned"
1611
- msgstr ""
1612
-
1613
- #: modules/flow/view/meta-flow-steps.php:89
1614
- msgid "Global Checkout - Remove selected checkout product"
1615
- msgstr ""
1616
-
1617
- #: modules/flow/view/meta-flow-steps.php:108
1618
- msgid "Edit"
1619
- msgstr ""
1620
-
1621
- #: modules/flow/view/meta-flow-steps.php:113
1622
- msgid "Clone Step"
1623
- msgstr ""
1624
-
1625
- #: modules/flow/view/meta-flow-steps.php:118
1626
- msgid "Delete Step"
1627
- msgstr ""
1628
-
1629
- #: modules/flow/view/meta-flow-steps.php:120
1630
- msgid "Delete"
1631
- msgstr ""
1632
-
1633
- #: modules/flow/view/meta-flow-steps.php:149
1634
- msgid "Steps Library"
1635
- msgstr ""
1636
-
1637
- #: modules/flow/view/meta-flow-steps.php:198
1638
- msgid "Create Step"
1639
- msgstr ""
1640
-
1641
- #: modules/flow/view/meta-flow-steps.php:200
1642
- msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1643
- msgstr ""
1644
-
1645
- #: modules/landing/classes/class-cartflows-landing-meta.php:66
1646
- msgid "Landing Page Settings"
1647
- msgstr ""
1648
-
1649
- #: modules/landing/classes/class-cartflows-landing-meta.php:169
1650
- msgid "Next Step Link"
1651
- msgstr ""
1652
-
1653
- #: modules/optin/classes/class-cartflows-optin-markup.php:165
1654
- msgid "Please place shortcode on Optin step-type only."
1655
- msgstr ""
1656
-
1657
- #: modules/optin/classes/class-cartflows-optin-markup.php:225
1658
- msgid ""
1659
- "No product is selected. Please select a Simple, Virtual and Free product "
1660
- "from the meta settings."
1661
- msgstr ""
1662
-
1663
- #: modules/optin/classes/class-cartflows-optin-markup.php:242
1664
- msgid "Please update the selected product's price to zero (0)."
1665
- msgstr ""
1666
-
1667
- #: modules/optin/classes/class-cartflows-optin-markup.php:251
1668
- #: modules/optin/classes/class-cartflows-optin-markup.php:255
1669
- msgid "Please select a Simple, Virtual and Free product."
1670
- msgstr ""
1671
-
1672
- #: modules/optin/classes/class-cartflows-optin-meta.php:65
1673
- msgid "Optin Settings"
1674
- msgstr ""
1675
-
1676
- #: modules/optin/classes/class-cartflows-optin-meta.php:138
1677
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1678
- msgid "Design"
1679
- msgstr ""
1680
-
1681
- #: modules/optin/classes/class-cartflows-optin-meta.php:144
1682
- msgid "Form Fields"
1683
- msgstr ""
1684
-
1685
- #: modules/optin/classes/class-cartflows-optin-meta.php:213
1686
- msgid "Add this shortcode to your optin page"
1687
- msgstr ""
1688
-
1689
- #: modules/optin/classes/class-cartflows-optin-meta.php:238
1690
- msgid "Select Free Product"
1691
- msgstr ""
1692
-
1693
- #: modules/optin/classes/class-cartflows-optin-meta.php:239
1694
- msgid "Select Free and Virtual product only."
1695
- msgstr ""
1696
-
1697
- #: modules/optin/classes/class-cartflows-optin-meta.php:291
1698
- msgid "Pass Fields as URL Parameters"
1699
- msgstr ""
1700
-
1701
- #: modules/optin/classes/class-cartflows-optin-meta.php:294
1702
- msgid "Enable"
1703
- msgstr ""
1704
-
1705
- #: modules/optin/classes/class-cartflows-optin-meta.php:295
1706
- msgid ""
1707
- "You can pass specific fields from the form to next step as URL query "
1708
- "parameters."
1709
- msgstr ""
1710
-
1711
- #: modules/optin/classes/class-cartflows-optin-meta.php:306
1712
- msgid "Enter form field"
1713
- msgstr ""
1714
-
1715
- #: modules/optin/classes/class-cartflows-optin-meta.php:309
1716
- #: modules/optin/classes/class-cartflows-optin-meta.php:319
1717
- msgid "Enter comma seprated field name. E.g. first_name, last_name"
1718
- msgstr ""
1719
-
1720
- #: modules/optin/classes/class-cartflows-optin-meta.php:311
1721
- msgid "Fields to pass, separated by commas"
1722
- msgstr ""
1723
-
1724
- #: modules/optin/classes/class-cartflows-optin-meta.php:321
1725
- #. translators: %s: link
1726
- msgid ""
1727
- "You can pass field value as a URL parameter to the next step. %1$sClick "
1728
- "here%2$s for more information."
1729
- msgstr ""
1730
-
1731
- #: modules/optin/classes/class-cartflows-optin-meta.php:478
1732
- msgid "Submit Button"
1733
- msgstr ""
1734
-
1735
- #: modules/optin/classes/class-cartflows-optin-meta.php:484
1736
- msgid "Button Text"
1737
- msgstr ""
1738
-
1739
- #: modules/optin/classes/class-cartflows-optin-meta.php:495
1740
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1741
- msgid "Font Size"
1742
- msgstr ""
1743
-
1744
- #: modules/optin/classes/class-cartflows-optin-meta.php:553
1745
- msgid "Position"
1746
- msgstr ""
1747
-
1748
- #: modules/optin/classes/class-cartflows-optin-meta.php:557
1749
- msgid "Left"
1750
- msgstr ""
1751
-
1752
- #: modules/optin/classes/class-cartflows-optin-meta.php:558
1753
- msgid "Center"
1754
- msgstr ""
1755
-
1756
- #: modules/optin/classes/class-cartflows-optin-meta.php:559
1757
- msgid "Right"
1758
- msgstr ""
1759
-
1760
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1761
- msgid "Thank You Page Settings"
1762
- msgstr ""
1763
-
1764
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1765
- msgid "Edit Fields"
1766
- msgstr ""
1767
-
1768
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1769
- msgid "Order Details"
1770
- msgstr ""
1771
-
1772
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1773
- msgid "Text"
1774
- msgstr ""
1775
-
1776
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1777
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1778
- msgid "Color"
1779
- msgstr ""
1780
-
1781
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1782
- msgid "Advanced Options"
1783
- msgstr ""
1784
-
1785
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1786
- msgid "Container Width (In px)"
1787
- msgstr ""
1788
-
1789
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1790
- msgid "Section Background Color"
1791
- msgstr ""
1792
-
1793
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1794
- msgid "Enable Order Overview "
1795
- msgstr ""
1796
-
1797
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1798
- msgid "Enable Order Details "
1799
- msgstr ""
1800
-
1801
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1802
- msgid "Enable Billing Details "
1803
- msgstr ""
1804
-
1805
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1806
- msgid "Enable Shipping Details "
1807
- msgstr ""
1808
-
1809
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1810
- msgid "Thank You Page Text"
1811
- msgstr ""
1812
-
1813
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1814
- #: woocommerce/template/checkout/thankyou.php:41
1815
- #: woocommerce/template/checkout/thankyou.php:83
1816
- msgid "Thank you. Your order has been received."
1817
- msgstr ""
1818
-
1819
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1820
- msgid "It will change the default text on thank you page."
1821
- msgstr ""
1822
-
1823
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1824
- msgid "Redirect After Purchase"
1825
- msgstr ""
1826
-
1827
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1828
- msgid "Redirect Link"
1829
- msgstr ""
1830
-
1831
- #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1832
- msgid "https://"
1833
- msgstr ""
1834
-
1835
- #: modules/widgets/class-cartflows-next-step.php:24
1836
- msgid "CartFlows Next Step"
1837
- msgstr ""
1838
-
1839
- #: modules/widgets/class-cartflows-next-step.php:26
1840
- msgid "Next Step Widgets"
1841
- msgstr ""
1842
-
1843
- #: modules/widgets/class-cartflows-next-step.php:106
1844
- msgid "New title"
1845
- msgstr ""
1846
-
1847
- #: modules/widgets/class-cartflows-next-step.php:123
1848
- msgid "Title:"
1849
- msgstr ""
1850
-
1851
- #: modules/widgets/class-cartflows-next-step.php:127
1852
- msgid "Flow ID:"
1853
- msgstr ""
1854
-
1855
- #: modules/widgets/class-cartflows-next-step.php:131
1856
- msgid "Step ID:"
1857
- msgstr ""
1858
-
1859
- #: woocommerce/template/cart/cart-shipping.php:51
1860
- #. Translators: $s shipping destination.
1861
- msgid "Estimate for %s."
1862
- msgstr ""
1863
-
1864
- #: woocommerce/template/cart/cart-shipping.php:52
1865
- msgid "Change address"
1866
- msgstr ""
1867
-
1868
- #: woocommerce/template/cart/cart-shipping.php:54
1869
- msgid "This is only an estimate. Prices will be updated during checkout."
1870
- msgstr ""
1871
-
1872
- #: woocommerce/template/cart/cart-shipping.php:61
1873
- msgid "Enter your address to view shipping options."
1874
- msgstr ""
1875
-
1876
- #: woocommerce/template/cart/cart-shipping.php:63
1877
- msgid ""
1878
- "There are no shipping methods available. Please ensure that your address "
1879
- "has been entered correctly, or contact us if you need any help."
1880
- msgstr ""
1881
-
1882
- #: woocommerce/template/cart/cart-shipping.php:66
1883
- #. Translators: $s shipping destination.
1884
- msgid "No shipping options were found for %s."
1885
- msgstr ""
1886
-
1887
- #: woocommerce/template/cart/cart-shipping.php:67
1888
- msgid "Enter a different address"
1889
- msgstr ""
1890
-
1891
- #: woocommerce/template/checkout/form-billing.php:27
1892
- msgid "Billing &amp; Shipping"
1893
- msgstr ""
1894
-
1895
- #: woocommerce/template/checkout/form-billing.php:31
1896
- msgid "Billing details"
1897
- msgstr ""
1898
-
1899
- #: woocommerce/template/checkout/form-billing.php:59
1900
- msgid "Create an account?"
1901
- msgstr ""
1902
-
1903
- #: woocommerce/template/checkout/form-checkout.php:26
1904
- msgid "You must be logged in to checkout."
1905
- msgstr ""
1906
-
1907
- #: woocommerce/template/checkout/form-checkout.php:52
1908
- msgid "Your order"
1909
- msgstr ""
1910
-
1911
- #: woocommerce/template/checkout/form-coupon.php:26
1912
- msgid "Have a coupon?"
1913
- msgstr ""
1914
-
1915
- #: woocommerce/template/checkout/form-coupon.php:26
1916
- msgid "Click here to enter your code"
1917
- msgstr ""
1918
-
1919
- #: woocommerce/template/checkout/form-coupon.php:31
1920
- msgid "If you have a coupon code, please apply it below."
1921
- msgstr ""
1922
-
1923
- #: woocommerce/template/checkout/form-coupon.php:34
1924
- msgid "Coupon code"
1925
- msgstr ""
1926
-
1927
- #: woocommerce/template/checkout/form-coupon.php:38
1928
- msgid "Apply coupon"
1929
- msgstr ""
1930
-
1931
- #: woocommerce/template/checkout/form-login.php:26
1932
- msgid "Returning customer?"
1933
- msgstr ""
1934
-
1935
- #: woocommerce/template/checkout/form-login.php:26
1936
- msgid "Click here to login"
1937
- msgstr ""
1938
-
1939
- #: woocommerce/template/checkout/form-login.php:32
1940
- msgid ""
1941
- "If you have shopped with us before, please enter your details below. If you "
1942
- "are a new customer, please proceed to the Billing &amp; Shipping section."
1943
- msgstr ""
1944
-
1945
- #: woocommerce/template/checkout/form-shipping.php:26
1946
- msgid "Ship to a different address?"
1947
- msgstr ""
1948
-
1949
- #: woocommerce/template/checkout/form-shipping.php:57
1950
- msgid "Additional information"
1951
- msgstr ""
1952
-
1953
- #: woocommerce/template/checkout/payment.php:33
1954
- msgid ""
1955
- "Sorry, it seems that there are no available payment methods for your state. "
1956
- "Please contact us if you require assistance or wish to make alternate "
1957
- "arrangements."
1958
- msgstr ""
1959
-
1960
- #: woocommerce/template/checkout/payment.php:33
1961
- msgid "Please fill in your details above to see available payment methods."
1962
- msgstr ""
1963
-
1964
- #: woocommerce/template/checkout/payment.php:42
1965
- #. translators: $1 and $2 opening and closing emphasis tags respectively
1966
- msgid ""
1967
- "Since your browser does not support JavaScript, or it is disabled, please "
1968
- "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1969
- "order. You may be charged more than the amount stated above if you fail to "
1970
- "do so."
1971
- msgstr ""
1972
-
1973
- #: woocommerce/template/checkout/payment.php:44
1974
- msgid "Update totals"
1975
- msgstr ""
1976
-
1977
- #: woocommerce/template/checkout/review-order.php:26
1978
- #: woocommerce/template/order/order-details.php:51
1979
- msgid "Product"
1980
- msgstr ""
1981
-
1982
- #: woocommerce/template/checkout/review-order.php:27
1983
- #: woocommerce/template/checkout/review-order.php:107
1984
- #: woocommerce/template/order/order-details.php:52
1985
- msgid "Total"
1986
- msgstr ""
1987
-
1988
- #: woocommerce/template/checkout/review-order.php:60
1989
- msgid "Subtotal"
1990
- msgstr ""
1991
-
1992
- #: woocommerce/template/checkout/thankyou.php:30
1993
- msgid ""
1994
- "Unfortunately your order cannot be processed as the originating "
1995
- "bank/merchant has declined your transaction. Please attempt your purchase "
1996
- "again."
1997
- msgstr ""
1998
-
1999
- #: woocommerce/template/checkout/thankyou.php:33
2000
- msgid "Pay"
2001
- msgstr ""
2002
-
2003
- #: woocommerce/template/checkout/thankyou.php:35
2004
- msgid "My account"
2005
- msgstr ""
2006
-
2007
- #: woocommerce/template/checkout/thankyou.php:46
2008
- msgid "Order number:"
2009
- msgstr ""
2010
-
2011
- #: woocommerce/template/checkout/thankyou.php:51
2012
- msgid "Date:"
2013
- msgstr ""
2014
-
2015
- #: woocommerce/template/checkout/thankyou.php:57
2016
- msgid "Email:"
2017
- msgstr ""
2018
-
2019
- #: woocommerce/template/checkout/thankyou.php:63
2020
- msgid "Total:"
2021
- msgstr ""
2022
-
2023
- #: woocommerce/template/checkout/thankyou.php:69
2024
- msgid "Payment method:"
2025
- msgstr ""
2026
-
2027
- #: woocommerce/template/global/form-login.php:34
2028
- msgid "Username or email"
2029
- msgstr ""
2030
-
2031
- #: woocommerce/template/global/form-login.php:38
2032
- msgid "Password"
2033
- msgstr ""
2034
-
2035
- #: woocommerce/template/global/form-login.php:48
2036
- msgid "Login"
2037
- msgstr ""
2038
-
2039
- #: woocommerce/template/global/form-login.php:53
2040
- msgid "Remember me"
2041
- msgstr ""
2042
-
2043
- #: woocommerce/template/global/form-login.php:57
2044
- msgid "Lost your password?"
2045
- msgstr ""
2046
-
2047
- #: woocommerce/template/order/order-details.php:45
2048
- msgid "Order details"
2049
- msgstr ""
2050
-
2051
- #: woocommerce/template/order/order-details.php:93
2052
- msgid "Note:"
2053
- msgstr ""
2054
-
2055
- #. Plugin Name of the plugin/theme
2056
- msgid "CartFlows"
2057
- msgstr ""
2058
-
2059
- #. Author URI of the plugin/theme
2060
- msgid "https://cartflows.com/"
2061
- msgstr ""
2062
-
2063
- #. Description of the plugin/theme
2064
- msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2065
- msgstr ""
2066
-
2067
- #. Author of the plugin/theme
2068
- msgid "CartFlows Inc"
2069
- msgstr ""
2070
-
2071
- #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2072
- msgctxt "flow general name"
2073
- msgid "Flows"
2074
- msgstr ""
2075
-
2076
- #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2077
- msgctxt "flow singular name"
2078
- msgid "Flow"
2079
- msgstr ""
2080
-
2081
- #: modules/flow/classes/class-cartflows-step-post-type.php:161
2082
- msgctxt "flow step general name"
2083
- msgid "Steps"
2084
- msgstr ""
2085
-
2086
- #: modules/flow/classes/class-cartflows-step-post-type.php:162
2087
- msgctxt "flow step singular name"
2088
- msgid "Step"
2089
- msgstr ""
2090
-
2091
- #: modules/flow/classes/class-cartflows-step-post-type.php:315
2092
- msgctxt "cartflows"
2093
- msgid "CartFlows — Boxed"
2094
- msgstr ""
2095
-
2096
- #: modules/flow/classes/class-cartflows-step-post-type.php:316
2097
- msgctxt "cartflows"
2098
- msgid "Template for Page Builders"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2099
  msgstr ""
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.13\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2020-07-21 06:58:49+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=utf-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+ "Language: en\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-Country: United States\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-KeywordsList: "
19
+ "__;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;_nx_noop:1,2,3c;esc_"
20
+ "attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;esc_html_x:1,2c;\n"
21
+ "X-Poedit-Basepath: ../\n"
22
+ "X-Poedit-SearchPath-0: .\n"
23
+ "X-Poedit-Bookmarks: \n"
24
+ "X-Textdomain-Support: yes\n"
25
+ "X-Generator: grunt-wp-i18n 1.0.3\n"
26
+
27
+ #: admin/bsf-analytics/class-bsf-analytics.php:229
28
+ #. translators: %s product name
29
+ msgid ""
30
+ "Want to help make <strong>%1s</strong> even more awesome? Allow us to "
31
+ "collect non-sensitive diagnostic data and usage information. "
32
+ msgstr ""
33
+
34
+ #: admin/bsf-analytics/class-bsf-analytics.php:232
35
+ msgid "This will be applicable for all sites from the network."
36
+ msgstr ""
37
+
38
+ #: admin/bsf-analytics/class-bsf-analytics.php:256
39
+ #. translators: %s usage doc link
40
+ msgid " Know More."
41
+ msgstr ""
42
+
43
+ #: admin/bsf-analytics/class-bsf-analytics.php:264
44
+ msgid "Yes! Allow it"
45
+ msgstr ""
46
+
47
+ #: admin/bsf-analytics/class-bsf-analytics.php:273
48
+ msgid "No Thanks"
49
+ msgstr ""
50
+
51
+ #: admin/bsf-analytics/class-bsf-analytics.php:353
52
+ msgid "Every two days"
53
+ msgstr ""
54
+
55
+ #: admin/bsf-analytics/class-bsf-analytics.php:412
56
+ msgid "Usage Tracking"
57
+ msgstr ""
58
+
59
+ #: admin/bsf-analytics/class-bsf-analytics.php:459
60
+ msgid " This will be applicable for all sites from the network."
61
+ msgstr ""
62
+
63
+ #: admin/bsf-analytics/class-bsf-analytics.php:464
64
+ msgid "Learn More."
65
+ msgstr ""
66
+
67
+ #: classes/batch-process/class-cartflows-importer-elementor.php:44
68
+ msgid "Invalid content."
69
+ msgstr ""
70
+
71
+ #: classes/batch-process/class-cartflows-importer-elementor.php:56
72
+ msgid "Invalid content. Expected an array."
73
+ msgstr ""
74
+
75
+ #: classes/batch-process/helpers/class-wp-background-process.php:435
76
+ msgid "Every %d Minutes"
77
+ msgstr ""
78
+
79
+ #: classes/class-cartflows-admin-fields.php:235
80
+ msgid "Select"
81
+ msgstr ""
82
+
83
+ #: classes/class-cartflows-admin-fields.php:238
84
+ msgid "No Checkout Steps"
85
+ msgstr ""
86
+
87
+ #: classes/class-cartflows-admin-fields.php:264
88
+ #. translators: %s: link
89
+ msgid ""
90
+ "Be sure not to add any product in above selected Global Checkout step. "
91
+ "Please read information about how to set up Global Checkout %1$shere%2$s."
92
+ msgstr ""
93
+
94
+ #: classes/class-cartflows-admin.php:153 classes/class-cartflows-admin.php:154
95
+ #: includes/admin/cartflows-general-bck.php:34
96
+ #: modules/optin/classes/class-cartflows-optin-meta.php:150
97
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:148
98
+ msgid "Settings"
99
+ msgstr ""
100
+
101
+ #: classes/class-cartflows-admin.php:440
102
+ msgid "Installing and activating.."
103
+ msgstr ""
104
+
105
+ #: classes/class-cartflows-admin.php:441
106
+ msgid "There was an error with the installation of plugin."
107
+ msgstr ""
108
+
109
+ #: classes/class-cartflows-admin.php:495
110
+ msgid "Flows Library"
111
+ msgstr ""
112
+
113
+ #: classes/class-cartflows-admin.php:502
114
+ #: modules/flow/view/meta-flow-steps.php:156
115
+ msgid "Ready Templates"
116
+ msgstr ""
117
+
118
+ #: classes/class-cartflows-admin.php:505
119
+ #: modules/flow/view/meta-flow-steps.php:159
120
+ msgid "Create Your Own"
121
+ msgstr ""
122
+
123
+ #: classes/class-cartflows-admin.php:516
124
+ #: modules/flow/view/meta-flow-steps.php:171
125
+ msgid "Search Sites"
126
+ msgstr ""
127
+
128
+ #: classes/class-cartflows-admin.php:517
129
+ #: modules/flow/view/meta-flow-steps.php:172
130
+ msgid "Search Flow..."
131
+ msgstr ""
132
+
133
+ #: classes/class-cartflows-admin.php:534
134
+ msgid "Design Your Flow"
135
+ msgstr ""
136
+
137
+ #: classes/class-cartflows-admin.php:535
138
+ #: classes/class-cartflows-importer.php:665
139
+ #: classes/class-cartflows-importer.php:764
140
+ #: modules/flow/view/meta-flow-steps.php:202
141
+ msgid "Learn How"
142
+ msgstr ""
143
+
144
+ #: classes/class-cartflows-api.php:369
145
+ msgid "Request successfully processed!"
146
+ msgstr ""
147
+
148
+ #: classes/class-cartflows-cloning.php:423
149
+ msgid "Clone this flow"
150
+ msgstr ""
151
+
152
+ #: classes/class-cartflows-cloning.php:423
153
+ #: modules/flow/view/meta-flow-steps.php:115
154
+ msgid "Clone"
155
+ msgstr ""
156
+
157
+ #: classes/class-cartflows-default-meta.php:745
158
+ #: modules/optin/classes/class-cartflows-optin-meta.php:490
159
+ msgid "Submit"
160
+ msgstr ""
161
+
162
+ #: classes/class-cartflows-flow-frontend.php:53
163
+ msgid ""
164
+ "Test mode is active — which displays random products for previewing. It can "
165
+ "be deactivated from the flow settings in the admin dashboard."
166
+ msgstr ""
167
+
168
+ #: classes/class-cartflows-flow-frontend.php:58
169
+ msgid "Click here to disable it"
170
+ msgstr ""
171
+
172
+ #: classes/class-cartflows-importer.php:81
173
+ msgid "Export this flow"
174
+ msgstr ""
175
+
176
+ #: classes/class-cartflows-importer.php:81 includes/exporter.php:18
177
+ msgid "Export"
178
+ msgstr ""
179
+
180
+ #: classes/class-cartflows-importer.php:92
181
+ msgid "Flow Export"
182
+ msgstr ""
183
+
184
+ #: classes/class-cartflows-importer.php:93
185
+ msgid "Flow Import"
186
+ msgstr ""
187
+
188
+ #: classes/class-cartflows-importer.php:104
189
+ msgid "No post to export has been supplied!"
190
+ msgstr ""
191
+
192
+ #: classes/class-cartflows-importer.php:278
193
+ msgid "Please upload a valid .json file"
194
+ msgstr ""
195
+
196
+ #: classes/class-cartflows-importer.php:284
197
+ msgid "Please upload a file to import"
198
+ msgstr ""
199
+
200
+ #: classes/class-cartflows-importer.php:506
201
+ msgid "Successfully imported flows."
202
+ msgstr ""
203
+
204
+ #: classes/class-cartflows-importer.php:538
205
+ msgid "Loading Steps"
206
+ msgstr ""
207
+
208
+ #: classes/class-cartflows-importer.php:540
209
+ msgid "Getting steps from the cloud. Please wait for the moment."
210
+ msgstr ""
211
+
212
+ #: classes/class-cartflows-importer.php:551
213
+ msgid "Searching Template.."
214
+ msgstr ""
215
+
216
+ #: classes/class-cartflows-importer.php:553
217
+ msgid "Getting templates from the cloud. Please wait for the moment."
218
+ msgstr ""
219
+
220
+ #: classes/class-cartflows-importer.php:562
221
+ msgid "Importing.."
222
+ msgstr ""
223
+
224
+ #: classes/class-cartflows-importer.php:571
225
+ #: classes/class-cartflows-importer.php:611
226
+ msgid "Imported"
227
+ msgstr ""
228
+
229
+ #: classes/class-cartflows-importer.php:572
230
+ #: classes/class-cartflows-importer.php:612
231
+ msgid "Thanks for patience"
232
+ msgstr ""
233
+
234
+ #: classes/class-cartflows-importer.php:581
235
+ #: classes/class-cartflows-importer.php:593
236
+ msgid "Coming Soon!"
237
+ msgstr ""
238
+
239
+ #: classes/class-cartflows-importer.php:612
240
+ msgid "Redirecting to the Elementor edit window."
241
+ msgstr ""
242
+
243
+ #: classes/class-cartflows-importer.php:658
244
+ #: classes/class-cartflows-importer.php:774
245
+ msgid "Pro"
246
+ msgstr ""
247
+
248
+ #: classes/class-cartflows-importer.php:699
249
+ #: classes/class-cartflows-importer.php:806
250
+ msgid "Activate License"
251
+ msgstr ""
252
+
253
+ #: classes/class-cartflows-importer.php:701
254
+ #: classes/class-cartflows-importer.php:808
255
+ #: modules/flow/classes/class-cartflows-flow-meta.php:474
256
+ msgid "Get Pro"
257
+ msgstr ""
258
+
259
+ #: classes/class-cartflows-importer.php:726
260
+ msgid "Create"
261
+ msgstr ""
262
+
263
+ #: classes/class-cartflows-importer.php:825
264
+ msgid "Under Maintenance.."
265
+ msgstr ""
266
+
267
+ #: classes/class-cartflows-importer.php:826
268
+ msgid ""
269
+ "If you are seeing this message, most likely our servers are under routine "
270
+ "maintenance and we will be back shortly."
271
+ msgstr ""
272
+
273
+ #: classes/class-cartflows-importer.php:827
274
+ msgid ""
275
+ "In rare case, it is possible your website is having trouble connecting with "
276
+ "ours. If you need help, please feel free to get in touch with us from our "
277
+ "website.."
278
+ msgstr ""
279
+
280
+ #: classes/class-cartflows-importer.php:857
281
+ #. translators: %s: Plugin string
282
+ msgid ""
283
+ "%1$s to see CartFlows templates. If you prefer another page builder tool, "
284
+ "you can <a href=\"%2$s\" target=\"blank\">select it here</a>."
285
+ msgstr ""
286
+
287
+ #: classes/class-cartflows-importer.php:872
288
+ msgid "All"
289
+ msgstr ""
290
+
291
+ #: classes/class-cartflows-importer.php:875
292
+ msgid "Select Step Type"
293
+ msgstr ""
294
+
295
+ #: classes/class-cartflows-importer.php:959
296
+ msgid "Import from Cloud"
297
+ msgstr ""
298
+
299
+ #: classes/class-cartflows-importer.php:1267
300
+ msgid "Sales Landing"
301
+ msgstr ""
302
+
303
+ #: classes/class-cartflows-importer.php:1271
304
+ #: modules/flow/classes/class-cartflows-step-post-type.php:253
305
+ #: modules/flow/view/meta-flow-steps.php:12
306
+ msgid "Checkout (Woo)"
307
+ msgstr ""
308
+
309
+ #: classes/class-cartflows-importer.php:1275
310
+ #: modules/flow/classes/class-cartflows-step-post-type.php:260
311
+ #: modules/flow/view/meta-flow-steps.php:13
312
+ msgid "Thank You (Woo)"
313
+ msgstr ""
314
+
315
+ #: classes/class-cartflows-importer.php:1283
316
+ #: modules/flow/classes/class-cartflows-step-post-type.php:239
317
+ #: modules/flow/view/meta-flow-steps.php:11
318
+ msgid "Landing"
319
+ msgstr ""
320
+
321
+ #: classes/class-cartflows-importer.php:1287
322
+ msgid "Thank You"
323
+ msgstr ""
324
+
325
+ #: classes/class-cartflows-importer.php:1397
326
+ #. translators: %s: template ID
327
+ msgid "Invalid template id %1$s or post id %2$s."
328
+ msgstr ""
329
+
330
+ #: classes/class-cartflows-importer.php:1472
331
+ #. translators: %s: flow ID
332
+ msgid "Invalid flow id %1$s OR step type %2$s."
333
+ msgstr ""
334
+
335
+ #: classes/class-cartflows-importer.php:1597
336
+ msgid ""
337
+ "Elementor is not activated. Please activate plugin Elementor Page Builder "
338
+ "to import the step."
339
+ msgstr ""
340
+
341
+ #: classes/class-cartflows-importer.php:1700
342
+ msgid "Action failed. Invalid Security Nonce."
343
+ msgstr ""
344
+
345
+ #: classes/class-cartflows-importer.php:1707
346
+ msgid "User have not plugin install permissions."
347
+ msgstr ""
348
+
349
+ #: classes/class-cartflows-importer.php:1729
350
+ msgid "Plugin Successfully Activated"
351
+ msgstr ""
352
+
353
+ #: classes/class-cartflows-learndash-compatibility.php:86
354
+ msgid "None"
355
+ msgstr ""
356
+
357
+ #: classes/class-cartflows-learndash-compatibility.php:113
358
+ #. translators: 1: anchor start, 2: anchor close
359
+ msgid ""
360
+ "Non-enrolled students will redirect to the selected CartFlows template. If "
361
+ "you have not created any Flow already, add new Flow from %1$shere%2$s."
362
+ msgstr ""
363
+
364
+ #: classes/class-cartflows-learndash-compatibility.php:119
365
+ msgid "Select CartFlows Template for this Course"
366
+ msgstr ""
367
+
368
+ #: classes/class-cartflows-loader.php:222
369
+ #. translators: %s: html tags
370
+ msgid ""
371
+ "You are using an older version of %1$sCartFlows Pro%2$s. Please update "
372
+ "%1$sCartFlows Pro%2$s plugin to version %1$s%3$s%2$s or higher."
373
+ msgstr ""
374
+
375
+ #: classes/class-cartflows-loader.php:485
376
+ #. translators: %s: html tags
377
+ msgid ""
378
+ "This %1$sCartFlows%2$s page requires %1$sWooCommerce%2$s plugin installed & "
379
+ "activated."
380
+ msgstr ""
381
+
382
+ #: classes/class-cartflows-loader.php:495
383
+ msgid "Activate WooCommerce"
384
+ msgstr ""
385
+
386
+ #: classes/class-cartflows-loader.php:503
387
+ msgid "Install WooCommerce"
388
+ msgstr ""
389
+
390
+ #: classes/class-cartflows-logger.php:161
391
+ msgid "Action failed. Please refresh the page and retry."
392
+ msgstr ""
393
+
394
+ #: classes/class-cartflows-meta-fields.php:84
395
+ msgid "Thin 100"
396
+ msgstr ""
397
+
398
+ #: classes/class-cartflows-meta-fields.php:85
399
+ msgid "Extra-Light 200"
400
+ msgstr ""
401
+
402
+ #: classes/class-cartflows-meta-fields.php:86
403
+ msgid "Light 300"
404
+ msgstr ""
405
+
406
+ #: classes/class-cartflows-meta-fields.php:87
407
+ msgid "Normal 400"
408
+ msgstr ""
409
+
410
+ #: classes/class-cartflows-meta-fields.php:88
411
+ msgid "Medium 500"
412
+ msgstr ""
413
+
414
+ #: classes/class-cartflows-meta-fields.php:89
415
+ msgid "Semi-Bold 600"
416
+ msgstr ""
417
+
418
+ #: classes/class-cartflows-meta-fields.php:90
419
+ msgid "Bold 700"
420
+ msgstr ""
421
+
422
+ #: classes/class-cartflows-meta-fields.php:91
423
+ msgid "Extra-Bold 800"
424
+ msgstr ""
425
+
426
+ #: classes/class-cartflows-meta-fields.php:92
427
+ msgid "Ultra-Bold 900"
428
+ msgstr ""
429
+
430
+ #: classes/class-cartflows-meta-fields.php:175
431
+ #. Translators: %d stock amount
432
+ msgid "Stock: %d"
433
+ msgstr ""
434
+
435
+ #: classes/class-cartflows-meta-fields.php:758
436
+ #: includes/meta-fields/generate-product-repeater.php:30
437
+ msgid "Search for a product&hellip;"
438
+ msgstr ""
439
+
440
+ #: classes/class-cartflows-meta-fields.php:809
441
+ msgid "Search for a coupon&hellip;"
442
+ msgstr ""
443
+
444
+ #: classes/class-cartflows-meta.php:34
445
+ msgid "Update"
446
+ msgstr ""
447
+
448
+ #: classes/class-cartflows-meta.php:42
449
+ #: modules/flow/classes/class-cartflows-flow-meta.php:95
450
+ #: modules/flow/classes/class-cartflows-flow-meta.php:733
451
+ msgid "Back to edit Flow"
452
+ msgstr ""
453
+
454
+ #: classes/class-cartflows-meta.php:63
455
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:198
456
+ #: modules/landing/classes/class-cartflows-landing-meta.php:136
457
+ #: modules/optin/classes/class-cartflows-optin-meta.php:156
458
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:154
459
+ msgid "Custom Script"
460
+ msgstr ""
461
+
462
+ #: classes/class-cartflows-meta.php:66
463
+ msgid ""
464
+ "Custom script lets you add your own custom script on front end of this flow "
465
+ "page."
466
+ msgstr ""
467
+
468
+ #: classes/class-cartflows-metabox.php:59
469
+ msgid "Flow Details"
470
+ msgstr ""
471
+
472
+ #: classes/class-cartflows-wizard.php:94
473
+ msgid "Thanks for installing and using CartFlows!"
474
+ msgstr ""
475
+
476
+ #: classes/class-cartflows-wizard.php:95
477
+ msgid ""
478
+ "It is easy to use the CartFlows. Please use the setup wizard to quick start "
479
+ "setup."
480
+ msgstr ""
481
+
482
+ #: classes/class-cartflows-wizard.php:97
483
+ msgid "Start Wizard"
484
+ msgstr ""
485
+
486
+ #: classes/class-cartflows-wizard.php:98
487
+ msgid "Skip Setup"
488
+ msgstr ""
489
+
490
+ #: classes/class-cartflows-wizard.php:128
491
+ #: includes/admin/cartflows-general-bck.php:24
492
+ msgid "Welcome"
493
+ msgstr ""
494
+
495
+ #: classes/class-cartflows-wizard.php:133
496
+ msgid "Page Builder"
497
+ msgstr ""
498
+
499
+ #: classes/class-cartflows-wizard.php:137
500
+ msgid "Checkout"
501
+ msgstr ""
502
+
503
+ #: classes/class-cartflows-wizard.php:141
504
+ msgid "Training"
505
+ msgstr ""
506
+
507
+ #: classes/class-cartflows-wizard.php:145
508
+ msgid "Ready!"
509
+ msgstr ""
510
+
511
+ #: classes/class-cartflows-wizard.php:220
512
+ msgid "CartFlows Setup"
513
+ msgstr ""
514
+
515
+ #: classes/class-cartflows-wizard.php:246
516
+ msgid "Exit Setup Wizard"
517
+ msgstr ""
518
+
519
+ #: classes/class-cartflows-wizard.php:299
520
+ msgid "Welcome to CartFlows!"
521
+ msgstr ""
522
+
523
+ #: classes/class-cartflows-wizard.php:300
524
+ msgid ""
525
+ "Thank you for choosing CartFlows to get more leads, increase conversions, & "
526
+ "maximize profits. This short setup wizard will guide you though configuring "
527
+ "CartFlows and creating your first funnel."
528
+ msgstr ""
529
+
530
+ #: classes/class-cartflows-wizard.php:304
531
+ msgid "Let&#x27;s Build it better!"
532
+ msgstr ""
533
+
534
+ #: classes/class-cartflows-wizard.php:305
535
+ msgid ""
536
+ "Get improved features and faster fixes by sharing non-sensitive data via "
537
+ "usage tracking that shows us how CartFlows is used. No personal data is "
538
+ "tracked or stored."
539
+ msgstr ""
540
+
541
+ #: classes/class-cartflows-wizard.php:306
542
+ msgid "Learn More"
543
+ msgstr ""
544
+
545
+ #: classes/class-cartflows-wizard.php:309
546
+ msgid "Yes, I am in."
547
+ msgstr ""
548
+
549
+ #: classes/class-cartflows-wizard.php:316
550
+ msgid "Lets Go »"
551
+ msgstr ""
552
+
553
+ #: classes/class-cartflows-wizard.php:344
554
+ msgid "Page Builder Setup"
555
+ msgstr ""
556
+
557
+ #: classes/class-cartflows-wizard.php:345
558
+ msgid "Please select a page builder you would like to use with CartFlows."
559
+ msgstr ""
560
+
561
+ #: classes/class-cartflows-wizard.php:350
562
+ msgid "Select Page Builder"
563
+ msgstr ""
564
+
565
+ #: classes/class-cartflows-wizard.php:357
566
+ #: includes/admin/cartflows-general.php:94
567
+ msgid "Elementor"
568
+ msgstr ""
569
+
570
+ #: classes/class-cartflows-wizard.php:367
571
+ msgid "Beaver Builder Plugin (Lite Version)"
572
+ msgstr ""
573
+
574
+ #: classes/class-cartflows-wizard.php:377
575
+ #: includes/admin/cartflows-general.php:96
576
+ msgid "Divi"
577
+ msgstr ""
578
+
579
+ #: classes/class-cartflows-wizard.php:387
580
+ #: includes/admin/cartflows-general.php:97
581
+ msgid "Gutenberg"
582
+ msgstr ""
583
+
584
+ #: classes/class-cartflows-wizard.php:397
585
+ #: includes/admin/cartflows-general.php:98
586
+ msgid "Other"
587
+ msgstr ""
588
+
589
+ #: classes/class-cartflows-wizard.php:419
590
+ msgid ""
591
+ "While CartFlows Should work with most page builders, we offer templates for "
592
+ "the above page builders."
593
+ msgstr ""
594
+
595
+ #: classes/class-cartflows-wizard.php:423
596
+ #: classes/class-cartflows-wizard.php:468
597
+ #: classes/class-cartflows-wizard.php:678
598
+ msgid "« Previous"
599
+ msgstr ""
600
+
601
+ #: classes/class-cartflows-wizard.php:426
602
+ msgid "Skip this step"
603
+ msgstr ""
604
+
605
+ #: classes/class-cartflows-wizard.php:427
606
+ msgid "Next »"
607
+ msgstr ""
608
+
609
+ #: classes/class-cartflows-wizard.php:446
610
+ msgid "Choose a checkout"
611
+ msgstr ""
612
+
613
+ #: classes/class-cartflows-wizard.php:449
614
+ msgid ""
615
+ "While CartFlows is designed to use WooCommerce sell digital and physical "
616
+ "products, not all funnels need a checkout system."
617
+ msgstr ""
618
+
619
+ #: classes/class-cartflows-wizard.php:451
620
+ msgid ""
621
+ "Would you like to install WooCommerce to sell digital and physical products "
622
+ "in your funnels?"
623
+ msgstr ""
624
+
625
+ #: classes/class-cartflows-wizard.php:458
626
+ msgid "The following plugin will be installed and activated for you:"
627
+ msgstr ""
628
+
629
+ #: classes/class-cartflows-wizard.php:459
630
+ msgid "WooCommerce"
631
+ msgstr ""
632
+
633
+ #: classes/class-cartflows-wizard.php:460
634
+ msgid "WooCommerce Cart Abandonment Recovery"
635
+ msgstr ""
636
+
637
+ #: classes/class-cartflows-wizard.php:471
638
+ #: classes/class-cartflows-wizard.php:681
639
+ msgid "No thanks"
640
+ msgstr ""
641
+
642
+ #: classes/class-cartflows-wizard.php:472
643
+ msgid "Yes"
644
+ msgstr ""
645
+
646
+ #: classes/class-cartflows-wizard.php:614
647
+ msgid "Congratulations, You Did It!"
648
+ msgstr ""
649
+
650
+ #: classes/class-cartflows-wizard.php:621
651
+ msgid ""
652
+ "CartFlows is ready to use on your website. You've successfully completed "
653
+ "the setup process and all that is left for you to do is create your first "
654
+ "flow."
655
+ msgstr ""
656
+
657
+ #: classes/class-cartflows-wizard.php:635
658
+ msgid "Create a flow"
659
+ msgstr ""
660
+
661
+ #: classes/class-cartflows-wizard.php:652
662
+ msgid "Exclusive CartFlows Training Course Offer"
663
+ msgstr ""
664
+
665
+ #: classes/class-cartflows-wizard.php:663
666
+ msgid ""
667
+ "We want you to get off to a great start using CartFlows, so we would like "
668
+ "to give access to our exclusive training course."
669
+ msgstr ""
670
+
671
+ #: classes/class-cartflows-wizard.php:664
672
+ msgid "Get access to this couse, for free, by entering your email below."
673
+ msgstr ""
674
+
675
+ #: classes/class-cartflows-wizard.php:666
676
+ msgid "Enter Email address"
677
+ msgstr ""
678
+
679
+ #: classes/class-cartflows-wizard.php:682
680
+ msgid "Allow"
681
+ msgstr ""
682
+
683
+ #: classes/lib/notices/class-astra-notices.php:125
684
+ msgid "WordPress Nonce not validated."
685
+ msgstr ""
686
+
687
+ #: classes/logger/class-cartflows-log-handler-file.php:351
688
+ #: classes/logger/class-cartflows-log-handler-file.php:371
689
+ msgid "This method should not be called before plugins_loaded."
690
+ msgstr ""
691
+
692
+ #: classes/logger/class-cartflows-wc-logger.php:58
693
+ #. translators: 1: class name 2: Cartflows_Log_Handler_Interface
694
+ msgid "The provided handler %1$s does not implement %2$s."
695
+ msgstr ""
696
+
697
+ #: classes/logger/class-cartflows-wc-logger.php:136
698
+ #. translators: 1: Cartflows_WC_Logger::log 2: level
699
+ msgid "%1$s was called with an invalid level \"%2$s\"."
700
+ msgstr ""
701
+
702
+ #: includes/admin/cartflows-admin.php:19
703
+ #: includes/admin/cartflows-general.php:48
704
+ msgid "Modernizing WordPress eCommerce!"
705
+ msgstr ""
706
+
707
+ #: includes/admin/cartflows-admin.php:29
708
+ msgid "Settings saved successfully."
709
+ msgstr ""
710
+
711
+ #: includes/admin/cartflows-error-log.php:36
712
+ msgid "%1$s at %2$s"
713
+ msgstr ""
714
+
715
+ #: includes/admin/cartflows-error-log.php:41
716
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:225
717
+ #: modules/flow/view/meta-flow-steps.php:104
718
+ msgid "View"
719
+ msgstr ""
720
+
721
+ #: includes/admin/cartflows-error-log.php:65
722
+ msgid "Delete log"
723
+ msgstr ""
724
+
725
+ #: includes/admin/cartflows-error-log.php:70
726
+ msgid "There are currently no logs to view."
727
+ msgstr ""
728
+
729
+ #: includes/admin/cartflows-general-bck.php:10
730
+ msgid "Selec"
731
+ msgstr ""
732
+
733
+ #: includes/admin/cartflows-general-bck.php:22
734
+ msgid "General"
735
+ msgstr ""
736
+
737
+ #: includes/admin/cartflows-general.php:31
738
+ #: includes/admin/cartflows-general.php:58
739
+ msgid "General Settings"
740
+ msgstr ""
741
+
742
+ #: includes/admin/cartflows-general.php:40
743
+ msgid "Getting Started"
744
+ msgstr ""
745
+
746
+ #: includes/admin/cartflows-general.php:71
747
+ msgid "Disallow search engines from indexing flows"
748
+ msgstr ""
749
+
750
+ #: includes/admin/cartflows-general.php:81
751
+ #: modules/flow/view/meta-flow-steps.php:93
752
+ msgid "Global Checkout"
753
+ msgstr ""
754
+
755
+ #: includes/admin/cartflows-general.php:90
756
+ msgid "Show Templates designed with"
757
+ msgstr ""
758
+
759
+ #: includes/admin/cartflows-general.php:91
760
+ msgid ""
761
+ "CartFlows offers flow templates that can be imported in one click. These "
762
+ "templates are available in few different page builders. Please choose your "
763
+ "preferred page builder from the list so you will only see templates that "
764
+ "are made using that page builder.."
765
+ msgstr ""
766
+
767
+ #: includes/admin/cartflows-general.php:95
768
+ msgid "Beaver Builder"
769
+ msgstr ""
770
+
771
+ #: includes/admin/cartflows-general.php:107
772
+ #: includes/admin/cartflows-general.php:193
773
+ #: includes/admin/cartflows-general.php:299
774
+ #: includes/admin/cartflows-general.php:416
775
+ msgid "Save Changes"
776
+ msgstr ""
777
+
778
+ #: includes/admin/cartflows-general.php:119
779
+ msgid "Permalink Settings"
780
+ msgstr ""
781
+
782
+ #: includes/admin/cartflows-general.php:134
783
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:647
784
+ #: modules/optin/classes/class-cartflows-optin-meta.php:383
785
+ msgid "Default"
786
+ msgstr ""
787
+
788
+ #: includes/admin/cartflows-general.php:140
789
+ msgid "Flow and Step Slug"
790
+ msgstr ""
791
+
792
+ #: includes/admin/cartflows-general.php:146
793
+ msgid "Flow Slug"
794
+ msgstr ""
795
+
796
+ #: includes/admin/cartflows-general.php:152
797
+ msgid "Step Slug"
798
+ msgstr ""
799
+
800
+ #: includes/admin/cartflows-general.php:164
801
+ msgid "Post Type Permalink Base"
802
+ msgstr ""
803
+
804
+ #: includes/admin/cartflows-general.php:172
805
+ msgid "Step Base"
806
+ msgstr ""
807
+
808
+ #: includes/admin/cartflows-general.php:182
809
+ msgid "Flow Base"
810
+ msgstr ""
811
+
812
+ #: includes/admin/cartflows-general.php:194
813
+ msgid "Set Default"
814
+ msgstr ""
815
+
816
+ #: includes/admin/cartflows-general.php:208
817
+ msgid "Facebook Pixel Settings"
818
+ msgstr ""
819
+
820
+ #: includes/admin/cartflows-general.php:223
821
+ msgid "Enable Facebook Pixel Tracking"
822
+ msgstr ""
823
+
824
+ #: includes/admin/cartflows-general.php:236
825
+ msgid "Enable for the whole site"
826
+ msgstr ""
827
+
828
+ #: includes/admin/cartflows-general.php:244
829
+ #: includes/admin/cartflows-general.php:343
830
+ msgid "If this option is unchecked, it will only apply to CartFlows steps."
831
+ msgstr ""
832
+
833
+ #: includes/admin/cartflows-general.php:254
834
+ msgid "Enter Facebook pixel ID"
835
+ msgstr ""
836
+
837
+ #: includes/admin/cartflows-general.php:262
838
+ #: includes/admin/cartflows-general.php:361
839
+ msgid "Enable Events:"
840
+ msgstr ""
841
+
842
+ #: includes/admin/cartflows-general.php:271
843
+ msgid "Initiate Checkout"
844
+ msgstr ""
845
+
846
+ #: includes/admin/cartflows-general.php:280
847
+ #: includes/admin/cartflows-general.php:387
848
+ msgid "Add Payment Info"
849
+ msgstr ""
850
+
851
+ #: includes/admin/cartflows-general.php:289
852
+ msgid "Purchase Complete"
853
+ msgstr ""
854
+
855
+ #: includes/admin/cartflows-general.php:311
856
+ msgid "Google Analytics Settings"
857
+ msgstr ""
858
+
859
+ #: includes/admin/cartflows-general.php:322
860
+ msgid "Enable Google Analytics Tracking"
861
+ msgstr ""
862
+
863
+ #: includes/admin/cartflows-general.php:335
864
+ msgid "Enable for the whole website"
865
+ msgstr ""
866
+
867
+ #: includes/admin/cartflows-general.php:353
868
+ msgid "Google Analytics ID"
869
+ msgstr ""
870
+
871
+ #: includes/admin/cartflows-general.php:355
872
+ msgid ""
873
+ "Log into your <a href=\"https://analytics.google.com/\" "
874
+ "target=\"_blank\">google analytics account</a> to find your ID. eg: "
875
+ "UA-XXXXXX-X&period;"
876
+ msgstr ""
877
+
878
+ #: includes/admin/cartflows-general.php:369
879
+ msgid "Begin Checkout"
880
+ msgstr ""
881
+
882
+ #: includes/admin/cartflows-general.php:378
883
+ msgid "Add To Cart"
884
+ msgstr ""
885
+
886
+ #: includes/admin/cartflows-general.php:396
887
+ msgid "Purchase"
888
+ msgstr ""
889
+
890
+ #: includes/admin/cartflows-general.php:404
891
+ msgid ""
892
+ "Google Analytics not working correctly? <a "
893
+ "href=\"https://cartflows.com/docs/troubleshooting-google-analytics-tracking-"
894
+ "issues/\" > Click here </a> to know more. "
895
+ msgstr ""
896
+
897
+ #: includes/admin/cartflows-general.php:437
898
+ msgid "Knowledge Base"
899
+ msgstr ""
900
+
901
+ #: includes/admin/cartflows-general.php:441
902
+ msgid "Not sure how something works? Take a peek at the knowledge base and learn."
903
+ msgstr ""
904
+
905
+ #: includes/admin/cartflows-general.php:444
906
+ msgid "Visit Knowledge Base »"
907
+ msgstr ""
908
+
909
+ #: includes/admin/cartflows-general.php:452
910
+ msgid "Community"
911
+ msgstr ""
912
+
913
+ #: includes/admin/cartflows-general.php:456
914
+ msgid ""
915
+ "Join the community of super helpful CartFlows users. Say hello, ask "
916
+ "questions, give feedback and help each other!"
917
+ msgstr ""
918
+
919
+ #: includes/admin/cartflows-general.php:459
920
+ msgid "Join Our Facebook Group »"
921
+ msgstr ""
922
+
923
+ #: includes/admin/cartflows-general.php:467
924
+ msgid "Five Star Support"
925
+ msgstr ""
926
+
927
+ #: includes/admin/cartflows-general.php:471
928
+ msgid "Got a question? Get in touch with CartFlows developers. We're happy to help!"
929
+ msgstr ""
930
+
931
+ #: includes/admin/cartflows-general.php:474
932
+ msgid "Submit a Ticket »"
933
+ msgstr ""
934
+
935
+ #: includes/admin/cartflows-general.php:484
936
+ msgid "Load Minified CSS"
937
+ msgstr ""
938
+
939
+ #: includes/admin/cartflows-general.php:489
940
+ msgid ""
941
+ "Load the Minified CSS from here. Just Enable it by checking the below given "
942
+ "checkbox."
943
+ msgstr ""
944
+
945
+ #: includes/admin/cartflows-general.php:496
946
+ msgid "Load minified CSS & JS Files"
947
+ msgstr ""
948
+
949
+ #: includes/admin/cartflows-general.php:501
950
+ msgid "Save"
951
+ msgstr ""
952
+
953
+ #: includes/exporter.php:12
954
+ msgid "Export Flows to a JSON file"
955
+ msgstr ""
956
+
957
+ #: includes/exporter.php:13
958
+ msgid ""
959
+ "This tool allows you to generate and download a JSON file containing a list "
960
+ "of all flows."
961
+ msgstr ""
962
+
963
+ #: includes/importer.php:12
964
+ msgid "Import Flows to a JSON file"
965
+ msgstr ""
966
+
967
+ #: includes/importer.php:13
968
+ msgid "This tool allows you to import the flows from the JSON file."
969
+ msgstr ""
970
+
971
+ #: includes/importer.php:21
972
+ msgid "Import"
973
+ msgstr ""
974
+
975
+ #: includes/meta-fields/generate-product-repeater.php:36
976
+ msgid "Remove"
977
+ msgstr ""
978
+
979
+ #: includes/meta-fields/generate-product-repeater.php:51
980
+ msgid "Product Quantity"
981
+ msgstr ""
982
+
983
+ #: includes/meta-fields/generate-product-repeater.php:65
984
+ msgid "Discount Type"
985
+ msgstr ""
986
+
987
+ #: includes/meta-fields/generate-product-repeater.php:69
988
+ msgid "Select Discount Type"
989
+ msgstr ""
990
+
991
+ #: includes/meta-fields/generate-product-repeater.php:70
992
+ msgid "Original"
993
+ msgstr ""
994
+
995
+ #: includes/meta-fields/generate-product-repeater.php:71
996
+ msgid "Percentage"
997
+ msgstr ""
998
+
999
+ #: includes/meta-fields/generate-product-repeater.php:72
1000
+ msgid "Price"
1001
+ msgstr ""
1002
+
1003
+ #: includes/meta-fields/generate-product-repeater.php:83
1004
+ msgid "Discount Value"
1005
+ msgstr ""
1006
+
1007
+ #: includes/meta-fields/generate-product-repeater.php:85
1008
+ msgid "Discount value will apply for each quantity of product."
1009
+ msgstr ""
1010
+
1011
+ #: includes/meta-fields/get-product-selection-repeater.php:112
1012
+ msgid "Add New Product"
1013
+ msgstr ""
1014
+
1015
+ #: includes/meta-fields/get-product-selection-repeater.php:113
1016
+ msgid "Create Product"
1017
+ msgstr ""
1018
+
1019
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:284
1020
+ #: modules/optin/classes/class-cartflows-optin-markup.php:146
1021
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:90
1022
+ msgid ""
1023
+ "WooCommerce functions do not exist. If you are in an IFrame, please reload "
1024
+ "it."
1025
+ msgstr ""
1026
+
1027
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:285
1028
+ #: modules/optin/classes/class-cartflows-optin-markup.php:147
1029
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:91
1030
+ msgid "Click Here to Reload"
1031
+ msgstr ""
1032
+
1033
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:303
1034
+ msgid "Checkout ID not found"
1035
+ msgstr ""
1036
+
1037
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:366
1038
+ #: modules/checkout/templates/embed/checkout-template-simple.php:25
1039
+ #: modules/checkout/templates/wcf-template.php:36
1040
+ #: modules/optin/templates/optin-template-simple.php:25
1041
+ msgid "Your cart is currently empty."
1042
+ msgstr ""
1043
+
1044
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:432
1045
+ msgid ""
1046
+ "No product is selected. Please select products from the checkout meta "
1047
+ "settings to continue."
1048
+ msgstr ""
1049
+
1050
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:521
1051
+ msgid "Variations Not set"
1052
+ msgstr ""
1053
+
1054
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:529
1055
+ msgid "This product can't be purchased"
1056
+ msgstr ""
1057
+
1058
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:974
1059
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1017
1060
+ msgid "Coupon Code"
1061
+ msgstr ""
1062
+
1063
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:975
1064
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1026
1065
+ msgid "Apply"
1066
+ msgstr ""
1067
+
1068
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1182
1069
+ msgid "Sorry there was a problem removing this coupon."
1070
+ msgstr ""
1071
+
1072
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1185
1073
+ msgid "Coupon has been removed."
1074
+ msgstr ""
1075
+
1076
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1204
1077
+ msgid "Sorry there was a problem removing "
1078
+ msgstr ""
1079
+
1080
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:1207
1081
+ msgid " has been removed."
1082
+ msgstr ""
1083
+
1084
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:65
1085
+ msgid "Checkout Layout"
1086
+ msgstr ""
1087
+
1088
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:150
1089
+ #: modules/landing/classes/class-cartflows-landing-meta.php:130
1090
+ #: modules/optin/classes/class-cartflows-optin-meta.php:126
1091
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:130
1092
+ msgid "Shortcodes"
1093
+ msgstr ""
1094
+
1095
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:156
1096
+ #: modules/optin/classes/class-cartflows-optin-meta.php:132
1097
+ msgid "Select Product"
1098
+ msgstr ""
1099
+
1100
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:162
1101
+ msgid "Product Options"
1102
+ msgstr ""
1103
+
1104
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:168
1105
+ msgid "Order Bump"
1106
+ msgstr ""
1107
+
1108
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:174
1109
+ msgid "Checkout Offer"
1110
+ msgstr ""
1111
+
1112
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:180
1113
+ msgid "Checkout Design"
1114
+ msgstr ""
1115
+
1116
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:186
1117
+ msgid "Checkout Fields"
1118
+ msgstr ""
1119
+
1120
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:192
1121
+ msgid "Checkout Settings"
1122
+ msgstr ""
1123
+
1124
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:209
1125
+ msgid "Logo (Optional)"
1126
+ msgstr ""
1127
+
1128
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:270
1129
+ #. translators: %s: link
1130
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Product Options feature."
1131
+ msgstr ""
1132
+
1133
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:281
1134
+ #. translators: %s: link.
1135
+ msgid "Update %1$sCartFlows Pro%2$s to %3$s or above for Product Options"
1136
+ msgstr ""
1137
+
1138
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:309
1139
+ msgid "Add this shortcode to your checkout page"
1140
+ msgstr ""
1141
+
1142
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:345
1143
+ #. translators: %s: link
1144
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Pre-applied Coupon."
1145
+ msgstr ""
1146
+
1147
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:372
1148
+ #. translators: %s: link
1149
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Checkout Offer feature"
1150
+ msgstr ""
1151
+
1152
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:382
1153
+ #. translators: %s: link
1154
+ msgid "Update to %1$sCartFlows Pro%2$s to %3$s or above for Checkout Offer feature"
1155
+ msgstr ""
1156
+
1157
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:409
1158
+ #. translators: %s: link
1159
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for animate browser tab feature"
1160
+ msgstr ""
1161
+
1162
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:419
1163
+ #. translators: %s: link
1164
+ msgid ""
1165
+ "Update to %1$sCartFlows Pro%2$s to %3$s or above for animate browser tab "
1166
+ "feature"
1167
+ msgstr ""
1168
+
1169
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:442
1170
+ #. translators: %s: link
1171
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Order Bump feature."
1172
+ msgstr ""
1173
+
1174
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:469
1175
+ #: modules/optin/classes/class-cartflows-optin-meta.php:270
1176
+ #. translators: %s: link
1177
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Custom Fields feature."
1178
+ msgstr ""
1179
+
1180
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:492
1181
+ msgid "Place Order Button Text"
1182
+ msgstr ""
1183
+
1184
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:496
1185
+ msgid "Place order"
1186
+ msgstr ""
1187
+
1188
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:498
1189
+ msgid "It will change the Place Order Button text on checkout page."
1190
+ msgstr ""
1191
+
1192
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:508
1193
+ msgid "Enable cart editing on checkout"
1194
+ msgstr ""
1195
+
1196
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:516
1197
+ #. translators: %s: link
1198
+ msgid "Users will able to remove products from the checkout page."
1199
+ msgstr ""
1200
+
1201
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:546
1202
+ msgid "One Column (Available in CartFlows Pro) "
1203
+ msgstr ""
1204
+
1205
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:547
1206
+ msgid "Two Step (Available in CartFlows Pro) "
1207
+ msgstr ""
1208
+
1209
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:553
1210
+ msgid "Checkout Skin"
1211
+ msgstr ""
1212
+
1213
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:557
1214
+ msgid "One Column"
1215
+ msgstr ""
1216
+
1217
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:558
1218
+ msgid "Two Column"
1219
+ msgstr ""
1220
+
1221
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:559
1222
+ msgid "Two Step"
1223
+ msgstr ""
1224
+
1225
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:568
1226
+ #: modules/optin/classes/class-cartflows-optin-meta.php:346
1227
+ msgid "Primary Color"
1228
+ msgstr ""
1229
+
1230
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:577
1231
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:612
1232
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:658
1233
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:750
1234
+ #: modules/optin/classes/class-cartflows-optin-meta.php:355
1235
+ #: modules/optin/classes/class-cartflows-optin-meta.php:394
1236
+ #: modules/optin/classes/class-cartflows-optin-meta.php:506
1237
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:209
1238
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:240
1239
+ msgid "Font Family"
1240
+ msgstr ""
1241
+
1242
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:585
1243
+ msgid "Advance Options"
1244
+ msgstr ""
1245
+
1246
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:597
1247
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:225
1248
+ msgid "Heading"
1249
+ msgstr ""
1250
+
1251
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:603
1252
+ msgid "Heading Color"
1253
+ msgstr ""
1254
+
1255
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:621
1256
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:667
1257
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:759
1258
+ #: modules/optin/classes/class-cartflows-optin-meta.php:403
1259
+ #: modules/optin/classes/class-cartflows-optin-meta.php:515
1260
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:249
1261
+ msgid "Font Weight"
1262
+ msgstr ""
1263
+
1264
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:629
1265
+ #: modules/optin/classes/class-cartflows-optin-meta.php:366
1266
+ msgid "Input Fields"
1267
+ msgstr ""
1268
+
1269
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:637
1270
+ #: modules/optin/classes/class-cartflows-optin-meta.php:373
1271
+ msgid "Floating Labels (Available in CartFlows Pro)"
1272
+ msgstr ""
1273
+
1274
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:643
1275
+ #: modules/optin/classes/class-cartflows-optin-meta.php:379
1276
+ msgid "Style"
1277
+ msgstr ""
1278
+
1279
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:648
1280
+ #: modules/optin/classes/class-cartflows-optin-meta.php:384
1281
+ msgid "Floating Labels"
1282
+ msgstr ""
1283
+
1284
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:675
1285
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:767
1286
+ #: modules/optin/classes/class-cartflows-optin-meta.php:411
1287
+ #: modules/optin/classes/class-cartflows-optin-meta.php:523
1288
+ msgid "Size"
1289
+ msgstr ""
1290
+
1291
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:679
1292
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:771
1293
+ #: modules/optin/classes/class-cartflows-optin-meta.php:415
1294
+ #: modules/optin/classes/class-cartflows-optin-meta.php:527
1295
+ msgid "Extra Small"
1296
+ msgstr ""
1297
+
1298
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:680
1299
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:772
1300
+ #: modules/optin/classes/class-cartflows-optin-meta.php:416
1301
+ #: modules/optin/classes/class-cartflows-optin-meta.php:528
1302
+ msgid "Small"
1303
+ msgstr ""
1304
+
1305
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:681
1306
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:773
1307
+ #: modules/optin/classes/class-cartflows-optin-meta.php:417
1308
+ #: modules/optin/classes/class-cartflows-optin-meta.php:529
1309
+ msgid "Medium"
1310
+ msgstr ""
1311
+
1312
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:682
1313
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:774
1314
+ #: modules/optin/classes/class-cartflows-optin-meta.php:418
1315
+ #: modules/optin/classes/class-cartflows-optin-meta.php:530
1316
+ msgid "Large"
1317
+ msgstr ""
1318
+
1319
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:683
1320
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:775
1321
+ #: modules/optin/classes/class-cartflows-optin-meta.php:419
1322
+ #: modules/optin/classes/class-cartflows-optin-meta.php:531
1323
+ msgid "Extra Large"
1324
+ msgstr ""
1325
+
1326
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:684
1327
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:776
1328
+ #: modules/optin/classes/class-cartflows-optin-meta.php:420
1329
+ #: modules/optin/classes/class-cartflows-optin-meta.php:532
1330
+ msgid "Custom"
1331
+ msgstr ""
1332
+
1333
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:691
1334
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:783
1335
+ #: modules/optin/classes/class-cartflows-optin-meta.php:427
1336
+ #: modules/optin/classes/class-cartflows-optin-meta.php:539
1337
+ msgid "Top Bottom Spacing"
1338
+ msgstr ""
1339
+
1340
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:699
1341
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:791
1342
+ #: modules/optin/classes/class-cartflows-optin-meta.php:435
1343
+ #: modules/optin/classes/class-cartflows-optin-meta.php:547
1344
+ msgid "Left Right Spacing"
1345
+ msgstr ""
1346
+
1347
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:707
1348
+ #: modules/optin/classes/class-cartflows-optin-meta.php:451
1349
+ msgid "Text / Placeholder Color"
1350
+ msgstr ""
1351
+
1352
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:715
1353
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:815
1354
+ #: modules/optin/classes/class-cartflows-optin-meta.php:459
1355
+ #: modules/optin/classes/class-cartflows-optin-meta.php:584
1356
+ msgid "Background Color"
1357
+ msgstr ""
1358
+
1359
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:723
1360
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:831
1361
+ #: modules/optin/classes/class-cartflows-optin-meta.php:467
1362
+ #: modules/optin/classes/class-cartflows-optin-meta.php:600
1363
+ msgid "Border Color"
1364
+ msgstr ""
1365
+
1366
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:730
1367
+ #: modules/optin/classes/class-cartflows-optin-meta.php:443
1368
+ msgid "Label Color"
1369
+ msgstr ""
1370
+
1371
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:743
1372
+ msgid "Buttons"
1373
+ msgstr ""
1374
+
1375
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:799
1376
+ #: modules/optin/classes/class-cartflows-optin-meta.php:568
1377
+ msgid "Text Color"
1378
+ msgstr ""
1379
+
1380
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:807
1381
+ #: modules/optin/classes/class-cartflows-optin-meta.php:576
1382
+ msgid "Text Hover Color"
1383
+ msgstr ""
1384
+
1385
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:823
1386
+ #: modules/optin/classes/class-cartflows-optin-meta.php:592
1387
+ msgid "Background Hover Color"
1388
+ msgstr ""
1389
+
1390
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:839
1391
+ #: modules/optin/classes/class-cartflows-optin-meta.php:608
1392
+ msgid "Border Hover Color"
1393
+ msgstr ""
1394
+
1395
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:852
1396
+ msgid "Sections"
1397
+ msgstr ""
1398
+
1399
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:858
1400
+ msgid "Highlight Area Background Color"
1401
+ msgstr ""
1402
+
1403
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:897
1404
+ msgid "Header Logo"
1405
+ msgstr ""
1406
+
1407
+ #: modules/checkout/classes/class-cartflows-checkout-meta.php:905
1408
+ msgid "Logo Width (In px)"
1409
+ msgstr ""
1410
+
1411
+ #: modules/checkout/templates/wcf-template.php:46
1412
+ msgid "Copyright &copy;"
1413
+ msgstr ""
1414
+
1415
+ #: modules/checkout/templates/wcf-template.php:50
1416
+ msgid "All Rights Reserved"
1417
+ msgstr ""
1418
+
1419
+ #: modules/flow/classes/class-cartflows-flow-meta.php:263
1420
+ #. translators: %s flow id
1421
+ msgid "Step not deleted for flow - %s"
1422
+ msgstr ""
1423
+
1424
+ #: modules/flow/classes/class-cartflows-flow-meta.php:294
1425
+ #. translators: %s flow id
1426
+ msgid "Step deleted for flow - %s"
1427
+ msgstr ""
1428
+
1429
+ #: modules/flow/classes/class-cartflows-flow-meta.php:322
1430
+ #. translators: %s flow id
1431
+ msgid "Steps not sorted for flow - %s"
1432
+ msgstr ""
1433
+
1434
+ #: modules/flow/classes/class-cartflows-flow-meta.php:345
1435
+ #. translators: %s flow id
1436
+ msgid "Steps sorted for flow - %s"
1437
+ msgstr ""
1438
+
1439
+ #: modules/flow/classes/class-cartflows-flow-meta.php:456
1440
+ msgid "Analytics"
1441
+ msgstr ""
1442
+
1443
+ #: modules/flow/classes/class-cartflows-flow-meta.php:473
1444
+ #. translators: %s: link
1445
+ msgid "Upgrade to %1$sCartFlows Pro%2$s for Analytics feature"
1446
+ msgstr ""
1447
+
1448
+ #: modules/flow/classes/class-cartflows-flow-meta.php:491
1449
+ msgid "Flow Settings"
1450
+ msgstr ""
1451
+
1452
+ #: modules/flow/classes/class-cartflows-flow-meta.php:576
1453
+ msgid "Enable Test Mode"
1454
+ msgstr ""
1455
+
1456
+ #: modules/flow/classes/class-cartflows-flow-meta.php:583
1457
+ msgid ""
1458
+ "If you are using WooCommerce plugin then test mode will add random products "
1459
+ "in your flow, so you can preview it easily while testing."
1460
+ msgstr ""
1461
+
1462
+ #: modules/flow/classes/class-cartflows-flow-meta.php:702
1463
+ #: modules/flow/view/meta-flow-steps.php:133
1464
+ msgid "Add New Step"
1465
+ msgstr ""
1466
+
1467
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1468
+ msgid "Flow: "
1469
+ msgstr ""
1470
+
1471
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:69
1472
+ msgid "Name: "
1473
+ msgstr ""
1474
+
1475
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:101
1476
+ msgid "Search Flows"
1477
+ msgstr ""
1478
+
1479
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:102
1480
+ msgid "All Flows"
1481
+ msgstr ""
1482
+
1483
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:103
1484
+ msgid "Edit Flow"
1485
+ msgstr ""
1486
+
1487
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:104
1488
+ msgid "View Flow"
1489
+ msgstr ""
1490
+
1491
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:105
1492
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:107
1493
+ #: modules/flow/classes/class-cartflows-step-post-type.php:167
1494
+ #: modules/flow/classes/class-cartflows-step-post-type.php:169
1495
+ msgid "Add New"
1496
+ msgstr ""
1497
+
1498
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:106
1499
+ msgid "Update Flow"
1500
+ msgstr ""
1501
+
1502
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:108
1503
+ msgid "New Flow Name"
1504
+ msgstr ""
1505
+
1506
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:190
1507
+ msgid "Upgrade to CartFlows Pro"
1508
+ msgstr ""
1509
+
1510
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:209
1511
+ msgid "Slug"
1512
+ msgstr ""
1513
+
1514
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:332
1515
+ msgid "Flows"
1516
+ msgstr ""
1517
+
1518
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:354
1519
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:360
1520
+ #: modules/flow/classes/class-cartflows-step-post-type.php:401
1521
+ #: modules/flow/classes/class-cartflows-step-post-type.php:407
1522
+ #. translators: %s: singular custom post type name
1523
+ msgid "%s updated."
1524
+ msgstr ""
1525
+
1526
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:356
1527
+ #: modules/flow/classes/class-cartflows-step-post-type.php:403
1528
+ #. translators: %s: singular custom post type name
1529
+ msgid "Custom %s updated."
1530
+ msgstr ""
1531
+
1532
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:358
1533
+ #: modules/flow/classes/class-cartflows-step-post-type.php:405
1534
+ #. translators: %s: singular custom post type name
1535
+ msgid "Custom %s deleted."
1536
+ msgstr ""
1537
+
1538
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:362
1539
+ #: modules/flow/classes/class-cartflows-step-post-type.php:409
1540
+ #. translators: %1$s: singular custom post type name ,%2$s: date and time of
1541
+ #. the revision
1542
+ msgid "%1$s restored to revision from %2$s"
1543
+ msgstr ""
1544
+
1545
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:364
1546
+ #: modules/flow/classes/class-cartflows-step-post-type.php:411
1547
+ #. translators: %s: singular custom post type name
1548
+ msgid "%s published."
1549
+ msgstr ""
1550
+
1551
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:366
1552
+ #: modules/flow/classes/class-cartflows-step-post-type.php:413
1553
+ #. translators: %s: singular custom post type name
1554
+ msgid "%s saved."
1555
+ msgstr ""
1556
+
1557
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:368
1558
+ #: modules/flow/classes/class-cartflows-step-post-type.php:415
1559
+ #. translators: %s: singular custom post type name
1560
+ msgid "%s submitted."
1561
+ msgstr ""
1562
+
1563
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:370
1564
+ #: modules/flow/classes/class-cartflows-step-post-type.php:417
1565
+ #. translators: %s: singular custom post type name
1566
+ msgid "%s scheduled for."
1567
+ msgstr ""
1568
+
1569
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:372
1570
+ #: modules/flow/classes/class-cartflows-step-post-type.php:419
1571
+ #. translators: %s: singular custom post type name
1572
+ msgid "%s draft updated."
1573
+ msgstr ""
1574
+
1575
+ #: modules/flow/classes/class-cartflows-flow-shortcodes.php:148
1576
+ #: modules/widgets/class-cartflows-next-step.php:78
1577
+ msgid "Next Step"
1578
+ msgstr ""
1579
+
1580
+ #: modules/flow/classes/class-cartflows-step-post-type.php:163
1581
+ msgid "Search Steps"
1582
+ msgstr ""
1583
+
1584
+ #: modules/flow/classes/class-cartflows-step-post-type.php:164
1585
+ msgid "All Steps"
1586
+ msgstr ""
1587
+
1588
+ #: modules/flow/classes/class-cartflows-step-post-type.php:165
1589
+ #: modules/flow/view/meta-flow-steps.php:106
1590
+ msgid "Edit Step"
1591
+ msgstr ""
1592
+
1593
+ #: modules/flow/classes/class-cartflows-step-post-type.php:166
1594
+ #: modules/flow/view/meta-flow-steps.php:102
1595
+ msgid "View Step"
1596
+ msgstr ""
1597
+
1598
+ #: modules/flow/classes/class-cartflows-step-post-type.php:168
1599
+ msgid "Update Step"
1600
+ msgstr ""
1601
+
1602
+ #: modules/flow/classes/class-cartflows-step-post-type.php:170
1603
+ msgid "New Step Name"
1604
+ msgstr ""
1605
+
1606
+ #: modules/flow/classes/class-cartflows-step-post-type.php:211
1607
+ msgid "Step Type"
1608
+ msgstr ""
1609
+
1610
+ #: modules/flow/classes/class-cartflows-step-post-type.php:221
1611
+ msgid "Step Flow"
1612
+ msgstr ""
1613
+
1614
+ #: modules/flow/classes/class-cartflows-step-post-type.php:246
1615
+ #: modules/flow/view/meta-flow-steps.php:16
1616
+ msgid "Optin (Woo)"
1617
+ msgstr ""
1618
+
1619
+ #: modules/flow/classes/class-cartflows-step-post-type.php:267
1620
+ #: modules/flow/view/meta-flow-steps.php:14
1621
+ msgid "Upsell (Woo)"
1622
+ msgstr ""
1623
+
1624
+ #: modules/flow/classes/class-cartflows-step-post-type.php:274
1625
+ #: modules/flow/view/meta-flow-steps.php:15
1626
+ msgid "Downsell (Woo)"
1627
+ msgstr ""
1628
+
1629
+ #: modules/flow/view/meta-flow-steps.php:85
1630
+ msgid "No Product Assigned"
1631
+ msgstr ""
1632
+
1633
+ #: modules/flow/view/meta-flow-steps.php:89
1634
+ msgid "Global Checkout - Remove selected checkout product"
1635
+ msgstr ""
1636
+
1637
+ #: modules/flow/view/meta-flow-steps.php:108
1638
+ msgid "Edit"
1639
+ msgstr ""
1640
+
1641
+ #: modules/flow/view/meta-flow-steps.php:113
1642
+ msgid "Clone Step"
1643
+ msgstr ""
1644
+
1645
+ #: modules/flow/view/meta-flow-steps.php:118
1646
+ msgid "Delete Step"
1647
+ msgstr ""
1648
+
1649
+ #: modules/flow/view/meta-flow-steps.php:120
1650
+ msgid "Delete"
1651
+ msgstr ""
1652
+
1653
+ #: modules/flow/view/meta-flow-steps.php:149
1654
+ msgid "Steps Library"
1655
+ msgstr ""
1656
+
1657
+ #: modules/flow/view/meta-flow-steps.php:198
1658
+ msgid "Create Step"
1659
+ msgstr ""
1660
+
1661
+ #: modules/flow/view/meta-flow-steps.php:200
1662
+ msgid "You need a Cartflows Pro version to import Upsell / Downsell"
1663
+ msgstr ""
1664
+
1665
+ #: modules/landing/classes/class-cartflows-landing-meta.php:66
1666
+ msgid "Landing Page Settings"
1667
+ msgstr ""
1668
+
1669
+ #: modules/landing/classes/class-cartflows-landing-meta.php:169
1670
+ msgid "Next Step Link"
1671
+ msgstr ""
1672
+
1673
+ #: modules/optin/classes/class-cartflows-optin-markup.php:165
1674
+ msgid "Please place shortcode on Optin step-type only."
1675
+ msgstr ""
1676
+
1677
+ #: modules/optin/classes/class-cartflows-optin-markup.php:225
1678
+ msgid ""
1679
+ "No product is selected. Please select a Simple, Virtual and Free product "
1680
+ "from the meta settings."
1681
+ msgstr ""
1682
+
1683
+ #: modules/optin/classes/class-cartflows-optin-markup.php:242
1684
+ msgid "Please update the selected product's price to zero (0)."
1685
+ msgstr ""
1686
+
1687
+ #: modules/optin/classes/class-cartflows-optin-markup.php:251
1688
+ #: modules/optin/classes/class-cartflows-optin-markup.php:255
1689
+ msgid "Please select a Simple, Virtual and Free product."
1690
+ msgstr ""
1691
+
1692
+ #: modules/optin/classes/class-cartflows-optin-meta.php:65
1693
+ msgid "Optin Settings"
1694
+ msgstr ""
1695
+
1696
+ #: modules/optin/classes/class-cartflows-optin-meta.php:138
1697
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:136
1698
+ msgid "Design"
1699
+ msgstr ""
1700
+
1701
+ #: modules/optin/classes/class-cartflows-optin-meta.php:144
1702
+ msgid "Form Fields"
1703
+ msgstr ""
1704
+
1705
+ #: modules/optin/classes/class-cartflows-optin-meta.php:213
1706
+ msgid "Add this shortcode to your optin page"
1707
+ msgstr ""
1708
+
1709
+ #: modules/optin/classes/class-cartflows-optin-meta.php:238
1710
+ msgid "Select Free Product"
1711
+ msgstr ""
1712
+
1713
+ #: modules/optin/classes/class-cartflows-optin-meta.php:239
1714
+ msgid "Select Free and Virtual product only."
1715
+ msgstr ""
1716
+
1717
+ #: modules/optin/classes/class-cartflows-optin-meta.php:293
1718
+ msgid "Pass Fields as URL Parameters"
1719
+ msgstr ""
1720
+
1721
+ #: modules/optin/classes/class-cartflows-optin-meta.php:296
1722
+ msgid "Enable"
1723
+ msgstr ""
1724
+
1725
+ #: modules/optin/classes/class-cartflows-optin-meta.php:297
1726
+ msgid ""
1727
+ "You can pass specific fields from the form to next step as URL query "
1728
+ "parameters."
1729
+ msgstr ""
1730
+
1731
+ #: modules/optin/classes/class-cartflows-optin-meta.php:308
1732
+ msgid "Enter form field"
1733
+ msgstr ""
1734
+
1735
+ #: modules/optin/classes/class-cartflows-optin-meta.php:311
1736
+ #: modules/optin/classes/class-cartflows-optin-meta.php:321
1737
+ msgid "Enter comma seprated field name. E.g. first_name, last_name"
1738
+ msgstr ""
1739
+
1740
+ #: modules/optin/classes/class-cartflows-optin-meta.php:313
1741
+ msgid "Fields to pass, separated by commas"
1742
+ msgstr ""
1743
+
1744
+ #: modules/optin/classes/class-cartflows-optin-meta.php:323
1745
+ #. translators: %s: link
1746
+ msgid ""
1747
+ "You can pass field value as a URL parameter to the next step. %1$sClick "
1748
+ "here%2$s for more information."
1749
+ msgstr ""
1750
+
1751
+ #: modules/optin/classes/class-cartflows-optin-meta.php:480
1752
+ msgid "Submit Button"
1753
+ msgstr ""
1754
+
1755
+ #: modules/optin/classes/class-cartflows-optin-meta.php:486
1756
+ msgid "Button Text"
1757
+ msgstr ""
1758
+
1759
+ #: modules/optin/classes/class-cartflows-optin-meta.php:497
1760
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:217
1761
+ msgid "Font Size"
1762
+ msgstr ""
1763
+
1764
+ #: modules/optin/classes/class-cartflows-optin-meta.php:555
1765
+ msgid "Position"
1766
+ msgstr ""
1767
+
1768
+ #: modules/optin/classes/class-cartflows-optin-meta.php:559
1769
+ msgid "Left"
1770
+ msgstr ""
1771
+
1772
+ #: modules/optin/classes/class-cartflows-optin-meta.php:560
1773
+ msgid "Center"
1774
+ msgstr ""
1775
+
1776
+ #: modules/optin/classes/class-cartflows-optin-meta.php:561
1777
+ msgid "Right"
1778
+ msgstr ""
1779
+
1780
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
1781
+ msgid "Thank You Page Settings"
1782
+ msgstr ""
1783
+
1784
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:142
1785
+ msgid "Edit Fields"
1786
+ msgstr ""
1787
+
1788
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:182
1789
+ msgid "Order Details"
1790
+ msgstr ""
1791
+
1792
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:194
1793
+ msgid "Text"
1794
+ msgstr ""
1795
+
1796
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:200
1797
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:231
1798
+ msgid "Color"
1799
+ msgstr ""
1800
+
1801
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:257
1802
+ msgid "Advanced Options"
1803
+ msgstr ""
1804
+
1805
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:267
1806
+ msgid "Container Width (In px)"
1807
+ msgstr ""
1808
+
1809
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:275
1810
+ msgid "Section Background Color"
1811
+ msgstr ""
1812
+
1813
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:289
1814
+ msgid "Enable Order Overview "
1815
+ msgstr ""
1816
+
1817
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:297
1818
+ msgid "Enable Order Details "
1819
+ msgstr ""
1820
+
1821
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:305
1822
+ msgid "Enable Billing Details "
1823
+ msgstr ""
1824
+
1825
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:313
1826
+ msgid "Enable Shipping Details "
1827
+ msgstr ""
1828
+
1829
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:329
1830
+ msgid "Thank You Page Text"
1831
+ msgstr ""
1832
+
1833
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:333
1834
+ #: woocommerce/template/checkout/thankyou.php:41
1835
+ #: woocommerce/template/checkout/thankyou.php:83
1836
+ msgid "Thank you. Your order has been received."
1837
+ msgstr ""
1838
+
1839
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:335
1840
+ msgid "It will change the default text on thank you page."
1841
+ msgstr ""
1842
+
1843
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:343
1844
+ msgid "Redirect After Purchase"
1845
+ msgstr ""
1846
+
1847
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:352
1848
+ msgid "Redirect Link"
1849
+ msgstr ""
1850
+
1851
+ #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:356
1852
+ msgid "https://"
1853
+ msgstr ""
1854
+
1855
+ #: modules/widgets/class-cartflows-next-step.php:24
1856
+ msgid "CartFlows Next Step"
1857
+ msgstr ""
1858
+
1859
+ #: modules/widgets/class-cartflows-next-step.php:26
1860
+ msgid "Next Step Widgets"
1861
+ msgstr ""
1862
+
1863
+ #: modules/widgets/class-cartflows-next-step.php:106
1864
+ msgid "New title"
1865
+ msgstr ""
1866
+
1867
+ #: modules/widgets/class-cartflows-next-step.php:123
1868
+ msgid "Title:"
1869
+ msgstr ""
1870
+
1871
+ #: modules/widgets/class-cartflows-next-step.php:127
1872
+ msgid "Flow ID:"
1873
+ msgstr ""
1874
+
1875
+ #: modules/widgets/class-cartflows-next-step.php:131
1876
+ msgid "Step ID:"
1877
+ msgstr ""
1878
+
1879
+ #: woocommerce/template/cart/cart-shipping.php:51
1880
+ #. Translators: $s shipping destination.
1881
+ msgid "Estimate for %s."
1882
+ msgstr ""
1883
+
1884
+ #: woocommerce/template/cart/cart-shipping.php:52
1885
+ msgid "Change address"
1886
+ msgstr ""
1887
+
1888
+ #: woocommerce/template/cart/cart-shipping.php:54
1889
+ msgid "This is only an estimate. Prices will be updated during checkout."
1890
+ msgstr ""
1891
+
1892
+ #: woocommerce/template/cart/cart-shipping.php:61
1893
+ msgid "Enter your address to view shipping options."
1894
+ msgstr ""
1895
+
1896
+ #: woocommerce/template/cart/cart-shipping.php:63
1897
+ msgid ""
1898
+ "There are no shipping methods available. Please ensure that your address "
1899
+ "has been entered correctly, or contact us if you need any help."
1900
+ msgstr ""
1901
+
1902
+ #: woocommerce/template/cart/cart-shipping.php:66
1903
+ #. Translators: $s shipping destination.
1904
+ msgid "No shipping options were found for %s."
1905
+ msgstr ""
1906
+
1907
+ #: woocommerce/template/cart/cart-shipping.php:67
1908
+ msgid "Enter a different address"
1909
+ msgstr ""
1910
+
1911
+ #: woocommerce/template/checkout/form-billing.php:27
1912
+ msgid "Billing &amp; Shipping"
1913
+ msgstr ""
1914
+
1915
+ #: woocommerce/template/checkout/form-billing.php:31
1916
+ msgid "Billing details"
1917
+ msgstr ""
1918
+
1919
+ #: woocommerce/template/checkout/form-billing.php:59
1920
+ msgid "Create an account?"
1921
+ msgstr ""
1922
+
1923
+ #: woocommerce/template/checkout/form-checkout.php:26
1924
+ msgid "You must be logged in to checkout."
1925
+ msgstr ""
1926
+
1927
+ #: woocommerce/template/checkout/form-checkout.php:52
1928
+ msgid "Your order"
1929
+ msgstr ""
1930
+
1931
+ #: woocommerce/template/checkout/form-coupon.php:26
1932
+ msgid "Have a coupon?"
1933
+ msgstr ""
1934
+
1935
+ #: woocommerce/template/checkout/form-coupon.php:26
1936
+ msgid "Click here to enter your code"
1937
+ msgstr ""
1938
+
1939
+ #: woocommerce/template/checkout/form-coupon.php:31
1940
+ msgid "If you have a coupon code, please apply it below."
1941
+ msgstr ""
1942
+
1943
+ #: woocommerce/template/checkout/form-coupon.php:34
1944
+ msgid "Coupon code"
1945
+ msgstr ""
1946
+
1947
+ #: woocommerce/template/checkout/form-coupon.php:38
1948
+ msgid "Apply coupon"
1949
+ msgstr ""
1950
+
1951
+ #: woocommerce/template/checkout/form-login.php:26
1952
+ msgid "Returning customer?"
1953
+ msgstr ""
1954
+
1955
+ #: woocommerce/template/checkout/form-login.php:26
1956
+ msgid "Click here to login"
1957
+ msgstr ""
1958
+
1959
+ #: woocommerce/template/checkout/form-login.php:32
1960
+ msgid ""
1961
+ "If you have shopped with us before, please enter your details below. If you "
1962
+ "are a new customer, please proceed to the Billing &amp; Shipping section."
1963
+ msgstr ""
1964
+
1965
+ #: woocommerce/template/checkout/form-shipping.php:26
1966
+ msgid "Ship to a different address?"
1967
+ msgstr ""
1968
+
1969
+ #: woocommerce/template/checkout/form-shipping.php:57
1970
+ msgid "Additional information"
1971
+ msgstr ""
1972
+
1973
+ #: woocommerce/template/checkout/payment.php:33
1974
+ msgid ""
1975
+ "Sorry, it seems that there are no available payment methods for your state. "
1976
+ "Please contact us if you require assistance or wish to make alternate "
1977
+ "arrangements."
1978
+ msgstr ""
1979
+
1980
+ #: woocommerce/template/checkout/payment.php:33
1981
+ msgid "Please fill in your details above to see available payment methods."
1982
+ msgstr ""
1983
+
1984
+ #: woocommerce/template/checkout/payment.php:42
1985
+ #. translators: $1 and $2 opening and closing emphasis tags respectively
1986
+ msgid ""
1987
+ "Since your browser does not support JavaScript, or it is disabled, please "
1988
+ "ensure you click the %1$sUpdate Totals%2$s button before placing your "
1989
+ "order. You may be charged more than the amount stated above if you fail to "
1990
+ "do so."
1991
+ msgstr ""
1992
+
1993
+ #: woocommerce/template/checkout/payment.php:44
1994
+ msgid "Update totals"
1995
+ msgstr ""
1996
+
1997
+ #: woocommerce/template/checkout/review-order.php:26
1998
+ #: woocommerce/template/order/order-details.php:51
1999
+ msgid "Product"
2000
+ msgstr ""
2001
+
2002
+ #: woocommerce/template/checkout/review-order.php:27
2003
+ #: woocommerce/template/checkout/review-order.php:107
2004
+ #: woocommerce/template/order/order-details.php:52
2005
+ msgid "Total"
2006
+ msgstr ""
2007
+
2008
+ #: woocommerce/template/checkout/review-order.php:60
2009
+ msgid "Subtotal"
2010
+ msgstr ""
2011
+
2012
+ #: woocommerce/template/checkout/thankyou.php:30
2013
+ msgid ""
2014
+ "Unfortunately your order cannot be processed as the originating "
2015
+ "bank/merchant has declined your transaction. Please attempt your purchase "
2016
+ "again."
2017
+ msgstr ""
2018
+
2019
+ #: woocommerce/template/checkout/thankyou.php:33
2020
+ msgid "Pay"
2021
+ msgstr ""
2022
+
2023
+ #: woocommerce/template/checkout/thankyou.php:35
2024
+ msgid "My account"
2025
+ msgstr ""
2026
+
2027
+ #: woocommerce/template/checkout/thankyou.php:46
2028
+ msgid "Order number:"
2029
+ msgstr ""
2030
+
2031
+ #: woocommerce/template/checkout/thankyou.php:51
2032
+ msgid "Date:"
2033
+ msgstr ""
2034
+
2035
+ #: woocommerce/template/checkout/thankyou.php:57
2036
+ msgid "Email:"
2037
+ msgstr ""
2038
+
2039
+ #: woocommerce/template/checkout/thankyou.php:63
2040
+ msgid "Total:"
2041
+ msgstr ""
2042
+
2043
+ #: woocommerce/template/checkout/thankyou.php:69
2044
+ msgid "Payment method:"
2045
+ msgstr ""
2046
+
2047
+ #: woocommerce/template/global/form-login.php:34
2048
+ msgid "Username or email"
2049
+ msgstr ""
2050
+
2051
+ #: woocommerce/template/global/form-login.php:38
2052
+ msgid "Password"
2053
+ msgstr ""
2054
+
2055
+ #: woocommerce/template/global/form-login.php:48
2056
+ msgid "Login"
2057
+ msgstr ""
2058
+
2059
+ #: woocommerce/template/global/form-login.php:53
2060
+ msgid "Remember me"
2061
+ msgstr ""
2062
+
2063
+ #: woocommerce/template/global/form-login.php:57
2064
+ msgid "Lost your password?"
2065
+ msgstr ""
2066
+
2067
+ #: woocommerce/template/order/order-details.php:45
2068
+ msgid "Order details"
2069
+ msgstr ""
2070
+
2071
+ #: woocommerce/template/order/order-details.php:93
2072
+ msgid "Note:"
2073
+ msgstr ""
2074
+
2075
+ #. Plugin Name of the plugin/theme
2076
+ msgid "CartFlows"
2077
+ msgstr ""
2078
+
2079
+ #. Author URI of the plugin/theme
2080
+ msgid "https://cartflows.com/"
2081
+ msgstr ""
2082
+
2083
+ #. Description of the plugin/theme
2084
+ msgid "Create beautiful checkout pages & sales flows for WooCommerce."
2085
+ msgstr ""
2086
+
2087
+ #. Author of the plugin/theme
2088
+ msgid "CartFlows Inc"
2089
+ msgstr ""
2090
+
2091
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:99
2092
+ msgctxt "flow general name"
2093
+ msgid "Flows"
2094
+ msgstr ""
2095
+
2096
+ #: modules/flow/classes/class-cartflows-flow-post-type.php:100
2097
+ msgctxt "flow singular name"
2098
+ msgid "Flow"
2099
+ msgstr ""
2100
+
2101
+ #: modules/flow/classes/class-cartflows-step-post-type.php:161
2102
+ msgctxt "flow step general name"
2103
+ msgid "Steps"
2104
+ msgstr ""
2105
+
2106
+ #: modules/flow/classes/class-cartflows-step-post-type.php:162
2107
+ msgctxt "flow step singular name"
2108
+ msgid "Step"
2109
+ msgstr ""
2110
+
2111
+ #: modules/flow/classes/class-cartflows-step-post-type.php:315
2112
+ msgctxt "cartflows"
2113
+ msgid "CartFlows — Boxed"
2114
+ msgstr ""
2115
+
2116
+ #: modules/flow/classes/class-cartflows-step-post-type.php:316
2117
+ msgctxt "cartflows"
2118
+ msgid "Template for Page Builders"
2119
  msgstr ""
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,1288 +1,1288 @@
1
- <?php
2
- /**
3
- * Checkout markup.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Checkout_Markup {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var object instance
19
- */
20
- private static $instance;
21
-
22
- /**
23
- * Initiator
24
- */
25
- public static function get_instance() {
26
- if ( ! isset( self::$instance ) ) {
27
- self::$instance = new self();
28
- }
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Set is checkout flag */
38
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
-
40
- add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
-
42
- /* Show notice if cart is empty */
43
- add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
-
45
- /* Checkout Shortcode */
46
- add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
-
48
- /* Preconfigured cart data */
49
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
-
51
- /* Embed Checkout */
52
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
-
54
- /* Ajax Endpoint */
55
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
-
57
- add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
-
59
- add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
-
61
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
-
63
- add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
- add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
-
66
- add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
-
68
- /* Global Checkout */
69
- add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
-
71
- add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
-
74
- add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
- add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
-
77
- add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
-
79
- add_filter( 'woocommerce_paypal_express_checkout_payment_button_data', array( $this, 'change_return_cancel_url' ), 10, 2 );
80
-
81
- add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
82
-
83
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
84
- }
85
-
86
- /**
87
- * Modify WooCommerce paypal arguments.
88
- *
89
- * @param array $args argumenets for payment.
90
- * @param WC_Order $order order data.
91
- * @return array
92
- */
93
- public function modify_paypal_args( $args, $order ) {
94
-
95
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
96
-
97
- if ( ! $checkout_id ) {
98
- return $args;
99
- }
100
-
101
- // Set cancel return URL.
102
- $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
103
-
104
- return $args;
105
- }
106
-
107
- /**
108
- * Change PayPal Express cancel URL.
109
- *
110
- * @param array $data button data.
111
- * @param string $page current page.
112
- * @return array $data modified button data with new cancel url.
113
- */
114
- public function change_return_cancel_url( $data, $page ) {
115
-
116
- global $post;
117
-
118
- if ( _is_wcf_checkout_type() ) {
119
-
120
- $checkout_id = $post->ID;
121
-
122
- if ( $checkout_id ) {
123
-
124
- // Change the default Cart URL with the CartFlows Checkout page.
125
- $data['cancel_url'] = esc_url_raw( get_permalink( $checkout_id ) );
126
- }
127
- }
128
-
129
- // Returing the modified data.
130
- return $data;
131
- }
132
-
133
- /**
134
- * Modify WooCommerce paypal arguments.
135
- *
136
- * @param string $product_name product name.
137
- * @param object $cart_item cart item.
138
- * @param string $cart_item_key cart item key.
139
- * @return string
140
- */
141
- public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
142
-
143
- $checkout_id = get_the_ID();
144
- if ( ! $checkout_id ) {
145
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
146
- }
147
-
148
- if ( ! empty( $checkout_id ) ) {
149
- $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
150
- if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
151
- $remove_label = apply_filters(
152
- 'woocommerce_cart_item_remove_link',
153
- sprintf(
154
- '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
155
- esc_attr( $cart_item['product_id'] ),
156
- $cart_item_key
157
- ),
158
- $cart_item_key
159
- );
160
-
161
- $product_name = $remove_label . $product_name;
162
- }
163
- }
164
-
165
- return $product_name;
166
-
167
- }
168
-
169
- /**
170
- * Change order button text .
171
- *
172
- * @param string $woo_button_text place order.
173
- * @return string
174
- */
175
- public function place_order_button_text( $woo_button_text ) {
176
-
177
- $checkout_id = get_the_ID();
178
- if ( ! $checkout_id ) {
179
- $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
180
- }
181
-
182
- $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
183
-
184
- if ( ! empty( $wcf_order_button_text ) ) {
185
- $woo_button_text = $wcf_order_button_text;
186
- }
187
-
188
- return $woo_button_text;
189
- }
190
-
191
- /**
192
- * Display all WooCommerce notices.
193
- *
194
- * @since 1.1.5
195
- */
196
- public function display_woo_notices() {
197
-
198
- if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
199
- woocommerce_output_all_notices();
200
- }
201
- }
202
-
203
-
204
- /**
205
- * Redirect from default to the global checkout page
206
- *
207
- * @since 1.0.0
208
- */
209
- public function global_checkout_template_redirect() {
210
-
211
- if ( ! is_checkout() ) {
212
- return;
213
- }
214
-
215
- if ( wcf()->utils->is_step_post_type() ) {
216
- return;
217
- }
218
-
219
- // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
220
- if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
221
- return;
222
- }
223
-
224
- // redirect only for cartflows checkout pages.
225
- $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
226
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
227
-
228
- $common = Cartflows_Helper::get_common_settings();
229
-
230
- $global_checkout = $common['global_checkout'];
231
-
232
- if (
233
- isset( $_SERVER['REQUEST_URI'] ) &&
234
- // ignore on order-pay.
235
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
236
- // ignore on TY page.
237
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
238
- // ignore if order-pay in query param.
239
- false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
240
- ) {
241
-
242
- if ( '' !== $global_checkout ) {
243
-
244
- $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
245
-
246
- if ( ! empty( $link ) ) {
247
-
248
- wp_safe_redirect( $link );
249
- die();
250
- }
251
- }
252
- }
253
- }
254
-
255
- /**
256
- * Check for checkout flag
257
- *
258
- * @param bool $is_checkout is checkout.
259
- *
260
- * @return bool
261
- */
262
- public function woo_checkout_flag( $is_checkout ) {
263
-
264
- if ( ! is_admin() ) {
265
-
266
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
267
-
268
- $is_checkout = true;
269
- }
270
- }
271
-
272
- return $is_checkout;
273
- }
274
-
275
- /**
276
- * Render checkout shortcode markup.
277
- *
278
- * @param array $atts attributes.
279
- * @return string
280
- */
281
- public function checkout_shortcode_markup( $atts ) {
282
-
283
- if ( ! function_exists( 'wc_print_notices' ) ) {
284
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
285
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
286
-
287
- return $notice_out;
288
- }
289
-
290
- $atts = shortcode_atts(
291
- array(
292
- 'id' => 0,
293
- ),
294
- $atts
295
- );
296
-
297
- $checkout_id = intval( $atts['id'] );
298
-
299
- if ( empty( $checkout_id ) ) {
300
-
301
- if ( ! _is_wcf_checkout_type() ) {
302
-
303
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
304
- }
305
-
306
- global $post;
307
-
308
- $checkout_id = intval( $post->ID );
309
- }
310
-
311
- $output = '';
312
-
313
- ob_start();
314
-
315
- do_action( 'cartflows_checkout_form_before', $checkout_id );
316
-
317
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
318
-
319
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
320
-
321
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
322
-
323
- if ( file_exists( $template_layout ) ) {
324
- include $template_layout;
325
- } else {
326
- include $template_default;
327
- }
328
-
329
- $output .= ob_get_clean();
330
-
331
- return $output;
332
- }
333
-
334
- /**
335
- * Configure Cart Data.
336
- *
337
- * @since 1.0.0
338
- *
339
- * @return void
340
- */
341
- public function preconfigured_cart_data() {
342
-
343
- if ( is_admin() ) {
344
- return;
345
- }
346
-
347
- global $post;
348
-
349
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
350
-
351
- if ( wp_doing_ajax() ) {
352
- return;
353
- } else {
354
-
355
- if ( _is_wcf_checkout_type() ) {
356
- $checkout_id = $post->ID;
357
- } else {
358
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
359
- }
360
-
361
- $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
362
-
363
- if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
364
-
365
- if ( WC()->cart->is_empty() ) {
366
- wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
367
- }
368
-
369
- return;
370
- }
371
-
372
- if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
373
- return;
374
- }
375
-
376
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
377
-
378
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
379
-
380
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
381
- $products = 'dummy';
382
- } else {
383
- $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
384
- }
385
-
386
- if ( ! is_array( $products ) ) {
387
-
388
- if ( 'dummy' === $products ) {
389
-
390
- $args = array(
391
- 'posts_per_page' => 1,
392
- 'orderby' => 'rand',
393
- 'post_type' => 'product',
394
- 'meta_query' => array( //phpcs:ignore
395
- // Exclude out of stock products.
396
- array(
397
- 'key' => '_stock_status',
398
- 'value' => 'outofstock',
399
- 'compare' => 'NOT IN',
400
- ),
401
- ),
402
- 'tax_query' => array( //phpcs:ignore
403
- array(
404
- 'taxonomy' => 'product_type',
405
- 'field' => 'slug',
406
- 'terms' => 'simple',
407
- ),
408
- ),
409
- );
410
-
411
- $random_product = get_posts( $args );
412
-
413
- if ( isset( $random_product[0]->ID ) ) {
414
- $products = array(
415
- array(
416
- 'product' => $random_product[0]->ID,
417
- 'add_to_cart' => true,
418
- ),
419
- );
420
- } else {
421
- return;
422
- }
423
- } else {
424
- return;
425
- }
426
- }
427
-
428
- /* Empty the current cart */
429
- WC()->cart->empty_cart();
430
-
431
- if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
432
- wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
433
- return;
434
- }
435
-
436
- /* Set customer session if not set */
437
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
438
- WC()->session->set_customer_session_cookie( true );
439
- }
440
-
441
- $cart_product_count = 0;
442
- $cart_key = '';
443
- $products_new = array();
444
-
445
- $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
446
-
447
- foreach ( $products as $index => $data ) {
448
-
449
- if ( ! isset( $data['product'] ) ) {
450
- continue;
451
- }
452
-
453
- if ( empty( $data['add_to_cart'] ) ) {
454
- continue;
455
- }
456
-
457
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
458
- break;
459
- }
460
-
461
- $product_id = $data['product'];
462
- $_product = wc_get_product( $product_id );
463
-
464
- if ( ! empty( $_product ) ) {
465
-
466
- $quantity = 1;
467
-
468
- if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
469
- $quantity = $data['quantity'];
470
- }
471
-
472
- $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
473
- $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
474
- $_product_price = $_product->get_price( $data['product'] );
475
-
476
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
477
-
478
- $cart_item_data = array();
479
-
480
- if ( ! empty( $custom_price ) ) {
481
-
482
- $cart_item_data = array(
483
- 'custom_price' => $custom_price,
484
- );
485
- }
486
-
487
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
488
-
489
- if ( $_product->is_type( 'variable' ) ) {
490
-
491
- $default_attributes = $_product->get_default_attributes();
492
-
493
- if ( ! empty( $default_attributes ) ) {
494
-
495
- foreach ( $_product->get_children() as $variation_id ) {
496
-
497
- $single_variation = new WC_Product_Variation( $variation_id );
498
-
499
- if ( $default_attributes == $single_variation->get_attributes() ) {
500
- $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
501
- $cart_product_count++;
502
- }
503
- }
504
- } else {
505
-
506
- $product_childrens = $_product->get_children();
507
-
508
- if ( isset( $product_childrens[0] ) ) {
509
- $variation = wc_get_product( $product_childrens[0] );
510
- $_product_price = $variation->get_price();
511
- $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
512
- if ( ! empty( $custom_price ) ) {
513
- $cart_item_data = array(
514
- 'custom_price' => $custom_price,
515
- 'data' => $data,
516
- );
517
- }
518
- $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
519
- $cart_product_count++;
520
- } else {
521
- echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
522
- }
523
- }
524
- } else {
525
- $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
526
- $cart_product_count++;
527
- }
528
- } else {
529
- $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
530
- wc_add_notice( $wrong_product_notice );
531
- /**
532
- WC()->cart->add_to_cart( $product_id, $quantity );.
533
- */
534
- }
535
- }
536
- $products_new[ $index ] = array(
537
- 'cart_item_key' => $cart_key,
538
- );
539
- }
540
-
541
- /* Set checkout products data */
542
- wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
543
-
544
- /* Since 1.2.2 */
545
- wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
546
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
547
- }
548
- }
549
- }
550
-
551
- /**
552
- * Load shortcode data.
553
- *
554
- * @return void
555
- */
556
- public function shortcode_load_data() {
557
-
558
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
559
-
560
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
561
-
562
- add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
563
-
564
- /* Show notices if cart has errors */
565
- add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
566
-
567
- add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
568
-
569
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
570
-
571
- // Outputting the hidden field in checkout page.
572
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
573
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
-
575
- remove_all_actions( 'woocommerce_checkout_billing' );
576
- remove_all_actions( 'woocommerce_checkout_shipping' );
577
-
578
- // Hook in actions once.
579
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
580
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
581
-
582
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
583
-
584
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
585
-
586
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
587
-
588
- add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
589
-
590
- add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
591
-
592
- global $post;
593
-
594
- if ( _is_wcf_checkout_type() ) {
595
- $checkout_id = $post->ID;
596
- } else {
597
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
598
- }
599
-
600
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
601
- }
602
- }
603
-
604
- /**
605
- * Render checkout ID hidden field.
606
- *
607
- * @param array $checkout checkout session data.
608
- * @return void
609
- */
610
- public function checkout_shortcode_post_id( $checkout ) {
611
-
612
- global $post;
613
-
614
- if ( _is_wcf_checkout_type() ) {
615
- $checkout_id = $post->ID;
616
- } else {
617
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
618
- }
619
-
620
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
621
-
622
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
623
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
624
- }
625
-
626
- /**
627
- * Load shortcode scripts.
628
- *
629
- * @return void
630
- */
631
- public function shortcode_scripts() {
632
-
633
- wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
634
-
635
- wp_enqueue_script(
636
- 'wcf-checkout-template',
637
- wcf()->utils->get_js_url( 'checkout-template' ),
638
- array( 'jquery' ),
639
- CARTFLOWS_VER,
640
- true
641
- );
642
-
643
- do_action( 'cartflows_checkout_scripts' );
644
-
645
- $style = $this->generate_style();
646
-
647
- wp_add_inline_style( 'wcf-checkout-template', $style );
648
-
649
- }
650
-
651
- /**
652
- * Load compatibility scripts.
653
- *
654
- * @return void
655
- */
656
- public function compatibility_scripts() {
657
-
658
- global $post;
659
-
660
- if ( _is_wcf_checkout_type() ) {
661
- $checkout_id = $post->ID;
662
- } else {
663
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
664
- }
665
-
666
- // Add DIVI Compatibility css if DIVI theme is enabled.
667
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
668
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
669
- ) {
670
- wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
671
- }
672
-
673
- // Add Flatsome Compatibility css if Flatsome theme is enabled.
674
- if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
675
- wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
676
- }
677
-
678
- // Add The7 Compatibility css if The7 theme is enabled.
679
- if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
680
- wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
681
- }
682
- }
683
-
684
- /**
685
- * Generate styles.
686
- *
687
- * @return string
688
- */
689
- public function generate_style() {
690
-
691
- global $post;
692
-
693
- if ( _is_wcf_checkout_type() ) {
694
- $checkout_id = $post->ID;
695
- } else {
696
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
697
- }
698
-
699
- /*Output css variable */
700
- $output = '';
701
-
702
- CartFlows_Font_Families::render_fonts( $checkout_id );
703
-
704
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
705
-
706
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
707
-
708
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
709
-
710
- /**
711
- $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
712
- $r = '';
713
- $g = '';
714
- $b = '';
715
-
716
- $field_tb_padding = '';
717
- $field_lr_padding = '';
718
-
719
- $field_heading_color = '';
720
- $field_color = '';
721
- $field_bg_color = '';
722
- $field_border_color = '';
723
- $field_label_color = '';
724
- $submit_tb_padding = '';
725
- $submit_lr_padding = '';
726
- $hl_bg_color = '';
727
- $field_input_size = '';
728
- $box_border_color = '';
729
- $section_bg_color = '';
730
- $submit_button_height = '';
731
- $submit_color = '';
732
- $submit_bg_color = $primary_color;
733
- $submit_border_color = $primary_color;
734
-
735
- $submit_hover_color = '';
736
- $submit_bg_hover_color = $primary_color;
737
- $submit_border_hover_color = $primary_color;
738
-
739
- $section_heading_color = '';
740
-
741
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
742
-
743
- $button_font_family = '';
744
- $button_font_weight = '';
745
- $input_font_family = '';
746
- $input_font_weight = '';
747
- $heading_font_family = '';
748
- $heading_font_weight = '';
749
- $base_font_family = $base_font_family;
750
- /**
751
- $base_font_weight = $base_font_weight;*/
752
-
753
- if ( 'yes' == $is_advance_option ) {
754
-
755
- /**
756
- * Get Font Family and Font Weight weight values
757
- */
758
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
759
-
760
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
761
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
762
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
763
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
764
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
765
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
766
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
767
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
768
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
769
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
770
-
771
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
772
-
773
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
774
-
775
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
776
-
777
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
778
-
779
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
780
-
781
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
782
-
783
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
784
-
785
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
786
-
787
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
788
-
789
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
790
-
791
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
792
-
793
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
794
-
795
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
796
-
797
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
798
-
799
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
800
-
801
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
802
-
803
- /**
804
- * Get font values
805
- */
806
-
807
- if ( 'custom' == $submit_button_height ) {
808
- $submit_button_height = '38px';
809
- }
810
-
811
- if ( 'custom' == $field_input_size ) {
812
- $field_input_size = '38px';
813
- }
814
- }
815
- if ( isset( $primary_color ) ) {
816
-
817
- list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
818
- }
819
-
820
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
821
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
822
-
823
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
824
-
825
- } else {
826
- include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
827
- }
828
-
829
- return $output;
830
- }
831
-
832
- /**
833
- * Get ajax end points.
834
- *
835
- * @param string $endpoint_url end point URL.
836
- * @param string $request end point request.
837
- * @return string
838
- */
839
- public function get_ajax_endpoint( $endpoint_url, $request ) {
840
-
841
- global $post;
842
-
843
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
844
-
845
- if ( _is_wcf_checkout_type() ) {
846
-
847
- if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
848
-
849
- if ( '' === $request ) {
850
- $query_args = array(
851
- 'wc-ajax' => '%%endpoint%%',
852
- );
853
- } else {
854
- $query_args = array(
855
- 'wc-ajax' => $request,
856
- );
857
- }
858
-
859
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
860
- $uri = $uri[0];
861
-
862
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
863
- }
864
- }
865
- }
866
-
867
- return $endpoint_url;
868
- }
869
-
870
-
871
- /**
872
- * Save checkout fields.
873
- *
874
- * @param int $order_id order id.
875
- * @param array $posted posted data.
876
- * @return void
877
- */
878
- public function save_checkout_fields( $order_id, $posted ) {
879
-
880
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
881
-
882
- $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
883
-
884
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
885
-
886
- if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
887
-
888
- $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
889
-
890
- update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
891
- }
892
- }
893
-
894
- }
895
-
896
- /**
897
- * Enable Logo In Header Of Checkout Page
898
- *
899
- * @return void
900
- */
901
- public function enable_logo_in_header() {
902
- global $post;
903
-
904
- if ( _is_wcf_checkout_type() ) {
905
- $checkout_id = $post->ID;
906
- } else {
907
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
908
- }
909
-
910
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
911
- $add_image_markup = '';
912
-
913
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
914
- $add_image_markup = '<div class="wcf-checkout-header-image">';
915
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
916
- $add_image_markup .= '</div>';
917
- }
918
-
919
- echo $add_image_markup;
920
- }
921
-
922
- /**
923
- * Add text to the bootom of the checkout page.
924
- *
925
- * @return void
926
- */
927
- public function show_cartflows_copyright_message() {
928
- $output_string = '';
929
-
930
- $output_string .= '<div class="wcf-footer-primary">';
931
- $output_string .= '<div class="wcf-footer-content">';
932
- $output_string .= '<p class="wcf-footer-message">';
933
- $output_string .= 'Checkout powered by CartFlows';
934
- $output_string .= '</p>';
935
- $output_string .= '</div>';
936
- $output_string .= '</div>';
937
-
938
- echo $output_string;
939
- }
940
-
941
- /**
942
- * Redirect users to our checkout if hidden param
943
- *
944
- * @param string $redirect redirect url.
945
- * @param object $user user.
946
- * @return string
947
- */
948
- public function after_login_redirect( $redirect, $user ) {
949
-
950
- if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
951
-
952
- $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
953
-
954
- $redirect = get_permalink( $checkout_id );
955
- }
956
-
957
- return $redirect;
958
- }
959
-
960
- /**
961
- * Display coupon code field after review order fields.
962
- */
963
- public function display_custom_coupon_field() {
964
-
965
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
966
- $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
967
-
968
- if ( ! ( $coupon_enabled && $show_coupon ) ) {
969
- return;
970
-
971
- }
972
-
973
- $coupon_field = array(
974
- 'field_text' => __( 'Coupon Code', 'cartflows' ),
975
- 'button_text' => __( 'Apply', 'cartflows' ),
976
- 'class' => '',
977
- );
978
-
979
- $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
980
-
981
- ob_start();
982
- ?>
983
- <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
984
- <div class="wcf-coupon-col-1">
985
- <span>
986
- <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
987
- </span>
988
- </div>
989
- <div class="wcf-coupon-col-2">
990
- <span>
991
- <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
992
- </span>
993
- </div>
994
- </div>
995
- <?php
996
- echo ob_get_clean();
997
- }
998
-
999
- /**
1000
- * Apply filter to change class of remove coupon field.
1001
- *
1002
- * @param string $coupon coupon.
1003
- * @return string
1004
- */
1005
- public function remove_coupon_text( $coupon ) {
1006
-
1007
- $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1008
- return $coupon;
1009
-
1010
- }
1011
- /**
1012
- * Apply filter to change the placeholder text of coupon field.
1013
- *
1014
- * @return string
1015
- */
1016
- public function coupon_field_placeholder() {
1017
- return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1018
- }
1019
-
1020
- /**
1021
- * Apply filter to change the button text of coupon field.
1022
- *
1023
- * @return string
1024
- */
1025
- public function coupon_button_text() {
1026
- return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1027
- }
1028
-
1029
- /**
1030
- * Apply coupon on submit of custom coupon form.
1031
- */
1032
- public function apply_coupon() {
1033
-
1034
- $response = '';
1035
-
1036
- check_ajax_referer( 'wcf-apply-coupon', 'security' );
1037
- if ( ! empty( $_POST['coupon_code'] ) ) {
1038
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1039
- } else {
1040
- wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1041
- }
1042
-
1043
- $response = array(
1044
- 'status' => $result,
1045
- 'msg' => wc_print_notices( true ),
1046
- );
1047
-
1048
- echo wp_json_encode( $response );
1049
-
1050
- die();
1051
- }
1052
-
1053
-
1054
- /**
1055
- * Added ajax nonce to localize variable.
1056
- *
1057
- * @param array $vars localize variables.
1058
- */
1059
- public function add_localize_vars( $vars ) {
1060
-
1061
- $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1062
-
1063
- $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1064
-
1065
- $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1066
-
1067
- $vars['allow_persistance'] = apply_filters( 'cartflows_allow_persistace', 'yes' );
1068
-
1069
- return $vars;
1070
- }
1071
-
1072
- /**
1073
- * Add custom class to the fields to change the UI to three column.
1074
- *
1075
- * @param array $fields fields.
1076
- */
1077
- public function add_three_column_layout_fields( $fields ) {
1078
-
1079
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
1080
-
1081
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1082
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1083
- }
1084
- }
1085
-
1086
- if ( ! empty( $fields['billing']['billing_company'] ) ) {
1087
-
1088
- if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1089
- $fields['billing']['billing_company']['class'][] = 'form-row-full';
1090
- }
1091
- }
1092
-
1093
- if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1094
-
1095
- if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1096
- $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1097
- }
1098
- }
1099
-
1100
- if ( ! empty( $fields['billing']['billing_country'] ) ) {
1101
-
1102
- if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1103
- $fields['billing']['billing_country']['class'][] = 'form-row-full';
1104
- }
1105
- }
1106
-
1107
- if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1108
-
1109
- if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1110
- $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1111
- }
1112
- }
1113
-
1114
- if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1115
-
1116
- if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1117
- $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1118
- }
1119
- }
1120
-
1121
- if ( ! empty( $fields['billing']['billing_email'] ) ) {
1122
-
1123
- if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1124
- $fields['billing']['billing_email']['class'][] = 'form-row-full';
1125
- }
1126
- }
1127
-
1128
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1129
-
1130
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1131
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1132
- }
1133
- }
1134
-
1135
- if ( isset( $fields['billing']['billing_city'] ) &&
1136
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1137
-
1138
- $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1139
- $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1140
- $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1141
- }
1142
-
1143
- if ( isset( $fields['shipping']['shipping_city'] ) &&
1144
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1145
-
1146
- $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1147
- $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1148
- $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1149
- }
1150
-
1151
- return $fields;
1152
- }
1153
-
1154
- /**
1155
- * Add opening dev
1156
- *
1157
- * @since 1.0.0
1158
- */
1159
- public function order_wrap_div_start() {
1160
-
1161
- echo "<div class='wcf-order-wrap'> ";
1162
- }
1163
-
1164
- /**
1165
- * Add closing dev
1166
- *
1167
- * @since 1.0.0
1168
- */
1169
- public function order_wrap_div_end() {
1170
-
1171
- echo '</div> ';
1172
- }
1173
- /**
1174
- * Remove coupon.
1175
- */
1176
- public function remove_coupon() {
1177
-
1178
- check_ajax_referer( 'wcf-remove-coupon', 'security' );
1179
- $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1180
-
1181
- if ( empty( $coupon ) ) {
1182
- echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1183
- } else {
1184
- WC()->cart->remove_coupon( $coupon );
1185
- echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1186
- }
1187
- wc_print_notices();
1188
- wp_die();
1189
- }
1190
-
1191
- /**
1192
- * Remove cart item.
1193
- */
1194
- public function wcf_woo_remove_cart_product() {
1195
-
1196
- check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1197
- $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1198
- $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1199
- $product_title = get_the_title( $product_id );
1200
-
1201
- $needs_shipping = false;
1202
-
1203
- if ( empty( $product_key ) ) {
1204
- $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1205
- } else {
1206
- WC()->cart->remove_cart_item( $product_key );
1207
- $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1208
- }
1209
-
1210
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1211
- if ( $values['data']->needs_shipping() ) {
1212
- $needs_shipping = true;
1213
- break;
1214
- }
1215
- }
1216
-
1217
- $response = array(
1218
- 'need_shipping' => $needs_shipping,
1219
- 'msg' => $msg,
1220
- );
1221
-
1222
- echo wp_json_encode( $response );
1223
- wp_die();
1224
- }
1225
-
1226
- /**
1227
- * Calculate discount for product.
1228
- *
1229
- * @param string $discount_coupon discount coupon.
1230
- * @param string $discount_type discount type.
1231
- * @param int $discount_value discount value.
1232
- * @param int $_product_price product price.
1233
- * @return int
1234
- * @since 1.1.5
1235
- */
1236
- public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1237
-
1238
- $custom_price = '';
1239
-
1240
- if ( ! empty( $discount_type ) ) {
1241
- if ( 'discount_percent' === $discount_type ) {
1242
-
1243
- if ( $discount_value > 0 ) {
1244
- $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1245
- }
1246
- } elseif ( 'discount_price' === $discount_type ) {
1247
-
1248
- if ( $discount_value > 0 ) {
1249
- $custom_price = $_product_price - $discount_value;
1250
- }
1251
- } elseif ( 'coupon' === $discount_type ) {
1252
-
1253
- if ( ! empty( $discount_coupon ) ) {
1254
- WC()->cart->add_discount( $discount_coupon );
1255
- }
1256
- }
1257
- }
1258
-
1259
- return $custom_price;
1260
- }
1261
-
1262
- /**
1263
- * Preserve the custom item price added by Variations & Quantity feature
1264
- *
1265
- * @param array $cart_object cart object.
1266
- * @since 1.0.0
1267
- */
1268
- public function custom_price_to_cart_item( $cart_object ) {
1269
-
1270
- if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1271
-
1272
- foreach ( $cart_object->cart_contents as $key => $value ) {
1273
-
1274
- if ( isset( $value['custom_price'] ) ) {
1275
-
1276
- $custom_price = floatval( $value['custom_price'] );
1277
- $value['data']->set_price( $custom_price );
1278
- }
1279
- }
1280
- }
1281
- }
1282
-
1283
- }
1284
-
1285
- /**
1286
- * Kicking this off by calling 'get_instance()' method
1287
- */
1288
- Cartflows_Checkout_Markup::get_instance();
1
+ <?php
2
+ /**
3
+ * Checkout markup.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Checkout_Markup {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var object instance
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Initiator
24
+ */
25
+ public static function get_instance() {
26
+ if ( ! isset( self::$instance ) ) {
27
+ self::$instance = new self();
28
+ }
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Set is checkout flag */
38
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
39
+
40
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'save_checkout_fields' ), 10, 2 );
41
+
42
+ /* Show notice if cart is empty */
43
+ add_action( 'cartflows_checkout_cart_empty', array( $this, 'display_woo_notices' ) );
44
+
45
+ /* Checkout Shortcode */
46
+ add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
47
+
48
+ /* Preconfigured cart data */
49
+ add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
50
+
51
+ /* Embed Checkout */
52
+ add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
53
+
54
+ /* Ajax Endpoint */
55
+ add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ), 10, 2 );
56
+
57
+ add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
58
+
59
+ add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
60
+
61
+ add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
62
+
63
+ add_action( 'wp_ajax_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
+ add_action( 'wp_ajax_nopriv_wcf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
65
+
66
+ add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
67
+
68
+ /* Global Checkout */
69
+ add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
70
+
71
+ add_action( 'wp_ajax_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
72
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_coupon', array( $this, 'remove_coupon' ) );
73
+
74
+ add_action( 'wp_ajax_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
75
+ add_action( 'wp_ajax_nopriv_wcf_woo_remove_cart_product', array( $this, 'wcf_woo_remove_cart_product' ) );
76
+
77
+ add_filter( 'woocommerce_paypal_args', array( $this, 'modify_paypal_args' ), 10, 2 );
78
+
79
+ add_filter( 'woocommerce_paypal_express_checkout_payment_button_data', array( $this, 'change_return_cancel_url' ), 10, 2 );
80
+
81
+ add_filter( 'woocommerce_cart_item_name', array( $this, 'wcf_add_remove_label' ), 10, 3 );
82
+
83
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'custom_price_to_cart_item' ), 9999 );
84
+ }
85
+
86
+ /**
87
+ * Modify WooCommerce paypal arguments.
88
+ *
89
+ * @param array $args argumenets for payment.
90
+ * @param WC_Order $order order data.
91
+ * @return array
92
+ */
93
+ public function modify_paypal_args( $args, $order ) {
94
+
95
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
96
+
97
+ if ( ! $checkout_id ) {
98
+ return $args;
99
+ }
100
+
101
+ // Set cancel return URL.
102
+ $args['cancel_return'] = esc_url_raw( $order->get_cancel_order_url_raw( get_permalink( $checkout_id ) ) );
103
+
104
+ return $args;
105
+ }
106
+
107
+ /**
108
+ * Change PayPal Express cancel URL.
109
+ *
110
+ * @param array $data button data.
111
+ * @param string $page current page.
112
+ * @return array $data modified button data with new cancel url.
113
+ */
114
+ public function change_return_cancel_url( $data, $page ) {
115
+
116
+ global $post;
117
+
118
+ if ( _is_wcf_checkout_type() ) {
119
+
120
+ $checkout_id = $post->ID;
121
+
122
+ if ( $checkout_id ) {
123
+
124
+ // Change the default Cart URL with the CartFlows Checkout page.
125
+ $data['cancel_url'] = esc_url_raw( get_permalink( $checkout_id ) );
126
+ }
127
+ }
128
+
129
+ // Returing the modified data.
130
+ return $data;
131
+ }
132
+
133
+ /**
134
+ * Modify WooCommerce paypal arguments.
135
+ *
136
+ * @param string $product_name product name.
137
+ * @param object $cart_item cart item.
138
+ * @param string $cart_item_key cart item key.
139
+ * @return string
140
+ */
141
+ public function wcf_add_remove_label( $product_name, $cart_item, $cart_item_key ) {
142
+
143
+ $checkout_id = get_the_ID();
144
+ if ( ! $checkout_id ) {
145
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? wp_unslash( $_POST['option']['checkout_id'] ) : '';//phpcs:ignore
146
+ }
147
+
148
+ if ( ! empty( $checkout_id ) ) {
149
+ $is_remove_product_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-remove-product-field' );
150
+ if ( 'checkout' === get_post_meta( $checkout_id, 'wcf-step-type', true ) && ( 'yes' === $is_remove_product_option ) ) {
151
+ $remove_label = apply_filters(
152
+ 'woocommerce_cart_item_remove_link',
153
+ sprintf(
154
+ '<a href="#" rel="nofollow" class="remove cartflows-icon-close" data-id="%s" data-item-key="%s" ></a>',
155
+ esc_attr( $cart_item['product_id'] ),
156
+ $cart_item_key
157
+ ),
158
+ $cart_item_key
159
+ );
160
+
161
+ $product_name = $remove_label . $product_name;
162
+ }
163
+ }
164
+
165
+ return $product_name;
166
+
167
+ }
168
+
169
+ /**
170
+ * Change order button text .
171
+ *
172
+ * @param string $woo_button_text place order.
173
+ * @return string
174
+ */
175
+ public function place_order_button_text( $woo_button_text ) {
176
+
177
+ $checkout_id = get_the_ID();
178
+ if ( ! $checkout_id ) {
179
+ $checkout_id = ( isset( $_POST['option']['checkout_id'] ) ) ? intval( $_POST['option']['checkout_id'] ) : 0; //phpcs:ignore
180
+ }
181
+
182
+ $wcf_order_button_text = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-place-order-button-text' );
183
+
184
+ if ( ! empty( $wcf_order_button_text ) ) {
185
+ $woo_button_text = $wcf_order_button_text;
186
+ }
187
+
188
+ return $woo_button_text;
189
+ }
190
+
191
+ /**
192
+ * Display all WooCommerce notices.
193
+ *
194
+ * @since 1.1.5
195
+ */
196
+ public function display_woo_notices() {
197
+
198
+ if ( null != WC()->session && function_exists( 'woocommerce_output_all_notices' ) ) {
199
+ woocommerce_output_all_notices();
200
+ }
201
+ }
202
+
203
+
204
+ /**
205
+ * Redirect from default to the global checkout page
206
+ *
207
+ * @since 1.0.0
208
+ */
209
+ public function global_checkout_template_redirect() {
210
+
211
+ if ( ! is_checkout() ) {
212
+ return;
213
+ }
214
+
215
+ if ( wcf()->utils->is_step_post_type() ) {
216
+ return;
217
+ }
218
+
219
+ // Return if the key OR Order paramater is found in the URL for certain Payment gateways.
220
+ if ( isset( $_GET['key'] ) || isset( $_GET['order'] ) ) { //phpcs:ignore
221
+ return;
222
+ }
223
+
224
+ // redirect only for cartflows checkout pages.
225
+ $order_pay_endpoint = get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' );
226
+ $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
227
+
228
+ $common = Cartflows_Helper::get_common_settings();
229
+
230
+ $global_checkout = $common['global_checkout'];
231
+
232
+ if (
233
+ isset( $_SERVER['REQUEST_URI'] ) &&
234
+ // ignore on order-pay.
235
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_pay_endpoint . '/' ) &&
236
+ // ignore on TY page.
237
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), '/' . $order_received_endpoint . '/' ) &&
238
+ // ignore if order-pay in query param.
239
+ false === wcf_mb_strpos( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), $order_pay_endpoint . '=' )
240
+ ) {
241
+
242
+ if ( '' !== $global_checkout ) {
243
+
244
+ $link = apply_filters( 'cartflows_global_checkout_url', get_permalink( $global_checkout ) );
245
+
246
+ if ( ! empty( $link ) ) {
247
+
248
+ wp_safe_redirect( $link );
249
+ die();
250
+ }
251
+ }
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Check for checkout flag
257
+ *
258
+ * @param bool $is_checkout is checkout.
259
+ *
260
+ * @return bool
261
+ */
262
+ public function woo_checkout_flag( $is_checkout ) {
263
+
264
+ if ( ! is_admin() ) {
265
+
266
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
267
+
268
+ $is_checkout = true;
269
+ }
270
+ }
271
+
272
+ return $is_checkout;
273
+ }
274
+
275
+ /**
276
+ * Render checkout shortcode markup.
277
+ *
278
+ * @param array $atts attributes.
279
+ * @return string
280
+ */
281
+ public function checkout_shortcode_markup( $atts ) {
282
+
283
+ if ( ! function_exists( 'wc_print_notices' ) ) {
284
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
285
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
286
+
287
+ return $notice_out;
288
+ }
289
+
290
+ $atts = shortcode_atts(
291
+ array(
292
+ 'id' => 0,
293
+ ),
294
+ $atts
295
+ );
296
+
297
+ $checkout_id = intval( $atts['id'] );
298
+
299
+ if ( empty( $checkout_id ) ) {
300
+
301
+ if ( ! _is_wcf_checkout_type() ) {
302
+
303
+ return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
304
+ }
305
+
306
+ global $post;
307
+
308
+ $checkout_id = intval( $post->ID );
309
+ }
310
+
311
+ $output = '';
312
+
313
+ ob_start();
314
+
315
+ do_action( 'cartflows_checkout_form_before', $checkout_id );
316
+
317
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
318
+
319
+ $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
320
+
321
+ $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
322
+
323
+ if ( file_exists( $template_layout ) ) {
324
+ include $template_layout;
325
+ } else {
326
+ include $template_default;
327
+ }
328
+
329
+ $output .= ob_get_clean();
330
+
331
+ return $output;
332
+ }
333
+
334
+ /**
335
+ * Configure Cart Data.
336
+ *
337
+ * @since 1.0.0
338
+ *
339
+ * @return void
340
+ */
341
+ public function preconfigured_cart_data() {
342
+
343
+ if ( is_admin() ) {
344
+ return;
345
+ }
346
+
347
+ global $post;
348
+
349
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
350
+
351
+ if ( wp_doing_ajax() ) {
352
+ return;
353
+ } else {
354
+
355
+ if ( _is_wcf_checkout_type() ) {
356
+ $checkout_id = $post->ID;
357
+ } else {
358
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
359
+ }
360
+
361
+ $global_checkout = intval( Cartflows_Helper::get_common_setting( 'global_checkout' ) );
362
+
363
+ if ( ! empty( $global_checkout ) && $checkout_id === $global_checkout ) {
364
+
365
+ if ( WC()->cart->is_empty() ) {
366
+ wc_add_notice( __( 'Your cart is currently empty.', 'cartflows' ), 'error' );
367
+ }
368
+
369
+ return;
370
+ }
371
+
372
+ if ( apply_filters( 'cartflows_skip_configure_cart', false, $checkout_id ) ) {
373
+ return;
374
+ }
375
+
376
+ do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
377
+
378
+ $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
379
+
380
+ if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
381
+ $products = 'dummy';
382
+ } else {
383
+ $products = wcf()->utils->get_selected_checkout_products( $checkout_id );
384
+ }
385
+
386
+ if ( ! is_array( $products ) ) {
387
+
388
+ if ( 'dummy' === $products ) {
389
+
390
+ $args = array(
391
+ 'posts_per_page' => 1,
392
+ 'orderby' => 'rand',
393
+ 'post_type' => 'product',
394
+ 'meta_query' => array( //phpcs:ignore
395
+ // Exclude out of stock products.
396
+ array(
397
+ 'key' => '_stock_status',
398
+ 'value' => 'outofstock',
399
+ 'compare' => 'NOT IN',
400
+ ),
401
+ ),
402
+ 'tax_query' => array( //phpcs:ignore
403
+ array(
404
+ 'taxonomy' => 'product_type',
405
+ 'field' => 'slug',
406
+ 'terms' => 'simple',
407
+ ),
408
+ ),
409
+ );
410
+
411
+ $random_product = get_posts( $args );
412
+
413
+ if ( isset( $random_product[0]->ID ) ) {
414
+ $products = array(
415
+ array(
416
+ 'product' => $random_product[0]->ID,
417
+ 'add_to_cart' => true,
418
+ ),
419
+ );
420
+ } else {
421
+ return;
422
+ }
423
+ } else {
424
+ return;
425
+ }
426
+ }
427
+
428
+ /* Empty the current cart */
429
+ WC()->cart->empty_cart();
430
+
431
+ if ( is_array( $products ) && empty( $products[0]['product'] ) ) {
432
+ wc_add_notice( __( 'No product is selected. Please select products from the checkout meta settings to continue.', 'cartflows' ), 'error' );
433
+ return;
434
+ }
435
+
436
+ /* Set customer session if not set */
437
+ if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
438
+ WC()->session->set_customer_session_cookie( true );
439
+ }
440
+
441
+ $cart_product_count = 0;
442
+ $cart_key = '';
443
+ $products_new = array();
444
+
445
+ $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
446
+
447
+ foreach ( $products as $index => $data ) {
448
+
449
+ if ( ! isset( $data['product'] ) ) {
450
+ continue;
451
+ }
452
+
453
+ if ( empty( $data['add_to_cart'] ) ) {
454
+ continue;
455
+ }
456
+
457
+ if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
458
+ break;
459
+ }
460
+
461
+ $product_id = $data['product'];
462
+ $_product = wc_get_product( $product_id );
463
+
464
+ if ( ! empty( $_product ) ) {
465
+
466
+ $quantity = 1;
467
+
468
+ if ( isset( $data['quantity'] ) && ! empty( $data['quantity'] ) ) {
469
+ $quantity = $data['quantity'];
470
+ }
471
+
472
+ $discount_type = isset( $data['discount_type'] ) ? $data['discount_type'] : '';
473
+ $discount_value = ! empty( $data['discount_value'] ) ? $data['discount_value'] : '';
474
+ $_product_price = $_product->get_price( $data['product'] );
475
+
476
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
477
+
478
+ $cart_item_data = array();
479
+
480
+ if ( ! empty( $custom_price ) ) {
481
+
482
+ $cart_item_data = array(
483
+ 'custom_price' => $custom_price,
484
+ );
485
+ }
486
+
487
+ if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
488
+
489
+ if ( $_product->is_type( 'variable' ) ) {
490
+
491
+ $default_attributes = $_product->get_default_attributes();
492
+
493
+ if ( ! empty( $default_attributes ) ) {
494
+
495
+ foreach ( $_product->get_children() as $variation_id ) {
496
+
497
+ $single_variation = new WC_Product_Variation( $variation_id );
498
+
499
+ if ( $default_attributes == $single_variation->get_attributes() ) {
500
+ $cart_key = WC()->cart->add_to_cart( $variation_id, $quantity, 0, array(), $cart_item_data );
501
+ $cart_product_count++;
502
+ }
503
+ }
504
+ } else {
505
+
506
+ $product_childrens = $_product->get_children();
507
+
508
+ if ( isset( $product_childrens[0] ) ) {
509
+ $variation = wc_get_product( $product_childrens[0] );
510
+ $_product_price = $variation->get_price();
511
+ $custom_price = $this->calculate_discount( '', $discount_type, $discount_value, $_product_price );
512
+ if ( ! empty( $custom_price ) ) {
513
+ $cart_item_data = array(
514
+ 'custom_price' => $custom_price,
515
+ 'data' => $data,
516
+ );
517
+ }
518
+ $cart_key = WC()->cart->add_to_cart( $product_childrens[0], $quantity, 0, array(), $cart_item_data );
519
+ $cart_product_count++;
520
+ } else {
521
+ echo '<p>' . esc_html__( 'Variations Not set', 'cartflows' ) . '</p>';
522
+ }
523
+ }
524
+ } else {
525
+ $cart_key = WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), $cart_item_data );
526
+ $cart_product_count++;
527
+ }
528
+ } else {
529
+ $wrong_product_notice = __( 'This product can\'t be purchased', 'cartflows' );
530
+ wc_add_notice( $wrong_product_notice );
531
+ /**
532
+ WC()->cart->add_to_cart( $product_id, $quantity );.
533
+ */
534
+ }
535
+ }
536
+ $products_new[ $index ] = array(
537
+ 'cart_item_key' => $cart_key,
538
+ );
539
+ }
540
+
541
+ /* Set checkout products data */
542
+ wcf()->utils->set_selcted_checkout_products( $checkout_id, $products_new );
543
+
544
+ /* Since 1.2.2 */
545
+ wcf_do_action_deprecated( 'cartflows_checkout_aftet_configure_cart', array( $checkout_id ), '1.2.2', 'cartflows_checkout_after_configure_cart' );
546
+ do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
547
+ }
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Load shortcode data.
553
+ *
554
+ * @return void
555
+ */
556
+ public function shortcode_load_data() {
557
+
558
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
559
+
560
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
561
+
562
+ add_action( 'wp_enqueue_scripts', array( $this, 'compatibility_scripts' ), 101 );
563
+
564
+ /* Show notices if cart has errors */
565
+ add_action( 'woocommerce_cart_has_errors', 'woocommerce_output_all_notices' );
566
+
567
+ add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
568
+
569
+ add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
570
+
571
+ // Outputting the hidden field in checkout page.
572
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
573
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
574
+
575
+ remove_all_actions( 'woocommerce_checkout_billing' );
576
+ remove_all_actions( 'woocommerce_checkout_shipping' );
577
+
578
+ // Hook in actions once.
579
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
580
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
581
+
582
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
583
+
584
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
585
+
586
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
587
+
588
+ add_filter( 'woocommerce_cart_totals_coupon_html', array( $this, 'remove_coupon_text' ) );
589
+
590
+ add_filter( 'woocommerce_order_button_text', array( $this, 'place_order_button_text' ), 10, 1 );
591
+
592
+ global $post;
593
+
594
+ if ( _is_wcf_checkout_type() ) {
595
+ $checkout_id = $post->ID;
596
+ } else {
597
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
598
+ }
599
+
600
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
601
+ }
602
+ }
603
+
604
+ /**
605
+ * Render checkout ID hidden field.
606
+ *
607
+ * @param array $checkout checkout session data.
608
+ * @return void
609
+ */
610
+ public function checkout_shortcode_post_id( $checkout ) {
611
+
612
+ global $post;
613
+
614
+ if ( _is_wcf_checkout_type() ) {
615
+ $checkout_id = $post->ID;
616
+ } else {
617
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
618
+ }
619
+
620
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
621
+
622
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
623
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
624
+ }
625
+
626
+ /**
627
+ * Load shortcode scripts.
628
+ *
629
+ * @return void
630
+ */
631
+ public function shortcode_scripts() {
632
+
633
+ wp_enqueue_style( 'wcf-checkout-template', wcf()->utils->get_css_url( 'checkout-template' ), '', CARTFLOWS_VER );
634
+
635
+ wp_enqueue_script(
636
+ 'wcf-checkout-template',
637
+ wcf()->utils->get_js_url( 'checkout-template' ),
638
+ array( 'jquery' ),
639
+ CARTFLOWS_VER,
640
+ true
641
+ );
642
+
643
+ do_action( 'cartflows_checkout_scripts' );
644
+
645
+ $style = $this->generate_style();
646
+
647
+ wp_add_inline_style( 'wcf-checkout-template', $style );
648
+
649
+ }
650
+
651
+ /**
652
+ * Load compatibility scripts.
653
+ *
654
+ * @return void
655
+ */
656
+ public function compatibility_scripts() {
657
+
658
+ global $post;
659
+
660
+ if ( _is_wcf_checkout_type() ) {
661
+ $checkout_id = $post->ID;
662
+ } else {
663
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
664
+ }
665
+
666
+ // Add DIVI Compatibility css if DIVI theme is enabled.
667
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
668
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id )
669
+ ) {
670
+ wp_enqueue_style( 'wcf-checkout-template-divi', wcf()->utils->get_css_url( 'checkout-template-divi' ), '', CARTFLOWS_VER );
671
+ }
672
+
673
+ // Add Flatsome Compatibility css if Flatsome theme is enabled.
674
+ if ( Cartflows_Compatibility::get_instance()->is_flatsome_enabled() ) {
675
+ wp_enqueue_style( 'wcf-checkout-template-flatsome', wcf()->utils->get_css_url( 'checkout-template-flatsome' ), '', CARTFLOWS_VER );
676
+ }
677
+
678
+ // Add The7 Compatibility css if The7 theme is enabled.
679
+ if ( Cartflows_Compatibility::get_instance()->is_the_seven_enabled() ) {
680
+ wp_enqueue_style( 'wcf-checkout-template-the-seven', wcf()->utils->get_css_url( 'checkout-template-the-seven' ), '', CARTFLOWS_VER );
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Generate styles.
686
+ *
687
+ * @return string
688
+ */
689
+ public function generate_style() {
690
+
691
+ global $post;
692
+
693
+ if ( _is_wcf_checkout_type() ) {
694
+ $checkout_id = $post->ID;
695
+ } else {
696
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
697
+ }
698
+
699
+ /*Output css variable */
700
+ $output = '';
701
+
702
+ CartFlows_Font_Families::render_fonts( $checkout_id );
703
+
704
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
705
+
706
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
707
+
708
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
709
+
710
+ /**
711
+ $base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
712
+ $r = '';
713
+ $g = '';
714
+ $b = '';
715
+
716
+ $field_tb_padding = '';
717
+ $field_lr_padding = '';
718
+
719
+ $field_heading_color = '';
720
+ $field_color = '';
721
+ $field_bg_color = '';
722
+ $field_border_color = '';
723
+ $field_label_color = '';
724
+ $submit_tb_padding = '';
725
+ $submit_lr_padding = '';
726
+ $hl_bg_color = '';
727
+ $field_input_size = '';
728
+ $box_border_color = '';
729
+ $section_bg_color = '';
730
+ $submit_button_height = '';
731
+ $submit_color = '';
732
+ $submit_bg_color = $primary_color;
733
+ $submit_border_color = $primary_color;
734
+
735
+ $submit_hover_color = '';
736
+ $submit_bg_hover_color = $primary_color;
737
+ $submit_border_hover_color = $primary_color;
738
+
739
+ $section_heading_color = '';
740
+
741
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
742
+
743
+ $button_font_family = '';
744
+ $button_font_weight = '';
745
+ $input_font_family = '';
746
+ $input_font_weight = '';
747
+ $heading_font_family = '';
748
+ $heading_font_weight = '';
749
+ $base_font_family = $base_font_family;
750
+ /**
751
+ $base_font_weight = $base_font_weight;*/
752
+
753
+ if ( 'yes' == $is_advance_option ) {
754
+
755
+ /**
756
+ * Get Font Family and Font Weight weight values
757
+ */
758
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
759
+
760
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
761
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
762
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
763
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
764
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
765
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
766
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
767
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
768
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
769
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
770
+
771
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
772
+
773
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
774
+
775
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
776
+
777
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
778
+
779
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
780
+
781
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
782
+
783
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
784
+
785
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
786
+
787
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
788
+
789
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
790
+
791
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
792
+
793
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
794
+
795
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
796
+
797
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
798
+
799
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
800
+
801
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
802
+
803
+ /**
804
+ * Get font values
805
+ */
806
+
807
+ if ( 'custom' == $submit_button_height ) {
808
+ $submit_button_height = '38px';
809
+ }
810
+
811
+ if ( 'custom' == $field_input_size ) {
812
+ $field_input_size = '38px';
813
+ }
814
+ }
815
+ if ( isset( $primary_color ) ) {
816
+
817
+ list($r, $g, $b) = sscanf( $primary_color, '#%02x%02x%02x' );
818
+ }
819
+
820
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
821
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $checkout_id ) ) {
822
+
823
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-divi-css.php';
824
+
825
+ } else {
826
+ include CARTFLOWS_CHECKOUT_DIR . 'includes/checkout-dynamic-css.php';
827
+ }
828
+
829
+ return $output;
830
+ }
831
+
832
+ /**
833
+ * Get ajax end points.
834
+ *
835
+ * @param string $endpoint_url end point URL.
836
+ * @param string $request end point request.
837
+ * @return string
838
+ */
839
+ public function get_ajax_endpoint( $endpoint_url, $request ) {
840
+
841
+ global $post;
842
+
843
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
844
+
845
+ if ( _is_wcf_checkout_type() ) {
846
+
847
+ if ( mb_strpos( $endpoint_url, 'checkout', 0, 'utf-8' ) === false ) {
848
+
849
+ if ( '' === $request ) {
850
+ $query_args = array(
851
+ 'wc-ajax' => '%%endpoint%%',
852
+ );
853
+ } else {
854
+ $query_args = array(
855
+ 'wc-ajax' => $request,
856
+ );
857
+ }
858
+
859
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 ); //phpcs:ignore
860
+ $uri = $uri[0];
861
+
862
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
863
+ }
864
+ }
865
+ }
866
+
867
+ return $endpoint_url;
868
+ }
869
+
870
+
871
+ /**
872
+ * Save checkout fields.
873
+ *
874
+ * @param int $order_id order id.
875
+ * @param array $posted posted data.
876
+ * @return void
877
+ */
878
+ public function save_checkout_fields( $order_id, $posted ) {
879
+
880
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
881
+
882
+ $checkout_id = wc_clean( intval( $_POST['_wcf_checkout_id'] ) ); //phpcs:ignore
883
+
884
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
885
+
886
+ if ( isset( $_POST['_wcf_flow_id'] ) ) { //phpcs:ignore
887
+
888
+ $flow_id = wc_clean( intval( $_POST['_wcf_flow_id'] ) ); //phpcs:ignore
889
+
890
+ update_post_meta( $order_id, '_wcf_flow_id', $flow_id );
891
+ }
892
+ }
893
+
894
+ }
895
+
896
+ /**
897
+ * Enable Logo In Header Of Checkout Page
898
+ *
899
+ * @return void
900
+ */
901
+ public function enable_logo_in_header() {
902
+ global $post;
903
+
904
+ if ( _is_wcf_checkout_type() ) {
905
+ $checkout_id = $post->ID;
906
+ } else {
907
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
908
+ }
909
+
910
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
911
+ $add_image_markup = '';
912
+
913
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
914
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
915
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
916
+ $add_image_markup .= '</div>';
917
+ }
918
+
919
+ echo $add_image_markup;
920
+ }
921
+
922
+ /**
923
+ * Add text to the bootom of the checkout page.
924
+ *
925
+ * @return void
926
+ */
927
+ public function show_cartflows_copyright_message() {
928
+ $output_string = '';
929
+
930
+ $output_string .= '<div class="wcf-footer-primary">';
931
+ $output_string .= '<div class="wcf-footer-content">';
932
+ $output_string .= '<p class="wcf-footer-message">';
933
+ $output_string .= 'Checkout powered by CartFlows';
934
+ $output_string .= '</p>';
935
+ $output_string .= '</div>';
936
+ $output_string .= '</div>';
937
+
938
+ echo $output_string;
939
+ }
940
+
941
+ /**
942
+ * Redirect users to our checkout if hidden param
943
+ *
944
+ * @param string $redirect redirect url.
945
+ * @param object $user user.
946
+ * @return string
947
+ */
948
+ public function after_login_redirect( $redirect, $user ) {
949
+
950
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) { //phpcs:ignore
951
+
952
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] ); //phpcs:ignore
953
+
954
+ $redirect = get_permalink( $checkout_id );
955
+ }
956
+
957
+ return $redirect;
958
+ }
959
+
960
+ /**
961
+ * Display coupon code field after review order fields.
962
+ */
963
+ public function display_custom_coupon_field() {
964
+
965
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
966
+ $show_coupon = apply_filters( 'cartflows_show_coupon_field', true );
967
+
968
+ if ( ! ( $coupon_enabled && $show_coupon ) ) {
969
+ return;
970
+
971
+ }
972
+
973
+ $coupon_field = array(
974
+ 'field_text' => __( 'Coupon Code', 'cartflows' ),
975
+ 'button_text' => __( 'Apply', 'cartflows' ),
976
+ 'class' => '',
977
+ );
978
+
979
+ $coupon_field = apply_filters( 'cartflows_coupon_field_options', $coupon_field );
980
+
981
+ ob_start();
982
+ ?>
983
+ <div class="wcf-custom-coupon-field <?php echo $coupon_field['class']; ?>" id="wcf_custom_coupon_field">
984
+ <div class="wcf-coupon-col-1">
985
+ <span>
986
+ <input type="text" name="coupon_code" class="input-text wcf-coupon-code-input" placeholder="<?php echo $coupon_field['field_text']; ?>" id="coupon_code" value="">
987
+ </span>
988
+ </div>
989
+ <div class="wcf-coupon-col-2">
990
+ <span>
991
+ <button type="button" class="button wcf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $coupon_field['button_text']; ?></button>
992
+ </span>
993
+ </div>
994
+ </div>
995
+ <?php
996
+ echo ob_get_clean();
997
+ }
998
+
999
+ /**
1000
+ * Apply filter to change class of remove coupon field.
1001
+ *
1002
+ * @param string $coupon coupon.
1003
+ * @return string
1004
+ */
1005
+ public function remove_coupon_text( $coupon ) {
1006
+
1007
+ $coupon = str_replace( 'woocommerce-remove-coupon', 'wcf-remove-coupon', $coupon );
1008
+ return $coupon;
1009
+
1010
+ }
1011
+ /**
1012
+ * Apply filter to change the placeholder text of coupon field.
1013
+ *
1014
+ * @return string
1015
+ */
1016
+ public function coupon_field_placeholder() {
1017
+ return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
1018
+ }
1019
+
1020
+ /**
1021
+ * Apply filter to change the button text of coupon field.
1022
+ *
1023
+ * @return string
1024
+ */
1025
+ public function coupon_button_text() {
1026
+ return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
1027
+ }
1028
+
1029
+ /**
1030
+ * Apply coupon on submit of custom coupon form.
1031
+ */
1032
+ public function apply_coupon() {
1033
+
1034
+ $response = '';
1035
+
1036
+ check_ajax_referer( 'wcf-apply-coupon', 'security' );
1037
+ if ( ! empty( $_POST['coupon_code'] ) ) {
1038
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
1039
+ } else {
1040
+ wc_add_notice( WC_Coupon::get_generic_coupon_error( WC_Coupon::E_WC_COUPON_PLEASE_ENTER ), 'error' );
1041
+ }
1042
+
1043
+ $response = array(
1044
+ 'status' => $result,
1045
+ 'msg' => wc_print_notices( true ),
1046
+ );
1047
+
1048
+ echo wp_json_encode( $response );
1049
+
1050
+ die();
1051
+ }
1052
+
1053
+
1054
+ /**
1055
+ * Added ajax nonce to localize variable.
1056
+ *
1057
+ * @param array $vars localize variables.
1058
+ */
1059
+ public function add_localize_vars( $vars ) {
1060
+
1061
+ $vars['wcf_validate_coupon_nonce'] = wp_create_nonce( 'wcf-apply-coupon' );
1062
+
1063
+ $vars['wcf_validate_remove_coupon_nonce'] = wp_create_nonce( 'wcf-remove-coupon' );
1064
+
1065
+ $vars['wcf_validate_remove_cart_product_nonce'] = wp_create_nonce( 'wcf-remove-cart-product' );
1066
+
1067
+ $vars['allow_persistence'] = wcf_apply_filters_deprecated( 'cartflows_allow_persistace', array( 'yes' ), '1.6.0', 'cartflows_allow_persistence' );
1068
+
1069
+ return $vars;
1070
+ }
1071
+
1072
+ /**
1073
+ * Add custom class to the fields to change the UI to three column.
1074
+ *
1075
+ * @param array $fields fields.
1076
+ */
1077
+ public function add_three_column_layout_fields( $fields ) {
1078
+
1079
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
1080
+
1081
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
1082
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
1083
+ }
1084
+ }
1085
+
1086
+ if ( ! empty( $fields['billing']['billing_company'] ) ) {
1087
+
1088
+ if ( isset( $fields['billing']['billing_company'] ) && is_array( $fields['billing']['billing_company'] ) ) {
1089
+ $fields['billing']['billing_company']['class'][] = 'form-row-full';
1090
+ }
1091
+ }
1092
+
1093
+ if ( ! empty( $fields['shipping']['shipping_company'] ) ) {
1094
+
1095
+ if ( isset( $fields['shipping']['shipping_company'] ) && is_array( $fields['shipping']['shipping_company'] ) ) {
1096
+ $fields['shipping']['shipping_company']['class'][] = 'form-row-full';
1097
+ }
1098
+ }
1099
+
1100
+ if ( ! empty( $fields['billing']['billing_country'] ) ) {
1101
+
1102
+ if ( isset( $fields['billing']['billing_country'] ) && is_array( $fields['billing']['billing_country'] ) ) {
1103
+ $fields['billing']['billing_country']['class'][] = 'form-row-full';
1104
+ }
1105
+ }
1106
+
1107
+ if ( ! empty( $fields['shipping']['shipping_country'] ) ) {
1108
+
1109
+ if ( isset( $fields['shipping']['shipping_country'] ) && is_array( $fields['shipping']['shipping_country'] ) ) {
1110
+ $fields['shipping']['shipping_country']['class'][] = 'form-row-full';
1111
+ }
1112
+ }
1113
+
1114
+ if ( ! empty( $fields['billing']['billing_phone'] ) ) {
1115
+
1116
+ if ( isset( $fields['billing']['billing_phone'] ) && is_array( $fields['billing']['billing_phone'] ) ) {
1117
+ $fields['billing']['billing_phone']['class'][] = 'form-row-full';
1118
+ }
1119
+ }
1120
+
1121
+ if ( ! empty( $fields['billing']['billing_email'] ) ) {
1122
+
1123
+ if ( isset( $fields['billing']['billing_email'] ) && is_array( $fields['billing']['billing_email'] ) ) {
1124
+ $fields['billing']['billing_email']['class'][] = 'form-row-full';
1125
+ }
1126
+ }
1127
+
1128
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
1129
+
1130
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
1131
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
1132
+ }
1133
+ }
1134
+
1135
+ if ( isset( $fields['billing']['billing_city'] ) &&
1136
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
1137
+
1138
+ $fields['billing']['billing_city']['class'][] = 'wcf-column-33';
1139
+ $fields['billing']['billing_state']['class'][] = 'wcf-column-33';
1140
+ $fields['billing']['billing_postcode']['class'][] = 'wcf-column-33';
1141
+ }
1142
+
1143
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
1144
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
1145
+
1146
+ $fields['shipping']['shipping_city']['class'][] = 'wcf-column-33';
1147
+ $fields['shipping']['shipping_state']['class'][] = 'wcf-column-33';
1148
+ $fields['shipping']['shipping_postcode']['class'][] = 'wcf-column-33';
1149
+ }
1150
+
1151
+ return $fields;
1152
+ }
1153
+
1154
+ /**
1155
+ * Add opening dev
1156
+ *
1157
+ * @since 1.0.0
1158
+ */
1159
+ public function order_wrap_div_start() {
1160
+
1161
+ echo "<div class='wcf-order-wrap'> ";
1162
+ }
1163
+
1164
+ /**
1165
+ * Add closing dev
1166
+ *
1167
+ * @since 1.0.0
1168
+ */
1169
+ public function order_wrap_div_end() {
1170
+
1171
+ echo '</div> ';
1172
+ }
1173
+ /**
1174
+ * Remove coupon.
1175
+ */
1176
+ public function remove_coupon() {
1177
+
1178
+ check_ajax_referer( 'wcf-remove-coupon', 'security' );
1179
+ $coupon = isset( $_POST['coupon_code'] ) ? wc_clean( wp_unslash( $_POST['coupon_code'] ) ) : false; //phpcs:ignore
1180
+
1181
+ if ( empty( $coupon ) ) {
1182
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Sorry there was a problem removing this coupon.', 'cartflows' );
1183
+ } else {
1184
+ WC()->cart->remove_coupon( $coupon );
1185
+ echo "<div class='woocommerce-error'>" . esc_html__( 'Coupon has been removed.', 'cartflows' ) . '</div>';
1186
+ }
1187
+ wc_print_notices();
1188
+ wp_die();
1189
+ }
1190
+
1191
+ /**
1192
+ * Remove cart item.
1193
+ */
1194
+ public function wcf_woo_remove_cart_product() {
1195
+
1196
+ check_ajax_referer( 'wcf-remove-cart-product', 'security' );
1197
+ $product_key = isset( $_POST['p_key'] ) ? wc_clean( wp_unslash( $_POST['p_key'] ) ) : false; //phpcs:ignore
1198
+ $product_id = isset( $_POST['p_id'] ) ? wc_clean( wp_unslash( $_POST['p_id'] ) ) : ''; //phpcs:ignore
1199
+ $product_title = get_the_title( $product_id );
1200
+
1201
+ $needs_shipping = false;
1202
+
1203
+ if ( empty( $product_key ) ) {
1204
+ $msg = "<div class='woocommerce-message'>" . __( 'Sorry there was a problem removing ', 'cartflows' ) . $product_title;
1205
+ } else {
1206
+ WC()->cart->remove_cart_item( $product_key );
1207
+ $msg = "<div class='woocommerce-message'>" . $product_title . __( ' has been removed.', 'cartflows' ) . '</div>';
1208
+ }
1209
+
1210
+ foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
1211
+ if ( $values['data']->needs_shipping() ) {
1212
+ $needs_shipping = true;
1213
+ break;
1214
+ }
1215
+ }
1216
+
1217
+ $response = array(
1218
+ 'need_shipping' => $needs_shipping,
1219
+ 'msg' => $msg,
1220
+ );
1221
+
1222
+ echo wp_json_encode( $response );
1223
+ wp_die();
1224
+ }
1225
+
1226
+ /**
1227
+ * Calculate discount for product.
1228
+ *
1229
+ * @param string $discount_coupon discount coupon.
1230
+ * @param string $discount_type discount type.
1231
+ * @param int $discount_value discount value.
1232
+ * @param int $_product_price product price.
1233
+ * @return int
1234
+ * @since 1.1.5
1235
+ */
1236
+ public function calculate_discount( $discount_coupon, $discount_type, $discount_value, $_product_price ) {
1237
+
1238
+ $custom_price = '';
1239
+
1240
+ if ( ! empty( $discount_type ) ) {
1241
+ if ( 'discount_percent' === $discount_type ) {
1242
+
1243
+ if ( $discount_value > 0 ) {
1244
+ $custom_price = $_product_price - ( ( $_product_price * $discount_value ) / 100 );
1245
+ }
1246
+ } elseif ( 'discount_price' === $discount_type ) {
1247
+
1248
+ if ( $discount_value > 0 ) {
1249
+ $custom_price = $_product_price - $discount_value;
1250
+ }
1251
+ } elseif ( 'coupon' === $discount_type ) {
1252
+
1253
+ if ( ! empty( $discount_coupon ) ) {
1254
+ WC()->cart->add_discount( $discount_coupon );
1255
+ }
1256
+ }
1257
+ }
1258
+
1259
+ return $custom_price;
1260
+ }
1261
+
1262
+ /**
1263
+ * Preserve the custom item price added by Variations & Quantity feature
1264
+ *
1265
+ * @param array $cart_object cart object.
1266
+ * @since 1.0.0
1267
+ */
1268
+ public function custom_price_to_cart_item( $cart_object ) {
1269
+
1270
+ if ( wp_doing_ajax() && ! WC()->session->__isset( 'reload_checkout' ) ) {
1271
+
1272
+ foreach ( $cart_object->cart_contents as $key => $value ) {
1273
+
1274
+ if ( isset( $value['custom_price'] ) ) {
1275
+
1276
+ $custom_price = floatval( $value['custom_price'] );
1277
+ $value['data']->set_price( $custom_price );
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ }
1284
+
1285
+ /**
1286
+ * Kicking this off by calling 'get_instance()' method
1287
+ */
1288
+ Cartflows_Checkout_Markup::get_instance();
modules/checkout/templates/embed/checkout-template-simple.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
- /**
3
- * Checkout template
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
9
- $fields_skins = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-fields-skins' );
10
- ?>
11
- <div id="wcf-embed-checkout-form" class="wcf-embed-checkout-form wcf-embed-checkout-form-<?php echo $checkout_layout; ?> wcf-field-<?php echo $fields_skins; ?>">
12
- <!-- CHECKOUT SHORTCODE -->
13
- <?php do_action( 'cartflows_add_before_main_section', $checkout_layout ); ?>
14
-
15
- <?php
16
- $checkout_html = do_shortcode( '[woocommerce_checkout]' );
17
-
18
- if (
19
- empty( $checkout_html ) ||
20
- trim( $checkout_html ) == '<div class="woocommerce"></div>'
21
- ) {
22
-
23
- do_action( 'cartflows_checkout_cart_empty', $checkout_id );
24
-
25
- echo esc_html__( 'Your cart is currently empty.', 'cartflows' );
26
- } else {
27
- echo $checkout_html;
28
- }
29
- ?>
30
-
31
- <?php do_action( 'cartflows_add_after_main_section', $arg = '' ); ?>
32
- <!-- END CHECKOUT SHORTCODE -->
33
- </div>
1
+ <?php
2
+ /**
3
+ * Checkout template
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
9
+ $fields_skins = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-fields-skins' );
10
+ ?>
11
+ <div id="wcf-embed-checkout-form" class="wcf-embed-checkout-form wcf-embed-checkout-form-<?php echo $checkout_layout; ?> wcf-field-<?php echo $fields_skins; ?>">
12
+ <!-- CHECKOUT SHORTCODE -->
13
+ <?php do_action( 'cartflows_add_before_main_section', $checkout_layout ); ?>
14
+
15
+ <?php
16
+ $checkout_html = do_shortcode( '[woocommerce_checkout]' );
17
+
18
+ if (
19
+ empty( $checkout_html ) ||
20
+ trim( $checkout_html ) == '<div class="woocommerce"></div>'
21
+ ) {
22
+
23
+ do_action( 'cartflows_checkout_cart_empty', $checkout_id );
24
+
25
+ echo esc_html__( 'Your cart is currently empty.', 'cartflows' );
26
+ } else {
27
+ echo $checkout_html;
28
+ }
29
+ ?>
30
+
31
+ <?php do_action( 'cartflows_add_after_main_section', $arg = '' ); ?>
32
+ <!-- END CHECKOUT SHORTCODE -->
33
+ </div>
modules/flow/classes/class-cartflows-flow-meta.php CHANGED
@@ -1,760 +1,760 @@
1
- <?php
2
- /**
3
- * Flow meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Flow_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option;
27
-
28
- /**
29
- * For Gutenberg
30
- *
31
- * @var $is_gutenberg_editor_active
32
- */
33
- private $is_gutenberg_editor_active = false;
34
-
35
- /**
36
- * Initiator
37
- */
38
- public static function get_instance() {
39
- if ( ! isset( self::$instance ) ) {
40
- self::$instance = new self();
41
- }
42
-
43
- return self::$instance;
44
- }
45
-
46
- /**
47
- * Constructor
48
- */
49
- public function __construct() {
50
-
51
- add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
-
53
- add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
-
55
- /* Init Metabox */
56
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
-
59
- /* Add Scripts */
60
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
-
62
- add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
- add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
-
65
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
-
67
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
-
69
- /* To check the status of gutenberg */
70
- add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
-
72
- /* Add back to edit flow button for gutenberg */
73
- add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
- }
75
-
76
- /**
77
- * Display admin notices.
78
- *
79
- * @since 1.0.0
80
- *
81
- * @return void
82
- */
83
- public function admin_notices() {
84
-
85
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
- return;
87
- }
88
-
89
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
- if ( $flow_id ) { ?>
91
- <div class="wcf-notice-back-edit-flow">
92
- <p>
93
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
- <i class="dashicons dashicons-arrow-left-alt"></i>
95
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
- </a>
97
- </p>
98
- </div>
99
- <?php
100
- }
101
- }
102
-
103
- /**
104
- * Initialize admin actions.
105
- *
106
- * @since 1.0.0
107
- *
108
- * @return void
109
- */
110
- public function admin_init_actions() {
111
- add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
- add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
- add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
- }
115
-
116
- /**
117
- * Delete term data and steps data after deleting flow.
118
- *
119
- * @since 1.0.0
120
- * @param int $pid post id.
121
- *
122
- * @return void
123
- */
124
- public function step_post_sync( $pid ) {
125
-
126
- global $post_type;
127
-
128
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
-
130
- $steps = get_post_meta( $pid, 'wcf-steps', true );
131
-
132
- if ( $steps && is_array( $steps ) ) {
133
- foreach ( $steps as $i => $step ) {
134
- wp_delete_post( $step['id'], true );
135
- }
136
- }
137
-
138
- $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
-
140
- if ( is_array( $term_data ) ) {
141
- wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
- }
143
- }
144
- }
145
-
146
- /**
147
- * Trash steps data after trashing flow.
148
- *
149
- * @since 1.0.0
150
- * @param int $pid post id.
151
- *
152
- * @return void
153
- */
154
- public function step_post_trash_sync( $pid ) {
155
-
156
- global $post_type;
157
-
158
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
-
160
- $steps = get_post_meta( $pid, 'wcf-steps', true );
161
-
162
- if ( $steps && is_array( $steps ) ) {
163
- foreach ( $steps as $i => $step ) {
164
- wp_trash_post( $step['id'] );
165
- }
166
- }
167
- }
168
- }
169
-
170
- /**
171
- * Untrash steps data after restoring flow.
172
- *
173
- * @since 1.0.0
174
- * @param int $pid post id.
175
- *
176
- * @return void
177
- */
178
- public function step_post_untrash_sync( $pid ) {
179
-
180
- global $post_type;
181
-
182
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
-
184
- $steps = get_post_meta( $pid, 'wcf-steps', true );
185
-
186
- if ( $steps && is_array( $steps ) ) {
187
- foreach ( $steps as $i => $step ) {
188
- wp_untrash_post( $step['id'] );
189
- }
190
- }
191
- }
192
- }
193
-
194
- /**
195
- * Create step for given flow.
196
- *
197
- * @param int $flow_id flow ID.
198
- * @param int $step_type step type.
199
- * @param int $step_title step title.
200
- * @since 1.0.0
201
- *
202
- * @return int
203
- */
204
- public function create_step( $flow_id, $step_type, $step_title ) {
205
-
206
- $new_step_id = wp_insert_post(
207
- array(
208
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
- 'post_title' => $step_title,
210
- 'post_status' => 'publish',
211
- )
212
- );
213
-
214
- if ( $new_step_id ) {
215
-
216
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
-
218
- if ( ! is_array( $flow_steps ) ) {
219
- $flow_steps = array();
220
- }
221
-
222
- $flow_steps[] = array(
223
- 'id' => $new_step_id,
224
- 'title' => $step_title,
225
- 'type' => $step_type,
226
- );
227
-
228
- // insert post meta.
229
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
-
232
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
- }
235
-
236
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
-
238
- return $new_step_id;
239
- }
240
-
241
- /**
242
- * Delete step for flow
243
- *
244
- * @since 1.0.0
245
- *
246
- * @return void
247
- */
248
- public function cartflows_delete_flow_step() {
249
-
250
- if ( ! current_user_can( 'manage_options' ) ) {
251
- return;
252
- }
253
-
254
- check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
-
256
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
- $flow_id = intval( $_POST['post_id'] );
258
- $step_id = intval( $_POST['step_id'] );
259
- }
260
- $result = array(
261
- 'status' => false,
262
- /* translators: %s flow id */
263
- 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
- );
265
-
266
- if ( ! $flow_id || ! $step_id ) {
267
- wp_send_json( $result );
268
- }
269
-
270
- wp_delete_post( $step_id, true );
271
-
272
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
-
274
- if ( ! is_array( $flow_steps ) ) {
275
- wp_send_json( $result );
276
- }
277
-
278
- foreach ( $flow_steps as $index => $data ) {
279
-
280
- if ( intval( $data['id'] ) === $step_id ) {
281
- unset( $flow_steps[ $index ] );
282
- break;
283
- }
284
- }
285
-
286
- /* Set index order properly */
287
- $flow_steps = array_merge( $flow_steps );
288
-
289
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
-
291
- $result = array(
292
- 'status' => true,
293
- /* translators: %s flow id */
294
- 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
- );
296
-
297
- wp_send_json( $result );
298
- }
299
-
300
- /**
301
- * Reorder step flow
302
- *
303
- * @since 1.0.0
304
- *
305
- * @return void
306
- */
307
- public function cartflows_reorder_flow_steps() {
308
-
309
- if ( ! current_user_can( 'manage_options' ) ) {
310
- return;
311
- }
312
-
313
- check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
-
315
- if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
- $flow_id = intval( $_POST['post_id'] );
317
- $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
- }
319
- $result = array(
320
- 'status' => false,
321
- /* translators: %s flow id */
322
- 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
- );
324
-
325
- if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
- wp_send_json( $result );
327
- }
328
-
329
- $new_flow_steps = array();
330
-
331
- foreach ( $step_ids as $index => $step_id ) {
332
-
333
- $new_flow_steps[] = array(
334
- 'id' => intval( $step_id ),
335
- 'title' => get_the_title( $step_id ),
336
- 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
- );
338
- }
339
-
340
- update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
-
342
- $result = array(
343
- 'status' => true,
344
- /* translators: %s flow id */
345
- 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
- );
347
-
348
- wp_send_json( $result );
349
- }
350
-
351
-
352
- /**
353
- * Load admin scripts
354
- *
355
- * @since 1.0.0
356
- *
357
- * @return void
358
- */
359
- public function admin_scripts() {
360
-
361
- global $pagenow;
362
- global $post;
363
-
364
- $screen = get_current_screen();
365
-
366
- if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
-
368
- wp_enqueue_script(
369
- 'wcf-flow-meta',
370
- CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
- array( 'jquery', 'jquery-ui-sortable' ),
372
- CARTFLOWS_VER,
373
- true
374
- );
375
-
376
- wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
- wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
-
379
- $localize = array(
380
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
- );
382
-
383
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
- }
385
- }
386
-
387
- /**
388
- * Initialize meta box
389
- *
390
- * @since 1.0.0
391
- *
392
- * @return void
393
- */
394
- public function init_metabox() {
395
-
396
- /**
397
- * Fires after the title field.
398
- *
399
- * @param WP_Post $post Post object.
400
- */
401
- add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
- add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
- }
405
-
406
- /**
407
- * Is first time import?
408
- *
409
- * @param integer $post_id post ID.
410
- * @return bool
411
- */
412
- public function is_flow_imported( $post_id = 0 ) {
413
-
414
- if ( 0 === $post_id ) {
415
- $post_id = get_the_ID();
416
- }
417
-
418
- $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
- $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
-
421
- if ( empty( $steps ) && 'import' === $choice ) {
422
- return true;
423
- }
424
-
425
- return false;
426
- }
427
-
428
- /**
429
- * Setup meta box.
430
- *
431
- * @return void
432
- */
433
- public function setup_meta_box() {
434
- if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
- return;
436
- }
437
-
438
- /**
439
- * Adding Add new step button to the top*/
440
- echo $this->add_add_new_step_button();
441
-
442
- $this->markup_meta_box();
443
-
444
- $this->add_upgrade_to_pro_metabox();
445
- }
446
-
447
-
448
- /**
449
- * Add metabox when cartflows pro is not enabled.
450
- */
451
- public function add_upgrade_to_pro_metabox() {
452
-
453
- if ( ! _is_cartflows_pro() ) {
454
- add_meta_box(
455
- 'wcf-upgrade-pro',
456
- __( 'Analytics', 'cartflows' ),
457
- array( $this, 'upgrade_to_pro' ),
458
- CARTFLOWS_FLOW_POST_TYPE,
459
- 'side',
460
- 'high'
461
- );
462
- }
463
-
464
- }
465
-
466
- /**
467
- * Show Upgrade To Pro markup.
468
- */
469
- public function upgrade_to_pro() {
470
-
471
- echo '<div>';
472
- /* translators: %s: link */
473
- echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
- echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
- echo '</div>';
476
-
477
- }
478
-
479
- /**
480
- * Settings meta box.
481
- *
482
- * @return void
483
- */
484
- public function settings_meta_box() {
485
-
486
- if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
-
488
- /* No need of sandbox will delete it later */
489
- add_meta_box(
490
- 'wcf-sandbox-settings', // Id.
491
- __( 'Flow Settings', 'cartflows' ), // Title.
492
- array( $this, 'sandbox_meta_box' ), // Callback.
493
- CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
- 'side', // Context.
495
- 'high' // Priority.
496
- );
497
-
498
- do_action( 'cartflows_add_flow_metabox' );
499
- }
500
- }
501
-
502
- /**
503
- * Metabox Markup
504
- *
505
- * @return void
506
- */
507
- public function markup_meta_box() {
508
- global $post;
509
-
510
- wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
-
512
- // Get defaults.
513
- $meta = self::get_current_post_meta( $post->ID );
514
-
515
- /**
516
- * Get options
517
- */
518
- $updated_data = array(
519
- 'steps' => $meta['wcf-steps']['default'],
520
- );
521
-
522
- do_action( 'wcf_flow_settings_markup_before', $meta );
523
- $this->page_header_tab( $updated_data );
524
- do_action( 'wcf_flow_settings_markup_after', $meta );
525
- }
526
-
527
- /**
528
- * Metabox Markup
529
- *
530
- * @param object $post Post object.
531
- * @return void
532
- */
533
- public function sandbox_meta_box( $post ) {
534
-
535
- // Get defaults.
536
- $meta = self::get_current_post_meta( $post->ID );
537
-
538
- /**
539
- * Get options
540
- */
541
- foreach ( $meta as $key => $value ) {
542
- $updated_data[ $key ] = $meta[ $key ]['default'];
543
- }
544
-
545
- do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
- $this->sandbox_markup( $updated_data );
547
- do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
- }
549
-
550
- /**
551
- * Page Header Tabs
552
- *
553
- * @param array $options Post meta.
554
- * @return void
555
- */
556
- public function page_header_tab( $options ) {
557
-
558
- include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
- }
560
-
561
- /**
562
- * Sandbox Markup
563
- *
564
- * @param array $options Post meta.
565
- * @return void
566
- */
567
- public function sandbox_markup( $options ) {
568
- ?>
569
- <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
- <div class="wcf-flow-sandbox-table-container">
571
- <?php
572
- echo wcf()->meta->get_checkbox_field(
573
- array(
574
- 'name' => 'wcf-testing',
575
- 'value' => $options['wcf-testing'],
576
- 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
- )
578
- );
579
-
580
- echo wcf()->meta->get_description_field(
581
- array(
582
- 'name' => 'wcf-testing-note',
583
- 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
- )
585
- );
586
-
587
- ?>
588
- </div>
589
- </div>
590
- <?php
591
- }
592
-
593
- /**
594
- * Keep the menu open when editing the flows.
595
- * Highlights the wanted admin (sub-) menu items for the CPT.
596
- *
597
- * @since 1.0.0
598
- */
599
- public function menu_highlight() {
600
- global $parent_file, $submenu_file, $post_type;
601
- if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
- $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
- $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
- endif;
605
- }
606
-
607
- /**
608
- * Get metabox options
609
- *
610
- * @param int $post_id post id.
611
- * @return array
612
- */
613
- public static function get_meta_option( $post_id ) {
614
-
615
- if ( null === self::$meta_option ) {
616
- /**
617
- * Set metabox options
618
- */
619
- self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
- }
621
-
622
- return self::$meta_option;
623
- }
624
-
625
- /**
626
- * Get metabox options
627
- *
628
- * @param int $post_id post ID.
629
- * @return array
630
- */
631
- public static function get_current_post_meta( $post_id ) {
632
-
633
- $stored = get_post_meta( $post_id );
634
-
635
- $default_meta = self::get_meta_option( $post_id );
636
-
637
- // Set stored and override defaults.
638
- foreach ( $stored as $key => $value ) {
639
- if ( array_key_exists( $key, $default_meta ) ) {
640
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
- } else {
642
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
- }
644
- }
645
-
646
- return self::get_meta_option( $post_id );
647
- }
648
-
649
- /**
650
- * Metabox Save
651
- *
652
- * @param number $post_id Post ID.
653
- * @return void
654
- */
655
- public function save_meta_box( $post_id ) {
656
-
657
- // Checks save status.
658
- $is_autosave = wp_is_post_autosave( $post_id );
659
- $is_revision = wp_is_post_revision( $post_id );
660
-
661
- $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
-
663
- // Exits script depending on save status.
664
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
- return;
666
- }
667
-
668
- wcf()->options->save_flow_fields( $post_id );
669
- }
670
-
671
- /**
672
- * Localize variables in admin
673
- *
674
- * @param array $vars variables.
675
- */
676
- public function localize_vars( $vars ) {
677
-
678
- $ajax_actions = array(
679
- 'wcf_setup_default_steps',
680
- 'wcf_add_flow_step',
681
- 'wcf_delete_flow_step',
682
- 'wcf_reorder_flow_steps',
683
- );
684
-
685
- foreach ( $ajax_actions as $action ) {
686
-
687
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
- }
689
-
690
- return $vars;
691
- }
692
-
693
- /**
694
- * Add New Step Button
695
- *
696
- * @return string
697
- */
698
- public function add_add_new_step_button() {
699
- $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
- $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
- $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
- $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
- $add_new_btn_markup .= '</button>';
704
- $add_new_btn_markup .= '</div>';
705
-
706
- return $add_new_btn_markup;
707
- }
708
-
709
- /**
710
- * Back to flow button gutenberg template
711
- *
712
- * @return void
713
- */
714
- public function gutenberg_module_templates() {
715
-
716
- // Exit if block editor is not enabled.
717
- if ( ! $this->is_gutenberg_editor_active ) {
718
- return;
719
- }
720
-
721
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
- return;
723
- }
724
-
725
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
-
727
- if ( $flow_id ) {
728
- ?>
729
- <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
- <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
- <i class="dashicons dashicons-arrow-left-alt"></i>
733
- <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
- </a>
735
- </div>
736
- </script>
737
- <?php
738
- }
739
- }
740
-
741
- /**
742
- * Set status true for gutenberg.
743
- *
744
- * @return void
745
- */
746
- public function set_block_editor_status() {
747
-
748
- if ( ! current_user_can( 'manage_options' ) ) {
749
- return;
750
- }
751
-
752
- // Set gutenberg status here.
753
- $this->is_gutenberg_editor_active = true;
754
- }
755
- }
756
-
757
- /**
758
- * Kicking this off by calling 'get_instance()' method
759
- */
760
- Cartflows_Flow_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Flow_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option;
27
+
28
+ /**
29
+ * For Gutenberg
30
+ *
31
+ * @var $is_gutenberg_editor_active
32
+ */
33
+ private $is_gutenberg_editor_active = false;
34
+
35
+ /**
36
+ * Initiator
37
+ */
38
+ public static function get_instance() {
39
+ if ( ! isset( self::$instance ) ) {
40
+ self::$instance = new self();
41
+ }
42
+
43
+ return self::$instance;
44
+ }
45
+
46
+ /**
47
+ * Constructor
48
+ */
49
+ public function __construct() {
50
+
51
+ add_action( 'admin_head', array( $this, 'menu_highlight' ) );
52
+
53
+ add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
54
+
55
+ /* Init Metabox */
56
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
57
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
58
+
59
+ /* Add Scripts */
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
61
+
62
+ add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
63
+ add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
64
+
65
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
66
+
67
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
68
+
69
+ /* To check the status of gutenberg */
70
+ add_action( 'enqueue_block_editor_assets', array( $this, 'set_block_editor_status' ) );
71
+
72
+ /* Add back to edit flow button for gutenberg */
73
+ add_action( 'admin_footer', array( $this, 'gutenberg_module_templates' ) );
74
+ }
75
+
76
+ /**
77
+ * Display admin notices.
78
+ *
79
+ * @since 1.0.0
80
+ *
81
+ * @return void
82
+ */
83
+ public function admin_notices() {
84
+
85
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
86
+ return;
87
+ }
88
+
89
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
90
+ if ( $flow_id ) { ?>
91
+ <div class="wcf-notice-back-edit-flow">
92
+ <p>
93
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero wcf-header-back-button" style="text-decoration: none;">
94
+ <i class="dashicons dashicons-arrow-left-alt"></i>
95
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
96
+ </a>
97
+ </p>
98
+ </div>
99
+ <?php
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Initialize admin actions.
105
+ *
106
+ * @since 1.0.0
107
+ *
108
+ * @return void
109
+ */
110
+ public function admin_init_actions() {
111
+ add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
112
+ add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
113
+ add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
114
+ }
115
+
116
+ /**
117
+ * Delete term data and steps data after deleting flow.
118
+ *
119
+ * @since 1.0.0
120
+ * @param int $pid post id.
121
+ *
122
+ * @return void
123
+ */
124
+ public function step_post_sync( $pid ) {
125
+
126
+ global $post_type;
127
+
128
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
129
+
130
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
131
+
132
+ if ( $steps && is_array( $steps ) ) {
133
+ foreach ( $steps as $i => $step ) {
134
+ wp_delete_post( $step['id'], true );
135
+ }
136
+ }
137
+
138
+ $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
139
+
140
+ if ( is_array( $term_data ) ) {
141
+ wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
142
+ }
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Trash steps data after trashing flow.
148
+ *
149
+ * @since 1.0.0
150
+ * @param int $pid post id.
151
+ *
152
+ * @return void
153
+ */
154
+ public function step_post_trash_sync( $pid ) {
155
+
156
+ global $post_type;
157
+
158
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
159
+
160
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
161
+
162
+ if ( $steps && is_array( $steps ) ) {
163
+ foreach ( $steps as $i => $step ) {
164
+ wp_trash_post( $step['id'] );
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Untrash steps data after restoring flow.
172
+ *
173
+ * @since 1.0.0
174
+ * @param int $pid post id.
175
+ *
176
+ * @return void
177
+ */
178
+ public function step_post_untrash_sync( $pid ) {
179
+
180
+ global $post_type;
181
+
182
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
183
+
184
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
185
+
186
+ if ( $steps && is_array( $steps ) ) {
187
+ foreach ( $steps as $i => $step ) {
188
+ wp_untrash_post( $step['id'] );
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Create step for given flow.
196
+ *
197
+ * @param int $flow_id flow ID.
198
+ * @param int $step_type step type.
199
+ * @param int $step_title step title.
200
+ * @since 1.0.0
201
+ *
202
+ * @return int
203
+ */
204
+ public function create_step( $flow_id, $step_type, $step_title ) {
205
+
206
+ $new_step_id = wp_insert_post(
207
+ array(
208
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
209
+ 'post_title' => $step_title,
210
+ 'post_status' => 'publish',
211
+ )
212
+ );
213
+
214
+ if ( $new_step_id ) {
215
+
216
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
217
+
218
+ if ( ! is_array( $flow_steps ) ) {
219
+ $flow_steps = array();
220
+ }
221
+
222
+ $flow_steps[] = array(
223
+ 'id' => $new_step_id,
224
+ 'title' => $step_title,
225
+ 'type' => $step_type,
226
+ );
227
+
228
+ // insert post meta.
229
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
230
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
231
+
232
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
233
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
234
+ }
235
+
236
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
237
+
238
+ return $new_step_id;
239
+ }
240
+
241
+ /**
242
+ * Delete step for flow
243
+ *
244
+ * @since 1.0.0
245
+ *
246
+ * @return void
247
+ */
248
+ public function cartflows_delete_flow_step() {
249
+
250
+ if ( ! current_user_can( 'manage_options' ) ) {
251
+ return;
252
+ }
253
+
254
+ check_ajax_referer( 'wcf-delete-flow-step', 'security' );
255
+
256
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_id'] ) ) {
257
+ $flow_id = intval( $_POST['post_id'] );
258
+ $step_id = intval( $_POST['step_id'] );
259
+ }
260
+ $result = array(
261
+ 'status' => false,
262
+ /* translators: %s flow id */
263
+ 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
264
+ );
265
+
266
+ if ( ! $flow_id || ! $step_id ) {
267
+ wp_send_json( $result );
268
+ }
269
+
270
+ wp_delete_post( $step_id, true );
271
+
272
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
273
+
274
+ if ( ! is_array( $flow_steps ) ) {
275
+ wp_send_json( $result );
276
+ }
277
+
278
+ foreach ( $flow_steps as $index => $data ) {
279
+
280
+ if ( intval( $data['id'] ) === $step_id ) {
281
+ unset( $flow_steps[ $index ] );
282
+ break;
283
+ }
284
+ }
285
+
286
+ /* Set index order properly */
287
+ $flow_steps = array_merge( $flow_steps );
288
+
289
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
290
+
291
+ $result = array(
292
+ 'status' => true,
293
+ /* translators: %s flow id */
294
+ 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
295
+ );
296
+
297
+ wp_send_json( $result );
298
+ }
299
+
300
+ /**
301
+ * Reorder step flow
302
+ *
303
+ * @since 1.0.0
304
+ *
305
+ * @return void
306
+ */
307
+ public function cartflows_reorder_flow_steps() {
308
+
309
+ if ( ! current_user_can( 'manage_options' ) ) {
310
+ return;
311
+ }
312
+
313
+ check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
314
+
315
+ if ( isset( $_POST['post_id'] ) && isset( $_POST['step_ids'] ) ) {
316
+ $flow_id = intval( $_POST['post_id'] );
317
+ $step_ids = array_map( 'intval', $_POST['step_ids'] );
318
+ }
319
+ $result = array(
320
+ 'status' => false,
321
+ /* translators: %s flow id */
322
+ 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
323
+ );
324
+
325
+ if ( ! $flow_id || ! is_array( $step_ids ) ) {
326
+ wp_send_json( $result );
327
+ }
328
+
329
+ $new_flow_steps = array();
330
+
331
+ foreach ( $step_ids as $index => $step_id ) {
332
+
333
+ $new_flow_steps[] = array(
334
+ 'id' => intval( $step_id ),
335
+ 'title' => get_the_title( $step_id ),
336
+ 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
337
+ );
338
+ }
339
+
340
+ update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
341
+
342
+ $result = array(
343
+ 'status' => true,
344
+ /* translators: %s flow id */
345
+ 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
346
+ );
347
+
348
+ wp_send_json( $result );
349
+ }
350
+
351
+
352
+ /**
353
+ * Load admin scripts
354
+ *
355
+ * @since 1.0.0
356
+ *
357
+ * @return void
358
+ */
359
+ public function admin_scripts() {
360
+
361
+ global $pagenow;
362
+ global $post;
363
+
364
+ $screen = get_current_screen();
365
+
366
+ if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
367
+
368
+ wp_enqueue_script(
369
+ 'wcf-flow-meta',
370
+ CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
371
+ array( 'jquery', 'jquery-ui-sortable' ),
372
+ CARTFLOWS_VER,
373
+ true
374
+ );
375
+
376
+ wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
377
+ wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
378
+
379
+ $localize = array(
380
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
381
+ );
382
+
383
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Initialize meta box
389
+ *
390
+ * @since 1.0.0
391
+ *
392
+ * @return void
393
+ */
394
+ public function init_metabox() {
395
+
396
+ /**
397
+ * Fires after the title field.
398
+ *
399
+ * @param WP_Post $post Post object.
400
+ */
401
+ add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
402
+ add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
403
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
404
+ }
405
+
406
+ /**
407
+ * Is first time import?
408
+ *
409
+ * @param integer $post_id post ID.
410
+ * @return bool
411
+ */
412
+ public function is_flow_imported( $post_id = 0 ) {
413
+
414
+ if ( 0 === $post_id ) {
415
+ $post_id = get_the_ID();
416
+ }
417
+
418
+ $steps = get_post_meta( $post_id, 'wcf-steps', true );
419
+ $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
420
+
421
+ if ( empty( $steps ) && 'import' === $choice ) {
422
+ return true;
423
+ }
424
+
425
+ return false;
426
+ }
427
+
428
+ /**
429
+ * Setup meta box.
430
+ *
431
+ * @return void
432
+ */
433
+ public function setup_meta_box() {
434
+ if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
435
+ return;
436
+ }
437
+
438
+ /**
439
+ * Adding Add new step button to the top*/
440
+ echo $this->add_add_new_step_button();
441
+
442
+ $this->markup_meta_box();
443
+
444
+ $this->add_upgrade_to_pro_metabox();
445
+ }
446
+
447
+
448
+ /**
449
+ * Add metabox when cartflows pro is not enabled.
450
+ */
451
+ public function add_upgrade_to_pro_metabox() {
452
+
453
+ if ( ! _is_cartflows_pro() ) {
454
+ add_meta_box(
455
+ 'wcf-upgrade-pro',
456
+ __( 'Analytics', 'cartflows' ),
457
+ array( $this, 'upgrade_to_pro' ),
458
+ CARTFLOWS_FLOW_POST_TYPE,
459
+ 'side',
460
+ 'high'
461
+ );
462
+ }
463
+
464
+ }
465
+
466
+ /**
467
+ * Show Upgrade To Pro markup.
468
+ */
469
+ public function upgrade_to_pro() {
470
+
471
+ echo '<div>';
472
+ /* translators: %s: link */
473
+ echo '<p><i>' . sprintf( esc_html__( 'Upgrade to %1$sCartFlows Pro%2$s for Analytics feature', 'cartflows' ), '<a href="https://cartflows.com/" target="_blank">', '</a>' ) . '</i></p>';
474
+ echo '<p><a target="_blank" href="https://cartflows.com/" class="button button-primary">' . esc_html__( 'Get Pro', 'cartflows' ) . '</a></p>';
475
+ echo '</div>';
476
+
477
+ }
478
+
479
+ /**
480
+ * Settings meta box.
481
+ *
482
+ * @return void
483
+ */
484
+ public function settings_meta_box() {
485
+
486
+ if ( CARTFLOWS_FLOW_POST_TYPE === get_post_type() ) {
487
+
488
+ /* No need of sandbox will delete it later */
489
+ add_meta_box(
490
+ 'wcf-sandbox-settings', // Id.
491
+ __( 'Flow Settings', 'cartflows' ), // Title.
492
+ array( $this, 'sandbox_meta_box' ), // Callback.
493
+ CARTFLOWS_FLOW_POST_TYPE, // Post_type.
494
+ 'side', // Context.
495
+ 'high' // Priority.
496
+ );
497
+
498
+ do_action( 'cartflows_add_flow_metabox' );
499
+ }
500
+ }
501
+
502
+ /**
503
+ * Metabox Markup
504
+ *
505
+ * @return void
506
+ */
507
+ public function markup_meta_box() {
508
+ global $post;
509
+
510
+ wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
511
+
512
+ // Get defaults.
513
+ $meta = self::get_current_post_meta( $post->ID );
514
+
515
+ /**
516
+ * Get options
517
+ */
518
+ $updated_data = array(
519
+ 'steps' => $meta['wcf-steps']['default'],
520
+ );
521
+
522
+ do_action( 'wcf_flow_settings_markup_before', $meta );
523
+ $this->page_header_tab( $updated_data );
524
+ do_action( 'wcf_flow_settings_markup_after', $meta );
525
+ }
526
+
527
+ /**
528
+ * Metabox Markup
529
+ *
530
+ * @param object $post Post object.
531
+ * @return void
532
+ */
533
+ public function sandbox_meta_box( $post ) {
534
+
535
+ // Get defaults.
536
+ $meta = self::get_current_post_meta( $post->ID );
537
+
538
+ /**
539
+ * Get options
540
+ */
541
+ foreach ( $meta as $key => $value ) {
542
+ $updated_data[ $key ] = $meta[ $key ]['default'];
543
+ }
544
+
545
+ do_action( 'wcf_flow_sandbox_markup_before', $meta );
546
+ $this->sandbox_markup( $updated_data );
547
+ do_action( 'wcf_flow_sandbox_markup_after', $meta );
548
+ }
549
+
550
+ /**
551
+ * Page Header Tabs
552
+ *
553
+ * @param array $options Post meta.
554
+ * @return void
555
+ */
556
+ public function page_header_tab( $options ) {
557
+
558
+ include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
559
+ }
560
+
561
+ /**
562
+ * Sandbox Markup
563
+ *
564
+ * @param array $options Post meta.
565
+ * @return void
566
+ */
567
+ public function sandbox_markup( $options ) {
568
+ ?>
569
+ <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
570
+ <div class="wcf-flow-sandbox-table-container">
571
+ <?php
572
+ echo wcf()->meta->get_checkbox_field(
573
+ array(
574
+ 'name' => 'wcf-testing',
575
+ 'value' => $options['wcf-testing'],
576
+ 'after' => esc_html__( 'Enable Test Mode', 'cartflows' ),
577
+ )
578
+ );
579
+
580
+ echo wcf()->meta->get_description_field(
581
+ array(
582
+ 'name' => 'wcf-testing-note',
583
+ 'content' => esc_html__( 'If you are using WooCommerce plugin then test mode will add random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
584
+ )
585
+ );
586
+
587
+ ?>
588
+ </div>
589
+ </div>
590
+ <?php
591
+ }
592
+
593
+ /**
594
+ * Keep the menu open when editing the flows.
595
+ * Highlights the wanted admin (sub-) menu items for the CPT.
596
+ *
597
+ * @since 1.0.0
598
+ */
599
+ public function menu_highlight() {
600
+ global $parent_file, $submenu_file, $post_type;
601
+ if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
602
+ $parent_file = CARTFLOWS_SLUG;//phpcs:ignore
603
+ $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;//phpcs:ignore
604
+ endif;
605
+ }
606
+
607
+ /**
608
+ * Get metabox options
609
+ *
610
+ * @param int $post_id post id.
611
+ * @return array
612
+ */
613
+ public static function get_meta_option( $post_id ) {
614
+
615
+ if ( null === self::$meta_option ) {
616
+ /**
617
+ * Set metabox options
618
+ */
619
+ self::$meta_option = wcf()->options->get_flow_fields( $post_id );
620
+ }
621
+
622
+ return self::$meta_option;
623
+ }
624
+
625
+ /**
626
+ * Get metabox options
627
+ *
628
+ * @param int $post_id post ID.
629
+ * @return array
630
+ */
631
+ public static function get_current_post_meta( $post_id ) {
632
+
633
+ $stored = get_post_meta( $post_id );
634
+
635
+ $default_meta = self::get_meta_option( $post_id );
636
+
637
+ // Set stored and override defaults.
638
+ foreach ( $stored as $key => $value ) {
639
+ if ( array_key_exists( $key, $default_meta ) ) {
640
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
641
+ } else {
642
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
643
+ }
644
+ }
645
+
646
+ return self::get_meta_option( $post_id );
647
+ }
648
+
649
+ /**
650
+ * Metabox Save
651
+ *
652
+ * @param number $post_id Post ID.
653
+ * @return void
654
+ */
655
+ public function save_meta_box( $post_id ) {
656
+
657
+ // Checks save status.
658
+ $is_autosave = wp_is_post_autosave( $post_id );
659
+ $is_revision = wp_is_post_revision( $post_id );
660
+
661
+ $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce-flow-meta'] ) ), 'save-nonce-flow-meta' ) ) ? true : false;
662
+
663
+ // Exits script depending on save status.
664
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
665
+ return;
666
+ }
667
+
668
+ wcf()->options->save_flow_fields( $post_id );
669
+ }
670
+
671
+ /**
672
+ * Localize variables in admin
673
+ *
674
+ * @param array $vars variables.
675
+ */
676
+ public function localize_vars( $vars ) {
677
+
678
+ $ajax_actions = array(
679
+ 'wcf_setup_default_steps',
680
+ 'wcf_add_flow_step',
681
+ 'wcf_delete_flow_step',
682
+ 'wcf_reorder_flow_steps',
683
+ );
684
+
685
+ foreach ( $ajax_actions as $action ) {
686
+
687
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
688
+ }
689
+
690
+ return $vars;
691
+ }
692
+
693
+ /**
694
+ * Add New Step Button
695
+ *
696
+ * @return string
697
+ */
698
+ public function add_add_new_step_button() {
699
+ $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
700
+ $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
701
+ $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
702
+ $add_new_btn_markup .= esc_html__( 'Add New Step', 'cartflows' );
703
+ $add_new_btn_markup .= '</button>';
704
+ $add_new_btn_markup .= '</div>';
705
+
706
+ return $add_new_btn_markup;
707
+ }
708
+
709
+ /**
710
+ * Back to flow button gutenberg template
711
+ *
712
+ * @return void
713
+ */
714
+ public function gutenberg_module_templates() {
715
+
716
+ // Exit if block editor is not enabled.
717
+ if ( ! $this->is_gutenberg_editor_active ) {
718
+ return;
719
+ }
720
+
721
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
722
+ return;
723
+ }
724
+
725
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
726
+
727
+ if ( $flow_id ) {
728
+ ?>
729
+ <script id="wcf-gutenberg-back-flow-button" type="text/html">
730
+ <div class="wcf-notice-back-edit-flow gutenberg-button" >
731
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-large wcf-header-back-button" style="text-decoration: none;">
732
+ <i class="dashicons dashicons-arrow-left-alt"></i>
733
+ <?php esc_html_e( 'Back to edit Flow', 'cartflows' ); ?>
734
+ </a>
735
+ </div>
736
+ </script>
737
+ <?php
738
+ }
739
+ }
740
+
741
+ /**
742
+ * Set status true for gutenberg.
743
+ *
744
+ * @return void
745
+ */
746
+ public function set_block_editor_status() {
747
+
748
+ if ( ! current_user_can( 'manage_options' ) ) {
749
+ return;
750
+ }
751
+
752
+ // Set gutenberg status here.
753
+ $this->is_gutenberg_editor_active = true;
754
+ }
755
+ }
756
+
757
+ /**
758
+ * Kicking this off by calling 'get_instance()' method
759
+ */
760
+ Cartflows_Flow_Meta::get_instance();
modules/flow/view/meta-flow-steps.php CHANGED
@@ -1,210 +1,210 @@
1
- <?php
2
- /**
3
- * View Flow steps
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
-
10
- $steps = array(
11
- 'landing' => __( 'Landing', 'cartflows' ),
12
- 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
- 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
- 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
- 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
- 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
- );
18
-
19
- ?>
20
- <div class="wcf-flow-steps-meta-box">
21
- <div class="wcf-flow-settings">
22
- <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
- <div class="wcf-flow-steps-wrap">
24
- <div class="wcf-flow-steps-container">
25
- <?php if ( is_array( $options['steps'] ) ) { ?>
26
- <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
- <?php
28
- $term_slug = '';
29
- $term_name = '';
30
- $step_wrap_class = '';
31
- $has_product_assigned = true;
32
- $is_global_checkout = '';
33
- $common = '';
34
- $data_step_id = intval( $data['id'] );
35
-
36
- if ( isset( $data['type'] ) ) {
37
- $term_slug = $data['type'];
38
- $term_name = $steps[ $data['type'] ];
39
- }
40
-
41
- if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
- $step_wrap_class .= ' invalid-step';
43
- }
44
-
45
- if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
-
47
- $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
-
49
- if ( $highlight_step_id === $data_step_id ) {
50
- $step_wrap_class .= ' wcf-new-step-highlight';
51
- }
52
- }
53
-
54
- if ( 'checkout' === $term_slug ) {
55
-
56
- $common = Cartflows_Helper::get_common_settings();
57
-
58
- $is_global_checkout = (int) $common['global_checkout'];
59
-
60
- if ( $data['id'] === $is_global_checkout ) {
61
- $step_wrap_class .= ' wcf-global-checkout';
62
- }
63
- }
64
-
65
- if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
-
67
- $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
-
69
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
- $step_wrap_class .= ' wcf-no-product-step';
71
- }
72
- }
73
-
74
- ?>
75
- <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
- <div class="wcf-step">
77
- <div class="wcf-step-left-content">
78
- <span class="dashicons dashicons-menu"></span>
79
- <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
- <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
-
82
- <?php
83
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
- ?>
85
- <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
- <?php
87
- } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
- ?>
89
- <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
- <?php
91
- } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
- ?>
93
- <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
- <?php
95
- }
96
- ?>
97
-
98
- <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
- <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
- </div>
101
- <div class="wcf-steps-action-buttons">
102
- <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
- <span class="dashicons dashicons-visibility"></span>
104
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
- </a>
106
- <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
- <span class="dashicons dashicons-edit"></span>
108
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
- </a>
110
- <?php
111
- if ( _is_cartflows_pro() ) {
112
- ?>
113
- <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
- <span class="dashicons dashicons-admin-page"></span>
115
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
- </a>
117
- <?php } ?>
118
- <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
- <span class="dashicons dashicons-trash"></span>
120
- <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
- </a>
122
- </div>
123
- </div>
124
- </div><!-- .wcf-step-wrap -->
125
- <?php } ?>
126
- <?php } ?>
127
- </div><!-- .wcf-flow-steps-container -->
128
- </div> <!-- .wcf-flow-steps-wrap -->
129
- <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
- <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
- <div class='wcf-add-new-step-btn-wrap'>
132
- <button class='wcf-trigger-popup button button-primary'>
133
- <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
- </button>
135
- </div>
136
- </div><!-- .wcf-flow-buttons-wrap -->
137
- </div><!-- .wcf-flow-settings -->
138
-
139
- <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
- <div class="wcf-templates-popup-content">
141
- <div class="spinner"></div>
142
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
-
144
- <div id="wcf-remote-step-actions" class="wcf-template-header">
145
- <div class="wcf-template-logo-wrap">
146
- <span class="wcf-cartflows-logo-img">
147
- <span class="cartflows-logo-icon"></span>
148
- </span>
149
- <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
- </div>
151
- <div class="wcf-tab-wrapper">
152
- <?php if ( 'other' !== $default_page_builder ) { ?>
153
- <div id="wcf-get-started-steps">
154
- <ul class="filter-links ">
155
- <li>
156
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
157
- </li>
158
- <li>
159
- <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
- </li>
161
- </ul>
162
- </div>
163
- <?php } ?>
164
- </div>
165
- <div class="wcf-popup-close-wrap">
166
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
- </div>
168
- </div>
169
-
170
- <!--<div class="wcf-search-form">
171
- <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
- <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
- </div>-->
174
-
175
- <div id="wcf-remote-content">
176
- <?php if ( 'other' !== $default_page_builder ) { ?>
177
- <div id="wcf-ready-templates">
178
- <div id="wcf-remote-filters">
179
- <div id="wcf-page-builders"></div>
180
- <div id="wcf-categories"></div>
181
- </div>
182
- <div class="wcf-page-builder-notice"></div>
183
- <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
- </div>
186
- <?php } ?>
187
- <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
- <div class="inner">
189
- <div id="wcf-scratch-steps-categories">
190
- <select class="step-type-filter-links filter-links">
191
- <option value="" class="current"> Select Step Type </option>
192
-
193
- <?php foreach ( $steps as $key => $value ) { ?>
194
- <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
- <?php } ?>
196
- </select>
197
- </div>
198
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
- <?php if ( ! _is_cartflows_pro() ) { ?>
200
- <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
- <?php } ?>
202
- <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
- </div><!-- .wcf-templates-popup-overlay -->
209
- </div>
210
- <?php
1
+ <?php
2
+ /**
3
+ * View Flow steps
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $default_page_builder = Cartflows_Helper::get_common_setting( 'default_page_builder' );
9
+
10
+ $steps = array(
11
+ 'landing' => __( 'Landing', 'cartflows' ),
12
+ 'checkout' => __( 'Checkout (Woo)', 'cartflows' ),
13
+ 'thankyou' => __( 'Thank You (Woo)', 'cartflows' ),
14
+ 'upsell' => __( 'Upsell (Woo)', 'cartflows' ),
15
+ 'downsell' => __( 'Downsell (Woo)', 'cartflows' ),
16
+ 'optin' => __( 'Optin (Woo)', 'cartflows' ),
17
+ );
18
+
19
+ ?>
20
+ <div class="wcf-flow-steps-meta-box">
21
+ <div class="wcf-flow-settings">
22
+ <?php do_action( 'cartflows_above_flow_steps' ); ?>
23
+ <div class="wcf-flow-steps-wrap">
24
+ <div class="wcf-flow-steps-container">
25
+ <?php if ( is_array( $options['steps'] ) ) { ?>
26
+ <?php foreach ( $options['steps'] as $index => $data ) { ?>
27
+ <?php
28
+ $term_slug = '';
29
+ $term_name = '';
30
+ $step_wrap_class = '';
31
+ $has_product_assigned = true;
32
+ $is_global_checkout = '';
33
+ $common = '';
34
+ $data_step_id = intval( $data['id'] );
35
+
36
+ if ( isset( $data['type'] ) ) {
37
+ $term_slug = $data['type'];
38
+ $term_name = $steps[ $data['type'] ];
39
+ }
40
+
41
+ if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
42
+ $step_wrap_class .= ' invalid-step';
43
+ }
44
+
45
+ if ( isset( $_GET['highlight-step-id'] ) ) { //phpcs:ignore
46
+
47
+ $highlight_step_id = intval( $_GET['highlight-step-id'] ); //phpcs:ignore
48
+
49
+ if ( $highlight_step_id === $data_step_id ) {
50
+ $step_wrap_class .= ' wcf-new-step-highlight';
51
+ }
52
+ }
53
+
54
+ if ( 'checkout' === $term_slug ) {
55
+
56
+ $common = Cartflows_Helper::get_common_settings();
57
+
58
+ $is_global_checkout = (int) $common['global_checkout'];
59
+
60
+ if ( $data['id'] === $is_global_checkout ) {
61
+ $step_wrap_class .= ' wcf-global-checkout';
62
+ }
63
+ }
64
+
65
+ if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
66
+
67
+ $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
68
+
69
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
70
+ $step_wrap_class .= ' wcf-no-product-step';
71
+ }
72
+ }
73
+
74
+ ?>
75
+ <div class="wcf-step-wrap <?php echo $step_wrap_class; ?>" data-id="<?php echo $data['id']; ?>" data-term-slug="<?php echo esc_attr( $term_slug ); ?>">
76
+ <div class="wcf-step">
77
+ <div class="wcf-step-left-content">
78
+ <span class="dashicons dashicons-menu"></span>
79
+ <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
80
+ <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
81
+
82
+ <?php
83
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
84
+ ?>
85
+ <span class="wcf-no-product-badge"><?php esc_html_e( 'No Product Assigned', 'cartflows' ); ?></span>
86
+ <?php
87
+ } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
88
+ ?>
89
+ <span class="wcf-global-checkout-badge wcf-error-badge"><?php esc_html_e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
90
+ <?php
91
+ } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
92
+ ?>
93
+ <span class="wcf-global-checkout-badge"><?php esc_html_e( 'Global Checkout', 'cartflows' ); ?></span>
94
+ <?php
95
+ }
96
+ ?>
97
+
98
+ <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
99
+ <?php do_action( 'cartflows_step_left_content', $data['id'], $term_slug ); ?>
100
+ </div>
101
+ <div class="wcf-steps-action-buttons">
102
+ <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'View Step', 'cartflows' ); ?>" >
103
+ <span class="dashicons dashicons-visibility"></span>
104
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'View', 'cartflows' ); ?></span>
105
+ </a>
106
+ <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Edit Step', 'cartflows' ); ?>" >
107
+ <span class="dashicons dashicons-edit"></span>
108
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Edit', 'cartflows' ); ?></span>
109
+ </a>
110
+ <?php
111
+ if ( _is_cartflows_pro() ) {
112
+ ?>
113
+ <a href="<?php echo wp_nonce_url( 'admin.php?action=cartflows_clone_step&post=' . $data['id'], 'step_clone', 'step_clone_nonce' ); ?>" class="wcf-step-clone wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
114
+ <span class="dashicons dashicons-admin-page"></span>
115
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Clone', 'cartflows' ); ?></span>
116
+ </a>
117
+ <?php } ?>
118
+ <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo esc_html__( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
119
+ <span class="dashicons dashicons-trash"></span>
120
+ <span class="wcf-step-act-btn-text"><?php echo esc_html__( 'Delete', 'cartflows' ); ?></span>
121
+ </a>
122
+ </div>
123
+ </div>
124
+ </div><!-- .wcf-step-wrap -->
125
+ <?php } ?>
126
+ <?php } ?>
127
+ </div><!-- .wcf-flow-steps-container -->
128
+ </div> <!-- .wcf-flow-steps-wrap -->
129
+ <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
130
+ <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
131
+ <div class='wcf-add-new-step-btn-wrap'>
132
+ <button class='wcf-trigger-popup button button-primary'>
133
+ <?php echo esc_html__( 'Add New Step', 'cartflows' ); ?>
134
+ </button>
135
+ </div>
136
+ </div><!-- .wcf-flow-buttons-wrap -->
137
+ </div><!-- .wcf-flow-settings -->
138
+
139
+ <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
140
+ <div class="wcf-templates-popup-content">
141
+ <div class="spinner"></div>
142
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
143
+
144
+ <div id="wcf-remote-step-actions" class="wcf-template-header">
145
+ <div class="wcf-template-logo-wrap">
146
+ <span class="wcf-cartflows-logo-img">
147
+ <span class="cartflows-logo-icon"></span>
148
+ </span>
149
+ <span class="wcf-cartflows-title"><?php esc_html_e( 'Steps Library', 'cartflows' ); ?></span>
150
+ </div>
151
+ <div class="wcf-tab-wrapper">
152
+ <?php if ( 'other' !== $default_page_builder ) { ?>
153
+ <div id="wcf-get-started-steps">
154
+ <ul class="filter-links ">
155
+ <li>
156
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php esc_html_e( 'Ready Templates', 'cartflows' ); ?>"><?php esc_html_e( 'Ready Templates', 'cartflows' ); ?></a>
157
+ </li>
158
+ <li>
159
+ <a href="#" data-slug="canvas" data-title="<?php esc_html_e( 'Create Your Own', 'cartflows' ); ?>"><?php esc_html_e( 'Create Your Own', 'cartflows' ); ?></a>
160
+ </li>
161
+ </ul>
162
+ </div>
163
+ <?php } ?>
164
+ </div>
165
+ <div class="wcf-popup-close-wrap">
166
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
167
+ </div>
168
+ </div>
169
+
170
+ <!--<div class="wcf-search-form">
171
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php esc_html_e( 'Search Sites', 'cartflows' ); ?> </label>
172
+ <input placeholder="<?php esc_html_e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
173
+ </div>-->
174
+
175
+ <div id="wcf-remote-content">
176
+ <?php if ( 'other' !== $default_page_builder ) { ?>
177
+ <div id="wcf-ready-templates">
178
+ <div id="wcf-remote-filters">
179
+ <div id="wcf-page-builders"></div>
180
+ <div id="wcf-categories"></div>
181
+ </div>
182
+ <div class="wcf-page-builder-notice"></div>
183
+ <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"><span class="spinner is-active"></span></div>
184
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
185
+ </div>
186
+ <?php } ?>
187
+ <div id="wcf-start-from-scratch" style="<?php echo ( 'other' !== $default_page_builder ) ? 'display: none;' : ''; ?>">
188
+ <div class="inner">
189
+ <div id="wcf-scratch-steps-categories">
190
+ <select class="step-type-filter-links filter-links">
191
+ <option value="" class="current"> Select Step Type </option>
192
+
193
+ <?php foreach ( $steps as $key => $value ) { ?>
194
+ <option class="<?php echo $key; ?>" data-slug="<?php echo $key; ?>" data-title="<?php echo $key; ?>"><?php echo $value; ?></option>
195
+ <?php } ?>
196
+ </select>
197
+ </div>
198
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php esc_html_e( 'Create Step', 'cartflows' ); ?></a>
199
+ <?php if ( ! _is_cartflows_pro() ) { ?>
200
+ <div class="wcf-template-notice"><p><?php echo esc_html__( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
201
+ <?php } ?>
202
+ <p class="wcf-learn-how"><a href="https://cartflows.com/docs/cartflows-step-types/" target="_blank"><?php esc_html_e( 'Learn How', 'cartflows' ); ?> <i class="dashicons dashicons-external"></i></a></p>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ </div><!-- .wcf-templates-popup-overlay -->
209
+ </div>
210
+ <?php
modules/optin/classes/class-cartflows-optin-meta.php CHANGED
@@ -239,7 +239,9 @@ class Cartflows_Optin_Meta extends Cartflows_Meta {
239
  'help' => __( 'Select Free and Virtual product only.', 'cartflows' ),
240
  'multiple' => false,
241
  'allow_clear' => true,
242
- 'excluded_product_types' => array( 'variation', 'variable', 'subscription', 'variable-subscription', 'grouped' ),
 
 
243
  )
244
  );
245
 
239
  'help' => __( 'Select Free and Virtual product only.', 'cartflows' ),
240
  'multiple' => false,
241
  'allow_clear' => true,
242
+ 'allowed_product_types' => array( 'simple' ),
243
+ 'excluded_product_types' => array(),
244
+ 'include_product_types' => array(),
245
  )
246
  );
247
 
modules/thankyou/classes/class-cartflows-thankyou-markup.php CHANGED
@@ -1,314 +1,314 @@
1
- <?php
2
- /**
3
- * Front end and markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Checkout Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Thankyou_Markup {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self();
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- /* Downsell Shortcode */
39
- add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
40
-
41
- add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
42
-
43
- add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
44
-
45
- /* Set is checkout flag */
46
- add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
47
-
48
- /* Custom redirection of thank you page */
49
- add_action( 'template_redirect', array( $this, 'redirect_tq_page_to_custom_url' ) );
50
-
51
- add_action( 'cartflows_thank_you_scripts', array( $this, 'add_divi_compatibility_css' ) );
52
- }
53
-
54
- /**
55
- * Redirect to custom url instead of thank you page.
56
- */
57
- public function redirect_tq_page_to_custom_url() {
58
- global $post;
59
-
60
- if ( _is_wcf_thankyou_type() ) {
61
-
62
- $thank_you_id = $post->ID;
63
- $enable_redirection = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-tq-redirect-section' );
64
- $redirect_link = wp_http_validate_url( wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-redirect-link' ) );
65
-
66
- if ( 'yes' === $enable_redirection && ! empty( $redirect_link ) ) {
67
- exit( wp_redirect( $redirect_link ) ); //phpcs:ignore
68
- }
69
- }
70
- }
71
- /**
72
- * Order shortcode markup
73
- *
74
- * @param array $atts attributes.
75
- * @since 1.0.0
76
- */
77
- public function cartflows_order_details_shortcode_markup( $atts ) {
78
-
79
- $output = '';
80
-
81
- if ( _is_wcf_thankyou_type() ) {
82
- /* Remove order item link */
83
- add_filter( 'woocommerce_order_item_permalink', '__return_false' );
84
-
85
- /* Change order text */
86
- add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'custom_tq_text' ), 10, 2 );
87
-
88
- if ( ! function_exists( 'wc_print_notices' ) ) {
89
-
90
- $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
91
- $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
92
-
93
- return $notice_out;
94
- }
95
-
96
- $order = false;
97
-
98
- $id_param = 'wcf-order';
99
- $key_param = 'wcf-key';
100
-
101
- if ( isset( $_GET['wcf-opt-order'] ) ) { //phpcs:ignore
102
- $id_param = 'wcf-opt-order';
103
- $key_param = 'wcf-opt-key';
104
- }
105
-
106
- if ( ! isset( $_GET[ $id_param ] ) && wcf()->flow->is_flow_testmode() ) { //phpcs:ignore
107
- $args = array(
108
- 'limit' => 1,
109
- 'order' => 'DESC',
110
- 'post_type' => 'shop_order',
111
- 'status' => array( 'completed', 'processing' ),
112
- );
113
-
114
- $latest_order = wc_get_orders( $args );
115
-
116
- $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
117
-
118
- if ( $order_id > 0 ) {
119
- $order = wc_get_order( $order_id );
120
-
121
- if ( ! $order ) {
122
- $order = false;
123
- }
124
- }
125
- } else {
126
- if ( ! isset( $_GET[ $id_param ] ) ) { //phpcs:ignore
127
- return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
128
- }
129
-
130
- // Get the order.
131
- $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET[ $id_param ] ) ? 0 : intval( $_GET[ $id_param ] ) ); //phpcs:ignore
132
- $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET[ $key_param ] ) ? '' : wc_clean( wp_unslash( $_GET[ $key_param ] ) ) ); //phpcs:ignore
133
-
134
- if ( $order_id > 0 ) {
135
- $order = wc_get_order( $order_id );
136
-
137
- if ( ! $order || $order->get_order_key() !== $order_key ) {
138
- $order = false;
139
- }
140
- }
141
- }
142
-
143
- // Empty awaiting payment session.
144
- unset( WC()->session->order_awaiting_payment );
145
-
146
- if ( null !== WC()->session ) {
147
- if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
148
- WC()->cart = new WC_Cart();
149
- }
150
-
151
- if ( ! WC()->cart->is_empty() ) {
152
- // wc_empty_cart();
153
- // Empty current cart.
154
- WC()->cart->empty_cart( true );
155
-
156
- wc_clear_notices();
157
- }
158
-
159
- wc_print_notices();
160
- }
161
-
162
- do_action( 'cartflows_thankyou_details_before', $order );
163
-
164
- ob_start();
165
- echo "<div class='wcf-thankyou-wrap' id='wcf-thankyou-wrap'>";
166
- wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
167
- echo '</div>';
168
- $output = ob_get_clean();
169
- }
170
-
171
- return $output;
172
- }
173
-
174
- /**
175
- * Load Thank You scripts.
176
- *
177
- * @return void
178
- */
179
- public function thank_you_scripts() {
180
-
181
- if ( _is_wcf_thankyou_type() ) {
182
-
183
- do_action( 'cartflows_thank_you_scripts' );
184
-
185
- $style = $this->generate_thank_you_style();
186
-
187
- wp_add_inline_style( 'wcf-frontend-global', $style );
188
- }
189
- }
190
-
191
- /**
192
- * Load DIVI compatibility Thank You style.
193
- *
194
- * @return void
195
- */
196
- public function add_divi_compatibility_css() {
197
-
198
- global $post;
199
-
200
- $thank_you_id = $post->ID;
201
-
202
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
203
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id )
204
- ) {
205
- wp_enqueue_style( 'wcf-frontend-global-divi', wcf()->utils->get_css_url( 'frontend-divi' ), array(), CARTFLOWS_VER );
206
- }
207
- }
208
-
209
- /**
210
- * Set thank you as a order received page.
211
- *
212
- * @param boolean $is_order_page order page.
213
- * @return boolean
214
- */
215
- public function set_order_received_page( $is_order_page ) {
216
-
217
- if ( _is_wcf_thankyou_type() ) {
218
- $is_order_page = true;
219
- }
220
-
221
- return $is_order_page;
222
- }
223
-
224
- /**
225
- * Generate Thank You Styles.
226
- *
227
- * @return string
228
- */
229
- public function generate_thank_you_style() {
230
-
231
- global $post;
232
-
233
- if ( _is_wcf_thankyou_type() ) {
234
- $thank_you_id = $post->ID;
235
- } else {
236
- $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
237
- }
238
-
239
- CartFlows_Font_Families::render_fonts( $thank_you_id );
240
-
241
- $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
242
- $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
243
- $text_font_size = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-size' );
244
- $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
245
- $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
246
- $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
247
- $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
248
- $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
249
-
250
- $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
251
-
252
- $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
253
-
254
- $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
255
-
256
- $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
257
-
258
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
259
- Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id ) ) {
260
-
261
- include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-divi-css.php';
262
-
263
- } else {
264
- include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-css.php';
265
- }
266
-
267
- return $output;
268
- }
269
-
270
- /**
271
- * Set as a checkout page if it is thank you page.
272
- * Thank you page need to be set as a checkout page.
273
- * Becauye ayment gateways will not load if it is not checkout.
274
- *
275
- * @param bool $is_checkout is checkout.
276
- *
277
- * @return bool
278
- */
279
- public function woo_checkout_flag( $is_checkout ) {
280
-
281
- if ( ! is_admin() ) {
282
- if ( _is_wcf_thankyou_type() ) {
283
- $is_checkout = true;
284
- }
285
- }
286
-
287
- return $is_checkout;
288
- }
289
-
290
- /**
291
- * Add custom text on thank you page.
292
- *
293
- * @param string $woo_text Default text.
294
- * @param int $order order.
295
- */
296
- public function custom_tq_text( $woo_text, $order ) {
297
-
298
- global $post;
299
-
300
- $thank_you_id = $post->ID;
301
- $new_text = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text' );
302
-
303
- if ( ! empty( $new_text ) ) {
304
- $woo_text = do_shortcode( $new_text );
305
- }
306
-
307
- return $woo_text;
308
- }
309
- }
310
-
311
- /**
312
- * Kicking this off by calling 'get_instance()' method
313
- */
314
- Cartflows_Thankyou_Markup::get_instance();
1
+ <?php
2
+ /**
3
+ * Front end and markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Checkout Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Thankyou_Markup {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self();
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ /* Downsell Shortcode */
39
+ add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
40
+
41
+ add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
42
+
43
+ add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
44
+
45
+ /* Set is checkout flag */
46
+ add_filter( 'woocommerce_is_checkout', array( $this, 'woo_checkout_flag' ), 9999 );
47
+
48
+ /* Custom redirection of thank you page */
49
+ add_action( 'template_redirect', array( $this, 'redirect_tq_page_to_custom_url' ) );
50
+
51
+ add_action( 'cartflows_thank_you_scripts', array( $this, 'add_divi_compatibility_css' ) );
52
+ }
53
+
54
+ /**
55
+ * Redirect to custom url instead of thank you page.
56
+ */
57
+ public function redirect_tq_page_to_custom_url() {
58
+ global $post;
59
+
60
+ if ( _is_wcf_thankyou_type() ) {
61
+
62
+ $thank_you_id = $post->ID;
63
+ $enable_redirection = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-tq-redirect-section' );
64
+ $redirect_link = wp_http_validate_url( wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-redirect-link' ) );
65
+
66
+ if ( 'yes' === $enable_redirection && ! empty( $redirect_link ) ) {
67
+ exit( wp_redirect( $redirect_link ) ); //phpcs:ignore
68
+ }
69
+ }
70
+ }
71
+ /**
72
+ * Order shortcode markup
73
+ *
74
+ * @param array $atts attributes.
75
+ * @since 1.0.0
76
+ */
77
+ public function cartflows_order_details_shortcode_markup( $atts ) {
78
+
79
+ $output = '';
80
+
81
+ if ( _is_wcf_thankyou_type() ) {
82
+ /* Remove order item link */
83
+ add_filter( 'woocommerce_order_item_permalink', '__return_false' );
84
+
85
+ /* Change order text */
86
+ add_filter( 'woocommerce_thankyou_order_received_text', array( $this, 'custom_tq_text' ), 10, 2 );
87
+
88
+ if ( ! function_exists( 'wc_print_notices' ) ) {
89
+
90
+ $notice_out = '<p class="woocommerce-notice">' . __( 'WooCommerce functions do not exist. If you are in an IFrame, please reload it.', 'cartflows' ) . '</p>';
91
+ $notice_out .= '<button onClick="location.reload()">' . __( 'Click Here to Reload', 'cartflows' ) . '</button>';
92
+
93
+ return $notice_out;
94
+ }
95
+
96
+ $order = false;
97
+
98
+ $id_param = 'wcf-order';
99
+ $key_param = 'wcf-key';
100
+
101
+ if ( isset( $_GET['wcf-opt-order'] ) ) { //phpcs:ignore
102
+ $id_param = 'wcf-opt-order';
103
+ $key_param = 'wcf-opt-key';
104
+ }
105
+
106
+ if ( ! isset( $_GET[ $id_param ] ) && wcf()->flow->is_flow_testmode() ) { //phpcs:ignore
107
+ $args = array(
108
+ 'limit' => 1,
109
+ 'order' => 'DESC',
110
+ 'post_type' => 'shop_order',
111
+ 'status' => array( 'completed', 'processing' ),
112
+ );
113
+
114
+ $latest_order = wc_get_orders( $args );
115
+
116
+ $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
117
+
118
+ if ( $order_id > 0 ) {
119
+ $order = wc_get_order( $order_id );
120
+
121
+ if ( ! $order ) {
122
+ $order = false;
123
+ }
124
+ }
125
+ } else {
126
+ if ( ! isset( $_GET[ $id_param ] ) ) { //phpcs:ignore
127
+ return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
128
+ }
129
+
130
+ // Get the order.
131
+ $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET[ $id_param ] ) ? 0 : intval( $_GET[ $id_param ] ) ); //phpcs:ignore
132
+ $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET[ $key_param ] ) ? '' : wc_clean( wp_unslash( $_GET[ $key_param ] ) ) ); //phpcs:ignore
133
+
134
+ if ( $order_id > 0 ) {
135
+ $order = wc_get_order( $order_id );
136
+
137
+ if ( ! $order || $order->get_order_key() !== $order_key ) {
138
+ $order = false;
139
+ }
140
+ }
141
+ }
142
+
143
+ // Empty awaiting payment session.
144
+ unset( WC()->session->order_awaiting_payment );
145
+
146
+ if ( null !== WC()->session ) {
147
+ if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
148
+ WC()->cart = new WC_Cart();
149
+ }
150
+
151
+ if ( ! WC()->cart->is_empty() ) {
152
+ // wc_empty_cart();
153
+ // Empty current cart.
154
+ WC()->cart->empty_cart( true );
155
+
156
+ wc_clear_notices();
157
+ }
158
+
159
+ wc_print_notices();
160
+ }
161
+
162
+ do_action( 'cartflows_thankyou_details_before', $order );
163
+
164
+ ob_start();
165
+ echo "<div class='wcf-thankyou-wrap' id='wcf-thankyou-wrap'>";
166
+ wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
167
+ echo '</div>';
168
+ $output = ob_get_clean();
169
+ }
170
+
171
+ return $output;
172
+ }
173
+
174
+ /**
175
+ * Load Thank You scripts.
176
+ *
177
+ * @return void
178
+ */
179
+ public function thank_you_scripts() {
180
+
181
+ if ( _is_wcf_thankyou_type() ) {
182
+
183
+ do_action( 'cartflows_thank_you_scripts' );
184
+
185
+ $style = $this->generate_thank_you_style();
186
+
187
+ wp_add_inline_style( 'wcf-frontend-global', $style );
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Load DIVI compatibility Thank You style.
193
+ *
194
+ * @return void
195
+ */
196
+ public function add_divi_compatibility_css() {
197
+
198
+ global $post;
199
+
200
+ $thank_you_id = $post->ID;
201
+
202
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
203
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id )
204
+ ) {
205
+ wp_enqueue_style( 'wcf-frontend-global-divi', wcf()->utils->get_css_url( 'frontend-divi' ), array(), CARTFLOWS_VER );
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Set thank you as a order received page.
211
+ *
212
+ * @param boolean $is_order_page order page.
213
+ * @return boolean
214
+ */
215
+ public function set_order_received_page( $is_order_page ) {
216
+
217
+ if ( _is_wcf_thankyou_type() ) {
218
+ $is_order_page = true;
219
+ }
220
+
221
+ return $is_order_page;
222
+ }
223
+
224
+ /**
225
+ * Generate Thank You Styles.
226
+ *
227
+ * @return string
228
+ */
229
+ public function generate_thank_you_style() {
230
+
231
+ global $post;
232
+
233
+ if ( _is_wcf_thankyou_type() ) {
234
+ $thank_you_id = $post->ID;
235
+ } else {
236
+ $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
237
+ }
238
+
239
+ CartFlows_Font_Families::render_fonts( $thank_you_id );
240
+
241
+ $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
242
+ $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
243
+ $text_font_size = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-size' );
244
+ $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
245
+ $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
246
+ $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
247
+ $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
248
+ $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
249
+
250
+ $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
251
+
252
+ $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
253
+
254
+ $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
255
+
256
+ $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
257
+
258
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ||
259
+ Cartflows_Compatibility::get_instance()->is_divi_builder_enabled( $thank_you_id ) ) {
260
+
261
+ include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-divi-css.php';
262
+
263
+ } else {
264
+ include CARTFLOWS_THANKYOU_DIR . 'includes/thankyou-dynamic-css.php';
265
+ }
266
+
267
+ return $output;
268
+ }
269
+
270
+ /**
271
+ * Set as a checkout page if it is thank you page.
272
+ * Thank you page need to be set as a checkout page.
273
+ * Becauye ayment gateways will not load if it is not checkout.
274
+ *
275
+ * @param bool $is_checkout is checkout.
276
+ *
277
+ * @return bool
278
+ */
279
+ public function woo_checkout_flag( $is_checkout ) {
280
+
281
+ if ( ! is_admin() ) {
282
+ if ( _is_wcf_thankyou_type() ) {
283
+ $is_checkout = true;
284
+ }
285
+ }
286
+
287
+ return $is_checkout;
288
+ }
289
+
290
+ /**
291
+ * Add custom text on thank you page.
292
+ *
293
+ * @param string $woo_text Default text.
294
+ * @param int $order order.
295
+ */
296
+ public function custom_tq_text( $woo_text, $order ) {
297
+
298
+ global $post;
299
+
300
+ $thank_you_id = $post->ID;
301
+ $new_text = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text' );
302
+
303
+ if ( ! empty( $new_text ) ) {
304
+ $woo_text = do_shortcode( $new_text );
305
+ }
306
+
307
+ return $woo_text;
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Kicking this off by calling 'get_instance()' method
313
+ */
314
+ Cartflows_Thankyou_Markup::get_instance();
modules/thankyou/includes/thankyou-dynamic-css.php CHANGED
@@ -56,6 +56,9 @@ if ( 'no' == $show_billing_details ) {
56
  .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
  display: none;
58
  }
 
 
 
59
  ';
60
  }
61
 
56
  .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
  display: none;
58
  }
59
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
+ float:left;
61
+ }
62
  ';
63
  }
64
 
modules/thankyou/includes/thankyou-dynamic-divi-css.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
- /**
3
- * Dynamic DIVI Thank you css.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $output = "
9
-
10
- .et_pb_module #wcf-thankyou-wrap{
11
- color: {$text_color};
12
- font-family: {$text_font_family};
13
- max-width:{$container_width}px;
14
- font-size: {$text_font_size}px;
15
- }
16
-
17
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-column__title,
18
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-details__title,
19
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-thankyou-order-received,
20
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order-details h2,
21
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.wc-bacs-bank-details-heading,
22
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-downloads__title {
23
- color: {$heading_text_color};
24
- font-family: {$heading_font_family};
25
- font-weight: {$heading_font_weight};
26
- }
27
-
28
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details,
29
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details,
30
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details,
31
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-bacs-bank-details,
32
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-downloads{
33
- background-color: {$section_bg_color}
34
- }
35
- img.emoji, img.wp-smiley {}
36
- ";
37
-
38
- if ( 'no' == $show_order_review ) {
39
- $output .= '
40
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details{
41
- display: none !important;
42
- }
43
- ';
44
- }
45
-
46
- if ( 'no' == $show_order_details ) {
47
- $output .= '
48
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details{
49
- display: none !important;
50
- }
51
- ';
52
- }
53
-
54
- if ( 'no' == $show_billing_details ) {
55
- $output .= '
56
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
- display: none;
58
- }
59
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
- float:left;
61
- }
62
- ';
63
- }
64
-
65
- if ( 'no' == $show_shipping_details ) {
66
- $output .= '
67
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
68
- display: none ;
69
- }
70
- ';
71
- }
72
-
73
- if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
74
- $output .= '
75
- .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details{
76
- display: none !important;
77
- }
78
- ';
79
- }
1
+ <?php
2
+ /**
3
+ * Dynamic DIVI Thank you css.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $output = "
9
+
10
+ .et_pb_module #wcf-thankyou-wrap{
11
+ color: {$text_color};
12
+ font-family: {$text_font_family};
13
+ max-width:{$container_width}px;
14
+ font-size: {$text_font_size}px;
15
+ }
16
+
17
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-column__title,
18
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-details__title,
19
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-thankyou-order-received,
20
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order-details h2,
21
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.wc-bacs-bank-details-heading,
22
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order h2.woocommerce-order-downloads__title {
23
+ color: {$heading_text_color};
24
+ font-family: {$heading_font_family};
25
+ font-weight: {$heading_font_weight};
26
+ }
27
+
28
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details,
29
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details,
30
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details,
31
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-bacs-bank-details,
32
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-downloads{
33
+ background-color: {$section_bg_color}
34
+ }
35
+ img.emoji, img.wp-smiley {}
36
+ ";
37
+
38
+ if ( 'no' == $show_order_review ) {
39
+ $output .= '
40
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order ul.order_details{
41
+ display: none !important;
42
+ }
43
+ ';
44
+ }
45
+
46
+ if ( 'no' == $show_order_details ) {
47
+ $output .= '
48
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-order-details{
49
+ display: none !important;
50
+ }
51
+ ';
52
+ }
53
+
54
+ if ( 'no' == $show_billing_details ) {
55
+ $output .= '
56
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
57
+ display: none;
58
+ }
59
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
60
+ float:left;
61
+ }
62
+ ';
63
+ }
64
+
65
+ if ( 'no' == $show_shipping_details ) {
66
+ $output .= '
67
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
68
+ display: none ;
69
+ }
70
+ ';
71
+ }
72
+
73
+ if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
74
+ $output .= '
75
+ .et_pb_module #wcf-thankyou-wrap .woocommerce-order .woocommerce-customer-details{
76
+ display: none !important;
77
+ }
78
+ ';
79
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4.2
7
- Stable tag: 1.5.12
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -127,6 +127,10 @@ Glad you asked! Most normal users have less than 3 funnels on a single website,
127
 
128
  == Changelog ==
129
 
 
 
 
 
130
  = Version 1.5.12 - Wednesday, 1st July 2020 =
131
  * Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
132
  * Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.
4
  Tags: woocommerce, funnel builder, sales funnels, elementor, beaver builder
5
  Requires at least: 4.4
6
  Tested up to: 5.4.2
7
+ Stable tag: 1.5.13
8
  Requires PHP: 5.6
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
127
 
128
  == Changelog ==
129
 
130
+ = Version 1.5.13 - Tuesday, 21st July 2020 =
131
+ * Improvement: Improved the product search query of meta options.
132
+ * Improvement: Added compatibility for a future release of CartFlows Pro.
133
+
134
  = Version 1.5.12 - Wednesday, 1st July 2020 =
135
  * Fix: PHP error if WooCommerce was not installed and the Google Analytics Purchase event is enabled.
136
  * Fix: Flows & Steps ready-made templates were unable to import due to the X-CSRF-TOKEN JS error.