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

Version Description

Download this release

Release Info

Developer Nikschavan
Plugin Icon Funnel Builder by CartFlows – Create High Converting Sales Funnels For WordPress
Version 1.1.3
Comparing to
See all releases

Code changes from version 1.1.2 to 1.1.3

Files changed (36) hide show
  1. admin/assets/css/global-admin-rtl.css +19 -0
  2. admin/assets/css/global-admin.css +19 -0
  3. assets/css/import-rtl.css +14 -0
  4. assets/css/import.css +14 -0
  5. assets/js/import.js +10 -1
  6. cartflows.php +1 -1
  7. changelog.txt +7 -0
  8. classes/batch-process/class-cartflows-batch-process.php +156 -156
  9. classes/batch-process/class-cartflows-importer-beaver-builder-batch.php +63 -63
  10. classes/batch-process/class-cartflows-importer-beaver-builder.php +228 -228
  11. classes/batch-process/class-cartflows-importer-elementor-batch.php +66 -66
  12. classes/batch-process/class-cartflows-importer-elementor.php +70 -70
  13. classes/class-cartflows-admin.php +410 -410
  14. classes/class-cartflows-cloning.php +9 -2
  15. classes/class-cartflows-compatibility.php +4 -2
  16. classes/class-cartflows-divi-compatibility.php +55 -55
  17. classes/class-cartflows-flow-frontend.php +1 -1
  18. classes/class-cartflows-frontend.php +330 -328
  19. classes/class-cartflows-helper.php +301 -301
  20. classes/class-cartflows-importer.php +1429 -1134
  21. classes/class-cartflows-loader.php +1 -1
  22. classes/class-cartflows-meta-fields.php +989 -993
  23. classes/class-cartflows-thrive-compatibility.php +63 -63
  24. includes/exporter.php +23 -0
  25. includes/importer.php +26 -0
  26. languages/cartflows.pot +124 -73
  27. modules/checkout/classes/class-cartflows-checkout-markup.php +1005 -987
  28. modules/checkout/templates/embed/checkout-template-simple.php +33 -33
  29. modules/flow/classes/class-cartflows-flow-meta.php +743 -743
  30. modules/flow/classes/class-cartflows-flow-post-type.php +1 -1
  31. modules/flow/classes/class-cartflows-step-post-type.php +450 -450
  32. modules/flow/templates/template-canvas.php +6 -1
  33. modules/flow/templates/template-default.php +6 -1
  34. modules/flow/view/meta-flow-steps.php +183 -183
  35. modules/thankyou/classes/class-cartflows-thankyou-markup.php +272 -264
  36. readme.txt +8 -1
admin/assets/css/global-admin-rtl.css CHANGED
@@ -460,6 +460,10 @@
460
  margin: 15px 0 10px;
461
  }
462
 
 
 
 
 
463
  .wcf-general-metabox-wrap .wcf-field-row{
464
  display: inline-flex;
465
  width: 100%;
@@ -800,4 +804,19 @@
800
  .wcf-metabox-wrap .select2-container--default .select2-search--dropdown .select2-search__field {
801
  border: 1px solid #ddd;
802
  box-shadow: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
  }
460
  margin: 15px 0 10px;
461
  }
462
 
463
+ body.post-php.post-type-cartflows_flow #postimagediv{
464
+ display: none;
465
+ }
466
+
467
  .wcf-general-metabox-wrap .wcf-field-row{
468
  display: inline-flex;
469
  width: 100%;
804
  .wcf-metabox-wrap .select2-container--default .select2-search--dropdown .select2-search__field {
805
  border: 1px solid #ddd;
806
  box-shadow: none;
807
+ }
808
+
809
+
810
+ /**
811
+ * ******************************
812
+ * Device Responsive Css
813
+ * ******************************
814
+ */
815
+ @media only screen and (min-width: 1200px){
816
+ .wcf-column-left{
817
+ width: 300px;
818
+ }
819
+ .wcf-column-right{
820
+ width: calc( 100% - 300px );
821
+ }
822
  }
admin/assets/css/global-admin.css CHANGED
@@ -460,6 +460,10 @@
460
  margin: 15px 0 10px;
461
  }
462
 
 
 
 
 
463
  .wcf-general-metabox-wrap .wcf-field-row{
464
  display: inline-flex;
465
  width: 100%;
@@ -800,4 +804,19 @@
800
  .wcf-metabox-wrap .select2-container--default .select2-search--dropdown .select2-search__field {
801
  border: 1px solid #ddd;
802
  box-shadow: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
  }
460
  margin: 15px 0 10px;
461
  }
462
 
463
+ body.post-php.post-type-cartflows_flow #postimagediv{
464
+ display: none;
465
+ }
466
+
467
  .wcf-general-metabox-wrap .wcf-field-row{
468
  display: inline-flex;
469
  width: 100%;
804
  .wcf-metabox-wrap .select2-container--default .select2-search--dropdown .select2-search__field {
805
  border: 1px solid #ddd;
806
  box-shadow: none;
807
+ }
808
+
809
+
810
+ /**
811
+ * ******************************
812
+ * Device Responsive Css
813
+ * ******************************
814
+ */
815
+ @media only screen and (min-width: 1200px){
816
+ .wcf-column-left{
817
+ width: 300px;
818
+ }
819
+ .wcf-column-right{
820
+ width: calc( 100% - 300px );
821
+ }
822
  }
assets/css/import-rtl.css CHANGED
@@ -932,4 +932,18 @@ html.wcf-popup-open{
932
  .wcf-notice-wrap .notice {
933
  display: inline-block;
934
  margin: 1.5em 0 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
  }
932
  .wcf-notice-wrap .notice {
933
  display: inline-block;
934
  margin: 1.5em 0 0 0;
935
+ }
936
+
937
+ .cartflows-ie .postbox {
938
+ padding: 1em;
939
+ }
940
+
941
+ .cartflows-ie {
942
+ padding-top: 2em;
943
+ padding-left: 2em;
944
+ }
945
+
946
+ .admin_page_flow_exporter .notice,
947
+ .admin_page_flow_importer .notice {
948
+ margin: 1em 0 0 0;
949
  }
assets/css/import.css CHANGED
@@ -932,4 +932,18 @@ html.wcf-popup-open{
932
  .wcf-notice-wrap .notice {
933
  display: inline-block;
934
  margin: 1.5em 0 0 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
  }
932
  .wcf-notice-wrap .notice {
933
  display: inline-block;
934
  margin: 1.5em 0 0 0;
935
+ }
936
+
937
+ .cartflows-ie .postbox {
938
+ padding: 1em;
939
+ }
940
+
941
+ .cartflows-ie {
942
+ padding-top: 2em;
943
+ padding-right: 2em;
944
+ }
945
+
946
+ .admin_page_flow_exporter .notice,
947
+ .admin_page_flow_importer .notice {
948
+ margin: 1em 0 0 0;
949
  }
assets/js/import.js CHANGED
@@ -127,6 +127,15 @@ var CartFlowsAjaxQueue = (function() {
127
  }, 1500);
128
  }
129
  }
 
 
 
 
 
 
 
 
 
130
  },
131
 
132
  /**
@@ -192,7 +201,7 @@ var CartFlowsAjaxQueue = (function() {
192
 
193
  $( document ).on('click', '.actions a', self._previewResponsive );
194
 
195
- $( document ).on( 'click', '.page-title-action', self._render_remote_flows );
196
  $( document ).on( 'click', '.wcf-trigger-popup', self._render_remote_steps );
197
 
198
  $( document ).on( 'click', '.wcf-templates-popup-overlay', self._close_template_popup );
127
  }, 1500);
128
  }
129
  }
130
+
131
+ if( $('.post-type-cartflows_flow').hasClass('edit-php') ) {
132
+ var $product_screen = $( '.edit-php.post-type-cartflows_flow' ),
133
+ $title_action = $product_screen.find( '.page-title-action:first' );
134
+
135
+ $title_action.after('<a href="'+CartFlowsImportVars.export_url+'" class="page-title-action">Export</a>' );
136
+ $title_action.after('<a href="'+CartFlowsImportVars.import_url+'" class="page-title-action">Import</a>');
137
+ }
138
+
139
  },
140
 
141
  /**
201
 
202
  $( document ).on('click', '.actions a', self._previewResponsive );
203
 
204
+ $( document ).on( 'click', '.page-title-action:first', self._render_remote_flows );
205
  $( document ).on( 'click', '.wcf-trigger-popup', self._render_remote_steps );
206
 
207
  $( document ).on( 'click', '.wcf-templates-popup-overlay', self._close_template_popup );
cartflows.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.1.2
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
3
  * Plugin Name: CartFlows
4
  * Plugin URI: https://cartflows.com/
5
  * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
+ * Version: 1.1.3
7
  * Author: CartFlows Inc
8
  * Author URI: https://cartflows.com/
9
  * Text Domain: cartflows
changelog.txt CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  Version 1.1.2 - Friday, 4th January 2019
2
  - Fix: Import Cloud Template option not visible in thrive visual editor.
3
  - Fix: Oceanwp css conflict with checkout layout.
1
+ Version 1.1.3 - Tuesday, 15th January 2019
2
+ - New: Import / Export the flows
3
+ - Improvement: Pixel Caffeine plugin pixel compatibility added.
4
+ - Improvement: Filter introduced to change the coupon field placeholder & button text.
5
+ - Fix: Clone option conflict with Duplicate post and Duplicate page plugin.
6
+ - Fix: Cart is not empty after purchase.
7
+
8
  Version 1.1.2 - Friday, 4th January 2019
9
  - Fix: Import Cloud Template option not visible in thrive visual editor.
10
  - Fix: Oceanwp css conflict with checkout layout.
classes/batch-process/class-cartflows-batch-process.php CHANGED
@@ -1,156 +1,156 @@
1
- <?php
2
- /**
3
- * Batch Processing
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
-
11
- /**
12
- * CartFlows_Batch_Process
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Batch_Process {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @var object Class object.
23
- * @access private
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Elementor Batch Instance
29
- *
30
- * @since 1.1.1 Updated instance name with elementor specific.
31
- *
32
- * @since 1.0.0
33
- * @var object Class object.
34
- * @access public
35
- */
36
- public static $batch_instance_elementor;
37
-
38
- /**
39
- * Beaver Builder Batch Instance
40
- *
41
- * @since 1.1.1
42
- * @var object Class object.
43
- * @access public
44
- */
45
- public static $batch_instance_bb;
46
-
47
- /**
48
- * Initiator
49
- *
50
- * @since 1.0.0
51
- * @return object initialized object of class.
52
- */
53
- public static function get_instance() {
54
- if ( ! isset( self::$instance ) ) {
55
- self::$instance = new self;
56
- }
57
- return self::$instance;
58
- }
59
-
60
- /**
61
- * Constructor
62
- *
63
- * @since 1.0.0
64
- */
65
- public function __construct() {
66
-
67
- // Not BB or Elementor then avoid importer.
68
- if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
69
- return;
70
- }
71
-
72
- // Core Helpers - Image.
73
- require_once ABSPATH . 'wp-admin/includes/image.php';
74
-
75
- // Core Helpers - Batch Processing.
76
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
77
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
78
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
79
-
80
- // Elementor.
81
- if ( class_exists( '\Elementor\Plugin' ) ) {
82
- // Add "elementor" in import [queue].
83
- // @todo Remove required `allow_url_fopen` support.
84
- if ( ini_get( 'allow_url_fopen' ) ) {
85
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
86
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
87
- self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
88
- }
89
- }
90
-
91
- // Beaver Builder.
92
- if ( class_exists( 'FLBuilder' ) ) {
93
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
94
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
95
- self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
96
- }
97
-
98
- // Start image importing after site import complete.
99
- add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
100
- add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
101
- }
102
-
103
- /**
104
- * Batch Process Complete.
105
- *
106
- * @return void
107
- */
108
- public function complete_batch_import() {
109
- wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
110
- }
111
-
112
- /**
113
- * Start Image Import
114
- *
115
- * @param integer $post_id Post Id.
116
- *
117
- * @return void
118
- */
119
- public function start_batch_process( $post_id = '' ) {
120
-
121
- wcf()->logger->import_log( '(✓) BATCH Started!' );
122
- wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
123
-
124
- // Add "elementor" in import [queue].
125
- if ( self::$batch_instance_bb ) {
126
-
127
- // Add to queue.
128
- self::$batch_instance_bb->push_to_queue( $post_id );
129
-
130
- // Dispatch Queue.
131
- self::$batch_instance_bb->save()->dispatch();
132
-
133
- wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
134
-
135
- } elseif ( self::$batch_instance_elementor ) {
136
-
137
- // Add to queue.
138
- self::$batch_instance_elementor->push_to_queue( $post_id );
139
-
140
- // Dispatch Queue.
141
- self::$batch_instance_elementor->save()->dispatch();
142
-
143
- wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
144
- } else {
145
- wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
146
- }
147
- }
148
-
149
- }
150
-
151
- /**
152
- * Kicking this off by calling 'get_instance()' method
153
- */
154
- CartFlows_Batch_Process::get_instance();
155
-
156
- endif;
1
+ <?php
2
+ /**
3
+ * Batch Processing
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Batch_Process' ) ) :
10
+
11
+ /**
12
+ * CartFlows_Batch_Process
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ class CartFlows_Batch_Process {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.0.0
22
+ * @var object Class object.
23
+ * @access private
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Elementor Batch Instance
29
+ *
30
+ * @since 1.1.1 Updated instance name with elementor specific.
31
+ *
32
+ * @since 1.0.0
33
+ * @var object Class object.
34
+ * @access public
35
+ */
36
+ public static $batch_instance_elementor;
37
+
38
+ /**
39
+ * Beaver Builder Batch Instance
40
+ *
41
+ * @since 1.1.1
42
+ * @var object Class object.
43
+ * @access public
44
+ */
45
+ public static $batch_instance_bb;
46
+
47
+ /**
48
+ * Initiator
49
+ *
50
+ * @since 1.0.0
51
+ * @return object initialized object of class.
52
+ */
53
+ public static function get_instance() {
54
+ if ( ! isset( self::$instance ) ) {
55
+ self::$instance = new self;
56
+ }
57
+ return self::$instance;
58
+ }
59
+
60
+ /**
61
+ * Constructor
62
+ *
63
+ * @since 1.0.0
64
+ */
65
+ public function __construct() {
66
+
67
+ // Not BB or Elementor then avoid importer.
68
+ if ( ! class_exists( '\Elementor\Plugin' ) && ! class_exists( 'FLBuilder' ) ) {
69
+ return;
70
+ }
71
+
72
+ // Core Helpers - Image.
73
+ require_once ABSPATH . 'wp-admin/includes/image.php';
74
+
75
+ // Core Helpers - Batch Processing.
76
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-cartflows-importer-image.php';
77
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
78
+ require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
79
+
80
+ // Elementor.
81
+ if ( class_exists( '\Elementor\Plugin' ) ) {
82
+ // Add "elementor" in import [queue].
83
+ // @todo Remove required `allow_url_fopen` support.
84
+ if ( ini_get( 'allow_url_fopen' ) ) {
85
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
86
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor-batch.php';
87
+ self::$batch_instance_elementor = new Cartflows_Importer_Elementor_Batch();
88
+ }
89
+ }
90
+
91
+ // Beaver Builder.
92
+ if ( class_exists( 'FLBuilder' ) ) {
93
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder.php';
94
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-beaver-builder-batch.php';
95
+ self::$batch_instance_bb = new Cartflows_Importer_Beaver_Builder_Batch();
96
+ }
97
+
98
+ // Start image importing after site import complete.
99
+ add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
100
+ add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
101
+ }
102
+
103
+ /**
104
+ * Batch Process Complete.
105
+ *
106
+ * @return void
107
+ */
108
+ public function complete_batch_import() {
109
+ wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
110
+ }
111
+
112
+ /**
113
+ * Start Image Import
114
+ *
115
+ * @param integer $post_id Post Id.
116
+ *
117
+ * @return void
118
+ */
119
+ public function start_batch_process( $post_id = '' ) {
120
+
121
+ wcf()->logger->import_log( '(✓) BATCH Started!' );
122
+ wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
123
+
124
+ // Add "elementor" in import [queue].
125
+ if ( self::$batch_instance_bb ) {
126
+
127
+ // Add to queue.
128
+ self::$batch_instance_bb->push_to_queue( $post_id );
129
+
130
+ // Dispatch Queue.
131
+ self::$batch_instance_bb->save()->dispatch();
132
+
133
+ wcf()->logger->import_log( '(✓) Dispatch "Beaver Builder" Request..' );
134
+
135
+ } elseif ( self::$batch_instance_elementor ) {
136
+
137
+ // Add to queue.
138
+ self::$batch_instance_elementor->push_to_queue( $post_id );
139
+
140
+ // Dispatch Queue.
141
+ self::$batch_instance_elementor->save()->dispatch();
142
+
143
+ wcf()->logger->import_log( '(✓) Dispatch "Elementor" Request..' );
144
+ } else {
145
+ wcf()->logger->import_log( '(✕) Could not import image due to allow_url_fopen() is disabled!' );
146
+ }
147
+ }
148
+
149
+ }
150
+
151
+ /**
152
+ * Kicking this off by calling 'get_instance()' method
153
+ */
154
+ CartFlows_Batch_Process::get_instance();
155
+
156
+ endif;
classes/batch-process/class-cartflows-importer-beaver-builder-batch.php CHANGED
@@ -1,63 +1,63 @@
1
- <?php
2
- /**
3
- * Beaver Builder Batch Process
4
- *
5
- * @package CartFlows
6
- * @since 1.1.1
7
- */
8
-
9
- if ( ! class_exists( 'Cartflows_Importer_Beaver_Builder_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
-
11
- /**
12
- * Image Background Process
13
- *
14
- * @since 1.1.1
15
- */
16
- class Cartflows_Importer_Beaver_Builder_Batch extends WP_Background_Process {
17
-
18
- /**
19
- * Image Process
20
- *
21
- * @var string
22
- */
23
- protected $action = 'cartflows_beaver_builder_image_process';
24
-
25
- /**
26
- * Task
27
- *
28
- * Override this method to perform any actions required on each
29
- * queue item. Return the modified item for further processing
30
- * in the next pass through. Or, return false to remove the
31
- * item from the queue.
32
- *
33
- * @since 1.1.1
34
- *
35
- * @param integer $post_id Post Id.
36
- * @return mixed
37
- */
38
- protected function task( $post_id ) {
39
-
40
- CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $post_id );
41
-
42
- return false;
43
- }
44
-
45
- /**
46
- * Complete
47
- *
48
- * Override if applicable, but ensure that the below actions are
49
- * performed, or, call parent::complete().
50
- *
51
- * @since 1.1.1
52
- */
53
- protected function complete() {
54
-
55
- parent::complete();
56
-
57
- do_action( 'cartflows_import_complete' );
58
-
59
- }
60
-
61
- }
62
-
63
- endif;
1
+ <?php
2
+ /**
3
+ * Beaver Builder Batch Process
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.1.1
7
+ */
8
+
9
+ if ( ! class_exists( 'Cartflows_Importer_Beaver_Builder_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
+
11
+ /**
12
+ * Image Background Process
13
+ *
14
+ * @since 1.1.1
15
+ */
16
+ class Cartflows_Importer_Beaver_Builder_Batch extends WP_Background_Process {
17
+
18
+ /**
19
+ * Image Process
20
+ *
21
+ * @var string
22
+ */
23
+ protected $action = 'cartflows_beaver_builder_image_process';
24
+
25
+ /**
26
+ * Task
27
+ *
28
+ * Override this method to perform any actions required on each
29
+ * queue item. Return the modified item for further processing
30
+ * in the next pass through. Or, return false to remove the
31
+ * item from the queue.
32
+ *
33
+ * @since 1.1.1
34
+ *
35
+ * @param integer $post_id Post Id.
36
+ * @return mixed
37
+ */
38
+ protected function task( $post_id ) {
39
+
40
+ CartFlows_Importer_Beaver_Builder::get_instance()->import_single_post( $post_id );
41
+
42
+ return false;
43
+ }
44
+
45
+ /**
46
+ * Complete
47
+ *
48
+ * Override if applicable, but ensure that the below actions are
49
+ * performed, or, call parent::complete().
50
+ *
51
+ * @since 1.1.1
52
+ */
53
+ protected function complete() {
54
+
55
+ parent::complete();
56
+
57
+ do_action( 'cartflows_import_complete' );
58
+
59
+ }
60
+
61
+ }
62
+
63
+ endif;
classes/batch-process/class-cartflows-importer-beaver-builder.php CHANGED
@@ -1,228 +1,228 @@
1
- <?php
2
- /**
3
- * Beaver Builder Importer
4
- *
5
- * @package CartFlows
6
- * @since 1.1.1
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer_Beaver_Builder' ) ) :
10
-
11
- /**
12
- * CartFlows Import Beaver Builder
13
- *
14
- * @since 1.1.1
15
- */
16
- class CartFlows_Importer_Beaver_Builder {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.1.1
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.1.1
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
-
35
- if ( ! isset( self::$instance ) ) {
36
- self::$instance = new self;
37
- }
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.1.1
45
- */
46
- public function __construct() {
47
- }
48
-
49
- /**
50
- * Update post meta.
51
- *
52
- * @param integer $post_id Post ID.
53
- * @return void
54
- */
55
- public function import_single_post( $post_id = 0 ) {
56
-
57
- $data = get_post_meta( $post_id, '_fl_builder_data', true );
58
- if ( ! empty( $data ) ) {
59
-
60
- // Download Images.
61
- $data = $this->get_import_data( $data );
62
-
63
- // Update page builder data.
64
- update_post_meta( $post_id, '_fl_builder_data', $data );
65
- update_post_meta( $post_id, '_fl_builder_draft', $data );
66
-
67
- // Clear all cache.
68
- FLBuilderModel::delete_asset_cache_for_all_posts();
69
- }
70
- }
71
-
72
- /**
73
- * Update post meta.
74
- *
75
- * @param array $data Page builder data.
76
- * @return mixed
77
- */
78
- public function get_import_data( $data ) {
79
-
80
- if ( empty( $data ) ) {
81
- return array();
82
- }
83
-
84
- foreach ( $data as $key => $el ) {
85
-
86
- // Import 'row' images.
87
- if ( 'row' === $el->type ) {
88
- $data[ $key ]->settings = self::import_row_images( $el->settings );
89
- }
90
-
91
- // Import 'module' images.
92
- if ( 'module' === $el->type ) {
93
- $data[ $key ]->settings = self::import_module_images( $el->settings );
94
- }
95
-
96
- // Import 'column' images.
97
- if ( 'column' === $el->type ) {
98
- $data[ $key ]->settings = self::import_column_images( $el->settings );
99
- }
100
- }
101
-
102
- return $data;
103
- }
104
-
105
- /**
106
- * Import Module Images.
107
- *
108
- * @param object $settings Module settings object.
109
- * @return object
110
- */
111
- public static function import_module_images( $settings ) {
112
-
113
- /**
114
- * 1) Set photos.
115
- */
116
- $settings = self::import_photo( $settings );
117
-
118
- /**
119
- * 2) Set `$settings->data` for Only type 'image-icon'
120
- *
121
- * @todo Remove the condition `'image-icon' === $settings->type` if `$settings->data` is used only for the Image Icon.
122
- */
123
- if (
124
- isset( $settings->data ) &&
125
- isset( $settings->photo ) && ! empty( $settings->photo ) &&
126
- 'image-icon' === $settings->type
127
- ) {
128
- $settings->data = FLBuilderPhoto::get_attachment_data( $settings->photo );
129
- }
130
-
131
- /**
132
- * 3) Set `list item` module images
133
- */
134
- if ( isset( $settings->add_list_item ) ) {
135
- foreach ( $settings->add_list_item as $key => $value ) {
136
- $settings->add_list_item[ $key ] = self::import_photo( $value );
137
- }
138
- }
139
-
140
- return $settings;
141
- }
142
-
143
- /**
144
- * Import Column Images.
145
- *
146
- * @param object $settings Column settings object.
147
- * @return object
148
- */
149
- public static function import_column_images( $settings ) {
150
-
151
- // 1) Set BG Images.
152
- $settings = self::import_bg_image( $settings );
153
-
154
- return $settings;
155
- }
156
-
157
- /**
158
- * Import Row Images.
159
- *
160
- * @param object $settings Row settings object.
161
- * @return object
162
- */
163
- public static function import_row_images( $settings ) {
164
-
165
- // 1) Set BG Images.
166
- $settings = self::import_bg_image( $settings );
167
-
168
- return $settings;
169
- }
170
-
171
- /**
172
- * Helper: Import BG Images.
173
- *
174
- * @param object $settings Row settings object.
175
- * @return object
176
- */
177
- public static function import_bg_image( $settings ) {
178
-
179
- if (
180
- ( ! empty( $settings->bg_image ) && ! empty( $settings->bg_image_src ) )
181
- ) {
182
- $image = array(
183
- 'url' => $settings->bg_image_src,
184
- 'id' => $settings->bg_image,
185
- );
186
-
187
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
188
-
189
- $settings->bg_image_src = $downloaded_image['url'];
190
- $settings->bg_image = $downloaded_image['id'];
191
- }
192
-
193
- return $settings;
194
- }
195
-
196
- /**
197
- * Helper: Import Photo.
198
- *
199
- * @param object $settings Row settings object.
200
- * @return object
201
- */
202
- public static function import_photo( $settings ) {
203
-
204
- if ( ! empty( $settings->photo ) && ! empty( $settings->photo_src ) ) {
205
-
206
- $image = array(
207
- 'url' => $settings->photo_src,
208
- 'id' => $settings->photo,
209
- );
210
-
211
- $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
212
-
213
- $settings->photo_src = $downloaded_image['url'];
214
- $settings->photo = $downloaded_image['id'];
215
- }
216
-
217
- return $settings;
218
- }
219
-
220
-
221
- }
222
-
223
- /**
224
- * Initialize class object with 'get_instance()' method
225
- */
226
- CartFlows_Importer_Beaver_Builder::get_instance();
227
-
228
- endif;
1
+ <?php
2
+ /**
3
+ * Beaver Builder Importer
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.1.1
7
+ */
8
+
9
+ if ( ! class_exists( 'CartFlows_Importer_Beaver_Builder' ) ) :
10
+
11
+ /**
12
+ * CartFlows Import Beaver Builder
13
+ *
14
+ * @since 1.1.1
15
+ */
16
+ class CartFlows_Importer_Beaver_Builder {
17
+
18
+ /**
19
+ * Instance
20
+ *
21
+ * @since 1.1.1
22
+ * @access private
23
+ * @var object Class object.
24
+ */
25
+ private static $instance;
26
+
27
+ /**
28
+ * Initiator
29
+ *
30
+ * @since 1.1.1
31
+ * @return object initialized object of class.
32
+ */
33
+ public static function get_instance() {
34
+
35
+ if ( ! isset( self::$instance ) ) {
36
+ self::$instance = new self;
37
+ }
38
+ return self::$instance;
39
+ }
40
+
41
+ /**
42
+ * Constructor
43
+ *
44
+ * @since 1.1.1
45
+ */
46
+ public function __construct() {
47
+ }
48
+
49
+ /**
50
+ * Update post meta.
51
+ *
52
+ * @param integer $post_id Post ID.
53
+ * @return void
54
+ */
55
+ public function import_single_post( $post_id = 0 ) {
56
+
57
+ $data = get_post_meta( $post_id, '_fl_builder_data', true );
58
+ if ( ! empty( $data ) ) {
59
+
60
+ // Download Images.
61
+ $data = $this->get_import_data( $data );
62
+
63
+ // Update page builder data.
64
+ update_post_meta( $post_id, '_fl_builder_data', $data );
65
+ update_post_meta( $post_id, '_fl_builder_draft', $data );
66
+
67
+ // Clear all cache.
68
+ FLBuilderModel::delete_asset_cache_for_all_posts();
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Update post meta.
74
+ *
75
+ * @param array $data Page builder data.
76
+ * @return mixed
77
+ */
78
+ public function get_import_data( $data ) {
79
+
80
+ if ( empty( $data ) ) {
81
+ return array();
82
+ }
83
+
84
+ foreach ( $data as $key => $el ) {
85
+
86
+ // Import 'row' images.
87
+ if ( 'row' === $el->type ) {
88
+ $data[ $key ]->settings = self::import_row_images( $el->settings );
89
+ }
90
+
91
+ // Import 'module' images.
92
+ if ( 'module' === $el->type ) {
93
+ $data[ $key ]->settings = self::import_module_images( $el->settings );
94
+ }
95
+
96
+ // Import 'column' images.
97
+ if ( 'column' === $el->type ) {
98
+ $data[ $key ]->settings = self::import_column_images( $el->settings );
99
+ }
100
+ }
101
+
102
+ return $data;
103
+ }
104
+
105
+ /**
106
+ * Import Module Images.
107
+ *
108
+ * @param object $settings Module settings object.
109
+ * @return object
110
+ */
111
+ public static function import_module_images( $settings ) {
112
+
113
+ /**
114
+ * 1) Set photos.
115
+ */
116
+ $settings = self::import_photo( $settings );
117
+
118
+ /**
119
+ * 2) Set `$settings->data` for Only type 'image-icon'
120
+ *
121
+ * @todo Remove the condition `'image-icon' === $settings->type` if `$settings->data` is used only for the Image Icon.
122
+ */
123
+ if (
124
+ isset( $settings->data ) &&
125
+ isset( $settings->photo ) && ! empty( $settings->photo ) &&
126
+ 'image-icon' === $settings->type
127
+ ) {
128
+ $settings->data = FLBuilderPhoto::get_attachment_data( $settings->photo );
129
+ }
130
+
131
+ /**
132
+ * 3) Set `list item` module images
133
+ */
134
+ if ( isset( $settings->add_list_item ) ) {
135
+ foreach ( $settings->add_list_item as $key => $value ) {
136
+ $settings->add_list_item[ $key ] = self::import_photo( $value );
137
+ }
138
+ }
139
+
140
+ return $settings;
141
+ }
142
+
143
+ /**
144
+ * Import Column Images.
145
+ *
146
+ * @param object $settings Column settings object.
147
+ * @return object
148
+ */
149
+ public static function import_column_images( $settings ) {
150
+
151
+ // 1) Set BG Images.
152
+ $settings = self::import_bg_image( $settings );
153
+
154
+ return $settings;
155
+ }
156
+
157
+ /**
158
+ * Import Row Images.
159
+ *
160
+ * @param object $settings Row settings object.
161
+ * @return object
162
+ */
163
+ public static function import_row_images( $settings ) {
164
+
165
+ // 1) Set BG Images.
166
+ $settings = self::import_bg_image( $settings );
167
+
168
+ return $settings;
169
+ }
170
+
171
+ /**
172
+ * Helper: Import BG Images.
173
+ *
174
+ * @param object $settings Row settings object.
175
+ * @return object
176
+ */
177
+ public static function import_bg_image( $settings ) {
178
+
179
+ if (
180
+ ( ! empty( $settings->bg_image ) && ! empty( $settings->bg_image_src ) )
181
+ ) {
182
+ $image = array(
183
+ 'url' => $settings->bg_image_src,
184
+ 'id' => $settings->bg_image,
185
+ );
186
+
187
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
188
+
189
+ $settings->bg_image_src = $downloaded_image['url'];
190
+ $settings->bg_image = $downloaded_image['id'];
191
+ }
192
+
193
+ return $settings;
194
+ }
195
+
196
+ /**
197
+ * Helper: Import Photo.
198
+ *
199
+ * @param object $settings Row settings object.
200
+ * @return object
201
+ */
202
+ public static function import_photo( $settings ) {
203
+
204
+ if ( ! empty( $settings->photo ) && ! empty( $settings->photo_src ) ) {
205
+
206
+ $image = array(
207
+ 'url' => $settings->photo_src,
208
+ 'id' => $settings->photo,
209
+ );
210
+
211
+ $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
212
+
213
+ $settings->photo_src = $downloaded_image['url'];
214
+ $settings->photo = $downloaded_image['id'];
215
+ }
216
+
217
+ return $settings;
218
+ }
219
+
220
+
221
+ }
222
+
223
+ /**
224
+ * Initialize class object with 'get_instance()' method
225
+ */
226
+ CartFlows_Importer_Beaver_Builder::get_instance();
227
+
228
+ endif;
classes/batch-process/class-cartflows-importer-elementor-batch.php CHANGED
@@ -1,66 +1,66 @@
1
- <?php
2
- /**
3
- * Elementor Batch Process
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'Cartflows_Importer_Elementor_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
-
11
- /**
12
- * Image Background Process
13
- *
14
- * @since 1.1.1 Updated class name with Elementor specific.
15
- *
16
- * @since 1.0.0
17
- */
18
- class Cartflows_Importer_Elementor_Batch extends WP_Background_Process {
19
-
20
- /**
21
- * Image Process
22
- *
23
- * @var string
24
- */
25
- protected $action = 'cartflows_elementor_image_process';
26
-
27
- /**
28
- * Task
29
- *
30
- * Override this method to perform any actions required on each
31
- * queue item. Return the modified item for further processing
32
- * in the next pass through. Or, return false to remove the
33
- * item from the queue.
34
- *
35
- * @since 1.0.0
36
- *
37
- * @param integer $post_id Post Id.
38
- * @return mixed
39
- */
40
- protected function task( $post_id ) {
41
-
42
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
43
- $obj->import_single_template( $post_id );
44
-
45
- return false;
46
- }
47
-
48
- /**
49
- * Complete
50
- *
51
- * Override if applicable, but ensure that the below actions are
52
- * performed, or, call parent::complete().
53
- *
54
- * @since 1.0.0
55
- */
56
- protected function complete() {
57
-
58
- parent::complete();
59
-
60
- do_action( 'cartflows_import_complete' );
61
-
62
- }
63
-
64
- }
65
-
66
- endif;
1
+ <?php
2
+ /**
3
+ * Elementor Batch Process
4
+ *
5
+ * @package CartFlows
6
+ * @since 1.0.0
7
+ */
8
+
9
+ if ( ! class_exists( 'Cartflows_Importer_Elementor_Batch' ) && class_exists( 'WP_Background_Process' ) ) :
10
+
11
+ /**
12
+ * Image Background Process
13
+ *
14
+ * @since 1.1.1 Updated class name with Elementor specific.
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ class Cartflows_Importer_Elementor_Batch extends WP_Background_Process {
19
+
20
+ /**
21
+ * Image Process
22
+ *
23
+ * @var string
24
+ */
25
+ protected $action = 'cartflows_elementor_image_process';
26
+
27
+ /**
28
+ * Task
29
+ *
30
+ * Override this method to perform any actions required on each
31
+ * queue item. Return the modified item for further processing
32
+ * in the next pass through. Or, return false to remove the
33
+ * item from the queue.
34
+ *
35
+ * @since 1.0.0
36
+ *
37
+ * @param integer $post_id Post Id.
38
+ * @return mixed
39
+ */
40
+ protected function task( $post_id ) {
41
+
42
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
43
+ $obj->import_single_template( $post_id );
44
+
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * Complete
50
+ *
51
+ * Override if applicable, but ensure that the below actions are
52
+ * performed, or, call parent::complete().
53
+ *
54
+ * @since 1.0.0
55
+ */
56
+ protected function complete() {
57
+
58
+ parent::complete();
59
+
60
+ do_action( 'cartflows_import_complete' );
61
+
62
+ }
63
+
64
+ }
65
+
66
+ endif;
classes/batch-process/class-cartflows-importer-elementor.php CHANGED
@@ -1,70 +1,70 @@
1
- <?php
2
- /**
3
- * Elementor Importer
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- namespace Elementor\TemplateLibrary;
9
-
10
- use Elementor\Core\Base\Document;
11
- use Elementor\DB;
12
- use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
- use Elementor\Core\Settings\Manager as SettingsManager;
14
- use Elementor\Core\Settings\Page\Model;
15
- use Elementor\Editor;
16
- use Elementor\Plugin;
17
- use Elementor\Settings;
18
- use Elementor\Utils;
19
-
20
- if ( ! defined( 'ABSPATH' ) ) {
21
- exit; // Exit if accessed directly.
22
- }
23
-
24
- /**
25
- * Elementor template library local source.
26
- *
27
- * Elementor template library local source handler class is responsible for
28
- * handling local Elementor templates saved by the user locally on his site.
29
- *
30
- * @since 1.0.0
31
- */
32
- class CartFlows_Importer_Elementor extends Source_Local {
33
-
34
- /**
35
- * Import single template
36
- *
37
- * @param int $post_id post ID.
38
- */
39
- public function import_single_template( $post_id ) {
40
-
41
- $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
-
43
- if ( empty( $rest_content ) ) {
44
- $data = __( 'Invalid content.', 'cartflows' );
45
- wcf()->logger->import_log( '(✕) ' . $data );
46
- }
47
-
48
- $rest_content = add_magic_quotes( $rest_content );
49
- $content = json_decode( $rest_content, true );
50
-
51
- if ( ! is_array( $content ) ) {
52
- $data = __( 'Invalid content. Expected an array.', 'cartflows' );
53
- wcf()->logger->import_log( '(✕) ' . $data );
54
- wcf()->logger->import_log( $content );
55
- } else {
56
-
57
- wcf()->logger->import_log( '(✓) Processing Request..' );
58
- wcf()->logger->import_log( '(✓) Data ' . json_encode( $content ) );
59
-
60
- // Import the data.
61
- $content = $this->process_export_import_content( $content, 'on_import' );
62
-
63
- // Update content.
64
- update_metadata( 'post', $post_id, '_elementor_data', $content );
65
-
66
- wcf()->logger->import_log( '(✓) Process Complete' );
67
- }
68
-
69
- }
70
- }
1
+ <?php
2
+ /**
3
+ * Elementor Importer
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ namespace Elementor\TemplateLibrary;
9
+
10
+ use Elementor\Core\Base\Document;
11
+ use Elementor\DB;
12
+ use Elementor\Core\Settings\Page\Manager as PageSettingsManager;
13
+ use Elementor\Core\Settings\Manager as SettingsManager;
14
+ use Elementor\Core\Settings\Page\Model;
15
+ use Elementor\Editor;
16
+ use Elementor\Plugin;
17
+ use Elementor\Settings;
18
+ use Elementor\Utils;
19
+
20
+ if ( ! defined( 'ABSPATH' ) ) {
21
+ exit; // Exit if accessed directly.
22
+ }
23
+
24
+ /**
25
+ * Elementor template library local source.
26
+ *
27
+ * Elementor template library local source handler class is responsible for
28
+ * handling local Elementor templates saved by the user locally on his site.
29
+ *
30
+ * @since 1.0.0
31
+ */
32
+ class CartFlows_Importer_Elementor extends Source_Local {
33
+
34
+ /**
35
+ * Import single template
36
+ *
37
+ * @param int $post_id post ID.
38
+ */
39
+ public function import_single_template( $post_id ) {
40
+
41
+ $rest_content = get_post_meta( $post_id, '_elementor_data', true );
42
+
43
+ if ( empty( $rest_content ) ) {
44
+ $data = __( 'Invalid content.', 'cartflows' );
45
+ wcf()->logger->import_log( '(✕) ' . $data );
46
+ }
47
+
48
+ $rest_content = add_magic_quotes( $rest_content );
49
+ $content = json_decode( $rest_content, true );
50
+
51
+ if ( ! is_array( $content ) ) {
52
+ $data = __( 'Invalid content. Expected an array.', 'cartflows' );
53
+ wcf()->logger->import_log( '(✕) ' . $data );
54
+ wcf()->logger->import_log( $content );
55
+ } else {
56
+
57
+ wcf()->logger->import_log( '(✓) Processing Request..' );
58
+ wcf()->logger->import_log( '(✓) Data ' . json_encode( $content ) );
59
+
60
+ // Import the data.
61
+ $content = $this->process_export_import_content( $content, 'on_import' );
62
+
63
+ // Update content.
64
+ update_metadata( 'post', $post_id, '_elementor_data', $content );
65
+
66
+ wcf()->logger->import_log( '(✓) Process Complete' );
67
+ }
68
+
69
+ }
70
+ }
classes/class-cartflows-admin.php CHANGED
@@ -1,410 +1,410 @@
1
- <?php
2
- /**
3
- * CartFlows Admin.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class Cartflows_Admin.
10
- */
11
- class Cartflows_Admin {
12
-
13
- /**
14
- * Calls on initialization
15
- *
16
- * @since 1.0.0
17
- */
18
- public static function init() {
19
-
20
- self::initialise_plugin();
21
- self::init_hooks();
22
- }
23
-
24
- /**
25
- * Init Hooks.
26
- *
27
- * @since 1.0.0
28
- * @return void
29
- */
30
- static public function init_hooks() {
31
-
32
- if ( ! is_admin() ) {
33
- return;
34
- }
35
-
36
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
-
38
- // Add CARTFLOWS menu option to admin.
39
- add_action( 'network_admin_menu', __CLASS__ . '::menu' );
40
- add_action( 'admin_menu', __CLASS__ . '::menu' );
41
- add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
42
-
43
- add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
44
-
45
- // Enqueue admin scripts.
46
- if ( isset( $_REQUEST['page'] ) && CARTFLOWS_SETTINGS == $_REQUEST['page'] ) {
47
-
48
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
49
-
50
- self::save_settings();
51
- }
52
-
53
- /* Global Addmin Script */
54
- add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
55
-
56
- add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
57
- }
58
-
59
- /**
60
- * Initialises the Plugin Name.
61
- *
62
- * @since 1.0.0
63
- * @return void
64
- */
65
- static public function initialise_plugin() {
66
-
67
- $name = 'Cartflows';
68
- $short_name = 'Cflows';
69
-
70
- define( 'CARTFLOWS_PLUGIN_NAME', $name );
71
- define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
72
- }
73
-
74
- /**
75
- * Renders the admin settings menu.
76
- *
77
- * @since 1.0.0
78
- * @return void
79
- */
80
- static public function menu() {
81
-
82
- if ( ! current_user_can( 'manage_options' ) ) {
83
- return;
84
- }
85
-
86
- add_menu_page(
87
- 'CartFlows',
88
- 'CartFlows',
89
- 'manage_options',
90
- CARTFLOWS_SLUG,
91
- __CLASS__ . '::render',
92
- 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),
93
- 39.7
94
- );
95
-
96
- }
97
-
98
- /**
99
- * Add submenu to admin menu.
100
- *
101
- * @since 1.0.0
102
- */
103
- static function submenu() {
104
-
105
- $parent_slug = CARTFLOWS_SLUG;
106
- $page_title = __( 'Settings', 'cartflows' );
107
- $menu_title = __( 'Settings', 'cartflows' );
108
- $capability = 'manage_options';
109
- $menu_slug = 'cartflows_settings';
110
- $callback = __CLASS__ . '::render';
111
-
112
- add_submenu_page(
113
- $parent_slug,
114
- $page_title,
115
- $menu_title,
116
- $capability,
117
- $menu_slug,
118
- $callback
119
- );
120
- }
121
-
122
- /**
123
- * Renders the admin settings.
124
- *
125
- * @since 1.0.0
126
- * @return void
127
- */
128
- static public function render() {
129
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
130
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
131
- $action = str_replace( '_', '-', $action );
132
-
133
- // Enable header icon filter below.
134
- $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
135
-
136
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
137
- }
138
-
139
- /**
140
- * Renders the admin settings content.
141
- *
142
- * @since 1.0.0
143
- * @return void
144
- */
145
- static public function render_content() {
146
-
147
- $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
148
- $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
149
- $action = str_replace( '_', '-', $action );
150
- $action = 'general';
151
-
152
- $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
153
-
154
- include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
155
- }
156
-
157
- /**
158
- * Save Global Setting options.
159
- *
160
- * @since 1.0.0
161
- */
162
- static public function save_common_settings() {
163
-
164
- if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( $_POST['cartflows-common-settings-nonce'], 'cartflows-common-settings' ) ) {
165
-
166
- $url = $_SERVER['REQUEST_URI'];
167
- $input_settings = array();
168
- $new_settings = array();
169
-
170
- if ( isset( $_POST['_cartflows_common'] ) ) {
171
-
172
- $input_settings = $_POST['_cartflows_common'];
173
-
174
- // Loop through the input and sanitize each of the values.
175
- foreach ( $input_settings as $key => $val ) {
176
-
177
- if ( is_array( $val ) ) {
178
- foreach ( $val as $k => $v ) {
179
- $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
180
- }
181
- } else {
182
- $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
183
- }
184
- }
185
- }
186
-
187
- Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, true );
188
-
189
- $query = array(
190
- 'message' => 'saved',
191
- );
192
-
193
- $redirect_to = add_query_arg( $query, $url );
194
-
195
- wp_redirect( $redirect_to );
196
- exit;
197
- } // End if statement.
198
- }
199
-
200
- /**
201
- * Check is cartflows admin.
202
- *
203
- * @since 1.0.0
204
- * @return boolean
205
- */
206
- static public function is_global_admin() {
207
-
208
- $current_screen = get_current_screen();
209
-
210
- if (
211
- is_object( $current_screen ) &&
212
- isset( $current_screen->post_type ) &&
213
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
214
- CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
215
- )
216
- ) {
217
- return true;
218
- }
219
- return false;
220
- }
221
-
222
- /**
223
- * Check is flow admin.
224
- *
225
- * @since 1.0.0
226
- * @return boolean
227
- */
228
- static public function is_flow_edit_admin() {
229
-
230
- $current_screen = get_current_screen();
231
-
232
- if (
233
- is_object( $current_screen ) &&
234
- isset( $current_screen->post_type ) &&
235
- ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
236
- isset( $current_screen->base ) &&
237
- ( 'post' === $current_screen->base )
238
- ) {
239
- return true;
240
- }
241
- return false;
242
- }
243
-
244
- /**
245
- * Global Admin Scripts.
246
- *
247
- * @since 1.0.0
248
- */
249
- static public function global_admin_scripts() {
250
-
251
- $localize = array(
252
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
253
- 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
254
- );
255
-
256
- wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
257
-
258
- if ( self::is_global_admin() ) {
259
-
260
- // Styles.
261
- wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
262
- wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
263
-
264
- wp_enqueue_script(
265
- 'wcf-global-admin',
266
- CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
267
- array( 'jquery' ),
268
- CARTFLOWS_VER,
269
- true
270
- );
271
-
272
- do_action( 'cartflows_global_admin_scripts' );
273
- }
274
- }
275
-
276
- /**
277
- * Global Admin Data.
278
- *
279
- * @since 1.0.0
280
- */
281
- static public function global_admin_data() {
282
-
283
- $current_screen = get_current_screen();
284
-
285
- if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
286
- return;
287
- }
288
-
289
- ?>
290
-
291
- <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
292
- <div class="wcf-templates-popup-content">
293
- <div class="spinner"></div>
294
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
295
-
296
- <div id="wcf-remote-flow-actions" class="wcf-template-header">
297
- <div class="wcf-template-logo-wrap">
298
- <span class="wcf-cartflows-logo-img">
299
- <span class="cartflows-icon"></span>
300
- </span>
301
- <span class="wcf-cartflows-title"><?php _e( 'Flows Library', 'cartflows' ); ?></span>
302
- </div>
303
- <div class="wcf-tab-wrapper">
304
- <div id="wcf-get-started-steps">
305
- <ul class="filter-links ">
306
- <li>
307
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php _e( 'Ready Templates', 'cartflows' ); ?>"><?php _e( 'Ready Templates', 'cartflows' ); ?></a>
308
- </li>
309
- <li>
310
- <a href="#" data-slug="canvas" data-title="<?php _e( 'Create Your Own', 'cartflows' ); ?>"><?php _e( 'Create Your Own', 'cartflows' ); ?></a>
311
- </li>
312
- </ul>
313
- </div>
314
- </div>
315
- <div class="wcf-popup-close-wrap">
316
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
317
- </div>
318
- </div>
319
- <!-- <div class="wcf-search-form">
320
- <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
321
- <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
322
- </div> -->
323
-
324
- <div id="wcf-remote-content">
325
- <div id="wcf-ready-templates">
326
- <div id="wcf-remote-filters">
327
- <div id="wcf-page-builders"></div>
328
- <div id="wcf-categories"></div>
329
- </div>
330
- <div class="wcf-page-builder-notice"></div>
331
- <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"></div>
332
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
333
- </div>
334
- <div id="wcf-start-from-scratch" style="display: none;">
335
- <div class="inner">
336
- <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php _e( 'Design Your Flow', 'cartflows' ); ?></a>
337
- </div>
338
- </div>
339
- </div>
340
- </div>
341
- </div>
342
- </div>
343
-
344
- <?php
345
- }
346
-
347
- /**
348
- * Enqueues the needed CSS/JS for the builder's admin settings page.
349
- *
350
- * @since 1.0.0
351
- */
352
- static public function styles_scripts() {
353
-
354
- // Styles.
355
- wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
356
- wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
357
-
358
- // Script.
359
- wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER );
360
-
361
- $localize = array(
362
- 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
363
- );
364
-
365
- wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
366
- }
367
-
368
- /**
369
- * Save All admin settings here
370
- */
371
- static public function save_settings() {
372
-
373
- // Only admins can save settings.
374
- if ( ! current_user_can( 'manage_options' ) ) {
375
- return;
376
- }
377
-
378
- self::save_common_settings();
379
-
380
- // Let extensions hook into saving.
381
- do_action( 'cartflows_admin_settings_save' );
382
- }
383
-
384
- /**
385
- * Get and return page URL
386
- *
387
- * @param string $menu_slug Menu name.
388
- * @since 1.0.0
389
- * @return string page url
390
- */
391
- static public function get_page_url( $menu_slug ) {
392
-
393
- $parent_page = self::$default_menu_position;
394
-
395
- if ( strpos( $parent_page, '?' ) !== false ) {
396
- $query_var = '&page=' . self::$plugin_slug;
397
- } else {
398
- $query_var = '?page=' . self::$plugin_slug;
399
- }
400
-
401
- $parent_page_url = admin_url( $parent_page . $query_var );
402
-
403
- $url = $parent_page_url . '&action=' . $menu_slug;
404
-
405
- return esc_url( $url );
406
- }
407
-
408
- }
409
-
410
- Cartflows_Admin::init();
1
+ <?php
2
+ /**
3
+ * CartFlows Admin.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class Cartflows_Admin.
10
+ */
11
+ class Cartflows_Admin {
12
+
13
+ /**
14
+ * Calls on initialization
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ public static function init() {
19
+
20
+ self::initialise_plugin();
21
+ self::init_hooks();
22
+ }
23
+
24
+ /**
25
+ * Init Hooks.
26
+ *
27
+ * @since 1.0.0
28
+ * @return void
29
+ */
30
+ static public function init_hooks() {
31
+
32
+ if ( ! is_admin() ) {
33
+ return;
34
+ }
35
+
36
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin-fields.php';
37
+
38
+ // Add CARTFLOWS menu option to admin.
39
+ add_action( 'network_admin_menu', __CLASS__ . '::menu' );
40
+ add_action( 'admin_menu', __CLASS__ . '::menu' );
41
+ add_action( 'admin_menu', __CLASS__ . '::submenu', 999 );
42
+
43
+ add_action( 'cartflows_render_admin_content', __CLASS__ . '::render_content' );
44
+
45
+ // Enqueue admin scripts.
46
+ if ( isset( $_REQUEST['page'] ) && CARTFLOWS_SETTINGS == $_REQUEST['page'] ) {
47
+
48
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::styles_scripts' );
49
+
50
+ self::save_settings();
51
+ }
52
+
53
+ /* Global Addmin Script */
54
+ add_action( 'admin_enqueue_scripts', __CLASS__ . '::global_admin_scripts', 20 );
55
+
56
+ add_action( 'admin_footer', __CLASS__ . '::global_admin_data', 9555 );
57
+ }
58
+
59
+ /**
60
+ * Initialises the Plugin Name.
61
+ *
62
+ * @since 1.0.0
63
+ * @return void
64
+ */
65
+ static public function initialise_plugin() {
66
+
67
+ $name = 'Cartflows';
68
+ $short_name = 'Cflows';
69
+
70
+ define( 'CARTFLOWS_PLUGIN_NAME', $name );
71
+ define( 'CARTFLOWS_PLUGIN_SHORT_NAME', $short_name );
72
+ }
73
+
74
+ /**
75
+ * Renders the admin settings menu.
76
+ *
77
+ * @since 1.0.0
78
+ * @return void
79
+ */
80
+ static public function menu() {
81
+
82
+ if ( ! current_user_can( 'manage_options' ) ) {
83
+ return;
84
+ }
85
+
86
+ add_menu_page(
87
+ 'CartFlows',
88
+ 'CartFlows',
89
+ 'manage_options',
90
+ CARTFLOWS_SLUG,
91
+ __CLASS__ . '::render',
92
+ 'data:image/svg+xml;base64,' . base64_encode( file_get_contents( CARTFLOWS_DIR . 'assets/images/cartflows-icon.svg' ) ),
93
+ 39.7
94
+ );
95
+
96
+ }
97
+
98
+ /**
99
+ * Add submenu to admin menu.
100
+ *
101
+ * @since 1.0.0
102
+ */
103
+ static function submenu() {
104
+
105
+ $parent_slug = CARTFLOWS_SLUG;
106
+ $page_title = __( 'Settings', 'cartflows' );
107
+ $menu_title = __( 'Settings', 'cartflows' );
108
+ $capability = 'manage_options';
109
+ $menu_slug = 'cartflows_settings';
110
+ $callback = __CLASS__ . '::render';
111
+
112
+ add_submenu_page(
113
+ $parent_slug,
114
+ $page_title,
115
+ $menu_title,
116
+ $capability,
117
+ $menu_slug,
118
+ $callback
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Renders the admin settings.
124
+ *
125
+ * @since 1.0.0
126
+ * @return void
127
+ */
128
+ static public function render() {
129
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
130
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
131
+ $action = str_replace( '_', '-', $action );
132
+
133
+ // Enable header icon filter below.
134
+ $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
135
+
136
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-admin.php';
137
+ }
138
+
139
+ /**
140
+ * Renders the admin settings content.
141
+ *
142
+ * @since 1.0.0
143
+ * @return void
144
+ */
145
+ static public function render_content() {
146
+
147
+ $action = ( isset( $_GET['action'] ) ) ? sanitize_text_field( $_GET['action'] ) : '';
148
+ $action = ( ! empty( $action ) && '' != $action ) ? $action : 'general';
149
+ $action = str_replace( '_', '-', $action );
150
+ $action = 'general';
151
+
152
+ $header_wrapper_class = apply_filters( 'cartflows_header_wrapper_class', array( $action ) );
153
+
154
+ include_once CARTFLOWS_DIR . 'includes/admin/cartflows-general.php';
155
+ }
156
+
157
+ /**
158
+ * Save Global Setting options.
159
+ *
160
+ * @since 1.0.0
161
+ */
162
+ static public function save_common_settings() {
163
+
164
+ if ( isset( $_POST['cartflows-common-settings-nonce'] ) && wp_verify_nonce( $_POST['cartflows-common-settings-nonce'], 'cartflows-common-settings' ) ) {
165
+
166
+ $url = $_SERVER['REQUEST_URI'];
167
+ $input_settings = array();
168
+ $new_settings = array();
169
+
170
+ if ( isset( $_POST['_cartflows_common'] ) ) {
171
+
172
+ $input_settings = $_POST['_cartflows_common'];
173
+
174
+ // Loop through the input and sanitize each of the values.
175
+ foreach ( $input_settings as $key => $val ) {
176
+
177
+ if ( is_array( $val ) ) {
178
+ foreach ( $val as $k => $v ) {
179
+ $new_settings[ $key ][ $k ] = ( isset( $val[ $k ] ) ) ? sanitize_text_field( $v ) : '';
180
+ }
181
+ } else {
182
+ $new_settings[ $key ] = ( isset( $input_settings[ $key ] ) ) ? sanitize_text_field( $val ) : '';
183
+ }
184
+ }
185
+ }
186
+
187
+ Cartflows_Helper::update_admin_settings_option( '_cartflows_common', $new_settings, true );
188
+
189
+ $query = array(
190
+ 'message' => 'saved',
191
+ );
192
+
193
+ $redirect_to = add_query_arg( $query, $url );
194
+
195
+ wp_redirect( $redirect_to );
196
+ exit;
197
+ } // End if statement.
198
+ }
199
+
200
+ /**
201
+ * Check is cartflows admin.
202
+ *
203
+ * @since 1.0.0
204
+ * @return boolean
205
+ */
206
+ static public function is_global_admin() {
207
+
208
+ $current_screen = get_current_screen();
209
+
210
+ if (
211
+ is_object( $current_screen ) &&
212
+ isset( $current_screen->post_type ) &&
213
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ||
214
+ CARTFLOWS_STEP_POST_TYPE === $current_screen->post_type
215
+ )
216
+ ) {
217
+ return true;
218
+ }
219
+ return false;
220
+ }
221
+
222
+ /**
223
+ * Check is flow admin.
224
+ *
225
+ * @since 1.0.0
226
+ * @return boolean
227
+ */
228
+ static public function is_flow_edit_admin() {
229
+
230
+ $current_screen = get_current_screen();
231
+
232
+ if (
233
+ is_object( $current_screen ) &&
234
+ isset( $current_screen->post_type ) &&
235
+ ( CARTFLOWS_FLOW_POST_TYPE === $current_screen->post_type ) &&
236
+ isset( $current_screen->base ) &&
237
+ ( 'post' === $current_screen->base )
238
+ ) {
239
+ return true;
240
+ }
241
+ return false;
242
+ }
243
+
244
+ /**
245
+ * Global Admin Scripts.
246
+ *
247
+ * @since 1.0.0
248
+ */
249
+ static public function global_admin_scripts() {
250
+
251
+ $localize = array(
252
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
253
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-nonce' ),
254
+ );
255
+
256
+ wp_localize_script( 'jquery', 'cartflows_admin', apply_filters( 'cartflows_admin_js_localize', $localize ) );
257
+
258
+ if ( self::is_global_admin() ) {
259
+
260
+ // Styles.
261
+ wp_enqueue_style( 'cartflows-global-admin', CARTFLOWS_URL . 'admin/assets/css/global-admin.css', array(), CARTFLOWS_VER );
262
+ wp_style_add_data( 'cartflows-global-admin', 'rtl', 'replace' );
263
+
264
+ wp_enqueue_script(
265
+ 'wcf-global-admin',
266
+ CARTFLOWS_URL . 'admin/assets/js/global-admin.js',
267
+ array( 'jquery' ),
268
+ CARTFLOWS_VER,
269
+ true
270
+ );
271
+
272
+ do_action( 'cartflows_global_admin_scripts' );
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Global Admin Data.
278
+ *
279
+ * @since 1.0.0
280
+ */
281
+ static public function global_admin_data() {
282
+
283
+ $current_screen = get_current_screen();
284
+
285
+ if ( 'edit-' . CARTFLOWS_FLOW_POST_TYPE != $current_screen->id ) {
286
+ return;
287
+ }
288
+
289
+ ?>
290
+
291
+ <div id="wcf-remote-flow-importer" class="wcf-templates-popup-overlay">
292
+ <div class="wcf-templates-popup-content">
293
+ <div class="spinner"></div>
294
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
295
+
296
+ <div id="wcf-remote-flow-actions" class="wcf-template-header">
297
+ <div class="wcf-template-logo-wrap">
298
+ <span class="wcf-cartflows-logo-img">
299
+ <span class="cartflows-icon"></span>
300
+ </span>
301
+ <span class="wcf-cartflows-title"><?php _e( 'Flows Library', 'cartflows' ); ?></span>
302
+ </div>
303
+ <div class="wcf-tab-wrapper">
304
+ <div id="wcf-get-started-steps">
305
+ <ul class="filter-links ">
306
+ <li>
307
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php _e( 'Ready Templates', 'cartflows' ); ?>"><?php _e( 'Ready Templates', 'cartflows' ); ?></a>
308
+ </li>
309
+ <li>
310
+ <a href="#" data-slug="canvas" data-title="<?php _e( 'Create Your Own', 'cartflows' ); ?>"><?php _e( 'Create Your Own', 'cartflows' ); ?></a>
311
+ </li>
312
+ </ul>
313
+ </div>
314
+ </div>
315
+ <div class="wcf-popup-close-wrap">
316
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
317
+ </div>
318
+ </div>
319
+ <!-- <div class="wcf-search-form">
320
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
321
+ <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
322
+ </div> -->
323
+
324
+ <div id="wcf-remote-content">
325
+ <div id="wcf-ready-templates">
326
+ <div id="wcf-remote-filters">
327
+ <div id="wcf-page-builders"></div>
328
+ <div id="wcf-categories"></div>
329
+ </div>
330
+ <div class="wcf-page-builder-notice"></div>
331
+ <div id="wcf-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"></div>
332
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
333
+ </div>
334
+ <div id="wcf-start-from-scratch" style="display: none;">
335
+ <div class="inner">
336
+ <a href="#" class="button button-hero button-primary cartflows-flow-import-blank"><?php _e( 'Design Your Flow', 'cartflows' ); ?></a>
337
+ </div>
338
+ </div>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ </div>
343
+
344
+ <?php
345
+ }
346
+
347
+ /**
348
+ * Enqueues the needed CSS/JS for the builder's admin settings page.
349
+ *
350
+ * @since 1.0.0
351
+ */
352
+ static public function styles_scripts() {
353
+
354
+ // Styles.
355
+ wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
356
+ wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
357
+
358
+ // Script.
359
+ wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER );
360
+
361
+ $localize = array(
362
+ 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
363
+ );
364
+
365
+ wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
366
+ }
367
+
368
+ /**
369
+ * Save All admin settings here
370
+ */
371
+ static public function save_settings() {
372
+
373
+ // Only admins can save settings.
374
+ if ( ! current_user_can( 'manage_options' ) ) {
375
+ return;
376
+ }
377
+
378
+ self::save_common_settings();
379
+
380
+ // Let extensions hook into saving.
381
+ do_action( 'cartflows_admin_settings_save' );
382
+ }
383
+
384
+ /**
385
+ * Get and return page URL
386
+ *
387
+ * @param string $menu_slug Menu name.
388
+ * @since 1.0.0
389
+ * @return string page url
390
+ */
391
+ static public function get_page_url( $menu_slug ) {
392
+
393
+ $parent_page = self::$default_menu_position;
394
+
395
+ if ( strpos( $parent_page, '?' ) !== false ) {
396
+ $query_var = '&page=' . self::$plugin_slug;
397
+ } else {
398
+ $query_var = '?page=' . self::$plugin_slug;
399
+ }
400
+
401
+ $parent_page_url = admin_url( $parent_page . $query_var );
402
+
403
+ $url = $parent_page_url . '&action=' . $menu_slug;
404
+
405
+ return esc_url( $url );
406
+ }
407
+
408
+ }
409
+
410
+ Cartflows_Admin::init();
classes/class-cartflows-cloning.php CHANGED
@@ -35,10 +35,9 @@ class Cartflows_Cloning {
35
  */
36
  public function __construct() {
37
 
38
- add_filter( 'post_row_actions', array( $this, 'clone_link' ), 10, 2 );
39
  add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
  add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
41
-
42
  }
43
 
44
  /**
@@ -83,6 +82,7 @@ class Cartflows_Cloning {
83
  /**
84
  * New post data array
85
  */
 
86
  $args = array(
87
  'comment_status' => $post->comment_status,
88
  'ping_status' => $post->ping_status,
@@ -404,6 +404,13 @@ class Cartflows_Cloning {
404
 
405
  if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
406
 
 
 
 
 
 
 
 
407
  $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
408
  }
409
 
35
  */
36
  public function __construct() {
37
 
38
+ add_filter( 'post_row_actions', array( $this, 'clone_link' ), 99, 2 );
39
  add_action( 'admin_action_cartflows_clone_flow', array( $this, 'clone_flow' ) );
40
  add_action( 'admin_action_cartflows_clone_step', array( $this, 'clone_step' ) );
 
41
  }
42
 
43
  /**
82
  /**
83
  * New post data array
84
  */
85
+
86
  $args = array(
87
  'comment_status' => $post->comment_status,
88
  'ping_status' => $post->ping_status,
404
 
405
  if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
406
 
407
+ if ( isset( $actions['duplicate'] ) ) { // Duplicate page plugin remove.
408
+ unset( $actions['duplicate'] );
409
+ }
410
+ if ( isset( $actions['edit_as_new_draft'] ) ) { // Duplicate post plugin remove.
411
+ unset( $actions['edit_as_new_draft'] );
412
+ }
413
+
414
  $actions['clone'] = '<a href="' . wp_nonce_url( 'admin.php?action=cartflows_clone_flow&post=' . $post->ID, basename( __FILE__ ), 'flow_clone_nonce' ) . '" title="' . __( 'Clone this flow', 'cartflows' ) . '" rel="permalink">' . __( 'Clone', 'cartflows' ) . '</a>';
415
  }
416
 
classes/class-cartflows-compatibility.php CHANGED
@@ -140,12 +140,14 @@ if ( ! class_exists( 'Cartflows_Compatibility' ) ) {
140
 
141
  $theme = wp_get_theme();
142
 
 
 
143
  if ( $this->is_divi_enabled( $theme ) || $this->is_flatsome_enabled( $theme ) ) {
144
 
145
- return true;
146
  }
147
 
148
- return false;
149
  }
150
 
151
  /**
140
 
141
  $theme = wp_get_theme();
142
 
143
+ $is_compatibility = false;
144
+
145
  if ( $this->is_divi_enabled( $theme ) || $this->is_flatsome_enabled( $theme ) ) {
146
 
147
+ $is_compatibility = true;
148
  }
149
 
150
+ return apply_filters( 'cartflows_is_compatibility_theme', $is_compatibility );
151
  }
152
 
153
  /**
classes/class-cartflows-divi-compatibility.php CHANGED
@@ -1,55 +1,55 @@
1
- <?php
2
- /**
3
- * Divi page builder compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class for divi page builder compatibility
10
- */
11
- class Cartflows_Divi_Compatibility {
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
- add_filter( 'cartflows_container_atts', array( $this, 'add_id_for_cartflows_container' ) );
36
- }
37
-
38
- /**
39
- * Add id attribute to cartflows container which is needed to apply style to divi elements.
40
- *
41
- * @param array $atts container HTML attributes.
42
- * @return array
43
- */
44
- public function add_id_for_cartflows_container( $atts ) {
45
-
46
- $atts['id'] = 'page-container';
47
-
48
- return $atts;
49
- }
50
- }
51
-
52
- /**
53
- * Kicking this off by calling 'get_instance()' method
54
- */
55
- Cartflows_Divi_Compatibility::get_instance();
1
+ <?php
2
+ /**
3
+ * Divi page builder compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class for divi page builder compatibility
10
+ */
11
+ class Cartflows_Divi_Compatibility {
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
+ add_filter( 'cartflows_container_atts', array( $this, 'add_id_for_cartflows_container' ) );
36
+ }
37
+
38
+ /**
39
+ * Add id attribute to cartflows container which is needed to apply style to divi elements.
40
+ *
41
+ * @param array $atts container HTML attributes.
42
+ * @return array
43
+ */
44
+ public function add_id_for_cartflows_container( $atts ) {
45
+
46
+ $atts['id'] = 'page-container';
47
+
48
+ return $atts;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Kicking this off by calling 'get_instance()' method
54
+ */
55
+ Cartflows_Divi_Compatibility::get_instance();
classes/class-cartflows-flow-frontend.php CHANGED
@@ -36,7 +36,7 @@ class Cartflows_Flow_Frontend {
36
  public function __construct() {
37
 
38
  /* Analytics */
39
- add_action( 'wp_footer', array( $this, 'footer_markup' ) );
40
  }
41
 
42
  /**
36
  public function __construct() {
37
 
38
  /* Analytics */
39
+ add_action( 'cartflows_wp_footer', array( $this, 'footer_markup' ) );
40
  }
41
 
42
  /**
classes/class-cartflows-frontend.php CHANGED
@@ -1,328 +1,330 @@
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
- /* Enqueue global required scripts */
39
- add_action( 'wp', array( $this, 'wp_actions' ), 55 );
40
-
41
- /* Modify the checkout order received url to go thank you page in our flow */
42
- add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
43
- }
44
-
45
- /**
46
- * Redirect to thank page if upsell not exists
47
- *
48
- * @param string $order_recieve_url url.
49
- * @param object $order order object.
50
- * @since 1.0.0
51
- */
52
- function redirect_to_thankyou_page( $order_recieve_url, $order ) {
53
-
54
- /* Only for thank you page */
55
- wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
56
- wcf()->logger->log( 'Only for thank you page' );
57
-
58
- if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
59
-
60
- if ( _is_wcf_doing_checkout_ajax() ) {
61
-
62
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
63
-
64
- if ( ! $checkout_id ) {
65
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
66
- }
67
- } else {
68
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
69
- }
70
-
71
- wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
72
-
73
- if ( $checkout_id ) {
74
-
75
- $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
76
-
77
- if ( $thankyou_step_id ) {
78
-
79
- $order_recieve_url = get_permalink( $thankyou_step_id );
80
-
81
- $order_recieve_url = add_query_arg(
82
- array(
83
- 'wcf-order' => $order->get_id(),
84
- 'wcf-key' => $order->get_order_key(),
85
- ),
86
- $order_recieve_url
87
- );
88
- }
89
- }
90
- }
91
-
92
- wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
93
-
94
- return $order_recieve_url;
95
- }
96
-
97
- /**
98
- * Cancel and redirect to checkout
99
- *
100
- * @param string $return_url url.
101
- * @since 1.0.0
102
- */
103
- function redirect_to_checkout_on_cancel( $return_url ) {
104
-
105
- if ( _is_wcf_doing_checkout_ajax() ) {
106
-
107
- $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
108
-
109
- if ( ! $checkout_id ) {
110
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
111
- }
112
- } else {
113
- $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
114
- }
115
-
116
- if ( $checkout_id ) {
117
-
118
- $return_url = add_query_arg(
119
- array(
120
- 'cancel_order' => 'true',
121
- '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
122
- ),
123
- get_permalink( $checkout_id )
124
- );
125
- }
126
-
127
- return $return_url;
128
- }
129
-
130
-
131
- /**
132
- * Remove theme styles.
133
- *
134
- * @since 1.0.0
135
- */
136
- function remove_theme_styles() {
137
-
138
- // get all styles data.
139
- global $wp_styles;
140
- global $wp_scripts;
141
-
142
- $get_stylesheet = get_stylesheet();
143
- $get_template = get_template();
144
-
145
- if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
146
- return;
147
- }
148
-
149
- $get_stylesheet = 'themes/' . get_stylesheet();
150
- $get_template = 'themes/' . get_template();
151
-
152
- // loop over all of the registered scripts..
153
- foreach ( $wp_styles->registered as $handle => $data ) {
154
-
155
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
156
-
157
- // remove it.
158
- wp_deregister_style( $handle );
159
- wp_dequeue_style( $handle );
160
- }
161
- }
162
-
163
- // loop over all of the registered scripts.
164
- foreach ( $wp_scripts->registered as $handle => $data ) {
165
-
166
- if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
167
-
168
- // remove it.
169
- wp_deregister_script( $handle );
170
- wp_dequeue_script( $handle );
171
- }
172
- }
173
- }
174
-
175
- /**
176
- * Update main order data in transient.
177
- *
178
- * @param array $woo_styles new styles array.
179
- * @since 1.0.0
180
- * @return array.
181
- */
182
- function woo_default_css( $woo_styles ) {
183
-
184
- $woo_styles = array(
185
- 'woocommerce-layout' => array(
186
- 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
187
- 'deps' => '',
188
- 'version' => WC_VERSION,
189
- 'media' => 'all',
190
- 'has_rtl' => true,
191
- ),
192
- 'woocommerce-smallscreen' => array(
193
- 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
194
- 'deps' => 'woocommerce-layout',
195
- 'version' => WC_VERSION,
196
- 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
197
- 'has_rtl' => true,
198
- ),
199
- 'woocommerce-general' => array(
200
- 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
201
- 'deps' => '',
202
- 'version' => WC_VERSION,
203
- 'media' => 'all',
204
- 'has_rtl' => true,
205
- ),
206
- );
207
-
208
- return $woo_styles;
209
- }
210
-
211
- /**
212
- * Init Actions.
213
- *
214
- * @since 1.0.0
215
- */
216
- function init_actions() {
217
-
218
- $this->set_flow_session();
219
- }
220
-
221
- /**
222
- * Set flow session.
223
- *
224
- * @since 1.0.0
225
- */
226
- function set_flow_session() {
227
-
228
- if ( wcf()->utils->is_step_post_type() ) {
229
-
230
- add_action( 'wp_head', array( $this, 'noindex_flow' ) );
231
-
232
- wcf()->utils->do_not_cache();
233
-
234
- /* Set key to support pixel */
235
- if ( isset( $_GET['wcf-key'] ) ) {
236
- $_GET['key'] = $_GET['wcf-key'];
237
- $_REQUEST['key'] = $_GET['wcf-key'];
238
- }
239
-
240
- if ( isset( $_GET['wcf-order'] ) ) {
241
- $_GET['order'] = $_GET['wcf-order'];
242
- $_REQUEST['order'] = $_GET['wcf-order'];
243
- }
244
- }
245
- }
246
-
247
- /**
248
- * Add noindex, nofollow.
249
- *
250
- * @since 1.0.0
251
- */
252
- function noindex_flow() {
253
-
254
- $common = Cartflows_Helper::get_common_settings();
255
-
256
- if ( 'enable' === $common['disallow_indexing'] ) {
257
- echo '<meta name="robots" content="noindex,nofollow">';
258
- }
259
- }
260
-
261
- /**
262
- * WP Actions.
263
- *
264
- * @since 1.0.0
265
- */
266
- function wp_actions() {
267
-
268
- if ( wcf()->utils->is_step_post_type() ) {
269
-
270
- /* CSS Compatibility for All theme */
271
- add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
272
-
273
- add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
274
-
275
- add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
276
- }
277
-
278
- }
279
-
280
- /**
281
- * Global flow scripts.
282
- *
283
- * @since 1.0.0
284
- */
285
- function global_flow_scripts() {
286
-
287
- global $post;
288
-
289
- $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
290
- $current_step = $post->ID;
291
- $next_step_link = '';
292
- $compatibility = Cartflows_Compatibility::get_instance();
293
-
294
- if ( _is_wcf_landing_type() ) {
295
-
296
- $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
297
- $next_step_link = get_permalink( $next_step_id );
298
- }
299
-
300
- $localize = array(
301
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
302
- 'is_pb_preview' => $compatibility->is_page_builder_preview(),
303
- 'current_theme' => $compatibility->get_current_theme(),
304
- 'current_flow' => $flow,
305
- 'current_step' => $current_step,
306
- 'next_step' => $next_step_link,
307
- );
308
-
309
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
310
-
311
- wp_enqueue_style( 'wcf-frontend-global', CARTFLOWS_URL . 'assets/css/frontend.css', array(), CARTFLOWS_VER );
312
- wp_style_add_data( 'wcf-frontend-global', 'rtl', 'replace' );
313
-
314
- wp_enqueue_script(
315
- 'wcf-frontend-global',
316
- CARTFLOWS_URL . 'assets/js/frontend.js',
317
- array( 'jquery' ),
318
- CARTFLOWS_VER,
319
- true
320
- );
321
- }
322
- }
323
-
324
- /**
325
- * Prepare if class 'Cartflows_Frontend' exist.
326
- * Kicking this off by calling 'get_instance()' method
327
- */
328
- 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
+ /* Enqueue global required scripts */
39
+ add_action( 'wp', array( $this, 'wp_actions' ), 55 );
40
+
41
+ /* Modify the checkout order received url to go thank you page in our flow */
42
+ add_filter( 'woocommerce_get_checkout_order_received_url', array( $this, 'redirect_to_thankyou_page' ), 10, 2 );
43
+ }
44
+
45
+ /**
46
+ * Redirect to thank page if upsell not exists
47
+ *
48
+ * @param string $order_recieve_url url.
49
+ * @param object $order order object.
50
+ * @since 1.0.0
51
+ */
52
+ function redirect_to_thankyou_page( $order_recieve_url, $order ) {
53
+
54
+ /* Only for thank you page */
55
+ wcf()->logger->log( 'Start-' . __CLASS__ . '::' . __FUNCTION__ );
56
+ wcf()->logger->log( 'Only for thank you page' );
57
+
58
+ if ( wcf()->flow->is_thankyou_page_exists( $order ) ) {
59
+
60
+ if ( _is_wcf_doing_checkout_ajax() ) {
61
+
62
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
63
+
64
+ if ( ! $checkout_id ) {
65
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
66
+ }
67
+ } else {
68
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
69
+ }
70
+
71
+ wcf()->logger->log( 'Checkout ID : ' . $checkout_id );
72
+
73
+ if ( $checkout_id ) {
74
+
75
+ $thankyou_step_id = wcf()->flow->get_thankyou_page_id( $order );
76
+
77
+ if ( $thankyou_step_id ) {
78
+
79
+ $order_recieve_url = get_permalink( $thankyou_step_id );
80
+
81
+ $order_recieve_url = add_query_arg(
82
+ array(
83
+ 'wcf-order' => $order->get_id(),
84
+ 'wcf-key' => $order->get_order_key(),
85
+ ),
86
+ $order_recieve_url
87
+ );
88
+ }
89
+ }
90
+ }
91
+
92
+ wcf()->logger->log( 'End-' . __CLASS__ . '::' . __FUNCTION__ );
93
+
94
+ return $order_recieve_url;
95
+ }
96
+
97
+ /**
98
+ * Cancel and redirect to checkout
99
+ *
100
+ * @param string $return_url url.
101
+ * @since 1.0.0
102
+ */
103
+ function redirect_to_checkout_on_cancel( $return_url ) {
104
+
105
+ if ( _is_wcf_doing_checkout_ajax() ) {
106
+
107
+ $checkout_id = wcf()->utils->get_checkout_id_from_post_data();
108
+
109
+ if ( ! $checkout_id ) {
110
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
111
+ }
112
+ } else {
113
+ $checkout_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
114
+ }
115
+
116
+ if ( $checkout_id ) {
117
+
118
+ $return_url = add_query_arg(
119
+ array(
120
+ 'cancel_order' => 'true',
121
+ '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),
122
+ ),
123
+ get_permalink( $checkout_id )
124
+ );
125
+ }
126
+
127
+ return $return_url;
128
+ }
129
+
130
+
131
+ /**
132
+ * Remove theme styles.
133
+ *
134
+ * @since 1.0.0
135
+ */
136
+ function remove_theme_styles() {
137
+
138
+ // get all styles data.
139
+ global $wp_styles;
140
+ global $wp_scripts;
141
+
142
+ $get_stylesheet = get_stylesheet();
143
+ $get_template = get_template();
144
+
145
+ if ( Cartflows_Compatibility::get_instance()->is_compatibility_theme_enabled() ) {
146
+ return;
147
+ }
148
+
149
+ $get_stylesheet = 'themes/' . get_stylesheet();
150
+ $get_template = 'themes/' . get_template();
151
+
152
+ // loop over all of the registered scripts..
153
+ foreach ( $wp_styles->registered as $handle => $data ) {
154
+
155
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
156
+
157
+ // remove it.
158
+ wp_deregister_style( $handle );
159
+ wp_dequeue_style( $handle );
160
+ }
161
+ }
162
+
163
+ // loop over all of the registered scripts.
164
+ foreach ( $wp_scripts->registered as $handle => $data ) {
165
+
166
+ if ( strpos( $data->src, $get_template ) !== false || strpos( $data->src, $get_stylesheet ) !== false ) {
167
+
168
+ // remove it.
169
+ wp_deregister_script( $handle );
170
+ wp_dequeue_script( $handle );
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Update main order data in transient.
177
+ *
178
+ * @param array $woo_styles new styles array.
179
+ * @since 1.0.0
180
+ * @return array.
181
+ */
182
+ function woo_default_css( $woo_styles ) {
183
+
184
+ $woo_styles = array(
185
+ 'woocommerce-layout' => array(
186
+ 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
187
+ 'deps' => '',
188
+ 'version' => WC_VERSION,
189
+ 'media' => 'all',
190
+ 'has_rtl' => true,
191
+ ),
192
+ 'woocommerce-smallscreen' => array(
193
+ 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
194
+ 'deps' => 'woocommerce-layout',
195
+ 'version' => WC_VERSION,
196
+ 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
197
+ 'has_rtl' => true,
198
+ ),
199
+ 'woocommerce-general' => array(
200
+ 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
201
+ 'deps' => '',
202
+ 'version' => WC_VERSION,
203
+ 'media' => 'all',
204
+ 'has_rtl' => true,
205
+ ),
206
+ );
207
+
208
+ return $woo_styles;
209
+ }
210
+
211
+ /**
212
+ * Init Actions.
213
+ *
214
+ * @since 1.0.0
215
+ */
216
+ function init_actions() {
217
+
218
+ $this->set_flow_session();
219
+ }
220
+
221
+ /**
222
+ * Set flow session.
223
+ *
224
+ * @since 1.0.0
225
+ */
226
+ function set_flow_session() {
227
+
228
+ if ( wcf()->utils->is_step_post_type() ) {
229
+
230
+ add_action( 'wp_head', array( $this, 'noindex_flow' ) );
231
+
232
+ wcf()->utils->do_not_cache();
233
+
234
+ /* Set key to support pixel */
235
+ if ( isset( $_GET['wcf-key'] ) ) {
236
+ $_GET['key'] = $_GET['wcf-key'];
237
+ $_REQUEST['key'] = $_GET['wcf-key'];
238
+ }
239
+
240
+ if ( isset( $_GET['wcf-order'] ) ) {
241
+ $_GET['order'] = $_GET['wcf-order'];
242
+ $_REQUEST['order'] = $_GET['wcf-order'];
243
+ $_GET['order-received'] = $_GET['wcf-order'];
244
+ $_REQUEST['order-received'] = $_GET['wcf-order'];
245
+ }
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Add noindex, nofollow.
251
+ *
252
+ * @since 1.0.0
253
+ */
254
+ function noindex_flow() {
255
+
256
+ $common = Cartflows_Helper::get_common_settings();
257
+
258
+ if ( 'enable' === $common['disallow_indexing'] ) {
259
+ echo '<meta name="robots" content="noindex,nofollow">';
260
+ }
261
+ }
262
+
263
+ /**
264
+ * WP Actions.
265
+ *
266
+ * @since 1.0.0
267
+ */
268
+ function wp_actions() {
269
+
270
+ if ( wcf()->utils->is_step_post_type() ) {
271
+
272
+ /* CSS Compatibility for All theme */
273
+ add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
274
+
275
+ add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
276
+
277
+ add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
278
+ }
279
+
280
+ }
281
+
282
+ /**
283
+ * Global flow scripts.
284
+ *
285
+ * @since 1.0.0
286
+ */
287
+ function global_flow_scripts() {
288
+
289
+ global $post;
290
+
291
+ $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
292
+ $current_step = $post->ID;
293
+ $next_step_link = '';
294
+ $compatibility = Cartflows_Compatibility::get_instance();
295
+
296
+ if ( _is_wcf_landing_type() ) {
297
+
298
+ $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
299
+ $next_step_link = get_permalink( $next_step_id );
300
+ }
301
+
302
+ $localize = array(
303
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
304
+ 'is_pb_preview' => $compatibility->is_page_builder_preview(),
305
+ 'current_theme' => $compatibility->get_current_theme(),
306
+ 'current_flow' => $flow,
307
+ 'current_step' => $current_step,
308
+ 'next_step' => $next_step_link,
309
+ );
310
+
311
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
312
+
313
+ wp_enqueue_style( 'wcf-frontend-global', CARTFLOWS_URL . 'assets/css/frontend.css', array(), CARTFLOWS_VER );
314
+ wp_style_add_data( 'wcf-frontend-global', 'rtl', 'replace' );
315
+
316
+ wp_enqueue_script(
317
+ 'wcf-frontend-global',
318
+ CARTFLOWS_URL . 'assets/js/frontend.js',
319
+ array( 'jquery' ),
320
+ CARTFLOWS_VER,
321
+ true
322
+ );
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Prepare if class 'Cartflows_Frontend' exist.
328
+ * Kicking this off by calling 'get_instance()' method
329
+ */
330
+ Cartflows_Frontend::get_instance();
classes/class-cartflows-helper.php CHANGED
@@ -1,301 +1,301 @@
1
- <?php
2
- /**
3
- * CARTFLOWS Helper.
4
- *
5
- * @package CARTFLOWS
6
- */
7
-
8
- if ( ! defined( 'ABSPATH' ) ) {
9
- exit; // Exit if accessed directly.
10
- }
11
-
12
- /**
13
- * Class Cartflows_Helper.
14
- */
15
- class Cartflows_Helper {
16
-
17
- /**
18
- * Common global data
19
- *
20
- * @var zapier
21
- */
22
- private static $common = null;
23
-
24
- /**
25
- * Checkout Fields
26
- *
27
- * @var checkout_fields
28
- */
29
- private static $checkout_fields = null;
30
-
31
- /**
32
- * Returns an option from the database for
33
- * the admin settings page.
34
- *
35
- * @param string $key The option key.
36
- * @param mixed $default Option default value if option is not available.
37
- * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
38
- * @return string Return the option value
39
- */
40
- public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
41
-
42
- // Get the site-wide option if we're in the network admin.
43
- if ( $network_override && is_multisite() ) {
44
- $value = get_site_option( $key, $default );
45
- } else {
46
- $value = get_option( $key, $default );
47
- }
48
-
49
- return $value;
50
- }
51
-
52
- /**
53
- * Updates an option from the admin settings page.
54
- *
55
- * @param string $key The option key.
56
- * @param mixed $value The value to update.
57
- * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
58
- * @return mixed
59
- */
60
- static public function update_admin_settings_option( $key, $value, $network = false ) {
61
-
62
- // Update the site-wide option since we're in the network admin.
63
- if ( $network && is_multisite() ) {
64
- update_site_option( $key, $value );
65
- } else {
66
- update_option( $key, $value );
67
- }
68
-
69
- }
70
-
71
- /**
72
- * Get zapier settings.
73
- *
74
- * @return array.
75
- */
76
- static public function get_common_settings() {
77
-
78
- if ( null === self::$common ) {
79
-
80
- $common_default = apply_filters(
81
- 'cartflows_common_settings_default',
82
- array(
83
- 'disallow_indexing' => 'disable',
84
- 'global_checkout' => '',
85
- )
86
- );
87
-
88
- $common = Cartflows_Helper::get_admin_settings_option( '_cartflows_common', false, true );
89
-
90
- self::$common = wp_parse_args( $common, $common_default );
91
- }
92
-
93
- return self::$common;
94
- }
95
-
96
- /**
97
- * Get Checkout field.
98
- *
99
- * @param string $key Field key.
100
- * @param int $post_id Post id.
101
- * @return array.
102
- */
103
- static public function get_checkout_fields( $key, $post_id ) {
104
-
105
- $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
106
-
107
- if ( ! $saved_fields ) {
108
- $saved_fields = array();
109
- }
110
-
111
- $fields = array_filter( $saved_fields );
112
-
113
- if ( empty( $fields ) ) {
114
- if ( 'billing' === $key || 'shipping' === $key ) {
115
-
116
- $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
117
-
118
- update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
119
- }
120
- }
121
-
122
- return $fields;
123
- }
124
-
125
- /**
126
- * Add Checkout field.
127
- *
128
- * @param string $type Field type.
129
- * @param string $field_key Field key.
130
- * @param array $field_data Field data.
131
- * @param int $post_id Post id.
132
- * @return boolean.
133
- */
134
- static public function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
135
-
136
- $fields = self::get_checkout_fields( $type, $post_id );
137
-
138
- $fields[ $field_key ] = $field_data;
139
-
140
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
141
-
142
- return true;
143
- }
144
-
145
- /**
146
- * Get checkout fields settings.
147
- *
148
- * @param string $type Field type.
149
- * @param string $field_key Field key.
150
- * @param int $post_id Post id.
151
- * @return array.
152
- */
153
- static public function delete_checkout_field( $type, $field_key, $post_id ) {
154
-
155
- $fields = self::get_checkout_fields( $type, $post_id );
156
-
157
- if ( isset( $fields[ $field_key ] ) ) {
158
- unset( $fields[ $field_key ] );
159
- }
160
-
161
- update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
162
-
163
- return true;
164
- }
165
-
166
- /**
167
- * Get checkout fields settings.
168
- *
169
- * @return array.
170
- */
171
- static public function get_checkout_fields_settings() {
172
-
173
- if ( null === self::$checkout_fields ) {
174
- $checkout_fields_default = array(
175
- 'enable_customization' => 'disable',
176
- 'enable_billing_fields' => 'disable',
177
- );
178
-
179
- $billing_fields = self::get_checkout_fields( 'billing' );
180
-
181
- if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
182
-
183
- foreach ( $billing_fields as $key => $value ) {
184
-
185
- $checkout_fields_default[ $key ] = 'enable';
186
- }
187
- }
188
-
189
- $checkout_fields = Cartflows_Helper::get_admin_settings_option( '_wcf_checkout_fields', false, true );
190
-
191
- self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
192
- }
193
-
194
- return self::$checkout_fields;
195
- }
196
-
197
- /**
198
- * Get meta options
199
- *
200
- * @since 1.0.0
201
- * @param int $post_id Product ID.
202
- * @param string $key Meta Key.
203
- * @param string $default Default value.
204
- * @return string Meta Value.
205
- */
206
- static public function get_meta_option( $post_id, $key, $default = '' ) {
207
-
208
- $value = get_post_meta( $post_id, $key, true );
209
-
210
- if ( ! $value ) {
211
- $value = $default;
212
- }
213
-
214
- return $value;
215
- }
216
-
217
- /**
218
- * Save meta option
219
- *
220
- * @since 1.0.0
221
- * @param int $post_id Product ID.
222
- * @param array $args Arguments array.
223
- */
224
- static public function save_meta_option( $post_id, $args = array() ) {
225
-
226
- if ( is_array( $args ) && ! empty( $args ) ) {
227
-
228
- foreach ( $args as $key => $value ) {
229
-
230
- update_post_meta( $post_id, $key, $value );
231
- }
232
- }
233
- }
234
-
235
- /**
236
- * Check if Elementor page builder is installed
237
- *
238
- * @since 1.0.0
239
- *
240
- * @access public
241
- */
242
- static public function _is_elementor_installed() {
243
- $path = 'elementor/elementor.php';
244
- $plugins = get_plugins();
245
-
246
- return isset( $plugins[ $path ] );
247
- }
248
-
249
- /**
250
- * Check if Step has product assigned.
251
- *
252
- * @since 1.0.0
253
- * @param int $step_id step ID.
254
- *
255
- * @access public
256
- */
257
- static public function has_product_assigned( $step_id ) {
258
-
259
- $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
260
-
261
- if ( 'checkout' == $step_type ) {
262
- $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
263
- } else {
264
- $product = get_post_meta( $step_id, 'wcf-offer-product', true );
265
- }
266
-
267
- if ( ! empty( $product ) ) {
268
- return true;
269
- }
270
- return false;
271
-
272
- }
273
-
274
- /**
275
- * Get attributes for cartflows wrap.
276
- *
277
- * @since x.x.x
278
- *
279
- * @access public
280
- */
281
- static public function get_cartflows_container_atts() {
282
-
283
- $attributes = apply_filters( 'cartflows_container_atts', array() );
284
- $atts_string = '';
285
-
286
- foreach ( $attributes as $key => $value ) {
287
-
288
- if ( ! $value ) {
289
- continue;
290
- }
291
-
292
- if ( true === $value ) {
293
- $atts_string .= esc_html( $key ) . ' ';
294
- } else {
295
- $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
296
- }
297
- }
298
-
299
- return $atts_string;
300
- }
301
- }
1
+ <?php
2
+ /**
3
+ * CARTFLOWS Helper.
4
+ *
5
+ * @package CARTFLOWS
6
+ */
7
+
8
+ if ( ! defined( 'ABSPATH' ) ) {
9
+ exit; // Exit if accessed directly.
10
+ }
11
+
12
+ /**
13
+ * Class Cartflows_Helper.
14
+ */
15
+ class Cartflows_Helper {
16
+
17
+ /**
18
+ * Common global data
19
+ *
20
+ * @var zapier
21
+ */
22
+ private static $common = null;
23
+
24
+ /**
25
+ * Checkout Fields
26
+ *
27
+ * @var checkout_fields
28
+ */
29
+ private static $checkout_fields = null;
30
+
31
+ /**
32
+ * Returns an option from the database for
33
+ * the admin settings page.
34
+ *
35
+ * @param string $key The option key.
36
+ * @param mixed $default Option default value if option is not available.
37
+ * @param boolean $network_override Whether to allow the network admin setting to be overridden on subsites.
38
+ * @return string Return the option value
39
+ */
40
+ public static function get_admin_settings_option( $key, $default = false, $network_override = false ) {
41
+
42
+ // Get the site-wide option if we're in the network admin.
43
+ if ( $network_override && is_multisite() ) {
44
+ $value = get_site_option( $key, $default );
45
+ } else {
46
+ $value = get_option( $key, $default );
47
+ }
48
+
49
+ return $value;
50
+ }
51
+
52
+ /**
53
+ * Updates an option from the admin settings page.
54
+ *
55
+ * @param string $key The option key.
56
+ * @param mixed $value The value to update.
57
+ * @param bool $network Whether to allow the network admin setting to be overridden on subsites.
58
+ * @return mixed
59
+ */
60
+ static public function update_admin_settings_option( $key, $value, $network = false ) {
61
+
62
+ // Update the site-wide option since we're in the network admin.
63
+ if ( $network && is_multisite() ) {
64
+ update_site_option( $key, $value );
65
+ } else {
66
+ update_option( $key, $value );
67
+ }
68
+
69
+ }
70
+
71
+ /**
72
+ * Get zapier settings.
73
+ *
74
+ * @return array.
75
+ */
76
+ static public function get_common_settings() {
77
+
78
+ if ( null === self::$common ) {
79
+
80
+ $common_default = apply_filters(
81
+ 'cartflows_common_settings_default',
82
+ array(
83
+ 'disallow_indexing' => 'disable',
84
+ 'global_checkout' => '',
85
+ )
86
+ );
87
+
88
+ $common = Cartflows_Helper::get_admin_settings_option( '_cartflows_common', false, true );
89
+
90
+ self::$common = wp_parse_args( $common, $common_default );
91
+ }
92
+
93
+ return self::$common;
94
+ }
95
+
96
+ /**
97
+ * Get Checkout field.
98
+ *
99
+ * @param string $key Field key.
100
+ * @param int $post_id Post id.
101
+ * @return array.
102
+ */
103
+ static public function get_checkout_fields( $key, $post_id ) {
104
+
105
+ $saved_fields = get_post_meta( $post_id, 'wcf_fields_' . $key, true );
106
+
107
+ if ( ! $saved_fields ) {
108
+ $saved_fields = array();
109
+ }
110
+
111
+ $fields = array_filter( $saved_fields );
112
+
113
+ if ( empty( $fields ) ) {
114
+ if ( 'billing' === $key || 'shipping' === $key ) {
115
+
116
+ $fields = WC()->countries->get_address_fields( WC()->countries->get_base_country(), $key . '_' );
117
+
118
+ update_post_meta( $post_id, 'wcf_fields_' . $key, $fields );
119
+ }
120
+ }
121
+
122
+ return $fields;
123
+ }
124
+
125
+ /**
126
+ * Add Checkout field.
127
+ *
128
+ * @param string $type Field type.
129
+ * @param string $field_key Field key.
130
+ * @param array $field_data Field data.
131
+ * @param int $post_id Post id.
132
+ * @return boolean.
133
+ */
134
+ static public function add_checkout_field( $type, $field_key, $field_data = array(), $post_id ) {
135
+
136
+ $fields = self::get_checkout_fields( $type, $post_id );
137
+
138
+ $fields[ $field_key ] = $field_data;
139
+
140
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
141
+
142
+ return true;
143
+ }
144
+
145
+ /**
146
+ * Get checkout fields settings.
147
+ *
148
+ * @param string $type Field type.
149
+ * @param string $field_key Field key.
150
+ * @param int $post_id Post id.
151
+ * @return array.
152
+ */
153
+ static public function delete_checkout_field( $type, $field_key, $post_id ) {
154
+
155
+ $fields = self::get_checkout_fields( $type, $post_id );
156
+
157
+ if ( isset( $fields[ $field_key ] ) ) {
158
+ unset( $fields[ $field_key ] );
159
+ }
160
+
161
+ update_post_meta( $post_id, 'wcf_fields_' . $type, $fields );
162
+
163
+ return true;
164
+ }
165
+
166
+ /**
167
+ * Get checkout fields settings.
168
+ *
169
+ * @return array.
170
+ */
171
+ static public function get_checkout_fields_settings() {
172
+
173
+ if ( null === self::$checkout_fields ) {
174
+ $checkout_fields_default = array(
175
+ 'enable_customization' => 'disable',
176
+ 'enable_billing_fields' => 'disable',
177
+ );
178
+
179
+ $billing_fields = self::get_checkout_fields( 'billing' );
180
+
181
+ if ( is_array( $billing_fields ) && ! empty( $billing_fields ) ) {
182
+
183
+ foreach ( $billing_fields as $key => $value ) {
184
+
185
+ $checkout_fields_default[ $key ] = 'enable';
186
+ }
187
+ }
188
+
189
+ $checkout_fields = Cartflows_Helper::get_admin_settings_option( '_wcf_checkout_fields', false, true );
190
+
191
+ self::$checkout_fields = wp_parse_args( $checkout_fields, $checkout_fields_default );
192
+ }
193
+
194
+ return self::$checkout_fields;
195
+ }
196
+
197
+ /**
198
+ * Get meta options
199
+ *
200
+ * @since 1.0.0
201
+ * @param int $post_id Product ID.
202
+ * @param string $key Meta Key.
203
+ * @param string $default Default value.
204
+ * @return string Meta Value.
205
+ */
206
+ static public function get_meta_option( $post_id, $key, $default = '' ) {
207
+
208
+ $value = get_post_meta( $post_id, $key, true );
209
+
210
+ if ( ! $value ) {
211
+ $value = $default;
212
+ }
213
+
214
+ return $value;
215
+ }
216
+
217
+ /**
218
+ * Save meta option
219
+ *
220
+ * @since 1.0.0
221
+ * @param int $post_id Product ID.
222
+ * @param array $args Arguments array.
223
+ */
224
+ static public function save_meta_option( $post_id, $args = array() ) {
225
+
226
+ if ( is_array( $args ) && ! empty( $args ) ) {
227
+
228
+ foreach ( $args as $key => $value ) {
229
+
230
+ update_post_meta( $post_id, $key, $value );
231
+ }
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Check if Elementor page builder is installed
237
+ *
238
+ * @since 1.0.0
239
+ *
240
+ * @access public
241
+ */
242
+ static public function _is_elementor_installed() {
243
+ $path = 'elementor/elementor.php';
244
+ $plugins = get_plugins();
245
+
246
+ return isset( $plugins[ $path ] );
247
+ }
248
+
249
+ /**
250
+ * Check if Step has product assigned.
251
+ *
252
+ * @since 1.0.0
253
+ * @param int $step_id step ID.
254
+ *
255
+ * @access public
256
+ */
257
+ static public function has_product_assigned( $step_id ) {
258
+
259
+ $step_type = get_post_meta( $step_id, 'wcf-step-type', true );
260
+
261
+ if ( 'checkout' == $step_type ) {
262
+ $product = get_post_meta( $step_id, 'wcf-checkout-products', true );
263
+ } else {
264
+ $product = get_post_meta( $step_id, 'wcf-offer-product', true );
265
+ }
266
+
267
+ if ( ! empty( $product ) ) {
268
+ return true;
269
+ }
270
+ return false;
271
+
272
+ }
273
+
274
+ /**
275
+ * Get attributes for cartflows wrap.
276
+ *
277
+ * @since x.x.x
278
+ *
279
+ * @access public
280
+ */
281
+ static public function get_cartflows_container_atts() {
282
+
283
+ $attributes = apply_filters( 'cartflows_container_atts', array() );
284
+ $atts_string = '';
285
+
286
+ foreach ( $attributes as $key => $value ) {
287
+
288
+ if ( ! $value ) {
289
+ continue;
290
+ }
291
+
292
+ if ( true === $value ) {
293
+ $atts_string .= esc_html( $key ) . ' ';
294
+ } else {
295
+ $atts_string .= sprintf( '%s="%s" ', esc_html( $key ), esc_attr( $value ) );
296
+ }
297
+ }
298
+
299
+ return $atts_string;
300
+ }
301
+ }
classes/class-cartflows-importer.php CHANGED
@@ -1,1134 +1,1429 @@
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
- * Installed Plugins
29
- *
30
- * @since 1.0.0
31
- * @access private
32
- * @var object Class object.
33
- */
34
- private static $installed_plugins = null;
35
-
36
- /**
37
- * Initiator
38
- *
39
- * @since 1.0.0
40
- * @return object initialized object of class.
41
- */
42
- public static function get_instance() {
43
- if ( ! isset( self::$instance ) ) {
44
- self::$instance = new self;
45
- }
46
-
47
- return self::$instance;
48
- }
49
-
50
- /**
51
- * Constructor
52
- *
53
- * @since 1.0.0
54
- */
55
- public function __construct() {
56
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
57
- add_action( 'wp_ajax_cartflows_load_steps', array( $this, 'load_templates' ) );
58
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
59
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
60
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
61
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
62
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
63
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
64
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
65
-
66
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
67
-
68
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
69
- }
70
-
71
- /**
72
- * Clear Cache.
73
- *
74
- * @since 1.0.0
75
- */
76
- public function clear_cache() {
77
- // Clear 'Elementor' file cache.
78
- if ( class_exists( '\Elementor\Plugin' ) ) {
79
- Elementor\Plugin::$instance->files_manager->clear_cache();
80
- }
81
- }
82
-
83
- /**
84
- * JS Templates
85
- *
86
- * @since 1.0.0
87
- *
88
- * @return void
89
- */
90
- function js_templates() {
91
-
92
- // Loading Templates.
93
- ?>
94
- <script type="text/template" id="tmpl-cartflows-step-loading">
95
- <div class="template-message-block cartflows-step-loading">
96
- <h2>
97
- <span class="spinner"></span>
98
- <?php _e( 'Loading Steps', 'cartflows' ); ?>
99
- </h2>
100
- <p class="description"><?php _e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
101
- </div>
102
- </script>
103
-
104
- <?php
105
- // Search Templates.
106
- ?>
107
- <script type="text/template" id="tmpl-cartflows-searching-templates">
108
- <div class="template-message-block cartflows-searching-templates">
109
- <h2>
110
- <span class="spinner"></span>
111
- <?php _e( 'Searching Template..', 'cartflows' ); ?>
112
- </h2>
113
- <p class="description"><?php _e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
114
- </div>
115
- </script>
116
-
117
- <?php
118
- // CartFlows Importing Template.
119
- ?>
120
- <script type="text/template" id="tmpl-cartflows-step-importing">
121
- <div class="template-message-block cartflows-step-importing">
122
- <h2><span class="spinner"></span> <?php _e( 'Importing..', 'cartflows' ); ?></h2>
123
- </div>
124
- </script>
125
-
126
- <?php
127
- // CartFlows Imported.
128
- ?>
129
- <script type="text/template" id="tmpl-cartflows-step-imported">
130
- <div class="template-message-block cartflows-step-imported">
131
- <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
132
- <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
133
- </script>
134
-
135
- <?php
136
- // No templates.
137
- ?>
138
- <script type="text/template" id="tmpl-cartflows-no-steps">
139
- <div class="cartflows-no-steps">
140
- <div class="template-message-block">
141
- <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
142
- <p class="description"></p>
143
- </div>
144
- </div>
145
- </script>
146
-
147
- <?php
148
- // No templates.
149
- ?>
150
- <script type="text/template" id="tmpl-cartflows-no-flows">
151
- <div class="cartflows-no-flows">
152
- <div class="template-message-block">
153
- <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
154
- <p class="description"></p>
155
- </div>
156
- </div>
157
- </script>
158
-
159
- <?php
160
- // Error handling.
161
- ?>
162
- <script type="text/template" id="tmpl-templator-error">
163
- <div class="notice notice-error"><p>{{ data }}</p></div>
164
- </script>
165
-
166
- <?php
167
- // Redirect to Elementor.
168
- ?>
169
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
170
- <div class="template-message-block templator-redirect-to-elementor">
171
- <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
172
- <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php _e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
173
- </script>
174
-
175
- <?php
176
- /**
177
- * Responsive Buttons
178
- */
179
- ?>
180
- <script type="text/template" id="tmpl-cartflows-responsive-view">
181
- <span class="responsive-view">
182
- <span class="actions">
183
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
184
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
185
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
186
- </span>
187
- </span>
188
- </script>
189
-
190
- <?php
191
- // Templates data.
192
- ?>
193
- <script type="text/template" id="tmpl-cartflows-flows-list">
194
-
195
- <# if ( data.items.length ) { #>
196
- <# for ( key in data.items ) { #>
197
- <#
198
- var flow_steps = [];
199
- if( data.items[ key ].flow_steps ) {
200
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
201
- return value['id'];
202
- });
203
- }
204
- #>
205
- <# console.log( 'here ' + key ); #>
206
- <div class="inner">
207
- <div class="template">
208
- <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 }}">
209
- <div class="template-screenshot">
210
- <# if( data.items[ key ].featured_image_url ) { #>
211
- <img src="{{ data.items[ key ].featured_image_url }}" />
212
- <# } else { #>
213
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
214
- <# } #>
215
- </div>
216
- <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>
217
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
218
- <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
219
- <# } #>
220
- </span>
221
- <div class="template-id-container">
222
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
223
- <div class="template-actions">
224
-
225
- <#
226
- if( data.items[ key ].page_builder.slug ) {
227
- required_plugin_group = data.items[ key ].page_builder.slug;
228
- } else {
229
- required_plugin_group = '';
230
- }
231
-
232
- 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 ) {
233
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
234
- } else {
235
- import_btn_title = 'Import';
236
- } #>
237
-
238
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
239
- <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>
240
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
241
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
242
- <# } else { #>
243
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
244
- <# } #>
245
- </div>
246
- </div>
247
- </div>
248
- </div>
249
- <# } #>
250
- <# } #>
251
- </script>
252
-
253
- <?php
254
- // Empty Step.
255
- ?>
256
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
257
- <div class="inner">
258
- <div class="template">
259
- <span class="thumbnail site-preview cartflows-flow-preview">
260
- <div class="template-screenshot">
261
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
262
- </div>
263
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
264
- </span>
265
- <div class="template-id-container">
266
- <h3 class="template-name"> Blank </h3>
267
- <div class="template-actions">
268
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
269
- </div>
270
- </div>
271
- </div>
272
- </div>
273
- </script>
274
-
275
- <?php
276
- // Templates data.
277
- ?>
278
- <script type="text/template" id="tmpl-cartflows-steps-list">
279
- <# if ( data.items.length ) { #>
280
- <# for ( key in data.items ) { #>
281
- <#
282
- var flow_steps = [];
283
- if( data.items[ key ].flow_steps ) {
284
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
285
- return value['id'];
286
- });
287
- }
288
- #>
289
- <div class="inner">
290
- <div class="template">
291
- <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 }}">
292
- <div class="template-screenshot">
293
- <# if( data.items[ key ].featured_image_url ) { #>
294
- <img src="{{ data.items[ key ].featured_image_url }}" />
295
- <# } else { #>
296
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
297
- <# } #>
298
- </div>
299
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
300
- <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>
301
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
302
- <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
303
- <# } #>
304
- </span>
305
- <div class="template-id-container">
306
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
307
- <div class="template-actions">
308
-
309
- <#
310
-
311
- var required_plugin_group = data.items[ key ].page_builder.slug || '';
312
- var step_slug = data.items[ key ].step_type.slug || '';
313
- var step_title = data.items[ key ].step_type.name || '';
314
-
315
- 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 ) {
316
- import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
317
- } else {
318
- import_btn_title = 'Import';
319
- } #>
320
-
321
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
322
- <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>
323
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
324
- <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
325
- <# } else { #>
326
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
327
- <# } #>
328
- </div>
329
- </div>
330
- </div>
331
- </div>
332
- <# } #>
333
- <# } #>
334
- </script>
335
-
336
- <?php
337
- /**
338
- * TMPL - Filters
339
- */
340
- ?>
341
- <script type="text/template" id="tmpl-cartflows-term-filters">
342
-
343
- <# if ( data ) { #>
344
-
345
- <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #>
346
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
347
-
348
- <# if ( data.args.show_all ) { #>
349
- <li>
350
- <a href="#" data-group="all"> All </a>
351
- </li>
352
- <# } #>
353
-
354
- <# for ( key in data.items ) { #>
355
- <li>
356
- <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>
357
- </li>
358
- <# } #>
359
-
360
- </ul>
361
-
362
- <# } else { #>
363
- <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
364
-
365
- <# if ( data.args.show_all ) { #>
366
- <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
367
- <# } #>
368
-
369
- <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
370
- <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
371
- <# } #>
372
-
373
- <# for ( key in data.items ) { #>
374
- <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>
375
- <# } #>
376
-
377
- </select>
378
- <# } #>
379
-
380
- <# } #>
381
- </script>
382
-
383
- <?php
384
- // Step Type.
385
- ?>
386
- <script type="text/template" id="tmpl-cartflows-step-types">
387
- <ul class="wcf-tab nav-tabs">
388
- <# if( data.items_count ) { #>
389
- <# for( key in data.items ) { #>
390
- <# console.log( data.items[ key ].id ) #>
391
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
392
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
393
- </li>
394
- <# } #>
395
- <# } #>
396
- </ul>
397
- </script>
398
-
399
- <?php
400
- // Add to library button.
401
- ?>
402
- <script type="text/template" id="tmpl-templator-add-to-library">
403
- <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>
404
- </script>
405
- <?php
406
- }
407
-
408
- /**
409
- * Get plugin button string.
410
- *
411
- * @param string $plugin_init_file Plguin init file.
412
- * @param string $plugin_title Plguin title.
413
- * @return string
414
- */
415
- function get_plugin_button_string( $plugin_init_file, $plugin_title ) {
416
-
417
- if ( null == self::$installed_plugins ) {
418
- self::$installed_plugins = get_plugins();
419
- }
420
-
421
- if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
422
- /* translators: %s is plugin name. */
423
- return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
424
- } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
425
- /* translators: %s is plugin name. */
426
- return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
427
- }
428
-
429
- return __( 'Import', 'cartflows' );
430
- }
431
-
432
- /**
433
- * Get plugin status
434
- *
435
- * @param string $plugin_init_file Plguin init file.
436
- * @return mixed
437
- */
438
- function get_plugin_status( $plugin_init_file ) {
439
-
440
- if ( null == self::$installed_plugins ) {
441
- self::$installed_plugins = get_plugins();
442
- }
443
-
444
- if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
445
- return 'install';
446
- } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
447
- return 'activate';
448
- }
449
-
450
- return;
451
- }
452
-
453
- /**
454
- * Enqueue scripts
455
- *
456
- * @since 1.0.0
457
- *
458
- * @hook admin_enqueue_scripts
459
- * @param string $hook Current page hook.
460
- */
461
- function scripts( $hook = '' ) {
462
-
463
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
464
- return;
465
- }
466
-
467
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
468
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
469
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
470
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
471
-
472
- $localize_vars = array(
473
- '_is_pro_active' => _is_cartflows_pro(),
474
-
475
- // Flow and its rest fields.
476
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
477
- 'flow_fields' => array(
478
- 'id',
479
- 'title',
480
- 'flow_type',
481
- 'page_builder',
482
- 'flow_steps',
483
- 'licence_status',
484
- 'featured_image_url',
485
- 'featured_media', // @required for field `featured_image_url`.
486
- ),
487
-
488
- // Flow type and rest fields.
489
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
490
- 'flow_type_fields' => array(
491
- 'id',
492
- 'name',
493
- 'slug',
494
- ),
495
-
496
- // Flow page builder and rest fields.
497
- 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
498
- 'flow_page_builder_fields' => array(
499
- 'id',
500
- 'name',
501
- 'slug',
502
- ),
503
-
504
- // Step page builder and rest fields.
505
- 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
506
- 'step_page_builder_fields' => array(
507
- 'id',
508
- 'name',
509
- 'slug',
510
- ),
511
-
512
- // Step and its rest fields.
513
- 'step' => CARTFLOWS_STEP_POST_TYPE,
514
- 'step_fields' => array(
515
- 'title',
516
- 'featured_image_url',
517
- 'featured_media', // @required for field `featured_image_url`.
518
- 'id',
519
- 'flow_type',
520
- 'step_type',
521
- 'page_builder',
522
- 'licence_status',
523
- ),
524
-
525
- // Step type and its rest fields.
526
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
527
- 'step_type_fields' => array(
528
- 'id',
529
- 'name',
530
- 'slug',
531
- ),
532
-
533
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
534
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
535
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
536
- 'site_url' => site_url(),
537
- 'admin_url' => admin_url(),
538
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
539
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
540
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
541
-
542
- 'required_plugins' => array(
543
- 'elementor' => array(
544
- 'button_title' => $this->get_plugin_button_string( 'elementor/elementor.php', 'Elementor' ),
545
- 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
546
- 'plugins' => array(
547
- array(
548
- 'slug' => 'elementor', // For download from wp.org.
549
- 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
550
- ),
551
- ),
552
- ),
553
- ),
554
- );
555
-
556
- // Add thickbox.
557
- add_thickbox();
558
-
559
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
560
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
561
- }
562
-
563
- /**
564
- * Load Template
565
- *
566
- * @since 1.0.0
567
- *
568
- * @hook cartflows_load_steps
569
- * @return void
570
- */
571
- function load_templates() {
572
-
573
- check_ajax_referer( 'cf-load-steps', 'security' );
574
-
575
- $args = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
576
- $templates = CartFlows_API::get_instance()->get_templates( $args );
577
-
578
- if ( $templates['templates_count'] ) {
579
- wp_send_json_success( $templates );
580
- } else {
581
- wp_send_json_error( $templates );
582
- }
583
- wp_die();
584
- }
585
-
586
- /**
587
- * Import.
588
- *
589
- * @since 1.0.0
590
- *
591
- * @hook wp_ajax_cartflows_import_flow_step
592
- * @return void
593
- */
594
- function import_flow() {
595
-
596
- check_ajax_referer( 'cf-import-flow-step', 'security' );
597
-
598
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
599
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
600
-
601
- wcf()->logger->import_log( '------------------------------------' );
602
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
603
- wcf()->logger->import_log( '------------------------------------' );
604
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
605
-
606
- $response = CartFlows_API::get_instance()->get_template( $template_id );
607
-
608
- if ( false === $response['success'] ) {
609
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
610
- wp_send_json_error( $response );
611
- }
612
-
613
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );
614
-
615
- $new_step_id = wp_insert_post(
616
- array(
617
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
618
- 'post_title' => $response['title'],
619
- 'post_content' => '',
620
- 'post_status' => 'publish',
621
- )
622
- );
623
-
624
- if ( is_wp_error( $new_step_id ) ) {
625
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
626
- wp_send_json_error( $new_step_id );
627
- }
628
-
629
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
630
- // insert post meta.
631
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
632
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
633
-
634
- /**
635
- * Import & Set type.
636
- */
637
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
638
- $term_slug = '';
639
- if ( $term ) {
640
-
641
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
642
- $term_exist = term_exists( $term->name, $taxonomy );
643
-
644
- if ( empty( $term_exist ) ) {
645
- $terms = array(
646
- array(
647
- 'name' => $term->name,
648
- ),
649
- );
650
-
651
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
652
- wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
653
- }
654
-
655
- $current_term = term_exists( $term->name, $taxonomy );
656
-
657
- // Set type object.
658
- $data = get_term( $current_term['term_id'], $taxonomy );
659
- $term_slug = $data->slug;
660
- $term_name = $data->name;
661
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
662
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
663
-
664
- // Set type.
665
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
666
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
667
- }
668
-
669
- // Set flow.
670
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
671
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
672
-
673
- /**
674
- * Update steps for the current flow.
675
- */
676
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
677
-
678
- if ( ! is_array( $flow_steps ) ) {
679
- $flow_steps = array();
680
- }
681
-
682
- $flow_steps[] = array(
683
- 'id' => $new_step_id,
684
- 'title' => $response['title'],
685
- 'type' => $term_slug,
686
- );
687
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
688
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
689
-
690
- // Import Post Meta.
691
- self::import_post_meta( $new_step_id, $response );
692
-
693
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
694
- wcf()->logger->import_log( '------------------------------------' );
695
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
696
- wcf()->logger->import_log( '------------------------------------' );
697
-
698
- do_action( 'cartflows_import_complete' );
699
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
700
-
701
- // Batch Process.
702
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
703
-
704
- /**
705
- * End
706
- */
707
- wp_send_json_success( $new_step_id );
708
- }
709
-
710
- /**
711
- * Import Step.
712
- *
713
- * @since 1.0.0
714
- * @hook wp_ajax_cartflows_step_import
715
- *
716
- * @return void
717
- */
718
- function create_default_flow() {
719
-
720
- check_ajax_referer( 'cf-default-flow', 'security' );
721
-
722
- // Create post object.
723
- $new_flow_post = array(
724
- 'post_content' => '',
725
- 'post_status' => 'publish',
726
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
727
- );
728
-
729
- // Insert the post into the database.
730
- $flow_id = wp_insert_post( $new_flow_post );
731
-
732
- if ( is_wp_error( $flow_id ) ) {
733
- wp_send_json_error( $flow_id->get_error_message() );
734
- }
735
-
736
- $flow_steps = array();
737
-
738
- $steps_data = array(
739
- 'landing' => __( 'Landing Page', 'cartflows' ),
740
- 'checkout' => __( 'Checkout Page', 'cartflows' ),
741
- 'thankyou' => __( 'Thank You Page', 'cartflows' ),
742
- );
743
-
744
- foreach ( $steps_data as $slug => $title ) {
745
-
746
- $post_content = '';
747
-
748
- switch ( $slug ) {
749
- case 'checkout':
750
- $post_content = '';
751
- break;
752
- case 'thankyou':
753
- $post_content = '';
754
- break;
755
- default:
756
- $post_content = '';
757
- break;
758
- }
759
-
760
- $step_id = wp_insert_post(
761
- array(
762
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
763
- 'post_title' => $title,
764
- 'post_content' => $post_content,
765
- 'post_status' => 'publish',
766
- )
767
- );
768
-
769
- if ( is_wp_error( $step_id ) ) {
770
- wp_send_json_error( $step_id->get_error_message() );
771
- }
772
-
773
- if ( $step_id ) {
774
-
775
- $flow_steps[] = array(
776
- 'id' => $step_id,
777
- 'title' => $title,
778
- 'type' => $slug,
779
- );
780
-
781
- // insert post meta.
782
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
783
- update_post_meta( $step_id, 'wcf-step-type', $slug );
784
-
785
- wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
786
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
787
- }
788
- }
789
-
790
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
791
-
792
- wp_send_json_success( $flow_id );
793
- }
794
-
795
- /**
796
- * Create Flow
797
- *
798
- * @return void
799
- */
800
- function create_flow() {
801
-
802
- check_ajax_referer( 'cf-create-flow', 'security' );
803
-
804
- // Create post object.
805
- $new_flow_post = array(
806
- 'post_content' => '',
807
- 'post_status' => 'publish',
808
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
809
- );
810
-
811
- // Insert the post into the database.
812
- $flow_id = wp_insert_post( $new_flow_post );
813
-
814
- if ( is_wp_error( $flow_id ) ) {
815
- wp_send_json_error( $flow_id->get_error_message() );
816
- }
817
-
818
- wp_send_json_success( $flow_id );
819
- }
820
-
821
- /**
822
- * Create Step
823
- *
824
- * @return void
825
- */
826
- function import_step() {
827
-
828
- check_ajax_referer( 'cf-step-import', 'security' );
829
-
830
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
831
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
832
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
833
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
834
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;
835
-
836
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
837
-
838
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
839
-
840
- wcf()->logger->import_log( '------------------------------------' );
841
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
842
- wcf()->logger->import_log( '------------------------------------' );
843
-
844
- if ( empty( $template_id ) || empty( $post_id ) ) {
845
- /* translators: %s: template ID */
846
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
847
- wcf()->logger->import_log( $data );
848
- wp_send_json_error( $data );
849
- }
850
-
851
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
852
-
853
- $response = CartFlows_API::get_instance()->get_template( $template_id );
854
-
855
- wcf()->logger->import_log( json_encode( $response ) );
856
-
857
- // Import Post Meta.
858
- self::import_post_meta( $post_id, $response );
859
-
860
- do_action( 'cartflows_import_complete' );
861
-
862
- // Batch Process.
863
- do_action( 'cartflows_after_template_import', $post_id, $response );
864
-
865
- wcf()->logger->import_log( '------------------------------------' );
866
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
867
- wcf()->logger->import_log( '------------------------------------' );
868
-
869
- wp_send_json_success( $post_id );
870
- }
871
-
872
- /**
873
- * Import Step.
874
- *
875
- * @since 1.0.0
876
- * @hook wp_ajax_cartflows_step_create_blank
877
- *
878
- * @return void
879
- */
880
- function step_create_blank() {
881
-
882
- check_ajax_referer( 'cf-step-create-blank', 'security' );
883
-
884
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
885
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
886
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
887
-
888
- if ( empty( $flow_id ) || empty( $step_type ) ) {
889
- /* translators: %s: flow ID */
890
- $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
891
- wcf()->logger->import_log( $data );
892
- wp_send_json_error( $data );
893
- }
894
-
895
- wcf()->logger->import_log( '------------------------------------' );
896
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
897
-
898
- $step_type_title = str_replace( '-', ' ', $step_type );
899
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
900
-
901
- $new_step_id = wp_insert_post(
902
- array(
903
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
904
- 'post_title' => $step_title,
905
- 'post_content' => '',
906
- 'post_status' => 'publish',
907
- )
908
- );
909
-
910
- // insert post meta.
911
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
912
-
913
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
914
- $term_exist = term_exists( $step_type_title, $taxonomy );
915
-
916
- if ( empty( $term_exist ) ) {
917
- $terms = array(
918
- array(
919
- 'name' => $step_type_title,
920
- ),
921
- );
922
-
923
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
924
- wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
925
- }
926
-
927
- $current_term = term_exists( $step_type_title, $taxonomy );
928
-
929
- // Set type object.
930
- $data = get_term( $current_term['term_id'], $taxonomy );
931
- $step_slug = $data->slug;
932
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
933
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
934
-
935
- // Set type.
936
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
937
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
938
-
939
- // Set flow.
940
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
941
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
942
-
943
- CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
944
-
945
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
946
- wcf()->logger->import_log( '------------------------------------' );
947
-
948
- wp_send_json_success( $new_step_id );
949
- }
950
-
951
- /**
952
- * Import Post Meta
953
- *
954
- * @since 1.0.0
955
- *
956
- * @param integer $post_id Post ID.
957
- * @param array $response Post meta.
958
- * @return void
959
- */
960
- public static function import_post_meta( $post_id, $response ) {
961
-
962
- $metadata = (array) $response['post_meta'];
963
-
964
- foreach ( $metadata as $meta_key => $meta_value ) {
965
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
966
-
967
- if ( $meta_value ) {
968
-
969
- if ( is_serialized( $meta_value, true ) ) {
970
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
971
- } elseif ( is_array( $meta_value ) ) {
972
- $raw_data = json_decode( stripslashes( $meta_value ), true );
973
- } else {
974
- $raw_data = $meta_value;
975
- }
976
-
977
- if ( '_elementor_data' === $meta_key ) {
978
- if ( is_array( $raw_data ) ) {
979
- $raw_data = wp_slash( json_encode( $raw_data ) );
980
- } else {
981
- $raw_data = wp_slash( $raw_data );
982
- }
983
- wcf()->logger->import_log( $raw_data );
984
- }
985
-
986
- if ( is_array( $raw_data ) ) {
987
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
988
- } else {
989
-
990
- if ( ! is_object( $raw_data ) ) {
991
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
992
- }
993
- }
994
-
995
- update_post_meta( $post_id, $meta_key, $raw_data );
996
- }
997
- }
998
- }
999
-
1000
- /**
1001
- * Import Template for Elementor
1002
- *
1003
- * @since 1.0.0
1004
- *
1005
- * @param integer $post_id Post ID.
1006
- * @param array $response Post meta.
1007
- * @param array $page_build_data Page build data.
1008
- * @return void
1009
- */
1010
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1011
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1012
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1013
- wcf()->logger->import_log( $data );
1014
- wp_send_json_error( $data );
1015
- }
1016
-
1017
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1018
-
1019
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1020
-
1021
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1022
- $obj->import_single_template( $post_id );
1023
-
1024
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1025
- }
1026
-
1027
- /**
1028
- * Supported post types
1029
- *
1030
- * @since 1.0.0
1031
- *
1032
- * @return array Supported post types.
1033
- */
1034
- public static function supported_post_types() {
1035
- return apply_filters(
1036
- 'cartflows_supported_post_types',
1037
- array(
1038
- CARTFLOWS_FLOW_POST_TYPE,
1039
- )
1040
- );
1041
- }
1042
-
1043
- /**
1044
- * Check supported post type
1045
- *
1046
- * @since 1.0.0
1047
- *
1048
- * @param string $post_type Post type.
1049
- * @return boolean Supported post type status.
1050
- */
1051
- public static function is_supported_post( $post_type = '' ) {
1052
- if ( in_array( $post_type, self::supported_post_types() ) ) {
1053
- return true;
1054
- }
1055
-
1056
- return false;
1057
- }
1058
-
1059
- /**
1060
- * Set steps to the flow
1061
- *
1062
- * @param integer $flow_id Flow ID.
1063
- * @param integer $new_step_id New step ID.
1064
- * @param string $step_title Flow Type.
1065
- * @param string $step_slug Flow Type.
1066
- */
1067
- function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1068
- // Update steps for the current flow.
1069
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1070
-
1071
- if ( ! is_array( $flow_steps ) ) {
1072
- $flow_steps = array();
1073
- }
1074
-
1075
- $flow_steps[] = array(
1076
- 'id' => $new_step_id,
1077
- 'title' => $step_title,
1078
- 'type' => $step_slug,
1079
- );
1080
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1081
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
1082
- }
1083
-
1084
- /**
1085
- * Localize variables in admin
1086
- *
1087
- * @param array $vars variables.
1088
- */
1089
- function localize_vars( $vars ) {
1090
-
1091
- $ajax_actions = array(
1092
- 'cf_step_import',
1093
- 'cf_load_steps',
1094
- 'cf_create_flow',
1095
- 'cf_default_flow',
1096
- 'cf_step_create_blank',
1097
- 'cf_import_flow_step',
1098
- );
1099
-
1100
- foreach ( $ajax_actions as $action ) {
1101
-
1102
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1103
- }
1104
-
1105
- return $vars;
1106
- }
1107
-
1108
- /**
1109
- * Ajax action to activate plugin
1110
- */
1111
- public function activate_plugin() {
1112
-
1113
- $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';
1114
-
1115
- if ( ! is_plugin_active( $plugin_slug ) ) {
1116
-
1117
- $activate = activate_plugin( $plugin_slug, '', false, true );
1118
-
1119
- if ( is_wp_error( $activate ) ) {
1120
- wp_send_json_error();
1121
- }
1122
- }
1123
-
1124
- wp_send_json_success();
1125
- }
1126
-
1127
- }
1128
-
1129
- /**
1130
- * Initialize class object with 'get_instance()' method
1131
- */
1132
- CartFlows_Importer::get_instance();
1133
-
1134
- 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
+ * Installed Plugins
29
+ *
30
+ * @since 1.0.0
31
+ * @access private
32
+ * @var object Class object.
33
+ */
34
+ private static $installed_plugins = null;
35
+
36
+ /**
37
+ * Initiator
38
+ *
39
+ * @since 1.0.0
40
+ * @return object initialized object of class.
41
+ */
42
+ public static function get_instance() {
43
+ if ( ! isset( self::$instance ) ) {
44
+ self::$instance = new self;
45
+ }
46
+
47
+ return self::$instance;
48
+ }
49
+
50
+ /**
51
+ * Constructor
52
+ *
53
+ * @since 1.0.0
54
+ */
55
+ public function __construct() {
56
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
57
+ add_action( 'wp_ajax_cartflows_load_steps', array( $this, 'load_templates' ) );
58
+ add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
59
+ add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
60
+ add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
61
+ add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
62
+ add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
63
+ add_action( 'admin_footer', array( $this, 'js_templates' ) );
64
+ add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
65
+
66
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
67
+
68
+ add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
69
+
70
+ add_action( 'admin_menu', array( $this, 'add_to_menus' ) );
71
+ add_action( 'admin_init', array( $this, 'export' ) );
72
+ add_action( 'admin_init', array( $this, 'import' ) );
73
+ add_filter( 'post_row_actions', array( $this, 'export_link' ), 10, 2 );
74
+ add_action( 'admin_action_cartflows_export_flow', array( $this, 'export_flow' ) );
75
+ }
76
+
77
+ /**
78
+ * Add the export link to action list for flows row actions
79
+ *
80
+ * @since x.x.x
81
+ *
82
+ * @param array $actions Actions array.
83
+ * @param object $post Post object.
84
+ *
85
+ * @return array
86
+ */
87
+ function export_link( $actions, $post ) {
88
+ if ( current_user_can( 'edit_posts' ) && isset( $post ) && CARTFLOWS_FLOW_POST_TYPE === $post->post_type ) {
89
+ $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>';
90
+ }
91
+ return $actions;
92
+ }
93
+
94
+ /**
95
+ * Add menus
96
+ *
97
+ * @since x.x.x
98
+ */
99
+ function add_to_menus() {
100
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Export', 'cartflows' ), __( 'Flow Export', 'cartflows' ), 'export', 'flow_exporter', array( $this, 'exporter_markup' ) );
101
+ add_submenu_page( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE, __( 'Flow Import', 'cartflows' ), __( 'Flow Import', 'cartflows' ), 'import', 'flow_importer', array( $this, 'importer_markup' ) );
102
+ }
103
+
104
+ /**
105
+ * Export flow with steps and its meta
106
+ *
107
+ * @since x.x.x
108
+ */
109
+ function export_flow() {
110
+
111
+ if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'cartflows_export_flow' == $_REQUEST['action'] ) ) ) {
112
+ wp_die( __( 'No post to export has been supplied!', 'cartflows' ) );
113
+ }
114
+
115
+ if ( ! isset( $_GET['flow_export_nonce'] ) || ! wp_verify_nonce( $_GET['flow_export_nonce'], basename( __FILE__ ) ) ) {
116
+ return;
117
+ }
118
+
119
+ // Get the original post id.
120
+ $flow_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );
121
+
122
+ $flows = array();
123
+ $flows[] = $this->get_flow_export_data( $flow_id );
124
+ $flows = apply_filters( 'cartflows_export_data', $flows );
125
+
126
+ nocache_headers();
127
+ header( 'Content-Type: application/json; charset=utf-8' );
128
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . date( 'm-d-Y' ) . '.json' );
129
+ header( 'Expires: 0' );
130
+
131
+ echo json_encode( $flows );
132
+ exit;
133
+ }
134
+
135
+ /**
136
+ * Export flow markup
137
+ *
138
+ * @since x.x.x
139
+ */
140
+ function exporter_markup() {
141
+ include_once CARTFLOWS_DIR . 'includes/exporter.php';
142
+ }
143
+
144
+ /**
145
+ * Import flow markup
146
+ *
147
+ * @since x.x.x
148
+ */
149
+ function importer_markup() {
150
+ include_once CARTFLOWS_DIR . 'includes/importer.php';
151
+ }
152
+
153
+ /**
154
+ * Export flow
155
+ *
156
+ * @since x.x.x
157
+ */
158
+ function export() {
159
+ if ( empty( $_POST['cartflows-action'] ) || 'export' != $_POST['cartflows-action'] ) {
160
+ return;
161
+ }
162
+
163
+ if ( ! wp_verify_nonce( $_POST['cartflows-action-nonce'], 'cartflows-action-nonce' ) ) {
164
+ return;
165
+ }
166
+
167
+ if ( ! current_user_can( 'manage_options' ) ) {
168
+ return;
169
+ }
170
+
171
+ $flows = $this->get_all_flow_export_data();
172
+ $flows = apply_filters( 'cartflows_export_data', $flows );
173
+
174
+ nocache_headers();
175
+ header( 'Content-Type: application/json; charset=utf-8' );
176
+ header( 'Content-Disposition: attachment; filename=cartflows-flow-export-' . date( 'm-d-Y' ) . '.json' );
177
+ header( 'Expires: 0' );
178
+
179
+ echo json_encode( $flows );
180
+ exit;
181
+ }
182
+
183
+ /**
184
+ * Get flow export data
185
+ *
186
+ * @since x.x.x
187
+ *
188
+ * @param integer $flow_id Flow ID.
189
+ * @return array
190
+ */
191
+ function get_flow_export_data( $flow_id ) {
192
+
193
+ $valid_step_meta_keys = array(
194
+ '_wp_page_template',
195
+ '_thumbnail_id',
196
+ 'classic-editor-remember',
197
+ );
198
+
199
+ $new_steps = array();
200
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
201
+ if ( $steps ) {
202
+ foreach ( $steps as $key => $step ) {
203
+
204
+ // Add step post meta.
205
+ $new_all_meta = array();
206
+ $all_meta = get_post_meta( $step['id'] );
207
+ if ( is_array( $all_meta ) ) {
208
+ foreach ( $all_meta as $meta_key => $value ) {
209
+ if ( substr( $meta_key, 0, strlen( 'wcf' ) ) === 'wcf' ) {
210
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
211
+ } elseif ( in_array( $meta_key, $valid_step_meta_keys ) ) {
212
+ $new_all_meta[ $meta_key ] = maybe_unserialize( $value[0] );
213
+ }
214
+ }
215
+ }
216
+
217
+ // Add single step.
218
+ $new_steps[] = array(
219
+ 'title' => get_the_title( $step['id'] ),
220
+ 'type' => $step['type'],
221
+ 'meta' => $new_all_meta,
222
+ );
223
+ }
224
+ }
225
+
226
+ // Add single flow.
227
+ return array(
228
+ 'title' => get_the_title( $flow_id ),
229
+ 'steps' => $new_steps,
230
+ );
231
+ }
232
+
233
+ /**
234
+ * Get all flow export data
235
+ *
236
+ * @since x.x.x
237
+ */
238
+ function get_all_flow_export_data() {
239
+
240
+ $query_args = array(
241
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
242
+
243
+ // Query performance optimization.
244
+ 'fields' => 'ids',
245
+ 'no_found_rows' => true,
246
+ 'posts_per_page' => -1,
247
+ );
248
+
249
+ $query = new WP_Query( $query_args );
250
+ $flows = array();
251
+ if ( $query->posts ) {
252
+ foreach ( $query->posts as $key => $post_id ) {
253
+ $flows[] = $this->get_flow_export_data( $post_id );
254
+ }
255
+ }
256
+
257
+ return $flows;
258
+ }
259
+
260
+ /**
261
+ * Import our exported file
262
+ *
263
+ * @since x.x.x
264
+ */
265
+ function import() {
266
+ if ( empty( $_POST['cartflows-action'] ) || 'import' != $_POST['cartflows-action'] ) {
267
+ return;
268
+ }
269
+
270
+ if ( ! wp_verify_nonce( $_POST['cartflows-action-nonce'], 'cartflows-action-nonce' ) ) {
271
+ return;
272
+ }
273
+
274
+ if ( ! current_user_can( 'manage_options' ) ) {
275
+ return;
276
+ }
277
+
278
+ $filename = $_FILES['file']['name'];
279
+ $file_info = explode( '.', $filename );
280
+ $extension = end( $file_info );
281
+
282
+ if ( 'json' != $extension ) {
283
+ wp_die( __( 'Please upload a valid .json file', 'cartflows' ) );
284
+ }
285
+
286
+ $file = $_FILES['file']['tmp_name'];
287
+
288
+ if ( empty( $file ) ) {
289
+ wp_die( __( 'Please upload a file to import', 'cartflows' ) );
290
+ }
291
+
292
+ // Retrieve the settings from the file and convert the JSON object to an array.
293
+ $flows = json_decode( file_get_contents( $file ), true );
294
+
295
+ if ( $flows ) {
296
+
297
+ foreach ( $flows as $key => $flow ) {
298
+
299
+ $flow_title = $flow['title'];
300
+ if ( post_exists( $flow['title'] ) ) {
301
+ $flow_title = $flow['title'] . ' Copy';
302
+ }
303
+
304
+ // Create post object.
305
+ $new_flow_args = array(
306
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
307
+ 'post_title' => $flow_title,
308
+ 'post_status' => 'draft',
309
+ );
310
+
311
+ // Insert the post into the database.
312
+ $flow_id = wp_insert_post( $new_flow_args );
313
+
314
+ if ( $flow['steps'] ) {
315
+ foreach ( $flow['steps'] as $key => $step ) {
316
+ $new_step_id = wp_insert_post(
317
+ array(
318
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
319
+ 'post_title' => $step['title'],
320
+ 'post_status' => 'draft',
321
+ 'meta_input' => $step['meta'],
322
+ )
323
+ );
324
+
325
+ // Insert post meta.
326
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
327
+
328
+ $step_taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
329
+ $current_term = term_exists( $step['type'], $step_taxonomy );
330
+
331
+ // // Set type object.
332
+ $data = get_term( $current_term['term_id'], $step_taxonomy );
333
+ $step_slug = $data->slug;
334
+ wp_set_object_terms( $new_step_id, $data->slug, $step_taxonomy );
335
+
336
+ // Set type.
337
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
338
+
339
+ // Set flow.
340
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
341
+
342
+ CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step['title'], $step_slug );
343
+ }
344
+ }
345
+ }
346
+ }
347
+
348
+ add_action( 'admin_notices', array( $this, 'imported_successfully' ) );
349
+ }
350
+
351
+ /**
352
+ * Imported notice
353
+ *
354
+ * @since x.x.x
355
+ */
356
+ function imported_successfully() {
357
+ ?>
358
+ <div class="notice notice-success">
359
+ <p><?php _e( 'Successfully imported flows.', 'cartflows' ); ?></p>
360
+ </div>
361
+ <?php
362
+ }
363
+
364
+ /**
365
+ * Clear Cache.
366
+ *
367
+ * @since 1.0.0
368
+ */
369
+ public function clear_cache() {
370
+ // Clear 'Elementor' file cache.
371
+ if ( class_exists( '\Elementor\Plugin' ) ) {
372
+ Elementor\Plugin::$instance->files_manager->clear_cache();
373
+ }
374
+ }
375
+
376
+ /**
377
+ * JS Templates
378
+ *
379
+ * @since 1.0.0
380
+ *
381
+ * @return void
382
+ */
383
+ function js_templates() {
384
+
385
+ // Loading Templates.
386
+ ?>
387
+ <script type="text/template" id="tmpl-cartflows-step-loading">
388
+ <div class="template-message-block cartflows-step-loading">
389
+ <h2>
390
+ <span class="spinner"></span>
391
+ <?php _e( 'Loading Steps', 'cartflows' ); ?>
392
+ </h2>
393
+ <p class="description"><?php _e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
394
+ </div>
395
+ </script>
396
+
397
+ <?php
398
+ // Search Templates.
399
+ ?>
400
+ <script type="text/template" id="tmpl-cartflows-searching-templates">
401
+ <div class="template-message-block cartflows-searching-templates">
402
+ <h2>
403
+ <span class="spinner"></span>
404
+ <?php _e( 'Searching Template..', 'cartflows' ); ?>
405
+ </h2>
406
+ <p class="description"><?php _e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
407
+ </div>
408
+ </script>
409
+
410
+ <?php
411
+ // CartFlows Importing Template.
412
+ ?>
413
+ <script type="text/template" id="tmpl-cartflows-step-importing">
414
+ <div class="template-message-block cartflows-step-importing">
415
+ <h2><span class="spinner"></span> <?php _e( 'Importing..', 'cartflows' ); ?></h2>
416
+ </div>
417
+ </script>
418
+
419
+ <?php
420
+ // CartFlows Imported.
421
+ ?>
422
+ <script type="text/template" id="tmpl-cartflows-step-imported">
423
+ <div class="template-message-block cartflows-step-imported">
424
+ <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
425
+ <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
426
+ </script>
427
+
428
+ <?php
429
+ // No templates.
430
+ ?>
431
+ <script type="text/template" id="tmpl-cartflows-no-steps">
432
+ <div class="cartflows-no-steps">
433
+ <div class="template-message-block">
434
+ <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
435
+ <p class="description"></p>
436
+ </div>
437
+ </div>
438
+ </script>
439
+
440
+ <?php
441
+ // No templates.
442
+ ?>
443
+ <script type="text/template" id="tmpl-cartflows-no-flows">
444
+ <div class="cartflows-no-flows">
445
+ <div class="template-message-block">
446
+ <h2><?php _e( 'Coming Soon!', 'cartflows' ); ?></h2>
447
+ <p class="description"></p>
448
+ </div>
449
+ </div>
450
+ </script>
451
+
452
+ <?php
453
+ // Error handling.
454
+ ?>
455
+ <script type="text/template" id="tmpl-templator-error">
456
+ <div class="notice notice-error"><p>{{ data }}</p></div>
457
+ </script>
458
+
459
+ <?php
460
+ // Redirect to Elementor.
461
+ ?>
462
+ <script type="text/template" id="tmpl-templator-redirect-to-elementor">
463
+ <div class="template-message-block templator-redirect-to-elementor">
464
+ <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
465
+ <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span><br/><br/><?php _e( 'Redirecting to the Elementor edit window.', 'cartflows' ); ?> </p></div>
466
+ </script>
467
+
468
+ <?php
469
+ /**
470
+ * Responsive Buttons
471
+ */
472
+ ?>
473
+ <script type="text/template" id="tmpl-cartflows-responsive-view">
474
+ <span class="responsive-view">
475
+ <span class="actions">
476
+ <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
477
+ <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
478
+ <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
479
+ </span>
480
+ </span>
481
+ </script>
482
+
483
+ <?php
484
+ // Templates data.
485
+ ?>
486
+ <script type="text/template" id="tmpl-cartflows-flows-list">
487
+
488
+ <# if ( data.items.length ) { #>
489
+ <# for ( key in data.items ) { #>
490
+ <#
491
+ var flow_steps = [];
492
+ if( data.items[ key ].flow_steps ) {
493
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
494
+ return value['id'];
495
+ });
496
+ }
497
+ #>
498
+ <# console.log( 'here ' + key ); #>
499
+ <div class="inner">
500
+ <div class="template">
501
+ <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 }}">
502
+ <div class="template-screenshot">
503
+ <# if( data.items[ key ].featured_image_url ) { #>
504
+ <img src="{{ data.items[ key ].featured_image_url }}" />
505
+ <# } else { #>
506
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
507
+ <# } #>
508
+ </div>
509
+ <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>
510
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
511
+ <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
512
+ <# } #>
513
+ </span>
514
+ <div class="template-id-container">
515
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
516
+ <div class="template-actions">
517
+
518
+ <#
519
+ if( data.items[ key ].page_builder.slug ) {
520
+ required_plugin_group = data.items[ key ].page_builder.slug;
521
+ } else {
522
+ required_plugin_group = '';
523
+ }
524
+
525
+ 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 ) {
526
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
527
+ } else {
528
+ import_btn_title = 'Import';
529
+ } #>
530
+
531
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
532
+ <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>
533
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
534
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
535
+ <# } else { #>
536
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
537
+ <# } #>
538
+ </div>
539
+ </div>
540
+ </div>
541
+ </div>
542
+ <# } #>
543
+ <# } #>
544
+ </script>
545
+
546
+ <?php
547
+ // Empty Step.
548
+ ?>
549
+ <script type="text/template" id="tmpl-cartflows-create-blank-step">
550
+ <div class="inner">
551
+ <div class="template">
552
+ <span class="thumbnail site-preview cartflows-flow-preview">
553
+ <div class="template-screenshot">
554
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
555
+ </div>
556
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
557
+ </span>
558
+ <div class="template-id-container">
559
+ <h3 class="template-name"> Blank </h3>
560
+ <div class="template-actions">
561
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
562
+ </div>
563
+ </div>
564
+ </div>
565
+ </div>
566
+ </script>
567
+
568
+ <?php
569
+ // Templates data.
570
+ ?>
571
+ <script type="text/template" id="tmpl-cartflows-steps-list">
572
+ <# if ( data.items.length ) { #>
573
+ <# for ( key in data.items ) { #>
574
+ <#
575
+ var flow_steps = [];
576
+ if( data.items[ key ].flow_steps ) {
577
+ flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
578
+ return value['id'];
579
+ });
580
+ }
581
+ #>
582
+ <div class="inner">
583
+ <div class="template">
584
+ <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 }}">
585
+ <div class="template-screenshot">
586
+ <# if( data.items[ key ].featured_image_url ) { #>
587
+ <img src="{{ data.items[ key ].featured_image_url }}" />
588
+ <# } else { #>
589
+ <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
590
+ <# } #>
591
+ </div>
592
+ <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
593
+ <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>
594
+ <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
595
+ <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
596
+ <# } #>
597
+ </span>
598
+ <div class="template-id-container">
599
+ <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
600
+ <div class="template-actions">
601
+
602
+ <#
603
+
604
+ var required_plugin_group = data.items[ key ].page_builder.slug || '';
605
+ var step_slug = data.items[ key ].step_type.slug || '';
606
+ var step_title = data.items[ key ].step_type.name || '';
607
+
608
+ 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 ) {
609
+ import_btn_title = CartFlowsImportVars.required_plugins[ data.items[ key ].page_builder.slug ].button_title;
610
+ } else {
611
+ import_btn_title = 'Import';
612
+ } #>
613
+
614
+ <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
615
+ <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>
616
+ <# } else if( CartFlowsImportVars._is_pro_active ) { #>
617
+ <a target="_blank" href="<?php echo esc_url( admin_url( 'plugins.php?cartflows-license-popup' ) ); ?>" class="button button-primary"><?php _e( 'Activate License', 'cartflows' ); ?></a>
618
+ <# } else { #>
619
+ <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
620
+ <# } #>
621
+ </div>
622
+ </div>
623
+ </div>
624
+ </div>
625
+ <# } #>
626
+ <# } #>
627
+ </script>
628
+
629
+ <?php
630
+ /**
631
+ * TMPL - Filters
632
+ */
633
+ ?>
634
+ <script type="text/template" id="tmpl-cartflows-term-filters">
635
+
636
+ <# if ( data ) { #>
637
+
638
+ <# if ( CartFlowsImportVars.flow_page_builder === data.args.remote_slug || CartFlowsImportVars.step_page_builder === data.args.remote_slug ) { #>
639
+ <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
640
+
641
+ <# if ( data.args.show_all ) { #>
642
+ <li>
643
+ <a href="#" data-group="all"> All </a>
644
+ </li>
645
+ <# } #>
646
+
647
+ <# for ( key in data.items ) { #>
648
+ <li>
649
+ <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>
650
+ </li>
651
+ <# } #>
652
+
653
+ </ul>
654
+
655
+ <# } else { #>
656
+ <select class="{{ data.args.wrapper_class }} {{ data.args.class }}">
657
+
658
+ <# if ( data.args.show_all ) { #>
659
+ <option value="all"> <?php _e( 'All', 'cartflows' ); ?> </option>
660
+ <# } #>
661
+
662
+ <# if ( CartFlowsImportVars.step_type === data.args.remote_slug ) { #>
663
+ <option value=""> <?php _e( 'Select Step Type', 'cartflows' ); ?> </option>
664
+ <# } #>
665
+
666
+ <# for ( key in data.items ) { #>
667
+ <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>
668
+ <# } #>
669
+
670
+ </select>
671
+ <# } #>
672
+
673
+ <# } #>
674
+ </script>
675
+
676
+ <?php
677
+ // Step Type.
678
+ ?>
679
+ <script type="text/template" id="tmpl-cartflows-step-types">
680
+ <ul class="wcf-tab nav-tabs">
681
+ <# if( data.items_count ) { #>
682
+ <# for( key in data.items ) { #>
683
+ <# console.log( data.items[ key ].id ) #>
684
+ <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
685
+ <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
686
+ </li>
687
+ <# } #>
688
+ <# } #>
689
+ </ul>
690
+ </script>
691
+
692
+ <?php
693
+ // Add to library button.
694
+ ?>
695
+ <script type="text/template" id="tmpl-templator-add-to-library">
696
+ <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>
697
+ </script>
698
+ <?php
699
+ }
700
+
701
+ /**
702
+ * Get plugin button string.
703
+ *
704
+ * @param string $plugin_init_file Plguin init file.
705
+ * @param string $plugin_title Plguin title.
706
+ * @return string
707
+ */
708
+ function get_plugin_button_string( $plugin_init_file, $plugin_title ) {
709
+
710
+ if ( null == self::$installed_plugins ) {
711
+ self::$installed_plugins = get_plugins();
712
+ }
713
+
714
+ if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
715
+ /* translators: %s is plugin name. */
716
+ return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
717
+ } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
718
+ /* translators: %s is plugin name. */
719
+ return sprintf( __( 'Import', 'cartflows' ), $plugin_title );
720
+ }
721
+
722
+ return __( 'Import', 'cartflows' );
723
+ }
724
+
725
+ /**
726
+ * Get plugin status
727
+ *
728
+ * @param string $plugin_init_file Plguin init file.
729
+ * @return mixed
730
+ */
731
+ function get_plugin_status( $plugin_init_file ) {
732
+
733
+ if ( null == self::$installed_plugins ) {
734
+ self::$installed_plugins = get_plugins();
735
+ }
736
+
737
+ if ( ! isset( self::$installed_plugins[ $plugin_init_file ] ) ) {
738
+ return 'install';
739
+ } elseif ( ! is_plugin_active( $plugin_init_file ) ) {
740
+ return 'activate';
741
+ }
742
+
743
+ return;
744
+ }
745
+
746
+ /**
747
+ * Enqueue scripts
748
+ *
749
+ * @since 1.0.0
750
+ *
751
+ * @hook admin_enqueue_scripts
752
+ * @param string $hook Current page hook.
753
+ */
754
+ function scripts( $hook = '' ) {
755
+
756
+ if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
757
+ return;
758
+ }
759
+
760
+ wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
761
+ wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
762
+ wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
763
+ wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
764
+
765
+ $localize_vars = array(
766
+ '_is_pro_active' => _is_cartflows_pro(),
767
+
768
+ // Flow and its rest fields.
769
+ 'flow' => CARTFLOWS_FLOW_POST_TYPE,
770
+ 'flow_fields' => array(
771
+ 'id',
772
+ 'title',
773
+ 'flow_type',
774
+ 'page_builder',
775
+ 'flow_steps',
776
+ 'licence_status',
777
+ 'featured_image_url',
778
+ 'featured_media', // @required for field `featured_image_url`.
779
+ ),
780
+
781
+ // Flow type and rest fields.
782
+ 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
783
+ 'flow_type_fields' => array(
784
+ 'id',
785
+ 'name',
786
+ 'slug',
787
+ ),
788
+
789
+ // Flow page builder and rest fields.
790
+ 'flow_page_builder' => CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER,
791
+ 'flow_page_builder_fields' => array(
792
+ 'id',
793
+ 'name',
794
+ 'slug',
795
+ ),
796
+
797
+ // Step page builder and rest fields.
798
+ 'step_page_builder' => CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER,
799
+ 'step_page_builder_fields' => array(
800
+ 'id',
801
+ 'name',
802
+ 'slug',
803
+ ),
804
+
805
+ // Step and its rest fields.
806
+ 'step' => CARTFLOWS_STEP_POST_TYPE,
807
+ 'step_fields' => array(
808
+ 'title',
809
+ 'featured_image_url',
810
+ 'featured_media', // @required for field `featured_image_url`.
811
+ 'id',
812
+ 'flow_type',
813
+ 'step_type',
814
+ 'page_builder',
815
+ 'licence_status',
816
+ ),
817
+
818
+ // Step type and its rest fields.
819
+ 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
820
+ 'step_type_fields' => array(
821
+ 'id',
822
+ 'name',
823
+ 'slug',
824
+ ),
825
+
826
+ 'domain_url' => CARTFLOWS_DOMAIN_URL,
827
+ 'server_url' => CARTFLOWS_TEMPLATES_URL,
828
+ 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
829
+ 'site_url' => site_url(),
830
+ 'import_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_importer' ),
831
+ 'export_url' => admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE . '&page=flow_exporter' ),
832
+ 'admin_url' => admin_url(),
833
+ 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
834
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
835
+ 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
836
+
837
+ 'required_plugins' => array(
838
+ 'elementor' => array(
839
+ 'button_title' => $this->get_plugin_button_string( 'elementor/elementor.php', 'Elementor' ),
840
+ 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
841
+ 'plugins' => array(
842
+ array(
843
+ 'slug' => 'elementor', // For download from wp.org.
844
+ 'status' => $this->get_plugin_status( 'elementor/elementor.php' ),
845
+ ),
846
+ ),
847
+ ),
848
+ ),
849
+ );
850
+
851
+ // Add thickbox.
852
+ add_thickbox();
853
+
854
+ wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
855
+ wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
856
+ }
857
+
858
+ /**
859
+ * Load Template
860
+ *
861
+ * @since 1.0.0
862
+ *
863
+ * @hook cartflows_load_steps
864
+ * @return void
865
+ */
866
+ function load_templates() {
867
+
868
+ check_ajax_referer( 'cf-load-steps', 'security' );
869
+
870
+ $args = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
871
+ $templates = CartFlows_API::get_instance()->get_templates( $args );
872
+
873
+ if ( $templates['templates_count'] ) {
874
+ wp_send_json_success( $templates );
875
+ } else {
876
+ wp_send_json_error( $templates );
877
+ }
878
+ wp_die();
879
+ }
880
+
881
+ /**
882
+ * Import.
883
+ *
884
+ * @since 1.0.0
885
+ *
886
+ * @hook wp_ajax_cartflows_import_flow_step
887
+ * @return void
888
+ */
889
+ function import_flow() {
890
+
891
+ check_ajax_referer( 'cf-import-flow-step', 'security' );
892
+
893
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
894
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
895
+
896
+ wcf()->logger->import_log( '------------------------------------' );
897
+ wcf()->logger->import_log( 'STARTED! Importing FLOW' );
898
+ wcf()->logger->import_log( '------------------------------------' );
899
+ wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
900
+
901
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
902
+
903
+ if ( false === $response['success'] ) {
904
+ wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
905
+ wp_send_json_error( $response );
906
+ }
907
+
908
+ wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );
909
+
910
+ $new_step_id = wp_insert_post(
911
+ array(
912
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
913
+ 'post_title' => $response['title'],
914
+ 'post_content' => '',
915
+ 'post_status' => 'publish',
916
+ )
917
+ );
918
+
919
+ if ( is_wp_error( $new_step_id ) ) {
920
+ wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
921
+ wp_send_json_error( $new_step_id );
922
+ }
923
+
924
+ wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
925
+ // insert post meta.
926
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
927
+ wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
928
+
929
+ /**
930
+ * Import & Set type.
931
+ */
932
+ $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
933
+ $term_slug = '';
934
+ if ( $term ) {
935
+
936
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
937
+ $term_exist = term_exists( $term->name, $taxonomy );
938
+
939
+ if ( empty( $term_exist ) ) {
940
+ $terms = array(
941
+ array(
942
+ 'name' => $term->name,
943
+ ),
944
+ );
945
+
946
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
947
+ wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
948
+ }
949
+
950
+ $current_term = term_exists( $term->name, $taxonomy );
951
+
952
+ // Set type object.
953
+ $data = get_term( $current_term['term_id'], $taxonomy );
954
+ $term_slug = $data->slug;
955
+ $term_name = $data->name;
956
+ wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
957
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
958
+
959
+ // Set type.
960
+ update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
961
+ wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
962
+ }
963
+
964
+ // Set flow.
965
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
966
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
967
+
968
+ /**
969
+ * Update steps for the current flow.
970
+ */
971
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
972
+
973
+ if ( ! is_array( $flow_steps ) ) {
974
+ $flow_steps = array();
975
+ }
976
+
977
+ $flow_steps[] = array(
978
+ 'id' => $new_step_id,
979
+ 'title' => $response['title'],
980
+ 'type' => $term_slug,
981
+ );
982
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
983
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
984
+
985
+ // Import Post Meta.
986
+ self::import_post_meta( $new_step_id, $response );
987
+
988
+ wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
989
+ wcf()->logger->import_log( '------------------------------------' );
990
+ wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
991
+ wcf()->logger->import_log( '------------------------------------' );
992
+
993
+ do_action( 'cartflows_import_complete' );
994
+ wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
995
+
996
+ // Batch Process.
997
+ do_action( 'cartflows_after_template_import', $new_step_id, $response );
998
+
999
+ /**
1000
+ * End
1001
+ */
1002
+ wp_send_json_success( $new_step_id );
1003
+ }
1004
+
1005
+ /**
1006
+ * Import Step.
1007
+ *
1008
+ * @since 1.0.0
1009
+ * @hook wp_ajax_cartflows_step_import
1010
+ *
1011
+ * @return void
1012
+ */
1013
+ function create_default_flow() {
1014
+
1015
+ check_ajax_referer( 'cf-default-flow', 'security' );
1016
+
1017
+ // Create post object.
1018
+ $new_flow_post = array(
1019
+ 'post_content' => '',
1020
+ 'post_status' => 'publish',
1021
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1022
+ );
1023
+
1024
+ // Insert the post into the database.
1025
+ $flow_id = wp_insert_post( $new_flow_post );
1026
+
1027
+ if ( is_wp_error( $flow_id ) ) {
1028
+ wp_send_json_error( $flow_id->get_error_message() );
1029
+ }
1030
+
1031
+ $flow_steps = array();
1032
+
1033
+ $steps_data = array(
1034
+ 'landing' => __( 'Landing Page', 'cartflows' ),
1035
+ 'checkout' => __( 'Checkout Page', 'cartflows' ),
1036
+ 'thankyou' => __( 'Thank You Page', 'cartflows' ),
1037
+ );
1038
+
1039
+ foreach ( $steps_data as $slug => $title ) {
1040
+
1041
+ $post_content = '';
1042
+
1043
+ switch ( $slug ) {
1044
+ case 'checkout':
1045
+ $post_content = '';
1046
+ break;
1047
+ case 'thankyou':
1048
+ $post_content = '';
1049
+ break;
1050
+ default:
1051
+ $post_content = '';
1052
+ break;
1053
+ }
1054
+
1055
+ $step_id = wp_insert_post(
1056
+ array(
1057
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1058
+ 'post_title' => $title,
1059
+ 'post_content' => $post_content,
1060
+ 'post_status' => 'publish',
1061
+ )
1062
+ );
1063
+
1064
+ if ( is_wp_error( $step_id ) ) {
1065
+ wp_send_json_error( $step_id->get_error_message() );
1066
+ }
1067
+
1068
+ if ( $step_id ) {
1069
+
1070
+ $flow_steps[] = array(
1071
+ 'id' => $step_id,
1072
+ 'title' => $title,
1073
+ 'type' => $slug,
1074
+ );
1075
+
1076
+ // insert post meta.
1077
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
1078
+ update_post_meta( $step_id, 'wcf-step-type', $slug );
1079
+
1080
+ wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1081
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1082
+ }
1083
+ }
1084
+
1085
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1086
+
1087
+ wp_send_json_success( $flow_id );
1088
+ }
1089
+
1090
+ /**
1091
+ * Create Flow
1092
+ *
1093
+ * @return void
1094
+ */
1095
+ function create_flow() {
1096
+
1097
+ check_ajax_referer( 'cf-create-flow', 'security' );
1098
+
1099
+ // Create post object.
1100
+ $new_flow_post = array(
1101
+ 'post_content' => '',
1102
+ 'post_status' => 'publish',
1103
+ 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
1104
+ );
1105
+
1106
+ // Insert the post into the database.
1107
+ $flow_id = wp_insert_post( $new_flow_post );
1108
+
1109
+ if ( is_wp_error( $flow_id ) ) {
1110
+ wp_send_json_error( $flow_id->get_error_message() );
1111
+ }
1112
+
1113
+ wp_send_json_success( $flow_id );
1114
+ }
1115
+
1116
+ /**
1117
+ * Create Step
1118
+ *
1119
+ * @return void
1120
+ */
1121
+ function import_step() {
1122
+
1123
+ check_ajax_referer( 'cf-step-import', 'security' );
1124
+
1125
+ $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
1126
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1127
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
1128
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
1129
+ $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;
1130
+
1131
+ $cartflow_meta = Cartflows_Flow_Meta::get_instance();
1132
+
1133
+ $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
1134
+
1135
+ wcf()->logger->import_log( '------------------------------------' );
1136
+ wcf()->logger->import_log( 'STARTED! Importing STEP' );
1137
+ wcf()->logger->import_log( '------------------------------------' );
1138
+
1139
+ if ( empty( $template_id ) || empty( $post_id ) ) {
1140
+ /* translators: %s: template ID */
1141
+ $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
1142
+ wcf()->logger->import_log( $data );
1143
+ wp_send_json_error( $data );
1144
+ }
1145
+
1146
+ wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
1147
+
1148
+ $response = CartFlows_API::get_instance()->get_template( $template_id );
1149
+
1150
+ wcf()->logger->import_log( json_encode( $response ) );
1151
+
1152
+ // Import Post Meta.
1153
+ self::import_post_meta( $post_id, $response );
1154
+
1155
+ do_action( 'cartflows_import_complete' );
1156
+
1157
+ // Batch Process.
1158
+ do_action( 'cartflows_after_template_import', $post_id, $response );
1159
+
1160
+ wcf()->logger->import_log( '------------------------------------' );
1161
+ wcf()->logger->import_log( 'COMPLETE! Importing Step' );
1162
+ wcf()->logger->import_log( '------------------------------------' );
1163
+
1164
+ wp_send_json_success( $post_id );
1165
+ }
1166
+
1167
+ /**
1168
+ * Import Step.
1169
+ *
1170
+ * @since 1.0.0
1171
+ * @hook wp_ajax_cartflows_step_create_blank
1172
+ *
1173
+ * @return void
1174
+ */
1175
+ function step_create_blank() {
1176
+
1177
+ check_ajax_referer( 'cf-step-create-blank', 'security' );
1178
+
1179
+ $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
1180
+ $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
1181
+ $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
1182
+
1183
+ if ( empty( $flow_id ) || empty( $step_type ) ) {
1184
+ /* translators: %s: flow ID */
1185
+ $data = sprintf( __( 'Invalid flow id %1$s OR step type %2$s.', 'cartflows' ), $flow_id, $step_type );
1186
+ wcf()->logger->import_log( $data );
1187
+ wp_send_json_error( $data );
1188
+ }
1189
+
1190
+ wcf()->logger->import_log( '------------------------------------' );
1191
+ wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
1192
+
1193
+ $step_type_title = str_replace( '-', ' ', $step_type );
1194
+ $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
1195
+
1196
+ $new_step_id = wp_insert_post(
1197
+ array(
1198
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
1199
+ 'post_title' => $step_title,
1200
+ 'post_content' => '',
1201
+ 'post_status' => 'publish',
1202
+ )
1203
+ );
1204
+
1205
+ // insert post meta.
1206
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
1207
+
1208
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
1209
+ $term_exist = term_exists( $step_type_title, $taxonomy );
1210
+
1211
+ if ( empty( $term_exist ) ) {
1212
+ $terms = array(
1213
+ array(
1214
+ 'name' => $step_type_title,
1215
+ ),
1216
+ );
1217
+
1218
+ Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
1219
+ wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
1220
+ }
1221
+
1222
+ $current_term = term_exists( $step_type_title, $taxonomy );
1223
+
1224
+ // Set type object.
1225
+ $data = get_term( $current_term['term_id'], $taxonomy );
1226
+ $step_slug = $data->slug;
1227
+ wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
1228
+ wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
1229
+
1230
+ // Set type.
1231
+ update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
1232
+ wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
1233
+
1234
+ // Set flow.
1235
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
1236
+ wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
1237
+
1238
+ CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
1239
+
1240
+ wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
1241
+ wcf()->logger->import_log( '------------------------------------' );
1242
+
1243
+ wp_send_json_success( $new_step_id );
1244
+ }
1245
+
1246
+ /**
1247
+ * Import Post Meta
1248
+ *
1249
+ * @since 1.0.0
1250
+ *
1251
+ * @param integer $post_id Post ID.
1252
+ * @param array $response Post meta.
1253
+ * @return void
1254
+ */
1255
+ public static function import_post_meta( $post_id, $response ) {
1256
+
1257
+ $metadata = (array) $response['post_meta'];
1258
+
1259
+ foreach ( $metadata as $meta_key => $meta_value ) {
1260
+ $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
1261
+
1262
+ if ( $meta_value ) {
1263
+
1264
+ if ( is_serialized( $meta_value, true ) ) {
1265
+ $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
1266
+ } elseif ( is_array( $meta_value ) ) {
1267
+ $raw_data = json_decode( stripslashes( $meta_value ), true );
1268
+ } else {
1269
+ $raw_data = $meta_value;
1270
+ }
1271
+
1272
+ if ( '_elementor_data' === $meta_key ) {
1273
+ if ( is_array( $raw_data ) ) {
1274
+ $raw_data = wp_slash( json_encode( $raw_data ) );
1275
+ } else {
1276
+ $raw_data = wp_slash( $raw_data );
1277
+ }
1278
+ wcf()->logger->import_log( $raw_data );
1279
+ }
1280
+
1281
+ if ( is_array( $raw_data ) ) {
1282
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
1283
+ } else {
1284
+
1285
+ if ( ! is_object( $raw_data ) ) {
1286
+ wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
1287
+ }
1288
+ }
1289
+
1290
+ update_post_meta( $post_id, $meta_key, $raw_data );
1291
+ }
1292
+ }
1293
+ }
1294
+
1295
+ /**
1296
+ * Import Template for Elementor
1297
+ *
1298
+ * @since 1.0.0
1299
+ *
1300
+ * @param integer $post_id Post ID.
1301
+ * @param array $response Post meta.
1302
+ * @param array $page_build_data Page build data.
1303
+ * @return void
1304
+ */
1305
+ public static function import_template_elementor( $post_id, $response, $page_build_data ) {
1306
+ if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
1307
+ $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
1308
+ wcf()->logger->import_log( $data );
1309
+ wp_send_json_error( $data );
1310
+ }
1311
+
1312
+ require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
1313
+
1314
+ wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
1315
+
1316
+ $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
1317
+ $obj->import_single_template( $post_id );
1318
+
1319
+ wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
1320
+ }
1321
+
1322
+ /**
1323
+ * Supported post types
1324
+ *
1325
+ * @since 1.0.0
1326
+ *
1327
+ * @return array Supported post types.
1328
+ */
1329
+ public static function supported_post_types() {
1330
+ return apply_filters(
1331
+ 'cartflows_supported_post_types',
1332
+ array(
1333
+ CARTFLOWS_FLOW_POST_TYPE,
1334
+ )
1335
+ );
1336
+ }
1337
+
1338
+ /**
1339
+ * Check supported post type
1340
+ *
1341
+ * @since 1.0.0
1342
+ *
1343
+ * @param string $post_type Post type.
1344
+ * @return boolean Supported post type status.
1345
+ */
1346
+ public static function is_supported_post( $post_type = '' ) {
1347
+ if ( in_array( $post_type, self::supported_post_types() ) ) {
1348
+ return true;
1349
+ }
1350
+
1351
+ return false;
1352
+ }
1353
+
1354
+ /**
1355
+ * Set steps to the flow
1356
+ *
1357
+ * @param integer $flow_id Flow ID.
1358
+ * @param integer $new_step_id New step ID.
1359
+ * @param string $step_title Flow Type.
1360
+ * @param string $step_slug Flow Type.
1361
+ */
1362
+ function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
1363
+ // Update steps for the current flow.
1364
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
1365
+
1366
+ if ( ! is_array( $flow_steps ) ) {
1367
+ $flow_steps = array();
1368
+ }
1369
+
1370
+ $flow_steps[] = array(
1371
+ 'id' => $new_step_id,
1372
+ 'title' => $step_title,
1373
+ 'type' => $step_slug,
1374
+ );
1375
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
1376
+ wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
1377
+ }
1378
+
1379
+ /**
1380
+ * Localize variables in admin
1381
+ *
1382
+ * @param array $vars variables.
1383
+ */
1384
+ function localize_vars( $vars ) {
1385
+
1386
+ $ajax_actions = array(
1387
+ 'cf_step_import',
1388
+ 'cf_load_steps',
1389
+ 'cf_create_flow',
1390
+ 'cf_default_flow',
1391
+ 'cf_step_create_blank',
1392
+ 'cf_import_flow_step',
1393
+ );
1394
+
1395
+ foreach ( $ajax_actions as $action ) {
1396
+
1397
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1398
+ }
1399
+
1400
+ return $vars;
1401
+ }
1402
+
1403
+ /**
1404
+ * Ajax action to activate plugin
1405
+ */
1406
+ public function activate_plugin() {
1407
+
1408
+ $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';
1409
+
1410
+ if ( ! is_plugin_active( $plugin_slug ) ) {
1411
+
1412
+ $activate = activate_plugin( $plugin_slug, '', false, true );
1413
+
1414
+ if ( is_wp_error( $activate ) ) {
1415
+ wp_send_json_error();
1416
+ }
1417
+ }
1418
+
1419
+ wp_send_json_success();
1420
+ }
1421
+
1422
+ }
1423
+
1424
+ /**
1425
+ * Initialize class object with 'get_instance()' method
1426
+ */
1427
+ CartFlows_Importer::get_instance();
1428
+
1429
+ endif;
classes/class-cartflows-loader.php CHANGED
@@ -115,7 +115,7 @@ if ( ! class_exists( 'Cartflows_Loader' ) ) {
115
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
116
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
117
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
118
- define( 'CARTFLOWS_VER', '1.1.2' );
119
  define( 'CARTFLOWS_SLUG', 'cartflows' );
120
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
121
 
115
  define( 'CARTFLOWS_BASE', plugin_basename( CARTFLOWS_FILE ) );
116
  define( 'CARTFLOWS_DIR', plugin_dir_path( CARTFLOWS_FILE ) );
117
  define( 'CARTFLOWS_URL', plugins_url( '/', CARTFLOWS_FILE ) );
118
+ define( 'CARTFLOWS_VER', '1.1.3' );
119
  define( 'CARTFLOWS_SLUG', 'cartflows' );
120
  define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
121
 
classes/class-cartflows-meta-fields.php CHANGED
@@ -1,993 +1,989 @@
1
- <?php
2
- // @codingStandardsIgnoreStart
3
- /**
4
- * Meta Fields.
5
- *
6
- * @package CartFlows
7
- */
8
-
9
- /**
10
- * Class Cartflows_Meta_Fields.
11
- */
12
- class Cartflows_Meta_Fields {
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Initiator
23
- */
24
- public static function get_instance() {
25
- if ( ! isset( self::$instance ) ) {
26
- self::$instance = new self;
27
- }
28
-
29
- return self::$instance;
30
- }
31
-
32
- /**
33
- * Constructor
34
- */
35
- public function __construct() {
36
-
37
- /* Add Scripts */
38
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_meta_scripts' ), 20 );
39
-
40
- add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
41
-
42
- add_action( 'wp_ajax_wcf_add_checkout_custom_field', array( $this, 'add_checkout_custom_field' ) );
43
- add_action( 'wp_ajax_wcf_delete_checkout_custom_field', array( $this, 'delete_checkout_custom_field' ) );
44
-
45
- add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
46
-
47
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
48
- }
49
-
50
- public function admin_meta_scripts() {
51
-
52
- global $pagenow;
53
- global $post;
54
-
55
- $screen = get_current_screen();
56
-
57
- if (
58
- ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) &&
59
- wcf()->utils->is_step_post_type( $screen->post_type )
60
- ) {
61
-
62
- wp_enqueue_style( 'woocommerce_admin_styles' );
63
-
64
- wp_enqueue_script( 'select2' );
65
- wp_enqueue_script( 'wc-enhanced-select' );
66
-
67
- wp_enqueue_script(
68
- 'wcf-admin-meta',
69
- CARTFLOWS_URL . 'admin/meta-assets/js/admin-edit.js',
70
- array( 'jquery', 'select2', 'wp-color-picker' ),
71
- CARTFLOWS_VER,
72
- true
73
- );
74
-
75
- wp_enqueue_style( 'wcf-admin-meta', CARTFLOWS_URL . 'admin/meta-assets/css/admin-edit.css', array( 'wp-color-picker' ), CARTFLOWS_VER );
76
- wp_style_add_data( 'wcf-admin-meta', 'rtl', 'replace' );
77
-
78
- $localize = array(
79
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
80
- 'google_fonts' => CartFlows_Font_Families::get_google_fonts(),
81
- 'system_fonts' => CartFlows_Font_Families::get_system_fonts(),
82
- 'font_weights' => array(
83
- '100' => __( 'Thin 100', 'cartflows' ),
84
- '200' => __( 'Extra-Light 200', 'cartflows' ),
85
- '300' => __( 'Light 300', 'cartflows' ),
86
- '400' => __( 'Normal 400', 'cartflows' ),
87
- '500' => __( 'Medium 500', 'cartflows' ),
88
- '600' => __( 'Semi-Bold 600', 'cartflows' ),
89
- '700' => __( 'Bold 700', 'cartflows' ),
90
- '800' => __( 'Extra-Bold 800', 'cartflows' ),
91
- '900' => __( 'Ultra-Bold 900', 'cartflows' ),
92
- )
93
- );
94
-
95
- wp_localize_script( 'jquery', 'wcf', apply_filters( 'wcf_js_localize', $localize ) );
96
-
97
- do_action( 'cartflows_admin_meta_scripts' );
98
- }
99
- }
100
-
101
- /**
102
- * Function to search coupons
103
- */
104
- public function json_search_coupons() {
105
-
106
- check_admin_referer( 'wcf-json-search-coupons', 'security' );
107
-
108
- global $wpdb;
109
-
110
- $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
111
-
112
- if ( empty( $term ) ) {
113
- die();
114
- }
115
-
116
- $posts = wp_cache_get( 'wcf_search_coupons', 'wcf_funnel_Cart' );
117
-
118
- if ( false === $posts ) {
119
- $posts = $wpdb->get_results( // phpcs:ignore
120
- $wpdb->prepare(
121
- "SELECT *
122
- FROM {$wpdb->prefix}posts
123
- WHERE post_type = %s
124
- AND post_title LIKE %s
125
- AND post_status = %s",
126
- 'shop_coupon',
127
- $wpdb->esc_like( $term ) . '%',
128
- 'publish'
129
- )
130
- );
131
- wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
132
- }
133
-
134
- $coupons_found = array();
135
- $all_discount_types = wc_get_coupon_types();
136
-
137
- if ( $posts ) {
138
- foreach ( $posts as $post ) {
139
-
140
- $discount_type = get_post_meta( $post->ID, 'discount_type', true );
141
-
142
- if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
143
- $coupons_found[ get_the_title( $post->ID ) ] = get_the_title( $post->ID ) . ' (Type: ' . $all_discount_types[ $discount_type ] . ')';
144
- }
145
- }
146
- }
147
-
148
- wp_send_json( $coupons_found );
149
- }
150
-
151
- /**
152
- * [add_checkout_custom_field description]
153
- *
154
- * @hook wcf_add_checkout_custom_field
155
- */
156
- public function add_checkout_custom_field() {
157
-
158
- check_ajax_referer( 'wcf-add-checkout-custom-field', 'security' );
159
-
160
- $post_id = intval( $_POST['post_id'] );
161
- $add_to = sanitize_text_field( wp_unslash( $_POST['add_to'] ) );
162
- $type = sanitize_text_field( wp_unslash( $_POST['type'] ) );
163
- $options = sanitize_text_field( wp_unslash( $_POST['options'] ) );
164
- $label = sanitize_text_field( wp_unslash( $_POST['label'] ) );
165
- $name = sanitize_text_field( wp_unslash( $_POST['name'] ) );
166
-
167
- if ( '' !== $name ) {
168
-
169
- $fields = Cartflows_Helper::get_checkout_fields( $add_to, $post_id );
170
- $field_keys = array_keys($fields);
171
-
172
- $name = $add_to . '_' . sanitize_key( $name );
173
- if( in_array($name, $field_keys) ) {
174
- $name = $name . '_' . rand( 0000, 9999 );
175
- }
176
-
177
- $field_data = array(
178
- 'type' => $type,
179
- 'label' => $label,
180
- 'placeholder' => '',
181
- 'class' => array( 'form-row-wide' ),
182
- 'label_class' => array(),
183
- 'required' => true,
184
- 'custom' => true,
185
- );
186
-
187
- if ( 'select' === $type ) {
188
-
189
- $options = explode( ',', $options );
190
- $field_data['options'] = array();
191
-
192
- if ( is_array( $options ) && ! empty( $options ) ) {
193
-
194
- foreach ( $options as $key => $value ) {
195
-
196
- $field_data['options'][ $value ] = $value;
197
- }
198
- }
199
- }
200
-
201
- Cartflows_Helper::add_checkout_field( $add_to, $name, $field_data, $post_id );
202
-
203
- $key = sanitize_key( $name );
204
- $name = 'wcf-' . $key;
205
-
206
- $field_args = array(
207
- 'label' => $label,
208
- 'name' => $name,
209
- 'value' => 'yes',
210
- 'after' => 'Enable',
211
- );
212
-
213
- $field_args['after_html'] = '<span class="wcf-cpf-actions" data-type="billing" data-key="' . $key . '"> | ';
214
- $field_args['after_html'] .= '<a class="wcf-cpf-action-remove">' . __( 'Remove', 'cartflows' ) . '</a>';
215
- $field_args['after_html'] .= '</span>';
216
-
217
- $field_markup = wcf()->meta->get_checkbox_field( $field_args );
218
-
219
- if( 'billing' === $add_to ) {
220
- $add_to_class = 'wcf-cb-fields';
221
- } else if( 'shipping' === $add_to ) {
222
- $add_to_class = 'wcf-sb-fields';
223
- }
224
-
225
- $data = array(
226
- 'field_data' => $field_data,
227
- 'field_args' => $field_args,
228
- 'add_to_class' => $add_to_class,
229
- 'markup' => $field_markup,
230
- );
231
-
232
- wp_send_json( $data );
233
- }
234
-
235
- wp_send_json( false );
236
-
237
- }
238
-
239
- /**
240
- * [delete_checkout_custom_field description]
241
- *
242
- * @hook wcf_delete_checkout_custom_field
243
- * @return [type] [description]
244
- */
245
- public function delete_checkout_custom_field() {
246
-
247
- check_ajax_referer( 'wcf-delete-checkout-custom-field', 'security' );
248
-
249
- $post_id = intval( $_POST['post_id'] );
250
- $type = sanitize_text_field( wp_unslash( $_POST['type'] ) );
251
- $key = sanitize_text_field( wp_unslash( $_POST['key'] ) );
252
-
253
- if ( '' !== $key ) {
254
-
255
- Cartflows_Helper::delete_checkout_field( $type, $key, $post_id );
256
-
257
- wp_send_json( true );
258
-
259
- }
260
-
261
- wp_send_json( false );
262
-
263
- }
264
-
265
- /**
266
- * Function to search coupons
267
- */
268
- public function json_search_pages() {
269
-
270
- check_ajax_referer( 'wcf-json-search-pages', 'security' );
271
-
272
- $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
273
-
274
- if ( empty( $term ) ) {
275
- die( 'not found' );
276
- }
277
-
278
- $search_string = $term;
279
- $data = array();
280
- $result = array();
281
-
282
- add_filter( 'posts_search', array( $this, 'search_only_titles' ), 10, 2 );
283
-
284
- $query = new WP_Query(
285
- array(
286
- 's' => $search_string,
287
- 'post_type' => 'page',
288
- 'posts_per_page' => - 1,
289
- )
290
- );
291
-
292
- if ( $query->have_posts() ) {
293
- while ( $query->have_posts() ) {
294
- $query->the_post();
295
- $title = get_the_title();
296
- $title .= ( 0 != $query->post->post_parent ) ? ' (' . get_the_title( $query->post->post_parent ) . ')' : '';
297
- $id = get_the_id();
298
- $data[] = array(
299
- 'id' => $id,
300
- 'text' => $title,
301
- );
302
- }
303
- }
304
-
305
- if ( is_array( $data ) && ! empty( $data ) ) {
306
- $result[] = array(
307
- 'text' => '',
308
- 'children' => $data,
309
- );
310
- }
311
-
312
- wp_reset_postdata();
313
-
314
- // return the result in json.
315
- wp_send_json( $result );
316
- }
317
-
318
- public function search_only_titles( $search, $wp_query ) {
319
- if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
320
- global $wpdb;
321
-
322
- $q = $wp_query->query_vars;
323
- $n = ! empty( $q['exact'] ) ? '' : '%';
324
-
325
- $search = array();
326
-
327
- foreach ( (array) $q['search_terms'] as $term ) {
328
- $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $n . $wpdb->esc_like( $term ) . $n );
329
- }
330
-
331
- if ( ! is_user_logged_in() ) {
332
- $search[] = "$wpdb->posts.post_password = ''";
333
- }
334
-
335
- $search = ' AND ' . implode( ' AND ', $search );
336
- }
337
-
338
- return $search;
339
- }
340
-
341
- function get_field( $field_data, $field_content ) {
342
-
343
- $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
344
- $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
345
- $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
346
-
347
- $name_class = 'field-' . $field_data['name'];
348
-
349
- $field_html = '<div class="wcf-field-row ' . $name_class . '">';
350
-
351
- if( ! empty( $label ) || ! empty( $help ) ) {
352
- $field_html .= '<div class="wcf-field-row-heading">';
353
- if( ! empty( $label ) ) {
354
- $field_html .= '<label>' . esc_html( $label ) . '</label>';
355
- }
356
- if ( ! empty( $help ) ) {
357
- $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help">';
358
- // $field_html .= '<span class="wcf-tooltip" data-tooltip= "'. esc_attr( $help ) .'"></span>';
359
- $field_html .= '</i>';
360
- $field_html .= '<span class="wcf-tooltip-text">';
361
- $field_html .= $help;
362
- $field_html .= '</span>';
363
- }
364
- $field_html .= '</div>';
365
- }
366
-
367
- $field_html .= '<div class="wcf-field-row-content">';
368
- $field_html .= $field_content;
369
-
370
- if ( ! empty( $after_html ) ) {
371
- $field_html .= $after_html;
372
- }
373
-
374
- $field_html .= '</div>';
375
- $field_html .= '</div>';
376
-
377
- return $field_html;
378
- }
379
-
380
- function get_text_field( $field_data ) {
381
-
382
- $value = $field_data['value'];
383
-
384
- $attr = '';
385
-
386
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
387
-
388
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
389
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
390
- }
391
- }
392
-
393
- $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
394
-
395
- return $this->get_field( $field_data, $field_content );
396
- }
397
-
398
- function get_shortcode_field( $field_data ) {
399
-
400
- $attr = '';
401
-
402
- $attr_fields = array(
403
- 'readonly' => 'readonly',
404
- 'onfocus' => 'this.select()',
405
- 'onmouseup' => 'return false',
406
- );
407
-
408
- if ( $attr_fields && is_array( $attr_fields ) ) {
409
-
410
- foreach ( $attr_fields as $attr_key => $attr_value ) {
411
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
412
- }
413
- }
414
-
415
- $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $field_data['content'] . '" ' . $attr . '>';
416
-
417
- return $this->get_field( $field_data, $field_content );
418
- }
419
-
420
- function get_display_field( $field_data ) {
421
-
422
- $field_content = $field_data['content'];
423
-
424
- return $this->get_field( $field_data, $field_content );
425
- }
426
-
427
- function get_hr_line_field( $field_data ) {
428
-
429
- $field_data = array(
430
- 'name' => 'wcf-hr-line',
431
- 'content' => '<hr>'
432
- );
433
-
434
- $field_content = $field_data['content'];
435
-
436
- return $this->get_field( $field_data, $field_content );
437
- }
438
-
439
- function get_number_field( $field_data ) {
440
-
441
- $value = $field_data['value'];
442
-
443
- $attr = '';
444
-
445
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
446
-
447
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
448
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
449
- }
450
- }
451
-
452
- $field_content = '<input type="number" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
453
-
454
- return $this->get_field( $field_data, $field_content );
455
- }
456
-
457
- function get_hidden_field( $field_data ) {
458
-
459
- $value = $field_data['value'];
460
-
461
- $attr = '';
462
-
463
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
464
-
465
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
466
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
467
- }
468
- }
469
-
470
- $field_content = '<input type="hidden" id="' . $field_data['name'] . '" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
471
-
472
- return $this->get_field( $field_data, $field_content );
473
- }
474
-
475
- function get_area_field( $field_data ) {
476
-
477
- $value = $field_data['value'];
478
-
479
- $field_content = '<textarea name="' . $field_data['name'] . '" rows="10" cols="50">';
480
- $field_content .= $value;
481
- $field_content .= '</textarea>';
482
-
483
- return $this->get_field( $field_data, $field_content );
484
- }
485
-
486
- function get_checkbox_field( $field_data ) {
487
-
488
- $value = $field_data['value'];
489
-
490
- $field_content = '';
491
- if ( isset( $field_data['before'] ) ) {
492
- $field_content .= '<span>' . $field_data['before'] . '</span>';
493
- }
494
- $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
495
- $field_content .= '<input type="checkbox" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . '>';
496
-
497
- if ( isset( $field_data['after'] ) ) {
498
- $field_content .= '<span>' . $field_data['after'] . '</span>';
499
- }
500
-
501
- return $this->get_field( $field_data, $field_content );
502
- }
503
-
504
- function get_radio_field( $field_data ) {
505
-
506
- $value = $field_data['value'];
507
- $field_content = '';
508
-
509
- if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
510
-
511
- foreach ( $field_data['options'] as $data_key => $data_value ) {
512
-
513
- $field_content .= '<div class="wcf-radio-option">';
514
- $field_content .= '<input type="radio" name="' . $field_data['name'] . '" value="' . $data_key . '" ' . checked( $data_key, $value, false ) . '>';
515
- $field_content .= $data_value;
516
- $field_content .= '</div>';
517
- }
518
- }
519
-
520
- return $this->get_field( $field_data, $field_content );
521
- }
522
-
523
- function get_font_family_field( $field_data ) {
524
-
525
- $value = $field_data['value'];
526
-
527
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
528
-
529
- $field_content = '<select class="wcf-field-font-family" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
530
-
531
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
532
-
533
- $field_content .= '<optgroup label="Other System Fonts">';
534
- foreach ( CartFlows_Font_Families::get_system_fonts() as $name => $variants ) {
535
- $field_content .= '<option value="' . esc_attr( $name ) . '" ' . selected( $name, $value, false ) . '>' . esc_attr( $name ) . '</option>';
536
- }
537
- $field_content .= '</optgroup>';
538
- $field_content .= '<optgroup label="Google">';
539
- foreach ( CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) {
540
- $variants = wcf_get_prop( $single_font, '0' );
541
- $category = wcf_get_prop( $single_font, '1' );
542
- $font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category );
543
- $field_content .= '<option value="' . esc_attr( $font_value ) . '" ' . selected( $font_value, $value, false ) . '>' . esc_attr( $name ) . '</option>';
544
- }
545
- $field_content .= '</optgroup>';
546
-
547
- $field_content .= '</select>';
548
-
549
- return $this->get_field( $field_data, $field_content );
550
- }
551
-
552
- function get_font_weight_field( $field_data ) {
553
-
554
- $value = $field_data['value'];
555
-
556
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
557
-
558
- $field_content = '<select data-selected="'.esc_attr( $value ).'" class="wcf-field-font-weight" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
559
-
560
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
561
-
562
- $field_content .= '</select>';
563
-
564
- return $this->get_field( $field_data, $field_content );
565
- }
566
-
567
- function get_select_field( $field_data ) {
568
-
569
- $value = $field_data['value'];
570
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
571
-
572
- $field_content = '<select name="' . $field_data['name'] . '">';
573
-
574
-
575
- if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
576
-
577
- foreach ( $field_data['options'] as $data_key => $data_value ) {
578
-
579
- $disabled = '';
580
-
581
- if ( array_key_exists( $data_key, $pro_options ) ) {
582
- $disabled = 'disabled ';
583
- $data_value = $pro_options[ $data_key ];
584
- }
585
-
586
- $field_content .= '<option value="' . $data_key . '" ' . selected( $value, $data_key, false ) . ' ' . $disabled .'>' . $data_value . '</option>';
587
- }
588
- }
589
-
590
- $field_content .= '</select>';
591
-
592
- if ( isset( $field_data['after'] ) ) {
593
- $field_content .= '<span>' . $field_data['after'] . '</span>';
594
- }
595
-
596
- return $this->get_field( $field_data, $field_content );
597
- }
598
-
599
- function get_color_picker_field( $field_data ) {
600
-
601
- $value = $field_data['value'];
602
-
603
- $field_content = '<input class="wcf-color-picker" type="text" name="' . $field_data['name'] . '" value="' . $value . '">';
604
-
605
- return $this->get_field( $field_data, $field_content );
606
- }
607
-
608
- function get_product_selection_field( $field_data ) {
609
-
610
- $value = $field_data['value'];
611
-
612
- $multiple = '';
613
-
614
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
615
- $multiple = ' multiple="multiple"';
616
- }
617
-
618
- $allow_clear = '';
619
-
620
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
621
- $allow_clear = ' data-allow_clear="allow_clear"';
622
- }
623
-
624
- $field_content = '<select
625
- name="' . $field_data['name'] . '[]"
626
- class="wcf-product-search" ' . $multiple . $allow_clear . '
627
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
628
- data-action="woocommerce_json_search_products_and_variations">';
629
-
630
- if ( is_array( $value ) && ! empty( $value ) ) {
631
-
632
- foreach ( $value as $data_key => $product_id ) {
633
-
634
- $product = wc_get_product( $product_id );
635
-
636
- // posts.
637
- if ( ! empty( $product ) ) {
638
- $post_title = $product->get_name() . ' (#' . $product_id . ')';
639
-
640
- $field_content .= '<option value="' . $product_id . '" selected="selected" >' . $post_title . '</option>';
641
- }
642
- }
643
- }
644
- $field_content .= '</select>';
645
-
646
- return $this->get_field( $field_data, $field_content );
647
- }
648
-
649
- function get_coupon_selection_field( $field_data ) {
650
-
651
- $value = $field_data['value'];
652
-
653
- $multiple = '';
654
-
655
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
656
- $multiple = ' multiple="multiple"';
657
- }
658
-
659
- $allow_clear = '';
660
-
661
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
662
- $allow_clear = ' data-allow_clear="allow_clear"';
663
- }
664
-
665
- $field_content = '<select
666
- name="' . $field_data['name'] . '[]"
667
- class="wc-coupon-search wcf-coupon-search" ' . $multiple . $allow_clear . '
668
- data-placeholder="' . __( 'Search for a coupon&hellip;', 'cartflows' ) . '"
669
- data-action="wcf_json_search_coupons">';
670
-
671
- if ( is_array( $value ) && ! empty( $value ) ) {
672
-
673
- $all_discount_types = wc_get_coupon_types();
674
-
675
- foreach ( $value as $coupon_title ) {
676
-
677
- $coupon = new WC_Coupon( $coupon_title );
678
-
679
- $discount_type = $coupon->get_discount_type();
680
-
681
- if ( isset( $discount_type ) && $discount_type ) {
682
- $discount_type = ' ( Type: ' . $all_discount_types[ $discount_type ] . ' )';
683
- }
684
-
685
- $field_content .= '<option value="' . $coupon_title . '" selected="selected">' . $coupon_title . $discount_type . '</option>';
686
- }
687
- }
688
-
689
- $field_content .= '</select>';
690
-
691
- return $this->get_field( $field_data, $field_content );
692
- }
693
-
694
- function get_page_selection_field( $field_data ) {
695
-
696
- $value = $field_data['value'];
697
-
698
- $multiple = '';
699
-
700
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
701
- $multiple = 'multiple="multiple"';
702
- }
703
-
704
- $field_content = '<select
705
- name="' . $field_data['name'] . '[]"
706
- class="wcf-search-pages" ' . $multiple . '"
707
- data-action="wcf_json_search_pages">';
708
-
709
- if ( is_array( $value ) && ! empty( $value ) ) {
710
-
711
- foreach ( $value as $data_key => $data_value ) {
712
-
713
- $field_content .= '<option value="' . $data_value . '">' . get_the_title( $data_value ) . '</option>';
714
- }
715
- }
716
-
717
- $field_content .= '</select>';
718
-
719
- return $this->get_field( $field_data, $field_content );
720
- }
721
-
722
- function get_section( $field_data ) {
723
- $field_html = '<div class="wcf-field-row wcf-field-section">';
724
- $field_html .= '<div class="wcf-field-section-heading" colspan="2">';
725
- $field_html .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
726
-
727
- if ( isset( $field_data['help'] ) ) {
728
- $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help" title="' . esc_attr( $field_data['help'] ) . '"></i>';
729
- }
730
- $field_html .= '</div>';
731
- $field_html .= '</div>';
732
- return $field_html;
733
- }
734
-
735
- function get_description_field( $field_data ) {
736
-
737
- $field_html = '<div class="wcf-field-row wcf-field-desc ' . $field_data['name'] . '">';
738
- $field_html .= '<div class="wcf-field-desc-content">';
739
- $field_html .= $field_data['content'];
740
- $field_html .= '</div>';
741
- $field_html .= '</div>';
742
-
743
- return $field_html;
744
- }
745
-
746
- function get_checkout_field_repeater( $field_data ) {
747
-
748
- $value = array();
749
-
750
- $value[0] = array(
751
- 'add_to' => '',
752
- 'type' => '',
753
- 'label' => '',
754
- 'name' => '',
755
- );
756
-
757
- $field_content = '';
758
-
759
- $field_content .= '<div class="wcf-field-row">';
760
- // $field_content .= '<div class="wcf-field-row-heading">';
761
- // $field_content .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
762
- // $field_content .= '</div>';
763
- $field_content .= '<div class="wcf-field-row-content">';
764
- $field_content .= '<div class="wcf-cpf-wrap">';
765
-
766
- foreach ( $value as $p_key => $p_data ) {
767
- $field_content .= '<div class="wcf-cpf-row" data-key="' . $p_key . '">';
768
- $field_content .= '<div class="wcf-cpf-row-header">';
769
- $field_content .= '<span class="wcf-cpf-row-title">Add New Custom Field</span>';
770
- $field_content .= '</div>';
771
-
772
- $field_content .= '<div class="wcf-cpf-row-standard-fields">';
773
-
774
- /* Add To */
775
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-add_to">';
776
- $field_content .= '<span class="wcf-cpf-row-setting-label">Add to</span>';
777
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
778
- $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][add_to]" class="wcf-cpf-add_to">';
779
- $field_content .= '<option value="billing">Billing</option>';
780
- $field_content .= '<option value="shipping">Shipping</option>';
781
- $field_content .= '</select>';
782
- $field_content .= '</span>';
783
- $field_content .= '</div>';
784
-
785
- /* Type */
786
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-type">';
787
- $field_content .= '<span class="wcf-cpf-row-setting-label">Type</span>';
788
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
789
- $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][type]" class="wcf-cpf-type">';
790
- $field_content .= '<option value="text">Text</option>';
791
- $field_content .= '<option value="textarea">Textarea</option>';
792
- $field_content .= '<option value="select">Select</option>';
793
- $field_content .= '<option value="checkbox">Checkbox</option>';
794
- $field_content .= '</select>';
795
- $field_content .= '</span>';
796
- $field_content .= '</div>';
797
-
798
- /* Textarea */
799
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-options">';
800
- $field_content .= '<span class="wcf-cpf-row-setting-label">Options *</span>';
801
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
802
- $field_content .= '<textarea value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-options" placeholder="Enter your options separated by comma."></textarea>';
803
- $field_content .= '</span>';
804
- $field_content .= '</div>';
805
-
806
- /* Label */
807
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-label">';
808
- $field_content .= '<span class="wcf-cpf-row-setting-label">Label *</span>';
809
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
810
- $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-label">';
811
- $field_content .= '</span>';
812
- $field_content .= '</div>';
813
-
814
- /* Name */
815
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-name">';
816
- $field_content .= '<span class="wcf-cpf-row-setting-label">Name *</span>';
817
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
818
- $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][name]" class="wcf-cpf-name">';
819
- $field_content .= '</span>';
820
- $field_content .= '</div>';
821
-
822
- $field_content .= '</div>';
823
- $field_content .= '</div>';
824
- }
825
-
826
- /* Add New Custom Field */
827
- $field_content .= '<div class="wcf-cpf-add-row">';
828
- $field_content .= '<div class="wcf-cpf-add-wrap">';
829
- $field_content .= '<button class="button button-secondary wcf-cpf-add" data-name="wcf-checkout-custom-fields">Add New Field</button>';
830
- $field_content .= '</div>';
831
- $field_content .= '</div>';
832
- /* End Add new custom field */
833
-
834
- $field_content .= '</div>';
835
- $field_content .= '</div>';
836
- $field_content .= '</div>';
837
-
838
- return $field_content;
839
- }
840
-
841
- function get_product_selection_repeater( $field_data ) {
842
-
843
- $value = $field_data['value'];
844
-
845
- if ( ! is_array( $value ) ) {
846
-
847
- $value[0] = array(
848
- 'product' => '',
849
- );
850
- } else {
851
-
852
- if ( ! isset( $value[0] ) ) {
853
-
854
- $value[0] = array(
855
- 'product' => '',
856
- );
857
- }
858
- }
859
-
860
- $field_html = '';
861
-
862
- $field_html .= '<script type="text/html" id="tmpl-wcf-product-repeater">';
863
- $field_html .= $this->generate_product_repeater_html( '{{id}}' );
864
- $field_html .= '</script>';
865
-
866
- $field_html .= '<div class="wcf-field-row">';
867
- $field_html .= '<div class="wcf-field-row-content">';
868
- $field_html .= '<div class="wcf-repeatables-wrap">';
869
-
870
- if ( is_array( $value ) ) {
871
-
872
- foreach ( $value as $p_key => $p_data ) {
873
-
874
- $selected_options = '';
875
-
876
- if ( isset( $p_data['product'] ) ) {
877
-
878
- $product = wc_get_product( $p_data['product'] );
879
-
880
- // posts.
881
- if ( ! empty( $product ) ) {
882
- $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
883
-
884
- $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
885
- }
886
- }
887
-
888
- $field_html .= $this->generate_product_repeater_html( $p_key, $selected_options );
889
- }
890
- }
891
-
892
- $field_html .= '<div class="wcf-add-repeatable-row">';
893
- $field_html .= '<div class="submit wcf-add-repeatable-wrap">';
894
- $field_html .= '<button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products">Add New Product</button>';
895
- $field_html .= '</div>';
896
- $field_html .= '</div>';
897
- $field_html .= '</div>';
898
- $field_html .= '</div>';
899
- $field_html .= '</div>';
900
-
901
- $field_html .= '<div class="wcf-field-row wcf-repeat-notice">';
902
- /*$field_html .= '<p><i>The selected products will be automatically added in the cart for this checkout.</i></p>';*/
903
- $field_html .= '</div>';
904
-
905
- return $field_html;
906
- }
907
-
908
- function generate_product_repeater_html( $id, $options = '' ) {
909
-
910
- $field_html = '<div class="wcf-repeatable-row" data-key="' . $id . '">';
911
-
912
- $field_html .= '<div class="wcf-repeatable-row-standard-fields">';
913
-
914
- /* Product Name */
915
- $field_html .= '<div class="wcf-repeatable-fields wcf-sel-product">';
916
- $field_html .= '<span class="wcf-repeatable-row-setting-field">';
917
- $field_html .= '<select
918
- name="wcf-checkout-products[' . $id . '][product]"
919
- class="wcf-product-search"
920
- data-allow_clear="allow_clear"
921
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
922
- data-action="woocommerce_json_search_products_and_variations">';
923
- $field_html .= $options;
924
- $field_html .= '</select>';
925
- $field_html .= '</span>';
926
- $field_html .= '<span class="wcf-repeatable-row-actions">';
927
- $field_html .= '<a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">';
928
- $field_html .= '<span class="dashicons dashicons-trash"></span>';
929
- $field_html .= '<span class="wcf-repeatable-remove-button">'. __( 'Remove', 'cartflows' ).'</span>';
930
- $field_html .= '</a>';
931
- $field_html .= '</span>';
932
- $field_html .= '</div>';
933
- $field_html .= '</div>';
934
- $field_html .= '</div>';
935
-
936
- return $field_html;
937
- }
938
-
939
- function get_image_field( $field_data ) {
940
-
941
- $value = $field_data['value'];
942
-
943
- $attr = '';
944
-
945
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
946
-
947
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
948
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
949
- }
950
- }
951
-
952
- $display_preview_box = ( isset( $value ) && '' != $value ) ? 'display:block;' : 'display:none';
953
-
954
- $field_content = '<div id="wcf-image-preview" style="'.$display_preview_box.'">';
955
- if( isset( $value ) ){
956
- $field_content .= '<img src="'. $value .'" class="saved-image" name="'. $field_data['name'] .'" width="150">';
957
- }
958
- $field_content .= '</div>';
959
- // $field_content .= '<input type="hidden" id="wcf-image-id" class="wcf-image-id" name="wcf-image-id[image-id]" value="">';
960
- $field_content .= '<input type="hidden" id="wcf-image-value" class="wcf-image" name="' . $field_data['name'] . '" value="'.$value.'">';
961
-
962
- $field_content .= '<button type="button" ' . $attr . ' class="wcf-select-image button-secondary">Select Image</button>';
963
-
964
- $display_remove_button = ( isset( $value ) && '' != $value ) ? 'display:inline-block; margin-left: 5px;' : 'display:none';
965
-
966
- $field_content .= '<button type="button" class="wcf-remove-image button-secondary" style="'.$display_remove_button.'">Remove Image</button>';
967
-
968
- return $this->get_field( $field_data, $field_content );
969
- }
970
-
971
- /**
972
- * Localize variables in admin
973
- *
974
- * @param array $vars variables.
975
- */
976
- function localize_vars( $vars ) {
977
-
978
- $ajax_actions = array(
979
- 'wcf_add_checkout_custom_field',
980
- 'wcf_delete_checkout_custom_field',
981
- 'wcf_json_search_pages',
982
- 'wcf_json_search_coupons'
983
- );
984
-
985
- foreach ( $ajax_actions as $action ) {
986
-
987
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
988
- }
989
-
990
- return $vars;
991
- }
992
- }
993
- // @codingStandardsIgnoreEnd
1
+ <?php
2
+ // @codingStandardsIgnoreStart
3
+ /**
4
+ * Meta Fields.
5
+ *
6
+ * @package CartFlows
7
+ */
8
+
9
+ /**
10
+ * Class Cartflows_Meta_Fields.
11
+ */
12
+ class Cartflows_Meta_Fields {
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Initiator
23
+ */
24
+ public static function get_instance() {
25
+ if ( ! isset( self::$instance ) ) {
26
+ self::$instance = new self;
27
+ }
28
+
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Constructor
34
+ */
35
+ public function __construct() {
36
+
37
+ /* Add Scripts */
38
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_meta_scripts' ), 20 );
39
+
40
+ add_action( 'wp_ajax_wcf_json_search_coupons', array( $this, 'json_search_coupons' ) );
41
+
42
+ add_action( 'wp_ajax_wcf_add_checkout_custom_field', array( $this, 'add_checkout_custom_field' ) );
43
+ add_action( 'wp_ajax_wcf_delete_checkout_custom_field', array( $this, 'delete_checkout_custom_field' ) );
44
+
45
+ add_action( 'wp_ajax_wcf_json_search_pages', array( $this, 'json_search_pages' ) );
46
+
47
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
48
+ }
49
+
50
+ public function admin_meta_scripts() {
51
+
52
+ global $pagenow;
53
+ global $post;
54
+
55
+ $screen = get_current_screen();
56
+
57
+ if (
58
+ ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) &&
59
+ wcf()->utils->is_step_post_type( $screen->post_type )
60
+ ) {
61
+
62
+ wp_enqueue_style( 'woocommerce_admin_styles' );
63
+
64
+ wp_enqueue_script( 'select2' );
65
+ wp_enqueue_script( 'wc-enhanced-select' );
66
+
67
+ wp_enqueue_script(
68
+ 'wcf-admin-meta',
69
+ CARTFLOWS_URL . 'admin/meta-assets/js/admin-edit.js',
70
+ array( 'jquery', 'select2', 'wp-color-picker' ),
71
+ CARTFLOWS_VER,
72
+ true
73
+ );
74
+
75
+ wp_enqueue_style( 'wcf-admin-meta', CARTFLOWS_URL . 'admin/meta-assets/css/admin-edit.css', array( 'wp-color-picker' ), CARTFLOWS_VER );
76
+ wp_style_add_data( 'wcf-admin-meta', 'rtl', 'replace' );
77
+
78
+ $localize = array(
79
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
80
+ 'google_fonts' => CartFlows_Font_Families::get_google_fonts(),
81
+ 'system_fonts' => CartFlows_Font_Families::get_system_fonts(),
82
+ 'font_weights' => array(
83
+ '100' => __( 'Thin 100', 'cartflows' ),
84
+ '200' => __( 'Extra-Light 200', 'cartflows' ),
85
+ '300' => __( 'Light 300', 'cartflows' ),
86
+ '400' => __( 'Normal 400', 'cartflows' ),
87
+ '500' => __( 'Medium 500', 'cartflows' ),
88
+ '600' => __( 'Semi-Bold 600', 'cartflows' ),
89
+ '700' => __( 'Bold 700', 'cartflows' ),
90
+ '800' => __( 'Extra-Bold 800', 'cartflows' ),
91
+ '900' => __( 'Ultra-Bold 900', 'cartflows' ),
92
+ )
93
+ );
94
+
95
+ wp_localize_script( 'jquery', 'wcf', apply_filters( 'wcf_js_localize', $localize ) );
96
+
97
+ do_action( 'cartflows_admin_meta_scripts' );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Function to search coupons
103
+ */
104
+ public function json_search_coupons() {
105
+
106
+ check_admin_referer( 'wcf-json-search-coupons', 'security' );
107
+
108
+ global $wpdb;
109
+
110
+ $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
111
+
112
+ if ( empty( $term ) ) {
113
+ die();
114
+ }
115
+
116
+ $posts = wp_cache_get( 'wcf_search_coupons', 'wcf_funnel_Cart' );
117
+
118
+ if ( false === $posts ) {
119
+ $posts = $wpdb->get_results( // phpcs:ignore
120
+ $wpdb->prepare(
121
+ "SELECT *
122
+ FROM {$wpdb->prefix}posts
123
+ WHERE post_type = %s
124
+ AND post_title LIKE %s
125
+ AND post_status = %s",
126
+ 'shop_coupon',
127
+ $wpdb->esc_like( $term ) . '%',
128
+ 'publish'
129
+ )
130
+ );
131
+ wp_cache_set( 'wcf_search_coupons', $posts, 'wcf_funnel_Cart' );
132
+ }
133
+
134
+ $coupons_found = array();
135
+ $all_discount_types = wc_get_coupon_types();
136
+
137
+ if ( $posts ) {
138
+ foreach ( $posts as $post ) {
139
+
140
+ $discount_type = get_post_meta( $post->ID, 'discount_type', true );
141
+
142
+ if ( ! empty( $all_discount_types[ $discount_type ] ) ) {
143
+ $coupons_found[ get_the_title( $post->ID ) ] = get_the_title( $post->ID ) . ' (Type: ' . $all_discount_types[ $discount_type ] . ')';
144
+ }
145
+ }
146
+ }
147
+
148
+ wp_send_json( $coupons_found );
149
+ }
150
+
151
+ /**
152
+ * [add_checkout_custom_field description]
153
+ *
154
+ * @hook wcf_add_checkout_custom_field
155
+ */
156
+ public function add_checkout_custom_field() {
157
+
158
+ check_ajax_referer( 'wcf-add-checkout-custom-field', 'security' );
159
+
160
+ $post_id = intval( $_POST['post_id'] );
161
+ $add_to = sanitize_text_field( wp_unslash( $_POST['add_to'] ) );
162
+ $type = sanitize_text_field( wp_unslash( $_POST['type'] ) );
163
+ $options = sanitize_text_field( wp_unslash( $_POST['options'] ) );
164
+ $label = sanitize_text_field( wp_unslash( $_POST['label'] ) );
165
+ $name = sanitize_text_field( wp_unslash( $_POST['name'] ) );
166
+
167
+ if ( '' !== $name ) {
168
+
169
+ $fields = Cartflows_Helper::get_checkout_fields( $add_to, $post_id );
170
+ $field_keys = array_keys($fields);
171
+
172
+ $name = $add_to . '_' . sanitize_key( $name );
173
+ if( in_array($name, $field_keys) ) {
174
+ $name = $name . '_' . rand( 0000, 9999 );
175
+ }
176
+
177
+ $field_data = array(
178
+ 'type' => $type,
179
+ 'label' => $label,
180
+ 'placeholder' => '',
181
+ 'class' => array( 'form-row-wide' ),
182
+ 'label_class' => array(),
183
+ 'required' => true,
184
+ 'custom' => true,
185
+ );
186
+
187
+ if ( 'select' === $type ) {
188
+
189
+ $options = explode( ',', $options );
190
+ $field_data['options'] = array();
191
+
192
+ if ( is_array( $options ) && ! empty( $options ) ) {
193
+
194
+ foreach ( $options as $key => $value ) {
195
+
196
+ $field_data['options'][ $value ] = $value;
197
+ }
198
+ }
199
+ }
200
+
201
+ Cartflows_Helper::add_checkout_field( $add_to, $name, $field_data, $post_id );
202
+
203
+ $key = sanitize_key( $name );
204
+ $name = 'wcf-' . $key;
205
+
206
+ $field_args = array(
207
+ 'label' => $label,
208
+ 'name' => $name,
209
+ 'value' => 'yes',
210
+ 'after' => 'Enable',
211
+ );
212
+
213
+ $field_args['after_html'] = '<span class="wcf-cpf-actions" data-type="billing" data-key="' . $key . '"> | ';
214
+ $field_args['after_html'] .= '<a class="wcf-cpf-action-remove">' . __( 'Remove', 'cartflows' ) . '</a>';
215
+ $field_args['after_html'] .= '</span>';
216
+
217
+ $field_markup = wcf()->meta->get_checkbox_field( $field_args );
218
+
219
+ if( 'billing' === $add_to ) {
220
+ $add_to_class = 'wcf-cb-fields';
221
+ } else if( 'shipping' === $add_to ) {
222
+ $add_to_class = 'wcf-sb-fields';
223
+ }
224
+
225
+ $data = array(
226
+ 'field_data' => $field_data,
227
+ 'field_args' => $field_args,
228
+ 'add_to_class' => $add_to_class,
229
+ 'markup' => $field_markup,
230
+ );
231
+
232
+ wp_send_json( $data );
233
+ }
234
+
235
+ wp_send_json( false );
236
+
237
+ }
238
+
239
+ /**
240
+ * [delete_checkout_custom_field description]
241
+ *
242
+ * @hook wcf_delete_checkout_custom_field
243
+ * @return [type] [description]
244
+ */
245
+ public function delete_checkout_custom_field() {
246
+
247
+ check_ajax_referer( 'wcf-delete-checkout-custom-field', 'security' );
248
+
249
+ $post_id = intval( $_POST['post_id'] );
250
+ $type = sanitize_text_field( wp_unslash( $_POST['type'] ) );
251
+ $key = sanitize_text_field( wp_unslash( $_POST['key'] ) );
252
+
253
+ if ( '' !== $key ) {
254
+
255
+ Cartflows_Helper::delete_checkout_field( $type, $key, $post_id );
256
+
257
+ wp_send_json( true );
258
+
259
+ }
260
+
261
+ wp_send_json( false );
262
+
263
+ }
264
+
265
+ /**
266
+ * Function to search coupons
267
+ */
268
+ public function json_search_pages() {
269
+
270
+ check_ajax_referer( 'wcf-json-search-pages', 'security' );
271
+
272
+ $term = (string) urldecode( sanitize_text_field( wp_unslash( $_GET['term'] ) ) ); // phpcs:ignore
273
+
274
+ if ( empty( $term ) ) {
275
+ die( 'not found' );
276
+ }
277
+
278
+ $search_string = $term;
279
+ $data = array();
280
+ $result = array();
281
+
282
+ add_filter( 'posts_search', array( $this, 'search_only_titles' ), 10, 2 );
283
+
284
+ $query = new WP_Query(
285
+ array(
286
+ 's' => $search_string,
287
+ 'post_type' => 'page',
288
+ 'posts_per_page' => - 1,
289
+ )
290
+ );
291
+
292
+ if ( $query->have_posts() ) {
293
+ while ( $query->have_posts() ) {
294
+ $query->the_post();
295
+ $title = get_the_title();
296
+ $title .= ( 0 != $query->post->post_parent ) ? ' (' . get_the_title( $query->post->post_parent ) . ')' : '';
297
+ $id = get_the_id();
298
+ $data[] = array(
299
+ 'id' => $id,
300
+ 'text' => $title,
301
+ );
302
+ }
303
+ }
304
+
305
+ if ( is_array( $data ) && ! empty( $data ) ) {
306
+ $result[] = array(
307
+ 'text' => '',
308
+ 'children' => $data,
309
+ );
310
+ }
311
+
312
+ wp_reset_postdata();
313
+
314
+ // return the result in json.
315
+ wp_send_json( $result );
316
+ }
317
+
318
+ public function search_only_titles( $search, $wp_query ) {
319
+ if ( ! empty( $search ) && ! empty( $wp_query->query_vars['search_terms'] ) ) {
320
+ global $wpdb;
321
+
322
+ $q = $wp_query->query_vars;
323
+ $n = ! empty( $q['exact'] ) ? '' : '%';
324
+
325
+ $search = array();
326
+
327
+ foreach ( (array) $q['search_terms'] as $term ) {
328
+ $search[] = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $n . $wpdb->esc_like( $term ) . $n );
329
+ }
330
+
331
+ if ( ! is_user_logged_in() ) {
332
+ $search[] = "$wpdb->posts.post_password = ''";
333
+ }
334
+
335
+ $search = ' AND ' . implode( ' AND ', $search );
336
+ }
337
+
338
+ return $search;
339
+ }
340
+
341
+ function get_field( $field_data, $field_content ) {
342
+
343
+ $label = isset( $field_data['label'] ) ? $field_data['label'] : '';
344
+ $help = isset( $field_data['help'] ) ? $field_data['help'] : '';
345
+ $after_html = isset( $field_data['after_html'] ) ? $field_data['after_html'] : '';
346
+
347
+ $name_class = 'field-' . $field_data['name'];
348
+
349
+ $field_html = '<div class="wcf-field-row ' . $name_class . '">';
350
+
351
+ if( ! empty( $label ) || ! empty( $help ) ) {
352
+ $field_html .= '<div class="wcf-field-row-heading">';
353
+ if( ! empty( $label ) ) {
354
+ $field_html .= '<label>' . esc_html( $label ) . '</label>';
355
+ }
356
+ if ( ! empty( $help ) ) {
357
+ $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help">';
358
+ // $field_html .= '<span class="wcf-tooltip" data-tooltip= "'. esc_attr( $help ) .'"></span>';
359
+ $field_html .= '</i>';
360
+ $field_html .= '<span class="wcf-tooltip-text">';
361
+ $field_html .= $help;
362
+ $field_html .= '</span>';
363
+ }
364
+ $field_html .= '</div>';
365
+ }
366
+
367
+ $field_html .= '<div class="wcf-field-row-content">';
368
+ $field_html .= $field_content;
369
+
370
+ if ( ! empty( $after_html ) ) {
371
+ $field_html .= $after_html;
372
+ }
373
+
374
+ $field_html .= '</div>';
375
+ $field_html .= '</div>';
376
+
377
+ return $field_html;
378
+ }
379
+
380
+ function get_text_field( $field_data ) {
381
+
382
+ $value = $field_data['value'];
383
+
384
+ $attr = '';
385
+
386
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
387
+
388
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
389
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
390
+ }
391
+ }
392
+
393
+ $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
394
+
395
+ return $this->get_field( $field_data, $field_content );
396
+ }
397
+
398
+ function get_shortcode_field( $field_data ) {
399
+
400
+ $attr = '';
401
+
402
+ $attr_fields = array(
403
+ 'readonly' => 'readonly',
404
+ 'onfocus' => 'this.select()',
405
+ 'onmouseup' => 'return false',
406
+ );
407
+
408
+ if ( $attr_fields && is_array( $attr_fields ) ) {
409
+
410
+ foreach ( $attr_fields as $attr_key => $attr_value ) {
411
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
412
+ }
413
+ }
414
+
415
+ $field_content = '<input type="text" name="' . $field_data['name'] . '" value="' . $field_data['content'] . '" ' . $attr . '>';
416
+
417
+ return $this->get_field( $field_data, $field_content );
418
+ }
419
+
420
+ function get_display_field( $field_data ) {
421
+
422
+ $field_content = $field_data['content'];
423
+
424
+ return $this->get_field( $field_data, $field_content );
425
+ }
426
+
427
+ function get_hr_line_field( $field_data ) {
428
+
429
+ $field_data = array(
430
+ 'name' => 'wcf-hr-line',
431
+ 'content' => '<hr>'
432
+ );
433
+
434
+ $field_content = $field_data['content'];
435
+
436
+ return $this->get_field( $field_data, $field_content );
437
+ }
438
+
439
+ function get_number_field( $field_data ) {
440
+
441
+ $value = $field_data['value'];
442
+
443
+ $attr = '';
444
+
445
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
446
+
447
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
448
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
449
+ }
450
+ }
451
+
452
+ $field_content = '<input type="number" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
453
+
454
+ return $this->get_field( $field_data, $field_content );
455
+ }
456
+
457
+ function get_hidden_field( $field_data ) {
458
+
459
+ $value = $field_data['value'];
460
+
461
+ $attr = '';
462
+
463
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
464
+
465
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
466
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
467
+ }
468
+ }
469
+
470
+ $field_content = '<input type="hidden" id="' . $field_data['name'] . '" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
471
+
472
+ return $this->get_field( $field_data, $field_content );
473
+ }
474
+
475
+ function get_area_field( $field_data ) {
476
+
477
+ $value = $field_data['value'];
478
+
479
+ $field_content = '<textarea name="' . $field_data['name'] . '" rows="10" cols="50">';
480
+ $field_content .= $value;
481
+ $field_content .= '</textarea>';
482
+
483
+ return $this->get_field( $field_data, $field_content );
484
+ }
485
+
486
+ function get_checkbox_field( $field_data ) {
487
+
488
+ $value = $field_data['value'];
489
+
490
+ $field_content = '';
491
+ if ( isset( $field_data['before'] ) ) {
492
+ $field_content .= '<span>' . $field_data['before'] . '</span>';
493
+ }
494
+ $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
495
+ $field_content .= '<input type="checkbox" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . '>';
496
+
497
+ if ( isset( $field_data['after'] ) ) {
498
+ $field_content .= '<span>' . $field_data['after'] . '</span>';
499
+ }
500
+
501
+ return $this->get_field( $field_data, $field_content );
502
+ }
503
+
504
+ function get_radio_field( $field_data ) {
505
+
506
+ $value = $field_data['value'];
507
+ $field_content = '';
508
+
509
+ if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
510
+
511
+ foreach ( $field_data['options'] as $data_key => $data_value ) {
512
+
513
+ $field_content .= '<div class="wcf-radio-option">';
514
+ $field_content .= '<input type="radio" name="' . $field_data['name'] . '" value="' . $data_key . '" ' . checked( $data_key, $value, false ) . '>';
515
+ $field_content .= $data_value;
516
+ $field_content .= '</div>';
517
+ }
518
+ }
519
+
520
+ return $this->get_field( $field_data, $field_content );
521
+ }
522
+
523
+ function get_font_family_field( $field_data ) {
524
+
525
+ $value = $field_data['value'];
526
+
527
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
528
+
529
+ $field_content = '<select class="wcf-field-font-family" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
530
+
531
+ $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
532
+
533
+ $field_content .= '<optgroup label="Other System Fonts">';
534
+ foreach ( CartFlows_Font_Families::get_system_fonts() as $name => $variants ) {
535
+ $field_content .= '<option value="' . esc_attr( $name ) . '" ' . selected( $name, $value, false ) . '>' . esc_attr( $name ) . '</option>';
536
+ }
537
+ $field_content .= '</optgroup>';
538
+ $field_content .= '<optgroup label="Google">';
539
+ foreach ( CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) {
540
+ $variants = wcf_get_prop( $single_font, '0' );
541
+ $category = wcf_get_prop( $single_font, '1' );
542
+ $font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category );
543
+ $field_content .= '<option value="' . esc_attr( $font_value ) . '" ' . selected( $font_value, $value, false ) . '>' . esc_attr( $name ) . '</option>';
544
+ }
545
+ $field_content .= '</optgroup>';
546
+
547
+ $field_content .= '</select>';
548
+
549
+ return $this->get_field( $field_data, $field_content );
550
+ }
551
+
552
+ function get_font_weight_field( $field_data ) {
553
+
554
+ $value = $field_data['value'];
555
+
556
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
557
+
558
+ $field_content = '<select data-selected="'.esc_attr( $value ).'" class="wcf-field-font-weight" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
559
+
560
+ $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
561
+
562
+ $field_content .= '</select>';
563
+
564
+ return $this->get_field( $field_data, $field_content );
565
+ }
566
+
567
+ function get_select_field( $field_data ) {
568
+
569
+ $value = $field_data['value'];
570
+ $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
571
+
572
+ $field_content = '<select name="' . $field_data['name'] . '">';
573
+
574
+
575
+ if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
576
+
577
+ foreach ( $field_data['options'] as $data_key => $data_value ) {
578
+
579
+ $disabled = '';
580
+
581
+ if ( array_key_exists( $data_key, $pro_options ) ) {
582
+ $disabled = 'disabled ';
583
+ $data_value = $pro_options[ $data_key ];
584
+ }
585
+
586
+ $field_content .= '<option value="' . $data_key . '" ' . selected( $value, $data_key, false ) . ' ' . $disabled .'>' . $data_value . '</option>';
587
+ }
588
+ }
589
+
590
+ $field_content .= '</select>';
591
+
592
+ if ( isset( $field_data['after'] ) ) {
593
+ $field_content .= '<span>' . $field_data['after'] . '</span>';
594
+ }
595
+
596
+ return $this->get_field( $field_data, $field_content );
597
+ }
598
+
599
+ function get_color_picker_field( $field_data ) {
600
+
601
+ $value = $field_data['value'];
602
+
603
+ $field_content = '<input class="wcf-color-picker" type="text" name="' . $field_data['name'] . '" value="' . $value . '">';
604
+
605
+ return $this->get_field( $field_data, $field_content );
606
+ }
607
+
608
+ function get_product_selection_field( $field_data ) {
609
+
610
+ $value = $field_data['value'];
611
+
612
+ $multiple = '';
613
+
614
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
615
+ $multiple = ' multiple="multiple"';
616
+ }
617
+
618
+ $allow_clear = '';
619
+
620
+ if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
621
+ $allow_clear = ' data-allow_clear="allow_clear"';
622
+ }
623
+
624
+ $field_content = '<select
625
+ name="' . $field_data['name'] . '[]"
626
+ class="wcf-product-search" ' . $multiple . $allow_clear . '
627
+ data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
628
+ data-action="woocommerce_json_search_products_and_variations">';
629
+
630
+ if ( is_array( $value ) && ! empty( $value ) ) {
631
+
632
+ foreach ( $value as $data_key => $product_id ) {
633
+
634
+ $product = wc_get_product( $product_id );
635
+
636
+ // posts.
637
+ if ( ! empty( $product ) ) {
638
+ $post_title = $product->get_name() . ' (#' . $product_id . ')';
639
+
640
+ $field_content .= '<option value="' . $product_id . '" selected="selected" >' . $post_title . '</option>';
641
+ }
642
+ }
643
+ }
644
+ $field_content .= '</select>';
645
+
646
+ return $this->get_field( $field_data, $field_content );
647
+ }
648
+
649
+ function get_coupon_selection_field( $field_data ) {
650
+
651
+ $value = $field_data['value'];
652
+
653
+ $multiple = '';
654
+
655
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
656
+ $multiple = ' multiple="multiple"';
657
+ }
658
+
659
+ $allow_clear = '';
660
+
661
+ if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
662
+ $allow_clear = ' data-allow_clear="allow_clear"';
663
+ }
664
+
665
+ $field_content = '<select
666
+ name="' . $field_data['name'] . '[]"
667
+ class="wc-coupon-search wcf-coupon-search" ' . $multiple . $allow_clear . '
668
+ data-placeholder="' . __( 'Search for a coupon&hellip;', 'cartflows' ) . '"
669
+ data-action="wcf_json_search_coupons">';
670
+
671
+ if ( is_array( $value ) && ! empty( $value ) ) {
672
+
673
+ $all_discount_types = wc_get_coupon_types();
674
+
675
+ foreach ( $value as $coupon_title ) {
676
+
677
+ $coupon = new WC_Coupon( $coupon_title );
678
+
679
+ $discount_type = $coupon->get_discount_type();
680
+
681
+ if ( isset( $discount_type ) && $discount_type ) {
682
+ $discount_type = ' ( Type: ' . $all_discount_types[ $discount_type ] . ' )';
683
+ }
684
+
685
+ $field_content .= '<option value="' . $coupon_title . '" selected="selected">' . $coupon_title . $discount_type . '</option>';
686
+ }
687
+ }
688
+
689
+ $field_content .= '</select>';
690
+
691
+ return $this->get_field( $field_data, $field_content );
692
+ }
693
+
694
+ function get_page_selection_field( $field_data ) {
695
+
696
+ $value = $field_data['value'];
697
+
698
+ $multiple = '';
699
+
700
+ if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
701
+ $multiple = 'multiple="multiple"';
702
+ }
703
+
704
+ $field_content = '<select
705
+ name="' . $field_data['name'] . '[]"
706
+ class="wcf-search-pages" ' . $multiple . '"
707
+ data-action="wcf_json_search_pages">';
708
+
709
+ if ( is_array( $value ) && ! empty( $value ) ) {
710
+
711
+ foreach ( $value as $data_key => $data_value ) {
712
+
713
+ $field_content .= '<option value="' . $data_value . '">' . get_the_title( $data_value ) . '</option>';
714
+ }
715
+ }
716
+
717
+ $field_content .= '</select>';
718
+
719
+ return $this->get_field( $field_data, $field_content );
720
+ }
721
+
722
+ function get_section( $field_data ) {
723
+ $field_html = '<div class="wcf-field-row wcf-field-section">';
724
+ $field_html .= '<div class="wcf-field-section-heading" colspan="2">';
725
+ $field_html .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
726
+
727
+ if ( isset( $field_data['help'] ) ) {
728
+ $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help" title="' . esc_attr( $field_data['help'] ) . '"></i>';
729
+ }
730
+ $field_html .= '</div>';
731
+ $field_html .= '</div>';
732
+ return $field_html;
733
+ }
734
+
735
+ function get_description_field( $field_data ) {
736
+
737
+ $field_html = '<div class="wcf-field-row wcf-field-desc ' . $field_data['name'] . '">';
738
+ $field_html .= '<div class="wcf-field-desc-content">';
739
+ $field_html .= $field_data['content'];
740
+ $field_html .= '</div>';
741
+ $field_html .= '</div>';
742
+
743
+ return $field_html;
744
+ }
745
+
746
+ function get_checkout_field_repeater( $field_data ) {
747
+
748
+ $value = array();
749
+
750
+ $value[0] = array(
751
+ 'add_to' => '',
752
+ 'type' => '',
753
+ 'label' => '',
754
+ 'name' => '',
755
+ );
756
+
757
+ $field_content = '';
758
+
759
+ $field_content .= '<div class="wcf-field-row">';
760
+ // $field_content .= '<div class="wcf-field-row-heading">';
761
+ // $field_content .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
762
+ // $field_content .= '</div>';
763
+ $field_content .= '<div class="wcf-field-row-content">';
764
+ $field_content .= '<div class="wcf-cpf-wrap">';
765
+
766
+ foreach ( $value as $p_key => $p_data ) {
767
+ $field_content .= '<div class="wcf-cpf-row" data-key="' . $p_key . '">';
768
+ $field_content .= '<div class="wcf-cpf-row-header">';
769
+ $field_content .= '<span class="wcf-cpf-row-title">Add New Custom Field</span>';
770
+ $field_content .= '</div>';
771
+
772
+ $field_content .= '<div class="wcf-cpf-row-standard-fields">';
773
+
774
+ /* Add To */
775
+ $field_content .= '<div class="wcf-cpf-fields wcf-cpf-add_to">';
776
+ $field_content .= '<span class="wcf-cpf-row-setting-label">Add to</span>';
777
+ $field_content .= '<span class="wcf-cpf-row-setting-field">';
778
+ $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][add_to]" class="wcf-cpf-add_to">';
779
+ $field_content .= '<option value="billing">Billing</option>';
780
+ $field_content .= '<option value="shipping">Shipping</option>';
781
+ $field_content .= '</select>';
782
+ $field_content .= '</span>';
783
+ $field_content .= '</div>';
784
+
785
+ /* Type */
786
+ $field_content .= '<div class="wcf-cpf-fields wcf-cpf-type">';
787
+ $field_content .= '<span class="wcf-cpf-row-setting-label">Type</span>';
788
+ $field_content .= '<span class="wcf-cpf-row-setting-field">';
789
+ $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][type]" class="wcf-cpf-type">';
790
+ $field_content .= '<option value="text">Text</option>';
791
+ $field_content .= '<option value="textarea">Textarea</option>';
792
+ $field_content .= '<option value="select">Select</option>';
793
+ $field_content .= '<option value="checkbox">Checkbox</option>';
794
+ $field_content .= '</select>';
795
+ $field_content .= '</span>';
796
+ $field_content .= '</div>';
797
+
798
+ /* Textarea */
799
+ $field_content .= '<div class="wcf-cpf-fields wcf-cpf-options">';
800
+ $field_content .= '<span class="wcf-cpf-row-setting-label">Options *</span>';
801
+ $field_content .= '<span class="wcf-cpf-row-setting-field">';
802
+ $field_content .= '<textarea value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-options" placeholder="Enter your options separated by comma."></textarea>';
803
+ $field_content .= '</span>';
804
+ $field_content .= '</div>';
805
+
806
+ /* Label */
807
+ $field_content .= '<div class="wcf-cpf-fields wcf-cpf-label">';
808
+ $field_content .= '<span class="wcf-cpf-row-setting-label">Label *</span>';
809
+ $field_content .= '<span class="wcf-cpf-row-setting-field">';
810
+ $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-label">';
811
+ $field_content .= '</span>';
812
+ $field_content .= '</div>';
813
+
814
+ /* Name */
815
+ $field_content .= '<div class="wcf-cpf-fields wcf-cpf-name">';
816
+ $field_content .= '<span class="wcf-cpf-row-setting-label">Name *</span>';
817
+ $field_content .= '<span class="wcf-cpf-row-setting-field">';
818
+ $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][name]" class="wcf-cpf-name">';
819
+ $field_content .= '</span>';
820
+ $field_content .= '</div>';
821
+
822
+ $field_content .= '</div>';
823
+ $field_content .= '</div>';
824
+ }
825
+
826
+ /* Add New Custom Field */
827
+ $field_content .= '<div class="wcf-cpf-add-row">';
828
+ $field_content .= '<div class="wcf-cpf-add-wrap">';
829
+ $field_content .= '<button class="button button-secondary wcf-cpf-add" data-name="wcf-checkout-custom-fields">Add New Field</button>';
830
+ $field_content .= '</div>';
831
+ $field_content .= '</div>';
832
+ /* End Add new custom field */
833
+
834
+ $field_content .= '</div>';
835
+ $field_content .= '</div>';
836
+ $field_content .= '</div>';
837
+
838
+ return $field_content;
839
+ }
840
+
841
+ function get_product_selection_repeater( $field_data ) {
842
+
843
+ $value = $field_data['value'];
844
+
845
+ if ( ! is_array( $value ) ) {
846
+
847
+ $value[0] = array(
848
+ 'product' => '',
849
+ );
850
+ } else {
851
+
852
+ if ( ! isset( $value[0] ) ) {
853
+
854
+ $value[0] = array(
855
+ 'product' => '',
856
+ );
857
+ }
858
+ }
859
+
860
+ $field_html = '';
861
+
862
+ $field_html .= '<script type="text/html" id="tmpl-wcf-product-repeater">';
863
+ $field_html .= $this->generate_product_repeater_html( '{{id}}' );
864
+ $field_html .= '</script>';
865
+
866
+ $field_html .= '<div class="wcf-field-row">';
867
+ $field_html .= '<div class="wcf-field-row-content">';
868
+ $field_html .= '<div class="wcf-repeatables-wrap">';
869
+
870
+ if ( is_array( $value ) ) {
871
+
872
+ foreach ( $value as $p_key => $p_data ) {
873
+
874
+ $selected_options = '';
875
+
876
+ if ( isset( $p_data['product'] ) ) {
877
+
878
+ $product = wc_get_product( $p_data['product'] );
879
+
880
+ // posts.
881
+ if ( ! empty( $product ) ) {
882
+ $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
883
+
884
+ $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
885
+ }
886
+ }
887
+
888
+ $field_html .= $this->generate_product_repeater_html( $p_key, $selected_options );
889
+ }
890
+ }
891
+
892
+ $field_html .= '<div class="wcf-add-repeatable-row">';
893
+ $field_html .= '<div class="submit wcf-add-repeatable-wrap">';
894
+ $field_html .= '<button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products">Add New Product</button>';
895
+ $field_html .= '</div>';
896
+ $field_html .= '</div>';
897
+ $field_html .= '</div>';
898
+ $field_html .= '</div>';
899
+ $field_html .= '</div>';
900
+
901
+ return $field_html;
902
+ }
903
+
904
+ function generate_product_repeater_html( $id, $options = '' ) {
905
+
906
+ $field_html = '<div class="wcf-repeatable-row" data-key="' . $id . '">';
907
+
908
+ $field_html .= '<div class="wcf-repeatable-row-standard-fields">';
909
+
910
+ /* Product Name */
911
+ $field_html .= '<div class="wcf-repeatable-fields wcf-sel-product">';
912
+ $field_html .= '<span class="wcf-repeatable-row-setting-field">';
913
+ $field_html .= '<select
914
+ name="wcf-checkout-products[' . $id . '][product]"
915
+ class="wcf-product-search"
916
+ data-allow_clear="allow_clear"
917
+ data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
918
+ data-action="woocommerce_json_search_products_and_variations">';
919
+ $field_html .= $options;
920
+ $field_html .= '</select>';
921
+ $field_html .= '</span>';
922
+ $field_html .= '<span class="wcf-repeatable-row-actions">';
923
+ $field_html .= '<a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">';
924
+ $field_html .= '<span class="dashicons dashicons-trash"></span>';
925
+ $field_html .= '<span class="wcf-repeatable-remove-button">'. __( 'Remove', 'cartflows' ).'</span>';
926
+ $field_html .= '</a>';
927
+ $field_html .= '</span>';
928
+ $field_html .= '</div>';
929
+ $field_html .= '</div>';
930
+ $field_html .= '</div>';
931
+
932
+ return $field_html;
933
+ }
934
+
935
+ function get_image_field( $field_data ) {
936
+
937
+ $value = $field_data['value'];
938
+
939
+ $attr = '';
940
+
941
+ if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
942
+
943
+ foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
944
+ $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
945
+ }
946
+ }
947
+
948
+ $display_preview_box = ( isset( $value ) && '' != $value ) ? 'display:block;' : 'display:none';
949
+
950
+ $field_content = '<div id="wcf-image-preview" style="'.$display_preview_box.'">';
951
+ if( isset( $value ) ){
952
+ $field_content .= '<img src="'. $value .'" class="saved-image" name="'. $field_data['name'] .'" width="150">';
953
+ }
954
+ $field_content .= '</div>';
955
+ // $field_content .= '<input type="hidden" id="wcf-image-id" class="wcf-image-id" name="wcf-image-id[image-id]" value="">';
956
+ $field_content .= '<input type="hidden" id="wcf-image-value" class="wcf-image" name="' . $field_data['name'] . '" value="'.$value.'">';
957
+
958
+ $field_content .= '<button type="button" ' . $attr . ' class="wcf-select-image button-secondary">Select Image</button>';
959
+
960
+ $display_remove_button = ( isset( $value ) && '' != $value ) ? 'display:inline-block; margin-left: 5px;' : 'display:none';
961
+
962
+ $field_content .= '<button type="button" class="wcf-remove-image button-secondary" style="'.$display_remove_button.'">Remove Image</button>';
963
+
964
+ return $this->get_field( $field_data, $field_content );
965
+ }
966
+
967
+ /**
968
+ * Localize variables in admin
969
+ *
970
+ * @param array $vars variables.
971
+ */
972
+ function localize_vars( $vars ) {
973
+
974
+ $ajax_actions = array(
975
+ 'wcf_add_checkout_custom_field',
976
+ 'wcf_delete_checkout_custom_field',
977
+ 'wcf_json_search_pages',
978
+ 'wcf_json_search_coupons'
979
+ );
980
+
981
+ foreach ( $ajax_actions as $action ) {
982
+
983
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
984
+ }
985
+
986
+ return $vars;
987
+ }
988
+ }
989
+ // @codingStandardsIgnoreEnd
 
 
 
 
classes/class-cartflows-thrive-compatibility.php CHANGED
@@ -1,63 +1,63 @@
1
- <?php
2
- /**
3
- * Thrive Visual Editor Compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Class for Thrive Visual Editor Compatibility
10
- */
11
- class Cartflows_Thrive_Compatibility {
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
- // Add CartFlows post type in the thrive page editor.
36
- add_filter( 'tve_landing_page_post_types', array( $this, 'send_post_type_to_thrive' ) );
37
-
38
- add_filter( 'tcb_can_use_landing_pages', array( $this, 'send_post_type_to_thrive' ) );
39
-
40
- add_filter( 'tcb_has_templates_tab', array( $this, 'send_post_type_to_thrive' ) );
41
- }
42
-
43
- /**
44
- * Return step post type for Thrive Architect.
45
- *
46
- * @since 1.0.0
47
- * @param array $post_type_pt the current step post type.
48
- * @return array $post_type_pt current step post type.
49
- */
50
- function send_post_type_to_thrive( $post_type_pt ) {
51
-
52
- $post_type_pt = array();
53
-
54
- $post_type_pt[] = CARTFLOWS_STEP_POST_TYPE;
55
-
56
- return $post_type_pt;
57
- }
58
- }
59
-
60
- /**
61
- * Kicking this off by calling 'get_instance()' method
62
- */
63
- Cartflows_Thrive_Compatibility::get_instance();
1
+ <?php
2
+ /**
3
+ * Thrive Visual Editor Compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Class for Thrive Visual Editor Compatibility
10
+ */
11
+ class Cartflows_Thrive_Compatibility {
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
+ // Add CartFlows post type in the thrive page editor.
36
+ add_filter( 'tve_landing_page_post_types', array( $this, 'send_post_type_to_thrive' ) );
37
+
38
+ add_filter( 'tcb_can_use_landing_pages', array( $this, 'send_post_type_to_thrive' ) );
39
+
40
+ add_filter( 'tcb_has_templates_tab', array( $this, 'send_post_type_to_thrive' ) );
41
+ }
42
+
43
+ /**
44
+ * Return step post type for Thrive Architect.
45
+ *
46
+ * @since 1.0.0
47
+ * @param array $post_type_pt the current step post type.
48
+ * @return array $post_type_pt current step post type.
49
+ */
50
+ function send_post_type_to_thrive( $post_type_pt ) {
51
+
52
+ $post_type_pt = array();
53
+
54
+ $post_type_pt[] = CARTFLOWS_STEP_POST_TYPE;
55
+
56
+ return $post_type_pt;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Kicking this off by calling 'get_instance()' method
62
+ */
63
+ Cartflows_Thrive_Compatibility::get_instance();
includes/exporter.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Exporter
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ ?>
9
+ <div class="cartflows-ie">
10
+ <div class="postbox">
11
+ <div class="inside">
12
+ <h3><?php _e( 'Export Flows to a JSON file', 'cartflows' ); ?></h3>
13
+ <p><?php _e( 'This tool allows you to generate and download a JSON file containing a list of all flows.', 'cartflows' ); ?></p>
14
+ <form method="post">
15
+ <p><input type="hidden" name="cartflows-action" value="export" /></p>
16
+ <p style="margin-bottom:0">
17
+ <?php wp_nonce_field( 'cartflows-action-nonce', 'cartflows-action-nonce' ); ?>
18
+ <?php submit_button( __( 'Export', 'cartflows' ), 'button-primary', 'submit', false, array( 'id' => '' ) ); ?>
19
+ </p>
20
+ </form>
21
+ </div>
22
+ </div>
23
+ </div>
includes/importer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Importer
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ ?>
9
+ <div class="cartflows-ie">
10
+ <div class="postbox">
11
+ <div class="inside">
12
+ <h3><?php _e( 'Import Flows to a JSON file', 'cartflows' ); ?></h3>
13
+ <p><?php _e( 'This tool allows you to import the flows from the JSON file.', 'cartflows' ); ?></p>
14
+ <form method="post" enctype="multipart/form-data">
15
+ <p>
16
+ <input type="file" name="file"/>
17
+ <input type="hidden" name="cartflows-action" value="import" />
18
+ </p>
19
+ <p style="margin-bottom:0">
20
+ <?php wp_nonce_field( 'cartflows-action-nonce', 'cartflows-action-nonce' ); ?>
21
+ <?php submit_button( __( 'Import', 'cartflows' ), 'button-primary', 'submit', false, array( 'id' => '' ) ); ?>
22
+ </p>
23
+ </form>
24
+ </div>
25
+ </div>
26
+ </div>
languages/cartflows.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: CartFlows 1.1.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2019-01-02 09:37:21+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -88,11 +88,11 @@ msgstr ""
88
  msgid "Request successfully processed!"
89
  msgstr ""
90
 
91
- #: classes/class-cartflows-cloning.php:407
92
  msgid "Clone this flow"
93
  msgstr ""
94
 
95
- #: classes/class-cartflows-cloning.php:407
96
  msgid "Clone"
97
  msgstr ""
98
 
@@ -102,109 +102,141 @@ msgid ""
102
  "be deactivated from the flow settings in the admin dashboard."
103
  msgstr ""
104
 
105
- #: classes/class-cartflows-importer.php:98
106
- msgid "Loading Steps"
 
 
 
 
107
  msgstr ""
108
 
109
  #: classes/class-cartflows-importer.php:100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  msgid "Getting steps from the cloud. Please wait for the moment."
111
  msgstr ""
112
 
113
- #: classes/class-cartflows-importer.php:111
114
  msgid "Searching Template.."
115
  msgstr ""
116
 
117
- #: classes/class-cartflows-importer.php:113
118
  msgid "Getting templates from the cloud. Please wait for the moment."
119
  msgstr ""
120
 
121
- #: classes/class-cartflows-importer.php:122
122
  msgid "Importing.."
123
  msgstr ""
124
 
125
- #: classes/class-cartflows-importer.php:131
126
- #: classes/class-cartflows-importer.php:171
127
  msgid "Imported"
128
  msgstr ""
129
 
130
- #: classes/class-cartflows-importer.php:132
131
- #: classes/class-cartflows-importer.php:172
132
  msgid "Thanks for patience"
133
  msgstr ""
134
 
135
- #: classes/class-cartflows-importer.php:141
136
- #: classes/class-cartflows-importer.php:153
137
  msgid "Coming Soon!"
138
  msgstr ""
139
 
140
- #: classes/class-cartflows-importer.php:172
141
  msgid "Redirecting to the Elementor edit window."
142
  msgstr ""
143
 
144
- #: classes/class-cartflows-importer.php:218
145
- #: classes/class-cartflows-importer.php:302
146
  msgid "Pro"
147
  msgstr ""
148
 
149
- #: classes/class-cartflows-importer.php:241
150
- #: classes/class-cartflows-importer.php:324
151
  msgid "Activate License"
152
  msgstr ""
153
 
154
- #: classes/class-cartflows-importer.php:243
155
- #: classes/class-cartflows-importer.php:326
156
  msgid "Get Pro"
157
  msgstr ""
158
 
159
- #: classes/class-cartflows-importer.php:268
160
  msgid "Create"
161
  msgstr ""
162
 
163
- #: classes/class-cartflows-importer.php:366
164
  msgid "All"
165
  msgstr ""
166
 
167
- #: classes/class-cartflows-importer.php:370
168
  msgid "Select Step Type"
169
  msgstr ""
170
 
171
- #: classes/class-cartflows-importer.php:403
172
  msgid "Import from Cloud"
173
  msgstr ""
174
 
175
- #: classes/class-cartflows-importer.php:423
176
- #: classes/class-cartflows-importer.php:426
177
- #: classes/class-cartflows-importer.php:429
178
  #. translators: %s is plugin name.
179
  msgid "Import"
180
  msgstr ""
181
 
182
- #: classes/class-cartflows-importer.php:739
183
  #: modules/flow/classes/class-cartflows-flow-meta.php:224
184
  msgid "Landing Page"
185
  msgstr ""
186
 
187
- #: classes/class-cartflows-importer.php:740
188
  #: modules/flow/classes/class-cartflows-flow-meta.php:225
189
  msgid "Checkout Page"
190
  msgstr ""
191
 
192
- #: classes/class-cartflows-importer.php:741
193
  #: modules/flow/classes/class-cartflows-flow-meta.php:226
194
  msgid "Thank You Page"
195
  msgstr ""
196
 
197
- #: classes/class-cartflows-importer.php:846
198
  #. translators: %s: template ID
199
  msgid "Invalid template id %1$s or post id %2$s."
200
  msgstr ""
201
 
202
- #: classes/class-cartflows-importer.php:890
203
  #. translators: %s: flow ID
204
  msgid "Invalid flow id %1$s OR step type %2$s."
205
  msgstr ""
206
 
207
- #: classes/class-cartflows-importer.php:1012
208
  msgid ""
209
  "Elementor is not activated. Please activate plugin Elementor Page Builder "
210
  "to import the step."
@@ -262,12 +294,12 @@ msgid "Ultra-Bold 900"
262
  msgstr ""
263
 
264
  #: classes/class-cartflows-meta-fields.php:214
265
- #: classes/class-cartflows-meta-fields.php:929
266
  msgid "Remove"
267
  msgstr ""
268
 
269
  #: classes/class-cartflows-meta-fields.php:627
270
- #: classes/class-cartflows-meta-fields.php:921
271
  msgid "Search for a product&hellip;"
272
  msgstr ""
273
 
@@ -443,6 +475,31 @@ msgstr ""
443
  msgid "Submit a Ticket »"
444
  msgstr ""
445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  #: modules/checkout/classes/class-cartflows-checkout-markup.php:161
447
  msgid "Checkout ID not found"
448
  msgstr ""
@@ -455,11 +512,11 @@ msgstr ""
455
  msgid "This product can't be purcahsed"
456
  msgstr ""
457
 
458
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:879
459
  msgid "Coupon Code"
460
  msgstr ""
461
 
462
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:884
463
  msgid "Apply"
464
  msgstr ""
465
 
@@ -755,8 +812,8 @@ msgstr ""
755
 
756
  #: modules/flow/classes/class-cartflows-flow-post-type.php:61
757
  #: modules/flow/classes/class-cartflows-flow-post-type.php:63
758
- #: modules/flow/classes/class-cartflows-step-post-type.php:143
759
- #: modules/flow/classes/class-cartflows-step-post-type.php:145
760
  msgid "Add New"
761
  msgstr ""
762
 
@@ -778,57 +835,57 @@ msgstr ""
778
 
779
  #: modules/flow/classes/class-cartflows-flow-post-type.php:252
780
  #: modules/flow/classes/class-cartflows-flow-post-type.php:258
781
- #: modules/flow/classes/class-cartflows-step-post-type.php:376
782
- #: modules/flow/classes/class-cartflows-step-post-type.php:382
783
  #. translators: %s: singular custom post type name
784
  msgid "%s updated."
785
  msgstr ""
786
 
787
  #: modules/flow/classes/class-cartflows-flow-post-type.php:254
788
- #: modules/flow/classes/class-cartflows-step-post-type.php:378
789
  #. translators: %s: singular custom post type name
790
  msgid "Custom %s updated."
791
  msgstr ""
792
 
793
  #: modules/flow/classes/class-cartflows-flow-post-type.php:256
794
- #: modules/flow/classes/class-cartflows-step-post-type.php:380
795
  #. translators: %s: singular custom post type name
796
  msgid "Custom %s deleted."
797
  msgstr ""
798
 
799
  #: modules/flow/classes/class-cartflows-flow-post-type.php:260
800
- #: modules/flow/classes/class-cartflows-step-post-type.php:384
801
  #. translators: %1$s: singular custom post type name ,%2$s: date and time of
802
  #. the revision
803
  msgid "%1$s restored to revision from %2$s"
804
  msgstr ""
805
 
806
  #: modules/flow/classes/class-cartflows-flow-post-type.php:262
807
- #: modules/flow/classes/class-cartflows-step-post-type.php:386
808
  #. translators: %s: singular custom post type name
809
  msgid "%s published."
810
  msgstr ""
811
 
812
  #: modules/flow/classes/class-cartflows-flow-post-type.php:264
813
- #: modules/flow/classes/class-cartflows-step-post-type.php:388
814
  #. translators: %s: singular custom post type name
815
  msgid "%s saved."
816
  msgstr ""
817
 
818
  #: modules/flow/classes/class-cartflows-flow-post-type.php:266
819
- #: modules/flow/classes/class-cartflows-step-post-type.php:390
820
  #. translators: %s: singular custom post type name
821
  msgid "%s submitted."
822
  msgstr ""
823
 
824
  #: modules/flow/classes/class-cartflows-flow-post-type.php:268
825
- #: modules/flow/classes/class-cartflows-step-post-type.php:392
826
  #. translators: %s: singular custom post type name
827
  msgid "%s scheduled for."
828
  msgstr ""
829
 
830
  #: modules/flow/classes/class-cartflows-flow-post-type.php:270
831
- #: modules/flow/classes/class-cartflows-step-post-type.php:394
832
  #. translators: %s: singular custom post type name
833
  msgid "%s draft updated."
834
  msgstr ""
@@ -838,61 +895,61 @@ msgstr ""
838
  msgid "Next Step"
839
  msgstr ""
840
 
841
- #: modules/flow/classes/class-cartflows-step-post-type.php:139
842
  msgid "Search Steps"
843
  msgstr ""
844
 
845
- #: modules/flow/classes/class-cartflows-step-post-type.php:140
846
  msgid "All Steps"
847
  msgstr ""
848
 
849
- #: modules/flow/classes/class-cartflows-step-post-type.php:141
850
  #: modules/flow/view/meta-flow-steps.php:97
851
  msgid "Edit Step"
852
  msgstr ""
853
 
854
- #: modules/flow/classes/class-cartflows-step-post-type.php:142
855
  #: modules/flow/view/meta-flow-steps.php:93
856
  msgid "View Step"
857
  msgstr ""
858
 
859
- #: modules/flow/classes/class-cartflows-step-post-type.php:144
860
  msgid "Update Step"
861
  msgstr ""
862
 
863
- #: modules/flow/classes/class-cartflows-step-post-type.php:146
864
  msgid "New Step Name"
865
  msgstr ""
866
 
867
- #: modules/flow/classes/class-cartflows-step-post-type.php:169
868
  msgid "Step Type"
869
  msgstr ""
870
 
871
- #: modules/flow/classes/class-cartflows-step-post-type.php:178
872
  msgid "Step Flow"
873
  msgstr ""
874
 
875
- #: modules/flow/classes/class-cartflows-step-post-type.php:195
876
  #: modules/flow/view/meta-flow-steps.php:9
877
  msgid "Landing"
878
  msgstr ""
879
 
880
- #: modules/flow/classes/class-cartflows-step-post-type.php:201
881
  #: modules/flow/view/meta-flow-steps.php:10
882
  msgid "Checkout"
883
  msgstr ""
884
 
885
- #: modules/flow/classes/class-cartflows-step-post-type.php:207
886
  #: modules/flow/view/meta-flow-steps.php:11
887
  msgid "Thank You"
888
  msgstr ""
889
 
890
- #: modules/flow/classes/class-cartflows-step-post-type.php:213
891
  #: modules/flow/view/meta-flow-steps.php:12
892
  msgid "Upsell"
893
  msgstr ""
894
 
895
- #: modules/flow/classes/class-cartflows-step-post-type.php:219
896
  #: modules/flow/view/meta-flow-steps.php:13
897
  msgid "Downsell"
898
  msgstr ""
@@ -937,12 +994,6 @@ msgstr ""
937
  msgid "Next Step Link"
938
  msgstr ""
939
 
940
- #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:62
941
- msgid ""
942
- "WooCommerce functions not exists. If you are in iframe, please reload the "
943
- "iframe"
944
- msgstr ""
945
-
946
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
947
  msgid "Thank You Page Settings"
948
  msgstr ""
@@ -1046,17 +1097,17 @@ msgctxt "flow singular name"
1046
  msgid "Flow"
1047
  msgstr ""
1048
 
1049
- #: modules/flow/classes/class-cartflows-step-post-type.php:137
1050
  msgctxt "flow step general name"
1051
  msgid "Steps"
1052
  msgstr ""
1053
 
1054
- #: modules/flow/classes/class-cartflows-step-post-type.php:138
1055
  msgctxt "flow step singular name"
1056
  msgid "Step"
1057
  msgstr ""
1058
 
1059
- #: modules/flow/classes/class-cartflows-step-post-type.php:257
1060
  msgctxt "cartflows"
1061
  msgid "Template for Page Builders"
1062
  msgstr ""
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: CartFlows 1.1.3\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
+ "POT-Creation-Date: 2019-01-15 10:41: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"
88
  msgid "Request successfully processed!"
89
  msgstr ""
90
 
91
+ #: classes/class-cartflows-cloning.php:414
92
  msgid "Clone this flow"
93
  msgstr ""
94
 
95
+ #: classes/class-cartflows-cloning.php:414
96
  msgid "Clone"
97
  msgstr ""
98
 
102
  "be deactivated from the flow settings in the admin dashboard."
103
  msgstr ""
104
 
105
+ #: classes/class-cartflows-importer.php:89
106
+ msgid "Export this flow"
107
+ msgstr ""
108
+
109
+ #: classes/class-cartflows-importer.php:89 includes/exporter.php:18
110
+ msgid "Export"
111
  msgstr ""
112
 
113
  #: classes/class-cartflows-importer.php:100
114
+ msgid "Flow Export"
115
+ msgstr ""
116
+
117
+ #: classes/class-cartflows-importer.php:101
118
+ msgid "Flow Import"
119
+ msgstr ""
120
+
121
+ #: classes/class-cartflows-importer.php:112
122
+ msgid "No post to export has been supplied!"
123
+ msgstr ""
124
+
125
+ #: classes/class-cartflows-importer.php:283
126
+ msgid "Please upload a valid .json file"
127
+ msgstr ""
128
+
129
+ #: classes/class-cartflows-importer.php:289
130
+ msgid "Please upload a file to import"
131
+ msgstr ""
132
+
133
+ #: classes/class-cartflows-importer.php:359
134
+ msgid "Successfully imported flows."
135
+ msgstr ""
136
+
137
+ #: classes/class-cartflows-importer.php:391
138
+ msgid "Loading Steps"
139
+ msgstr ""
140
+
141
+ #: classes/class-cartflows-importer.php:393
142
  msgid "Getting steps from the cloud. Please wait for the moment."
143
  msgstr ""
144
 
145
+ #: classes/class-cartflows-importer.php:404
146
  msgid "Searching Template.."
147
  msgstr ""
148
 
149
+ #: classes/class-cartflows-importer.php:406
150
  msgid "Getting templates from the cloud. Please wait for the moment."
151
  msgstr ""
152
 
153
+ #: classes/class-cartflows-importer.php:415
154
  msgid "Importing.."
155
  msgstr ""
156
 
157
+ #: classes/class-cartflows-importer.php:424
158
+ #: classes/class-cartflows-importer.php:464
159
  msgid "Imported"
160
  msgstr ""
161
 
162
+ #: classes/class-cartflows-importer.php:425
163
+ #: classes/class-cartflows-importer.php:465
164
  msgid "Thanks for patience"
165
  msgstr ""
166
 
167
+ #: classes/class-cartflows-importer.php:434
168
+ #: classes/class-cartflows-importer.php:446
169
  msgid "Coming Soon!"
170
  msgstr ""
171
 
172
+ #: classes/class-cartflows-importer.php:465
173
  msgid "Redirecting to the Elementor edit window."
174
  msgstr ""
175
 
176
+ #: classes/class-cartflows-importer.php:511
177
+ #: classes/class-cartflows-importer.php:595
178
  msgid "Pro"
179
  msgstr ""
180
 
181
+ #: classes/class-cartflows-importer.php:534
182
+ #: classes/class-cartflows-importer.php:617
183
  msgid "Activate License"
184
  msgstr ""
185
 
186
+ #: classes/class-cartflows-importer.php:536
187
+ #: classes/class-cartflows-importer.php:619
188
  msgid "Get Pro"
189
  msgstr ""
190
 
191
+ #: classes/class-cartflows-importer.php:561
192
  msgid "Create"
193
  msgstr ""
194
 
195
+ #: classes/class-cartflows-importer.php:659
196
  msgid "All"
197
  msgstr ""
198
 
199
+ #: classes/class-cartflows-importer.php:663
200
  msgid "Select Step Type"
201
  msgstr ""
202
 
203
+ #: classes/class-cartflows-importer.php:696
204
  msgid "Import from Cloud"
205
  msgstr ""
206
 
207
+ #: classes/class-cartflows-importer.php:716
208
+ #: classes/class-cartflows-importer.php:719
209
+ #: classes/class-cartflows-importer.php:722 includes/importer.php:21
210
  #. translators: %s is plugin name.
211
  msgid "Import"
212
  msgstr ""
213
 
214
+ #: classes/class-cartflows-importer.php:1034
215
  #: modules/flow/classes/class-cartflows-flow-meta.php:224
216
  msgid "Landing Page"
217
  msgstr ""
218
 
219
+ #: classes/class-cartflows-importer.php:1035
220
  #: modules/flow/classes/class-cartflows-flow-meta.php:225
221
  msgid "Checkout Page"
222
  msgstr ""
223
 
224
+ #: classes/class-cartflows-importer.php:1036
225
  #: modules/flow/classes/class-cartflows-flow-meta.php:226
226
  msgid "Thank You Page"
227
  msgstr ""
228
 
229
+ #: classes/class-cartflows-importer.php:1141
230
  #. translators: %s: template ID
231
  msgid "Invalid template id %1$s or post id %2$s."
232
  msgstr ""
233
 
234
+ #: classes/class-cartflows-importer.php:1185
235
  #. translators: %s: flow ID
236
  msgid "Invalid flow id %1$s OR step type %2$s."
237
  msgstr ""
238
 
239
+ #: classes/class-cartflows-importer.php:1307
240
  msgid ""
241
  "Elementor is not activated. Please activate plugin Elementor Page Builder "
242
  "to import the step."
294
  msgstr ""
295
 
296
  #: classes/class-cartflows-meta-fields.php:214
297
+ #: classes/class-cartflows-meta-fields.php:925
298
  msgid "Remove"
299
  msgstr ""
300
 
301
  #: classes/class-cartflows-meta-fields.php:627
302
+ #: classes/class-cartflows-meta-fields.php:917
303
  msgid "Search for a product&hellip;"
304
  msgstr ""
305
 
475
  msgid "Submit a Ticket »"
476
  msgstr ""
477
 
478
+ #: includes/exporter.php:12
479
+ msgid "Export Flows to a JSON file"
480
+ msgstr ""
481
+
482
+ #: includes/exporter.php:13
483
+ msgid ""
484
+ "This tool allows you to generate and download a JSON file containing a list "
485
+ "of all flows."
486
+ msgstr ""
487
+
488
+ #: includes/importer.php:12
489
+ msgid "Import Flows to a JSON file"
490
+ msgstr ""
491
+
492
+ #: includes/importer.php:13
493
+ msgid "This tool allows you to import the flows from the JSON file."
494
+ msgstr ""
495
+
496
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:145
497
+ #: modules/thankyou/classes/class-cartflows-thankyou-markup.php:62
498
+ msgid ""
499
+ "WooCommerce functions not exists. If you are in iframe, please reload the "
500
+ "iframe"
501
+ msgstr ""
502
+
503
  #: modules/checkout/classes/class-cartflows-checkout-markup.php:161
504
  msgid "Checkout ID not found"
505
  msgstr ""
512
  msgid "This product can't be purcahsed"
513
  msgstr ""
514
 
515
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:904
516
  msgid "Coupon Code"
517
  msgstr ""
518
 
519
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:913
520
  msgid "Apply"
521
  msgstr ""
522
 
812
 
813
  #: modules/flow/classes/class-cartflows-flow-post-type.php:61
814
  #: modules/flow/classes/class-cartflows-flow-post-type.php:63
815
+ #: modules/flow/classes/class-cartflows-step-post-type.php:144
816
+ #: modules/flow/classes/class-cartflows-step-post-type.php:146
817
  msgid "Add New"
818
  msgstr ""
819
 
835
 
836
  #: modules/flow/classes/class-cartflows-flow-post-type.php:252
837
  #: modules/flow/classes/class-cartflows-flow-post-type.php:258
838
+ #: modules/flow/classes/class-cartflows-step-post-type.php:377
839
+ #: modules/flow/classes/class-cartflows-step-post-type.php:383
840
  #. translators: %s: singular custom post type name
841
  msgid "%s updated."
842
  msgstr ""
843
 
844
  #: modules/flow/classes/class-cartflows-flow-post-type.php:254
845
+ #: modules/flow/classes/class-cartflows-step-post-type.php:379
846
  #. translators: %s: singular custom post type name
847
  msgid "Custom %s updated."
848
  msgstr ""
849
 
850
  #: modules/flow/classes/class-cartflows-flow-post-type.php:256
851
+ #: modules/flow/classes/class-cartflows-step-post-type.php:381
852
  #. translators: %s: singular custom post type name
853
  msgid "Custom %s deleted."
854
  msgstr ""
855
 
856
  #: modules/flow/classes/class-cartflows-flow-post-type.php:260
857
+ #: modules/flow/classes/class-cartflows-step-post-type.php:385
858
  #. translators: %1$s: singular custom post type name ,%2$s: date and time of
859
  #. the revision
860
  msgid "%1$s restored to revision from %2$s"
861
  msgstr ""
862
 
863
  #: modules/flow/classes/class-cartflows-flow-post-type.php:262
864
+ #: modules/flow/classes/class-cartflows-step-post-type.php:387
865
  #. translators: %s: singular custom post type name
866
  msgid "%s published."
867
  msgstr ""
868
 
869
  #: modules/flow/classes/class-cartflows-flow-post-type.php:264
870
+ #: modules/flow/classes/class-cartflows-step-post-type.php:389
871
  #. translators: %s: singular custom post type name
872
  msgid "%s saved."
873
  msgstr ""
874
 
875
  #: modules/flow/classes/class-cartflows-flow-post-type.php:266
876
+ #: modules/flow/classes/class-cartflows-step-post-type.php:391
877
  #. translators: %s: singular custom post type name
878
  msgid "%s submitted."
879
  msgstr ""
880
 
881
  #: modules/flow/classes/class-cartflows-flow-post-type.php:268
882
+ #: modules/flow/classes/class-cartflows-step-post-type.php:393
883
  #. translators: %s: singular custom post type name
884
  msgid "%s scheduled for."
885
  msgstr ""
886
 
887
  #: modules/flow/classes/class-cartflows-flow-post-type.php:270
888
+ #: modules/flow/classes/class-cartflows-step-post-type.php:395
889
  #. translators: %s: singular custom post type name
890
  msgid "%s draft updated."
891
  msgstr ""
895
  msgid "Next Step"
896
  msgstr ""
897
 
898
+ #: modules/flow/classes/class-cartflows-step-post-type.php:140
899
  msgid "Search Steps"
900
  msgstr ""
901
 
902
+ #: modules/flow/classes/class-cartflows-step-post-type.php:141
903
  msgid "All Steps"
904
  msgstr ""
905
 
906
+ #: modules/flow/classes/class-cartflows-step-post-type.php:142
907
  #: modules/flow/view/meta-flow-steps.php:97
908
  msgid "Edit Step"
909
  msgstr ""
910
 
911
+ #: modules/flow/classes/class-cartflows-step-post-type.php:143
912
  #: modules/flow/view/meta-flow-steps.php:93
913
  msgid "View Step"
914
  msgstr ""
915
 
916
+ #: modules/flow/classes/class-cartflows-step-post-type.php:145
917
  msgid "Update Step"
918
  msgstr ""
919
 
920
+ #: modules/flow/classes/class-cartflows-step-post-type.php:147
921
  msgid "New Step Name"
922
  msgstr ""
923
 
924
+ #: modules/flow/classes/class-cartflows-step-post-type.php:170
925
  msgid "Step Type"
926
  msgstr ""
927
 
928
+ #: modules/flow/classes/class-cartflows-step-post-type.php:179
929
  msgid "Step Flow"
930
  msgstr ""
931
 
932
+ #: modules/flow/classes/class-cartflows-step-post-type.php:196
933
  #: modules/flow/view/meta-flow-steps.php:9
934
  msgid "Landing"
935
  msgstr ""
936
 
937
+ #: modules/flow/classes/class-cartflows-step-post-type.php:202
938
  #: modules/flow/view/meta-flow-steps.php:10
939
  msgid "Checkout"
940
  msgstr ""
941
 
942
+ #: modules/flow/classes/class-cartflows-step-post-type.php:208
943
  #: modules/flow/view/meta-flow-steps.php:11
944
  msgid "Thank You"
945
  msgstr ""
946
 
947
+ #: modules/flow/classes/class-cartflows-step-post-type.php:214
948
  #: modules/flow/view/meta-flow-steps.php:12
949
  msgid "Upsell"
950
  msgstr ""
951
 
952
+ #: modules/flow/classes/class-cartflows-step-post-type.php:220
953
  #: modules/flow/view/meta-flow-steps.php:13
954
  msgid "Downsell"
955
  msgstr ""
994
  msgid "Next Step Link"
995
  msgstr ""
996
 
 
 
 
 
 
 
997
  #: modules/thankyou/classes/class-cartflows-thankyou-meta.php:65
998
  msgid "Thank You Page Settings"
999
  msgstr ""
1097
  msgid "Flow"
1098
  msgstr ""
1099
 
1100
+ #: modules/flow/classes/class-cartflows-step-post-type.php:138
1101
  msgctxt "flow step general name"
1102
  msgid "Steps"
1103
  msgstr ""
1104
 
1105
+ #: modules/flow/classes/class-cartflows-step-post-type.php:139
1106
  msgctxt "flow step singular name"
1107
  msgid "Step"
1108
  msgstr ""
1109
 
1110
+ #: modules/flow/classes/class-cartflows-step-post-type.php:258
1111
  msgctxt "cartflows"
1112
  msgid "Template for Page Builders"
1113
  msgstr ""
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,987 +1,1005 @@
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', 'woocommerce_output_all_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' ) );
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_cf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
- add_action( 'wp_ajax_nopriv_cf_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( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
72
-
73
- add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
74
- }
75
-
76
-
77
- /**
78
- * Redirect from default to the global checkout page
79
- *
80
- * @since 1.0.0
81
- */
82
- function global_checkout_template_redirect() {
83
-
84
- if ( ! is_checkout() ) {
85
- return;
86
- }
87
-
88
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
89
- return;
90
- }
91
-
92
- // redirect only from any non HC checkout pages.
93
- $order_pay_endpoint = get_option( 'woocommerce_checkout_order_pay_endpoint', 'order-pay' );
94
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
95
-
96
- $common = Cartflows_Helper::get_common_settings();
97
-
98
- $global_checkout = $common['global_checkout'];
99
-
100
- if (
101
- // ignore on order-pay.
102
- false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_pay_endpoint . '/' ) &&
103
- // ignore on TY page.
104
- false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_received_endpoint . '/' )
105
- ) {
106
-
107
- if ( '' !== $global_checkout ) {
108
-
109
- $link = get_permalink( $global_checkout );
110
-
111
- if ( ! empty( $link ) ) {
112
-
113
- wp_redirect( $link );
114
- die();
115
- }
116
- }
117
- }
118
- }
119
-
120
- /**
121
- * Check for checkout flag
122
- *
123
- * @param bool $is_checkout is checkout.
124
- *
125
- * @return bool
126
- */
127
- function woo_checkout_flag( $is_checkout ) {
128
-
129
- if ( ! is_admin() ) {
130
-
131
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
132
-
133
- $is_checkout = true;
134
- }
135
- }
136
-
137
- return $is_checkout;
138
- }
139
-
140
- /**
141
- * Render checkout shortcode markup.
142
- *
143
- * @param array $atts attributes.
144
- * @return string
145
- */
146
- function checkout_shortcode_markup( $atts ) {
147
-
148
- if ( ! function_exists( 'wc_print_notices' ) ) {
149
- return '<p class="woocommerce-notice">' . __( 'WooCommerce functions not exists. If you are in iframe, please reload the iframe', 'cartflows' ) . '</p>';
150
- }
151
-
152
- $atts = shortcode_atts(
153
- array(
154
- 'id' => 0,
155
- ),
156
- $atts
157
- );
158
-
159
- $checkout_id = intval( $atts['id'] );
160
-
161
- if ( empty( $checkout_id ) ) {
162
-
163
- if ( ! _is_wcf_checkout_type() ) {
164
-
165
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
166
- }
167
-
168
- global $post;
169
-
170
- $checkout_id = intval( $post->ID );
171
- }
172
-
173
- $output = '';
174
-
175
- ob_start();
176
-
177
- do_action( 'cartflows_checkout_form_before', $checkout_id );
178
-
179
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
180
-
181
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
182
-
183
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
184
-
185
- if ( file_exists( $template_layout ) ) {
186
- include $template_layout;
187
- } else {
188
- include $template_default;
189
- }
190
-
191
- $output .= ob_get_clean();
192
-
193
- return $output;
194
- }
195
-
196
- /**
197
- * Configure Cart Data.
198
- *
199
- * @since 1.0.0
200
- *
201
- * @return void
202
- */
203
- function preconfigured_cart_data() {
204
-
205
- if ( is_admin() ) {
206
- return;
207
- }
208
-
209
- global $post;
210
-
211
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
212
-
213
- if ( wp_doing_ajax() ) {
214
-
215
- return;
216
- } else {
217
-
218
- if ( _is_wcf_checkout_type() ) {
219
- $checkout_id = $post->ID;
220
- } else {
221
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
222
- }
223
-
224
- do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
225
-
226
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
227
-
228
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
229
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products', 'dummy' );
230
- } else {
231
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
232
- }
233
-
234
- if ( ! is_array( $products ) ) {
235
-
236
- if ( 'dummy' === $products ) {
237
-
238
- $args = array(
239
- 'posts_per_page' => 1,
240
- 'orderby' => 'rand',
241
- 'post_type' => 'product',
242
- 'meta_query' => array(
243
- // Exclude out of stock products.
244
- array(
245
- 'key' => '_stock_status',
246
- 'value' => 'outofstock',
247
- 'compare' => 'NOT IN',
248
- ),
249
- ),
250
- 'tax_query' => array(
251
- array(
252
- 'taxonomy' => 'product_type',
253
- 'field' => 'slug',
254
- 'terms' => 'simple',
255
- ),
256
- ),
257
- );
258
-
259
- $random_product = get_posts( $args );
260
-
261
- if ( isset( $random_product[0]->ID ) ) {
262
- $products = array(
263
- array(
264
- 'product' => $random_product[0]->ID,
265
- ),
266
- );
267
- } else {
268
- return;
269
- }
270
- } else {
271
- return;
272
- }
273
- }
274
-
275
- if ( is_array( $products ) && count( $products ) < 1 ) {
276
-
277
- return;
278
- }
279
- /* Empty the current cart */
280
- WC()->cart->empty_cart();
281
-
282
- /* Set customer session if not set */
283
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
284
- WC()->session->set_customer_session_cookie( true );
285
- }
286
-
287
- $cart_product_count = 0;
288
-
289
- foreach ( $products as $index => $data ) {
290
-
291
- if ( ! isset( $data['product'] ) ) {
292
- return;
293
- }
294
-
295
- if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
296
- return;
297
- }
298
-
299
- $product_id = $data['product'];
300
- $_product = wc_get_product( $product_id );
301
-
302
- if ( ! empty( $_product ) ) {
303
-
304
- $quantity = 1;
305
-
306
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
307
-
308
- if ( $_product->is_type( 'variable' ) ) {
309
-
310
- $default_attributes = $_product->get_default_attributes();
311
-
312
- if ( ! empty( $default_attributes ) ) {
313
-
314
- foreach ( $_product->get_children() as $variation_id ) {
315
-
316
- $single_variation = new WC_Product_Variation( $variation_id );
317
-
318
- if ( $default_attributes == $single_variation->get_attributes() ) {
319
- WC()->cart->add_to_cart( $variation_id, $quantity );
320
- $cart_product_count++;
321
- }
322
- }
323
- } else {
324
-
325
- $product_childrens = $_product->get_children();
326
-
327
- if ( isset( $product_childrens[0] ) ) {
328
- WC()->cart->add_to_cart( $product_childrens[0], $quantity );
329
- $cart_product_count++;
330
- } else {
331
- echo '<p>' . __( 'Variations Not set', 'cartflows' ) . '</p>';
332
- }
333
- }
334
- } else {
335
- WC()->cart->add_to_cart( $product_id, $quantity );
336
- $cart_product_count++;
337
- }
338
- } else {
339
-
340
- echo '<p>' . __( 'This product can\'t be purcahsed', 'cartflows' ) . '</p>';
341
- // WC()->cart->add_to_cart( $product_id, $quantity );.
342
- }
343
- }
344
- }
345
-
346
- do_action( 'cartflows_checkout_aftet_configure_cart', $checkout_id );
347
- do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
348
- }
349
- }
350
- }
351
-
352
- /**
353
- * Load shortcode data.
354
- *
355
- * @return void
356
- */
357
- function shortcode_load_data() {
358
-
359
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
360
-
361
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
362
-
363
- // Outputting the hidden field in checkout page.
364
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
365
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
366
-
367
- remove_all_actions( 'woocommerce_checkout_billing' );
368
- remove_all_actions( 'woocommerce_checkout_shipping' );
369
-
370
- // Hook in actions once.
371
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
372
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
373
-
374
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
375
-
376
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
377
-
378
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
379
-
380
- global $post;
381
-
382
- if ( _is_wcf_checkout_type() ) {
383
- $checkout_id = $post->ID;
384
- } else {
385
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
386
- }
387
-
388
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
389
- }
390
- }
391
-
392
- /**
393
- * Render checkout ID hidden field.
394
- *
395
- * @param array $checkout checkout session data.
396
- * @return void
397
- */
398
- function checkout_shortcode_post_id( $checkout ) {
399
-
400
- global $post;
401
-
402
- if ( _is_wcf_checkout_type() ) {
403
- $checkout_id = $post->ID;
404
- } else {
405
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
406
- }
407
-
408
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
409
-
410
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
411
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
412
- }
413
-
414
- /**
415
- * Load shortcode scripts.
416
- *
417
- * @return void
418
- */
419
- function shortcode_scripts() {
420
-
421
- wp_enqueue_style( 'wcf-checkout-template', CARTFLOWS_URL . 'assets/css/checkout-template.css', '', CARTFLOWS_VER );
422
- wp_style_add_data( 'wcf-checkout-template', 'rtl', 'replace' );
423
-
424
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
425
- wp_enqueue_style( 'wcf-checkout-template-divi', CARTFLOWS_URL . 'assets/css/checkout-template-divi.css', '', CARTFLOWS_VER );
426
- wp_style_add_data( 'wcf-checkout-template-divi', 'rtl', 'replace' );
427
- }
428
-
429
- wp_enqueue_script(
430
- 'wcf-checkout-template',
431
- CARTFLOWS_URL . 'assets/js/checkout-template.js',
432
- array( 'jquery' ),
433
- CARTFLOWS_VER,
434
- true
435
- );
436
-
437
- do_action( 'cartflows_checkout_scripts' );
438
-
439
- $style = $this->generate_style();
440
-
441
- wp_add_inline_style( 'wcf-checkout-template', $style );
442
-
443
- }
444
-
445
-
446
- /**
447
- * Generate styles.
448
- *
449
- * @return string
450
- */
451
- function generate_style() {
452
-
453
- global $post;
454
-
455
- if ( _is_wcf_checkout_type() ) {
456
- $checkout_id = $post->ID;
457
- } else {
458
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
459
- }
460
-
461
- CartFlows_Font_Families::render_fonts( $checkout_id );
462
-
463
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
464
-
465
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
466
-
467
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
468
-
469
- /*$base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
470
-
471
- $field_tb_padding = '';
472
- $field_lr_padding = '';
473
-
474
- $field_heading_color = '';
475
- $field_color = '';
476
- $field_bg_color = '';
477
- $field_border_color = '';
478
- $field_label_color = '';
479
- $submit_tb_padding = '';
480
- $submit_lr_padding = '';
481
- $hl_bg_color = '';
482
- $field_input_size = '';
483
- $box_border_color = '';
484
- $section_bg_color = '';
485
- $submit_button_height = '';
486
- $submit_color = '';
487
- $submit_bg_color = $primary_color;
488
- $submit_border_color = $primary_color;
489
-
490
- $submit_hover_color = '';
491
- $submit_bg_hover_color = $primary_color;
492
- $submit_border_hover_color = $primary_color;
493
-
494
- $section_heading_color = '';
495
-
496
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
497
-
498
- $button_font_family = '';
499
- $button_font_weight = '';
500
- $input_font_family = '';
501
- $input_font_weight = '';
502
- $heading_font_family = '';
503
- $heading_font_weight = '';
504
- $base_font_family = $base_font_family;
505
- /*$base_font_weight = $base_font_weight;*/
506
-
507
- if ( 'yes' == $is_advance_option ) {
508
-
509
- /**
510
- * Get Font Family and Font Weight weight values
511
- */
512
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
513
-
514
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
515
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
516
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
517
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
518
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
519
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
520
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
521
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
522
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
523
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
524
-
525
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
526
-
527
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
528
-
529
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
530
-
531
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
532
-
533
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
534
-
535
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
536
-
537
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
538
-
539
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
540
-
541
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
542
-
543
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
544
-
545
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
546
-
547
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
548
-
549
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
550
-
551
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
552
-
553
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
554
-
555
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
556
-
557
- /**
558
- * Get font values
559
- */
560
-
561
- if ( 'custom' == $submit_button_height ) {
562
- $submit_button_height = '38px';
563
- }
564
-
565
- if ( 'custom' == $field_input_size ) {
566
- $field_input_size = '38px';
567
- }
568
- }
569
-
570
- $output = "
571
- .wcf-embed-checkout-form .wcf-checkout-header-image img{
572
- width: {$header_logo_width}px;
573
- }
574
- .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:checked:after,
575
- .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:not(:checked):after,
576
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label:after,
577
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label:after {
578
- background: {$primary_color};
579
- }
580
-
581
- .wcf-embed-checkout-form .woocommerce-checkout label{
582
- color: {$field_label_color};
583
- }
584
- .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box{
585
- background-color: {$hl_bg_color};
586
- font-family: {$input_font_family};
587
- font-weight: {$input_font_weight};
588
- }
589
-
590
- .wcf-embed-checkout-form #add_payment_method #payment div.payment_box::before,
591
- .wcf-embed-checkout-form .woocommerce-cart #payment div.payment_box::before,
592
- .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box::before
593
- {
594
- border-color: {$hl_bg_color};
595
- border-right-color: transparent;
596
- border-left-color: transparent;
597
- border-top-color: transparent;
598
- position: absolute;
599
- }
600
-
601
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label,
602
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label{
603
- font-family: {$input_font_family};
604
- font-weight: {$input_font_weight};
605
- }
606
-
607
- .wcf-embed-checkout-form #order_review .wcf-custom-coupon-field input[type='text'],
608
- .wcf-embed-checkout-form .woocommerce form .form-row input.input-text,
609
- .wcf-embed-checkout-form .woocommerce form .form-row textarea,
610
- .wcf-embed-checkout-form .select2-container--default .select2-selection--single {
611
- color: {$field_color};
612
- background: {$field_bg_color};
613
- border-color: {$field_border_color};
614
- padding-top: {$field_tb_padding}px;
615
- padding-bottom: {$field_tb_padding}px;
616
- padding-left: {$field_lr_padding}px;
617
- padding-right: {$field_lr_padding}px;
618
- min-height: {$field_input_size};
619
- font-family: {$input_font_family};
620
- font-weight: {$input_font_weight};
621
- }
622
-
623
- .wcf-embed-checkout-form .woocommerce .col2-set .col-1,
624
- .wcf-embed-checkout-form .woocommerce .col2-set .col-2,
625
- .wcf-embed-checkout-form .woocommerce-checkout .shop_table,
626
- .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading,
627
- .wcf-embed-checkout-form .woocommerce-checkout #payment,
628
- .wcf-embed-checkout-form .woocommerce form.checkout_coupon
629
- {
630
- background-color: {$section_bg_color};
631
- border-color: {$box_border_color};
632
- font-family: {$input_font_family};
633
- font-weight: {$input_font_weight};
634
- }
635
-
636
- .woocommerce table.shop_table th{
637
- color: {$field_label_color};
638
- }
639
- .wcf-embed-checkout-form .woocommerce .woocommerce-info,
640
- .wcf-embed-checkout-form .woocommerce-message{
641
- border-top-color: {$primary_color};
642
- background-color: {$hl_bg_color};
643
- }
644
- .wcf-embed-checkout-form .woocommerce a{
645
- color: {$primary_color};
646
- }
647
- .wcf-embed-checkout-form .select2-container--default .select2-selection--single .select2-selection__rendered {
648
- color: {$field_color};
649
- }
650
- .wcf-embed-checkout-form ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
651
- color: {$field_color};
652
- }
653
- .wcf-embed-checkout-form ::-moz-placeholder { /* Firefox 19+ */
654
- color: {$field_color};
655
- }
656
- .wcf-embed-checkout-form :-ms-input-placeholder { /* IE 10+ */
657
- color: {$field_color};
658
- }
659
- .wcf-embed-checkout-form :-moz-placeholder { /* Firefox 18- */
660
- color: {$field_color};
661
- }
662
- .wcf-embed-checkout-form .woocommerce form p.form-row label {
663
- color: {$field_label_color};
664
- font-family: {$input_font_family};
665
- font-weight: {$input_font_weight};
666
- }
667
- .wcf-embed-checkout-form .woocommerce #order_review button {
668
- color: {$submit_color};
669
- background: {$submit_bg_color};
670
- padding-top: {$submit_tb_padding}px;
671
- padding-bottom: {$submit_tb_padding}px;
672
- padding-left: {$submit_lr_padding}px;
673
- padding-right: {$submit_lr_padding}px;
674
- border-color: {$submit_border_color};
675
- min-height: {$submit_button_height};
676
- font-family: {$button_font_family};
677
- font-weight: {$button_font_weight};
678
- }
679
- .wcf-embed-checkout-form .woocommerce-checkout form.woocommerce-form-login .button,
680
- .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button{
681
- background: {$submit_bg_color};
682
- border: 1px {$submit_border_color} solid;
683
- color: {$submit_color};
684
- min-height: {$submit_button_height};
685
- font-family: {$button_font_family};
686
- font-weight: {$button_font_weight};
687
- }
688
- .wcf-embed-checkout-form .woocommerce-checkout form.login .button:hover,
689
- .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button:hover,
690
- .wcf-embed-checkout-form .woocommerce #payment #place_order:hover,
691
- .wcf-embed-checkout-form .woocommerce #order_review button.wcf-btn-small:hover{
692
- color: {$submit_hover_color};
693
- background-color: {$submit_bg_hover_color};
694
- border-color: {$submit_border_hover_color};
695
- }
696
- .wcf-embed-checkout-form .woocommerce h3,
697
- .wcf-embed-checkout-form .woocommerce h3 span,
698
- .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
699
- color: {$section_heading_color};
700
- font-family: {$heading_font_family};
701
- font-weight: {$heading_font_weight};
702
- }
703
- .wcf-embed-checkout-form .woocommerce-info::before,
704
- .wcf-embed-checkout-form .woocommerce-message::before{
705
- color: {$primary_color};
706
- }
707
- .wcf-embed-checkout-form{
708
- font-family: {$base_font_family};
709
- }";
710
-
711
- return $output;
712
- }
713
-
714
- /**
715
- * Get ajax end points.
716
- *
717
- * @param string $endpoint_url end point URL.
718
- * @return string
719
- */
720
- function get_ajax_endpoint( $endpoint_url ) {
721
-
722
- global $post;
723
-
724
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
725
-
726
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
727
-
728
- if ( mb_strpos( $endpoint_url, 'checkout' ) === false ) {
729
-
730
- $query_args = array(
731
- 'wc-ajax' => '%%endpoint%%',
732
- );
733
-
734
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 );
735
- $uri = $uri[0];
736
-
737
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
738
- }
739
- }
740
- }
741
-
742
- return $endpoint_url;
743
- }
744
-
745
-
746
- /**
747
- * Save checkout fields.
748
- *
749
- * @param int $order_id order id.
750
- * @param array $posted posted data.
751
- * @return void
752
- */
753
- function save_checkout_fields( $order_id, $posted ) {
754
-
755
- if ( isset( $_POST['_wcf_checkout_id'] ) ) {
756
-
757
- $checkout_id = wc_clean( $_POST['_wcf_checkout_id'] );
758
-
759
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
760
-
761
- /*
762
- Custom Field To Do
763
- $custom_fields = get_post_meta( $checkout_id, 'wcf-custom-checkout-fields', true );
764
-
765
- if ( 'yes' === $custom_fields ) {
766
-
767
- $billing_fields = get_post_meta( $checkout_id, 'wcf_fields_billing', true );
768
-
769
- foreach ( $billing_fields as $field => $data ) {
770
-
771
- if ( isset( $data['custom'] ) && $data['custom'] ) {
772
-
773
- if ( isset( $_POST[ $field ] ) ) {
774
- update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
775
- }
776
- }
777
- }
778
-
779
- $shipping_fields = get_post_meta( $checkout_id, 'wcf_fields_shipping', true );
780
-
781
- foreach ( $shipping_fields as $field => $data ) {
782
-
783
- if ( isset( $data['custom'] ) && $data['custom'] ) {
784
-
785
- if ( isset( $_POST[ $field ] ) ) {
786
- update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
787
- }
788
- }
789
- }
790
- }
791
- */
792
- if ( isset( $_POST['_wcf_flow_id'] ) ) {
793
-
794
- $checkout_id = wc_clean( $_POST['_wcf_flow_id'] );
795
-
796
- update_post_meta( $order_id, '_wcf_flow_id', $checkout_id );
797
- }
798
- }
799
-
800
- }
801
-
802
- /**
803
- * Enable Logo In Header Of Checkout Page
804
- *
805
- * @return void
806
- */
807
- function enable_logo_in_header() {
808
- global $post;
809
-
810
- if ( _is_wcf_checkout_type() ) {
811
- $checkout_id = $post->ID;
812
- } else {
813
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
814
- }
815
-
816
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
817
- $add_image_markup = '';
818
-
819
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
820
- $add_image_markup = '<div class="wcf-checkout-header-image">';
821
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
822
- $add_image_markup .= '</div>';
823
- }
824
-
825
- echo $add_image_markup;
826
- }
827
-
828
- /**
829
- * Add text to the bootom of the checkout page.
830
- *
831
- * @return void
832
- */
833
- function show_cartflows_copyright_message() {
834
- $output_string = '';
835
-
836
- $output_string .= '<div class="wcf-footer-primary">';
837
- $output_string .= '<div class="wcf-footer-content">';
838
- $output_string .= '<p class="wcf-footer-message">';
839
- $output_string .= 'Checkout powered by CartFlows';
840
- $output_string .= '</p>';
841
- $output_string .= '</div>';
842
- $output_string .= '</div>';
843
-
844
- echo $output_string;
845
- }
846
-
847
- /**
848
- * Redirect users to our checkout if hidden param
849
- *
850
- * @param string $redirect redirect url.
851
- * @param object $user user.
852
- * @return string
853
- */
854
- function after_login_redirect( $redirect, $user ) {
855
-
856
- if ( isset( $_POST['_wcf_checkout_id'] ) ) {
857
-
858
- $checkout_id = intval( $_POST['_wcf_checkout_id'] );
859
-
860
- $redirect = get_permalink( $checkout_id );
861
- }
862
-
863
- return $redirect;
864
- }
865
-
866
- /**
867
- * Display coupon code field after review order fields.
868
- */
869
- function display_custom_coupon_field() {
870
-
871
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
872
-
873
- if ( ! $coupon_enabled ) {
874
- return;
875
- }
876
-
877
- ob_start();
878
-
879
- ?>
880
- <div class="wcf-custom-coupon-field">
881
- <div class="wcf-coupon-col-1">
882
- <span>
883
- <input type="text" name="coupon_code" class="input-text cf-coupon-code-input" placeholder="<?php _e( 'Coupon Code', 'cartflows' ); ?>" id="coupon_code" value="">
884
- </span>
885
- </div>
886
- <div class="wcf-coupon-col-2">
887
- <span>
888
- <button type="button" class="button cf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php _e( 'Apply', 'cartflows' ); ?></button>
889
- </span>
890
- </div>
891
- </div>
892
-
893
- <?php
894
-
895
- echo ob_get_clean();
896
- }
897
-
898
- /**
899
- * Apply coupon on submit of custom coupon form.
900
- */
901
- function apply_coupon() {
902
-
903
- check_ajax_referer( 'cf-apply-coupon', 'security' );
904
-
905
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
906
-
907
- echo json_encode( $result );
908
- die();
909
- }
910
-
911
- /**
912
- * Added ajax nonce to localize variable.
913
- *
914
- * @param array $vars localize variables.
915
- */
916
- function add_localize_vars( $vars ) {
917
-
918
- $vars['cf_validate_coupon_nonce'] = wp_create_nonce( 'cf-apply-coupon' );
919
-
920
- return $vars;
921
- }
922
-
923
- /**
924
- * Add custom class to the fields to change the UI to three column.
925
- *
926
- * @param array $fields fields.
927
- */
928
- function add_three_column_layout_fields( $fields ) {
929
-
930
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
931
-
932
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
933
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
934
- }
935
- }
936
-
937
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
938
-
939
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
940
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
941
- }
942
- }
943
-
944
- if ( isset( $fields['billing']['billing_city'] ) &&
945
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
946
-
947
- $fields['billing']['billing_city']['class'] = array( 'wcf-form-col-3' );
948
- $fields['billing']['billing_state']['class'] = array( 'wcf-form-col-3' );
949
- $fields['billing']['billing_postcode']['class'] = array( 'wcf-form-col-3' );
950
- }
951
-
952
- if ( isset( $fields['shipping']['shipping_city'] ) &&
953
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
954
-
955
- $fields['shipping']['shipping_city']['class'] = array( 'wcf-form-col-3' );
956
- $fields['shipping']['shipping_state']['class'] = array( 'wcf-form-col-3' );
957
- $fields['shipping']['shipping_postcode']['class'] = array( 'wcf-form-col-3' );
958
- }
959
-
960
- return $fields;
961
- }
962
-
963
- /**
964
- * Add opening dev
965
- *
966
- * @since 1.0.0
967
- */
968
- function order_wrap_div_start() {
969
-
970
- echo "<div class='wcf-order-wrap'> ";
971
- }
972
-
973
- /**
974
- * Add closing dev
975
- *
976
- * @since 1.0.0
977
- */
978
- function order_wrap_div_end() {
979
-
980
- echo '</div> ';
981
- }
982
- }
983
-
984
- /**
985
- * Kicking this off by calling 'get_instance()' method
986
- */
987
- 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', 'woocommerce_output_all_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' ) );
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_cf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
64
+ add_action( 'wp_ajax_nopriv_cf_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
+
72
+
73
+ /**
74
+ * Redirect from default to the global checkout page
75
+ *
76
+ * @since 1.0.0
77
+ */
78
+ function global_checkout_template_redirect() {
79
+
80
+ if ( ! is_checkout() ) {
81
+ return;
82
+ }
83
+
84
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
85
+ return;
86
+ }
87
+
88
+ // redirect only from any non HC checkout pages.
89
+ $order_pay_endpoint = get_option( 'woocommerce_checkout_order_pay_endpoint', 'order-pay' );
90
+ $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
91
+
92
+ $common = Cartflows_Helper::get_common_settings();
93
+
94
+ $global_checkout = $common['global_checkout'];
95
+
96
+ if (
97
+ // ignore on order-pay.
98
+ false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_pay_endpoint . '/' ) &&
99
+ // ignore on TY page.
100
+ false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_received_endpoint . '/' )
101
+ ) {
102
+
103
+ if ( '' !== $global_checkout ) {
104
+
105
+ $link = get_permalink( $global_checkout );
106
+
107
+ if ( ! empty( $link ) ) {
108
+
109
+ wp_redirect( $link );
110
+ die();
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Check for checkout flag
118
+ *
119
+ * @param bool $is_checkout is checkout.
120
+ *
121
+ * @return bool
122
+ */
123
+ function woo_checkout_flag( $is_checkout ) {
124
+
125
+ if ( ! is_admin() ) {
126
+
127
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
128
+
129
+ $is_checkout = true;
130
+ }
131
+ }
132
+
133
+ return $is_checkout;
134
+ }
135
+
136
+ /**
137
+ * Render checkout shortcode markup.
138
+ *
139
+ * @param array $atts attributes.
140
+ * @return string
141
+ */
142
+ function checkout_shortcode_markup( $atts ) {
143
+
144
+ if ( ! function_exists( 'wc_print_notices' ) ) {
145
+ return '<p class="woocommerce-notice">' . __( 'WooCommerce functions not exists. If you are in iframe, please reload the iframe', 'cartflows' ) . '</p>';
146
+ }
147
+
148
+ $atts = shortcode_atts(
149
+ array(
150
+ 'id' => 0,
151
+ ),
152
+ $atts
153
+ );
154
+
155
+ $checkout_id = intval( $atts['id'] );
156
+
157
+ if ( empty( $checkout_id ) ) {
158
+
159
+ if ( ! _is_wcf_checkout_type() ) {
160
+
161
+ return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
162
+ }
163
+
164
+ global $post;
165
+
166
+ $checkout_id = intval( $post->ID );
167
+ }
168
+
169
+ $output = '';
170
+
171
+ ob_start();
172
+
173
+ do_action( 'cartflows_checkout_form_before', $checkout_id );
174
+
175
+ $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
176
+
177
+ $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
178
+
179
+ $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
180
+
181
+ if ( file_exists( $template_layout ) ) {
182
+ include $template_layout;
183
+ } else {
184
+ include $template_default;
185
+ }
186
+
187
+ $output .= ob_get_clean();
188
+
189
+ return $output;
190
+ }
191
+
192
+ /**
193
+ * Configure Cart Data.
194
+ *
195
+ * @since 1.0.0
196
+ *
197
+ * @return void
198
+ */
199
+ function preconfigured_cart_data() {
200
+
201
+ if ( is_admin() ) {
202
+ return;
203
+ }
204
+
205
+ global $post;
206
+
207
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
208
+
209
+ if ( wp_doing_ajax() ) {
210
+
211
+ return;
212
+ } else {
213
+
214
+ if ( _is_wcf_checkout_type() ) {
215
+ $checkout_id = $post->ID;
216
+ } else {
217
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
218
+ }
219
+
220
+ do_action( 'cartflows_checkout_before_configure_cart', $checkout_id );
221
+
222
+ $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
223
+
224
+ if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
225
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products', 'dummy' );
226
+ } else {
227
+ $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
228
+ }
229
+
230
+ if ( ! is_array( $products ) ) {
231
+
232
+ if ( 'dummy' === $products ) {
233
+
234
+ $args = array(
235
+ 'posts_per_page' => 1,
236
+ 'orderby' => 'rand',
237
+ 'post_type' => 'product',
238
+ 'meta_query' => array(
239
+ // Exclude out of stock products.
240
+ array(
241
+ 'key' => '_stock_status',
242
+ 'value' => 'outofstock',
243
+ 'compare' => 'NOT IN',
244
+ ),
245
+ ),
246
+ 'tax_query' => array(
247
+ array(
248
+ 'taxonomy' => 'product_type',
249
+ 'field' => 'slug',
250
+ 'terms' => 'simple',
251
+ ),
252
+ ),
253
+ );
254
+
255
+ $random_product = get_posts( $args );
256
+
257
+ if ( isset( $random_product[0]->ID ) ) {
258
+ $products = array(
259
+ array(
260
+ 'product' => $random_product[0]->ID,
261
+ ),
262
+ );
263
+ } else {
264
+ return;
265
+ }
266
+ } else {
267
+ return;
268
+ }
269
+ }
270
+
271
+ if ( is_array( $products ) && count( $products ) < 1 ) {
272
+
273
+ return;
274
+ }
275
+ /* Empty the current cart */
276
+ WC()->cart->empty_cart();
277
+
278
+ /* Set customer session if not set */
279
+ if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
280
+ WC()->session->set_customer_session_cookie( true );
281
+ }
282
+
283
+ $cart_product_count = 0;
284
+
285
+ foreach ( $products as $index => $data ) {
286
+
287
+ if ( ! isset( $data['product'] ) ) {
288
+ return;
289
+ }
290
+
291
+ if ( apply_filters( 'cartflows_skip_other_products', false, $cart_product_count ) ) {
292
+ return;
293
+ }
294
+
295
+ $product_id = $data['product'];
296
+ $_product = wc_get_product( $product_id );
297
+
298
+ if ( ! empty( $_product ) ) {
299
+
300
+ $quantity = 1;
301
+
302
+ if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
303
+
304
+ if ( $_product->is_type( 'variable' ) ) {
305
+
306
+ $default_attributes = $_product->get_default_attributes();
307
+
308
+ if ( ! empty( $default_attributes ) ) {
309
+
310
+ foreach ( $_product->get_children() as $variation_id ) {
311
+
312
+ $single_variation = new WC_Product_Variation( $variation_id );
313
+
314
+ if ( $default_attributes == $single_variation->get_attributes() ) {
315
+ WC()->cart->add_to_cart( $variation_id, $quantity );
316
+ $cart_product_count++;
317
+ }
318
+ }
319
+ } else {
320
+
321
+ $product_childrens = $_product->get_children();
322
+
323
+ if ( isset( $product_childrens[0] ) ) {
324
+ WC()->cart->add_to_cart( $product_childrens[0], $quantity );
325
+ $cart_product_count++;
326
+ } else {
327
+ echo '<p>' . __( 'Variations Not set', 'cartflows' ) . '</p>';
328
+ }
329
+ }
330
+ } else {
331
+ WC()->cart->add_to_cart( $product_id, $quantity );
332
+ $cart_product_count++;
333
+ }
334
+ } else {
335
+
336
+ echo '<p>' . __( 'This product can\'t be purcahsed', 'cartflows' ) . '</p>';
337
+ // WC()->cart->add_to_cart( $product_id, $quantity );.
338
+ }
339
+ }
340
+ }
341
+
342
+ do_action( 'cartflows_checkout_aftet_configure_cart', $checkout_id );
343
+ do_action( 'cartflows_checkout_after_configure_cart', $checkout_id );
344
+ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Load shortcode data.
350
+ *
351
+ * @return void
352
+ */
353
+ function shortcode_load_data() {
354
+
355
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
356
+
357
+ add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
358
+
359
+ add_action( 'woocommerce_checkout_after_customer_details', array( $this, 'order_wrap_div_start' ), 99 );
360
+
361
+ add_action( 'woocommerce_checkout_after_order_review', array( $this, 'order_wrap_div_end' ), 99 );
362
+
363
+ // Outputting the hidden field in checkout page.
364
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
365
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
366
+
367
+ remove_all_actions( 'woocommerce_checkout_billing' );
368
+ remove_all_actions( 'woocommerce_checkout_shipping' );
369
+
370
+ // Hook in actions once.
371
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
372
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
373
+
374
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
375
+
376
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
377
+
378
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
379
+
380
+ global $post;
381
+
382
+ if ( _is_wcf_checkout_type() ) {
383
+ $checkout_id = $post->ID;
384
+ } else {
385
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
386
+ }
387
+
388
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Render checkout ID hidden field.
394
+ *
395
+ * @param array $checkout checkout session data.
396
+ * @return void
397
+ */
398
+ function checkout_shortcode_post_id( $checkout ) {
399
+
400
+ global $post;
401
+
402
+ if ( _is_wcf_checkout_type() ) {
403
+ $checkout_id = $post->ID;
404
+ } else {
405
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
406
+ }
407
+
408
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
409
+
410
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
411
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
412
+ }
413
+
414
+ /**
415
+ * Load shortcode scripts.
416
+ *
417
+ * @return void
418
+ */
419
+ function shortcode_scripts() {
420
+
421
+ wp_enqueue_style( 'wcf-checkout-template', CARTFLOWS_URL . 'assets/css/checkout-template.css', '', CARTFLOWS_VER );
422
+ wp_style_add_data( 'wcf-checkout-template', 'rtl', 'replace' );
423
+
424
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
425
+ wp_enqueue_style( 'wcf-checkout-template-divi', CARTFLOWS_URL . 'assets/css/checkout-template-divi.css', '', CARTFLOWS_VER );
426
+ wp_style_add_data( 'wcf-checkout-template-divi', 'rtl', 'replace' );
427
+ }
428
+
429
+ wp_enqueue_script(
430
+ 'wcf-checkout-template',
431
+ CARTFLOWS_URL . 'assets/js/checkout-template.js',
432
+ array( 'jquery' ),
433
+ CARTFLOWS_VER,
434
+ true
435
+ );
436
+
437
+ do_action( 'cartflows_checkout_scripts' );
438
+
439
+ $style = $this->generate_style();
440
+
441
+ wp_add_inline_style( 'wcf-checkout-template', $style );
442
+
443
+ }
444
+
445
+
446
+ /**
447
+ * Generate styles.
448
+ *
449
+ * @return string
450
+ */
451
+ function generate_style() {
452
+
453
+ global $post;
454
+
455
+ if ( _is_wcf_checkout_type() ) {
456
+ $checkout_id = $post->ID;
457
+ } else {
458
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
459
+ }
460
+
461
+ CartFlows_Font_Families::render_fonts( $checkout_id );
462
+
463
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
464
+
465
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
466
+
467
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
468
+
469
+ /*$base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
470
+
471
+ $field_tb_padding = '';
472
+ $field_lr_padding = '';
473
+
474
+ $field_heading_color = '';
475
+ $field_color = '';
476
+ $field_bg_color = '';
477
+ $field_border_color = '';
478
+ $field_label_color = '';
479
+ $submit_tb_padding = '';
480
+ $submit_lr_padding = '';
481
+ $hl_bg_color = '';
482
+ $field_input_size = '';
483
+ $box_border_color = '';
484
+ $section_bg_color = '';
485
+ $submit_button_height = '';
486
+ $submit_color = '';
487
+ $submit_bg_color = $primary_color;
488
+ $submit_border_color = $primary_color;
489
+
490
+ $submit_hover_color = '';
491
+ $submit_bg_hover_color = $primary_color;
492
+ $submit_border_hover_color = $primary_color;
493
+
494
+ $section_heading_color = '';
495
+
496
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
497
+
498
+ $button_font_family = '';
499
+ $button_font_weight = '';
500
+ $input_font_family = '';
501
+ $input_font_weight = '';
502
+ $heading_font_family = '';
503
+ $heading_font_weight = '';
504
+ $base_font_family = $base_font_family;
505
+ /*$base_font_weight = $base_font_weight;*/
506
+
507
+ if ( 'yes' == $is_advance_option ) {
508
+
509
+ /**
510
+ * Get Font Family and Font Weight weight values
511
+ */
512
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
513
+
514
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
515
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
516
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
517
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
518
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
519
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
520
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
521
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
522
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
523
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
524
+
525
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
526
+
527
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
528
+
529
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
530
+
531
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
532
+
533
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
534
+
535
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
536
+
537
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
538
+
539
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
540
+
541
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
542
+
543
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
544
+
545
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
546
+
547
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
548
+
549
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
550
+
551
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
552
+
553
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
554
+
555
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
556
+
557
+ /**
558
+ * Get font values
559
+ */
560
+
561
+ if ( 'custom' == $submit_button_height ) {
562
+ $submit_button_height = '38px';
563
+ }
564
+
565
+ if ( 'custom' == $field_input_size ) {
566
+ $field_input_size = '38px';
567
+ }
568
+ }
569
+
570
+ $output = "
571
+ .wcf-embed-checkout-form .wcf-checkout-header-image img{
572
+ width: {$header_logo_width}px;
573
+ }
574
+ .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:checked:after,
575
+ .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:not(:checked):after,
576
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label:after,
577
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label:after {
578
+ background: {$primary_color};
579
+ }
580
+
581
+ .wcf-embed-checkout-form .woocommerce-checkout label{
582
+ color: {$field_label_color};
583
+ }
584
+ .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box{
585
+ background-color: {$hl_bg_color};
586
+ font-family: {$input_font_family};
587
+ font-weight: {$input_font_weight};
588
+ }
589
+
590
+ .wcf-embed-checkout-form #add_payment_method #payment div.payment_box::before,
591
+ .wcf-embed-checkout-form .woocommerce-cart #payment div.payment_box::before,
592
+ .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box::before
593
+ {
594
+ border-color: {$hl_bg_color};
595
+ border-right-color: transparent;
596
+ border-left-color: transparent;
597
+ border-top-color: transparent;
598
+ position: absolute;
599
+ }
600
+
601
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label,
602
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label{
603
+ font-family: {$input_font_family};
604
+ font-weight: {$input_font_weight};
605
+ }
606
+
607
+ .wcf-embed-checkout-form #order_review .wcf-custom-coupon-field input[type='text'],
608
+ .wcf-embed-checkout-form .woocommerce form .form-row input.input-text,
609
+ .wcf-embed-checkout-form .woocommerce form .form-row textarea,
610
+ .wcf-embed-checkout-form .select2-container--default .select2-selection--single {
611
+ color: {$field_color};
612
+ background: {$field_bg_color};
613
+ border-color: {$field_border_color};
614
+ padding-top: {$field_tb_padding}px;
615
+ padding-bottom: {$field_tb_padding}px;
616
+ padding-left: {$field_lr_padding}px;
617
+ padding-right: {$field_lr_padding}px;
618
+ min-height: {$field_input_size};
619
+ font-family: {$input_font_family};
620
+ font-weight: {$input_font_weight};
621
+ }
622
+
623
+ .wcf-embed-checkout-form .woocommerce .col2-set .col-1,
624
+ .wcf-embed-checkout-form .woocommerce .col2-set .col-2,
625
+ .wcf-embed-checkout-form .woocommerce-checkout .shop_table,
626
+ .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading,
627
+ .wcf-embed-checkout-form .woocommerce-checkout #payment,
628
+ .wcf-embed-checkout-form .woocommerce form.checkout_coupon
629
+ {
630
+ background-color: {$section_bg_color};
631
+ border-color: {$box_border_color};
632
+ font-family: {$input_font_family};
633
+ font-weight: {$input_font_weight};
634
+ }
635
+
636
+ .woocommerce table.shop_table th{
637
+ color: {$field_label_color};
638
+ }
639
+ .wcf-embed-checkout-form .woocommerce .woocommerce-info,
640
+ .wcf-embed-checkout-form .woocommerce-message{
641
+ border-top-color: {$primary_color};
642
+ background-color: {$hl_bg_color};
643
+ }
644
+ .wcf-embed-checkout-form .woocommerce a{
645
+ color: {$primary_color};
646
+ }
647
+ .wcf-embed-checkout-form .select2-container--default .select2-selection--single .select2-selection__rendered {
648
+ color: {$field_color};
649
+ }
650
+ .wcf-embed-checkout-form ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
651
+ color: {$field_color};
652
+ }
653
+ .wcf-embed-checkout-form ::-moz-placeholder { /* Firefox 19+ */
654
+ color: {$field_color};
655
+ }
656
+ .wcf-embed-checkout-form :-ms-input-placeholder { /* IE 10+ */
657
+ color: {$field_color};
658
+ }
659
+ .wcf-embed-checkout-form :-moz-placeholder { /* Firefox 18- */
660
+ color: {$field_color};
661
+ }
662
+ .wcf-embed-checkout-form .woocommerce form p.form-row label {
663
+ color: {$field_label_color};
664
+ font-family: {$input_font_family};
665
+ font-weight: {$input_font_weight};
666
+ }
667
+ .wcf-embed-checkout-form .woocommerce #order_review button {
668
+ color: {$submit_color};
669
+ background: {$submit_bg_color};
670
+ padding-top: {$submit_tb_padding}px;
671
+ padding-bottom: {$submit_tb_padding}px;
672
+ padding-left: {$submit_lr_padding}px;
673
+ padding-right: {$submit_lr_padding}px;
674
+ border-color: {$submit_border_color};
675
+ min-height: {$submit_button_height};
676
+ font-family: {$button_font_family};
677
+ font-weight: {$button_font_weight};
678
+ }
679
+ .wcf-embed-checkout-form .woocommerce-checkout form.woocommerce-form-login .button,
680
+ .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button{
681
+ background: {$submit_bg_color};
682
+ border: 1px {$submit_border_color} solid;
683
+ color: {$submit_color};
684
+ min-height: {$submit_button_height};
685
+ font-family: {$button_font_family};
686
+ font-weight: {$button_font_weight};
687
+ }
688
+ .wcf-embed-checkout-form .woocommerce-checkout form.login .button:hover,
689
+ .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button:hover,
690
+ .wcf-embed-checkout-form .woocommerce #payment #place_order:hover,
691
+ .wcf-embed-checkout-form .woocommerce #order_review button.wcf-btn-small:hover{
692
+ color: {$submit_hover_color};
693
+ background-color: {$submit_bg_hover_color};
694
+ border-color: {$submit_border_hover_color};
695
+ }
696
+ .wcf-embed-checkout-form .woocommerce h3,
697
+ .wcf-embed-checkout-form .woocommerce h3 span,
698
+ .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
699
+ color: {$section_heading_color};
700
+ font-family: {$heading_font_family};
701
+ font-weight: {$heading_font_weight};
702
+ }
703
+ .wcf-embed-checkout-form .woocommerce-info::before,
704
+ .wcf-embed-checkout-form .woocommerce-message::before{
705
+ color: {$primary_color};
706
+ }
707
+ .wcf-embed-checkout-form{
708
+ font-family: {$base_font_family};
709
+ }";
710
+
711
+ return $output;
712
+ }
713
+
714
+ /**
715
+ * Get ajax end points.
716
+ *
717
+ * @param string $endpoint_url end point URL.
718
+ * @return string
719
+ */
720
+ function get_ajax_endpoint( $endpoint_url ) {
721
+
722
+ global $post;
723
+
724
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
725
+
726
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
727
+
728
+ if ( mb_strpos( $endpoint_url, 'checkout' ) === false ) {
729
+
730
+ $query_args = array(
731
+ 'wc-ajax' => '%%endpoint%%',
732
+ );
733
+
734
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 );
735
+ $uri = $uri[0];
736
+
737
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
738
+ }
739
+ }
740
+ }
741
+
742
+ return $endpoint_url;
743
+ }
744
+
745
+
746
+ /**
747
+ * Save checkout fields.
748
+ *
749
+ * @param int $order_id order id.
750
+ * @param array $posted posted data.
751
+ * @return void
752
+ */
753
+ function save_checkout_fields( $order_id, $posted ) {
754
+
755
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) {
756
+
757
+ $checkout_id = wc_clean( $_POST['_wcf_checkout_id'] );
758
+
759
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
760
+
761
+ /*
762
+ Custom Field To Do
763
+ $custom_fields = get_post_meta( $checkout_id, 'wcf-custom-checkout-fields', true );
764
+
765
+ if ( 'yes' === $custom_fields ) {
766
+
767
+ $billing_fields = get_post_meta( $checkout_id, 'wcf_fields_billing', true );
768
+
769
+ foreach ( $billing_fields as $field => $data ) {
770
+
771
+ if ( isset( $data['custom'] ) && $data['custom'] ) {
772
+
773
+ if ( isset( $_POST[ $field ] ) ) {
774
+ update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
775
+ }
776
+ }
777
+ }
778
+
779
+ $shipping_fields = get_post_meta( $checkout_id, 'wcf_fields_shipping', true );
780
+
781
+ foreach ( $shipping_fields as $field => $data ) {
782
+
783
+ if ( isset( $data['custom'] ) && $data['custom'] ) {
784
+
785
+ if ( isset( $_POST[ $field ] ) ) {
786
+ update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
787
+ }
788
+ }
789
+ }
790
+ }
791
+ */
792
+ if ( isset( $_POST['_wcf_flow_id'] ) ) {
793
+
794
+ $checkout_id = wc_clean( $_POST['_wcf_flow_id'] );
795
+
796
+ update_post_meta( $order_id, '_wcf_flow_id', $checkout_id );
797
+ }
798
+ }
799
+
800
+ }
801
+
802
+ /**
803
+ * Enable Logo In Header Of Checkout Page
804
+ *
805
+ * @return void
806
+ */
807
+ function enable_logo_in_header() {
808
+ global $post;
809
+
810
+ if ( _is_wcf_checkout_type() ) {
811
+ $checkout_id = $post->ID;
812
+ } else {
813
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
814
+ }
815
+
816
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
817
+ $add_image_markup = '';
818
+
819
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
820
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
821
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
822
+ $add_image_markup .= '</div>';
823
+ }
824
+
825
+ echo $add_image_markup;
826
+ }
827
+
828
+ /**
829
+ * Add text to the bootom of the checkout page.
830
+ *
831
+ * @return void
832
+ */
833
+ function show_cartflows_copyright_message() {
834
+ $output_string = '';
835
+
836
+ $output_string .= '<div class="wcf-footer-primary">';
837
+ $output_string .= '<div class="wcf-footer-content">';
838
+ $output_string .= '<p class="wcf-footer-message">';
839
+ $output_string .= 'Checkout powered by CartFlows';
840
+ $output_string .= '</p>';
841
+ $output_string .= '</div>';
842
+ $output_string .= '</div>';
843
+
844
+ echo $output_string;
845
+ }
846
+
847
+ /**
848
+ * Redirect users to our checkout if hidden param
849
+ *
850
+ * @param string $redirect redirect url.
851
+ * @param object $user user.
852
+ * @return string
853
+ */
854
+ function after_login_redirect( $redirect, $user ) {
855
+
856
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) {
857
+
858
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] );
859
+
860
+ $redirect = get_permalink( $checkout_id );
861
+ }
862
+
863
+ return $redirect;
864
+ }
865
+
866
+ /**
867
+ * Display coupon code field after review order fields.
868
+ */
869
+ function display_custom_coupon_field() {
870
+
871
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
872
+
873
+ if ( ! $coupon_enabled ) {
874
+ return;
875
+ }
876
+
877
+ ob_start();
878
+
879
+ ?>
880
+ <div class="wcf-custom-coupon-field">
881
+ <div class="wcf-coupon-col-1">
882
+ <span>
883
+ <input type="text" name="coupon_code" class="input-text cf-coupon-code-input" placeholder="<?php echo $this->coupon_field_placeholder(); ?>" id="coupon_code" value="">
884
+ </span>
885
+ </div>
886
+ <div class="wcf-coupon-col-2">
887
+ <span>
888
+ <button type="button" class="button cf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php echo $this->coupon_button_text(); ?></button>
889
+ </span>
890
+ </div>
891
+ </div>
892
+
893
+ <?php
894
+
895
+ echo ob_get_clean();
896
+ }
897
+
898
+ /**
899
+ * Apply filter to change the placeholder text of coupon field.
900
+ *
901
+ * @return string
902
+ */
903
+ function coupon_field_placeholder() {
904
+ return apply_filters( 'cartflows_coupon_field_placeholder', __( 'Coupon Code', 'cartflows' ) );
905
+ }
906
+
907
+ /**
908
+ * Apply filter to change the button text of coupon field.
909
+ *
910
+ * @return string
911
+ */
912
+ function coupon_button_text() {
913
+ return apply_filters( 'cartflows_coupon_button_text', __( 'Apply', 'cartflows' ) );
914
+ }
915
+
916
+ /**
917
+ * Apply coupon on submit of custom coupon form.
918
+ */
919
+ function apply_coupon() {
920
+
921
+ check_ajax_referer( 'cf-apply-coupon', 'security' );
922
+
923
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
924
+
925
+ echo json_encode( $result );
926
+ die();
927
+ }
928
+
929
+ /**
930
+ * Added ajax nonce to localize variable.
931
+ *
932
+ * @param array $vars localize variables.
933
+ */
934
+ function add_localize_vars( $vars ) {
935
+
936
+ $vars['cf_validate_coupon_nonce'] = wp_create_nonce( 'cf-apply-coupon' );
937
+
938
+ return $vars;
939
+ }
940
+
941
+ /**
942
+ * Add custom class to the fields to change the UI to three column.
943
+ *
944
+ * @param array $fields fields.
945
+ */
946
+ function add_three_column_layout_fields( $fields ) {
947
+
948
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
949
+
950
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
951
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
952
+ }
953
+ }
954
+
955
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
956
+
957
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
958
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
959
+ }
960
+ }
961
+
962
+ if ( isset( $fields['billing']['billing_city'] ) &&
963
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
964
+
965
+ $fields['billing']['billing_city']['class'] = array( 'wcf-form-col-3' );
966
+ $fields['billing']['billing_state']['class'] = array( 'wcf-form-col-3' );
967
+ $fields['billing']['billing_postcode']['class'] = array( 'wcf-form-col-3' );
968
+ }
969
+
970
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
971
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
972
+
973
+ $fields['shipping']['shipping_city']['class'] = array( 'wcf-form-col-3' );
974
+ $fields['shipping']['shipping_state']['class'] = array( 'wcf-form-col-3' );
975
+ $fields['shipping']['shipping_postcode']['class'] = array( 'wcf-form-col-3' );
976
+ }
977
+
978
+ return $fields;
979
+ }
980
+
981
+ /**
982
+ * Add opening dev
983
+ *
984
+ * @since 1.0.0
985
+ */
986
+ function order_wrap_div_start() {
987
+
988
+ echo "<div class='wcf-order-wrap'> ";
989
+ }
990
+
991
+ /**
992
+ * Add closing dev
993
+ *
994
+ * @since 1.0.0
995
+ */
996
+ function order_wrap_div_end() {
997
+
998
+ echo '</div> ';
999
+ }
1000
+ }
1001
+
1002
+ /**
1003
+ * Kicking this off by calling 'get_instance()' method
1004
+ */
1005
+ 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 __( '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 __( '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,743 +1,743 @@
1
- <?php
2
- /**
3
- * Flow meta
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Meta Boxes setup
10
- */
11
- class Cartflows_Flow_Meta {
12
-
13
-
14
- /**
15
- * Instance
16
- *
17
- * @var $instance
18
- */
19
- private static $instance;
20
-
21
- /**
22
- * Meta Option
23
- *
24
- * @var $meta_option
25
- */
26
- private static $meta_option;
27
-
28
- /**
29
- * Initiator
30
- */
31
- public static function get_instance() {
32
- if ( ! isset( self::$instance ) ) {
33
- self::$instance = new self;
34
- }
35
-
36
- return self::$instance;
37
- }
38
-
39
- /**
40
- * Constructor
41
- */
42
- public function __construct() {
43
-
44
- add_action( 'admin_head', array( $this, 'menu_highlight' ) );
45
-
46
- add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
47
-
48
- /* Init Metabox */
49
- add_action( 'load-post.php', array( $this, 'init_metabox' ) );
50
- add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
51
-
52
- /* Add Scripts */
53
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
54
-
55
- add_action( 'wp_ajax_cartflows_setup_default_steps', array( $this, 'cartflows_setup_default_steps' ) );
56
- add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
57
-
58
- add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
59
-
60
- add_action( 'admin_notices', array( $this, 'admin_notices' ) );
61
-
62
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
63
- }
64
-
65
- /**
66
- * Display admin notices.
67
- *
68
- * @since 1.0.0
69
- *
70
- * @return void
71
- */
72
- function admin_notices() {
73
-
74
- if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
75
- return;
76
- }
77
-
78
- $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
79
- if ( $flow_id ) { ?>
80
- <div class="wcf-notice-back-edit-flow">
81
- <p>
82
- <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero" style="text-decoration: none;">
83
- <i class="dashicons dashicons-arrow-left-alt"></i>
84
- <?php _e( 'Back to edit Flow', 'cartflows' ); ?>
85
- </a>
86
- </p>
87
- </div>
88
- <?php
89
- }
90
- }
91
-
92
- /**
93
- * Initialize admin actions.
94
- *
95
- * @since 1.0.0
96
- *
97
- * @return void
98
- */
99
- function admin_init_actions() {
100
- add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
101
- add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
102
- add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
103
- }
104
-
105
- /**
106
- * Delete term data and steps data after deleting flow.
107
- *
108
- * @since 1.0.0
109
- * @param int $pid post id.
110
- *
111
- * @return void
112
- */
113
- function step_post_sync( $pid ) {
114
-
115
- global $post_type;
116
-
117
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
118
-
119
- $steps = get_post_meta( $pid, 'wcf-steps', true );
120
-
121
- if ( $steps && is_array( $steps ) ) {
122
- foreach ( $steps as $i => $step ) {
123
- wp_delete_post( $step['id'], true );
124
- }
125
- }
126
-
127
- $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
128
-
129
- if ( is_array( $term_data ) ) {
130
- wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
131
- }
132
- }
133
- }
134
-
135
- /**
136
- * Trash steps data after trashing flow.
137
- *
138
- * @since 1.0.0
139
- * @param int $pid post id.
140
- *
141
- * @return void
142
- */
143
- function step_post_trash_sync( $pid ) {
144
-
145
- global $post_type;
146
-
147
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
148
-
149
- $steps = get_post_meta( $pid, 'wcf-steps', true );
150
-
151
- if ( $steps && is_array( $steps ) ) {
152
- foreach ( $steps as $i => $step ) {
153
- wp_trash_post( $step['id'] );
154
- }
155
- }
156
- }
157
- }
158
-
159
- /**
160
- * Untrash steps data after restoring flow.
161
- *
162
- * @since 1.0.0
163
- * @param int $pid post id.
164
- *
165
- * @return void
166
- */
167
- function step_post_untrash_sync( $pid ) {
168
-
169
- global $post_type;
170
-
171
- if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
172
-
173
- $steps = get_post_meta( $pid, 'wcf-steps', true );
174
-
175
- if ( $steps && is_array( $steps ) ) {
176
- foreach ( $steps as $i => $step ) {
177
- wp_untrash_post( $step['id'] );
178
- }
179
- }
180
- }
181
- }
182
-
183
- /**
184
- * Setup default steps for flow
185
- *
186
- * @since 1.0.0
187
- *
188
- * @return void
189
- */
190
- public function cartflows_setup_default_steps() {
191
-
192
- check_ajax_referer( 'wcf-setup-default-steps', 'security' );
193
-
194
- $flow_id = intval( $_POST['post_id'] );
195
-
196
- $result = array(
197
- 'status' => false,
198
- /* translators: %s flow id */
199
- 'text' => sprintf( __( 'Steps not created for flow - %s', 'cartflows' ), $flow_id ),
200
- );
201
-
202
- if ( ! $flow_id ) {
203
- wp_send_json( $result );
204
- }
205
-
206
- $is_step_exists = get_post_meta( $flow_id, 'wcf-steps', true );
207
-
208
- if ( $is_step_exists ) {
209
-
210
- $result = array(
211
- 'status' => false,
212
- /* translators: %s flow id */
213
- 'text' => sprintf( __( 'Steps already exists. Flow - %s', 'cartflows' ), $flow_id ),
214
- );
215
-
216
- wp_send_json( $result );
217
- }
218
-
219
- /* Start Creating */
220
-
221
- $flow_steps = array();
222
-
223
- $steps_data = array(
224
- 'landing' => __( 'Landing Page', 'cartflows' ),
225
- 'checkout' => __( 'Checkout Page', 'cartflows' ),
226
- 'thankyou' => __( 'Thank You Page', 'cartflows' ),
227
- );
228
-
229
- foreach ( $steps_data as $slug => $title ) {
230
-
231
- $step_id = wp_insert_post(
232
- array(
233
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
234
- 'post_title' => $title,
235
- 'post_content' => '[cartflows_navigation]',
236
- 'post_status' => 'publish',
237
- )
238
- );
239
-
240
- if ( $step_id ) {
241
-
242
- $flow_steps[] = array(
243
- 'id' => $step_id,
244
- 'title' => $title,
245
- 'type' => $slug,
246
- );
247
-
248
- // insert post meta.
249
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
250
- update_post_meta( $step_id, 'wcf-step-type', $slug );
251
-
252
- wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
253
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
254
- }
255
- }
256
-
257
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
258
-
259
- $result = array(
260
- 'status' => true,
261
- /* translators: %s flow id */
262
- 'text' => sprintf( __( 'Steps created for flow - %s', 'cartflows' ), $flow_id ),
263
- 'redirect' => get_edit_post_link( $flow_id ),
264
- );
265
-
266
- wp_send_json( $result );
267
- }
268
-
269
- /**
270
- * Create step for given flow.
271
- *
272
- * @param int $flow_id flow ID.
273
- * @param int $step_type step type.
274
- * @param int $step_title step title.
275
- * @since 1.0.0
276
- *
277
- * @return int
278
- */
279
- public function create_step( $flow_id, $step_type, $step_title ) {
280
-
281
- $new_step_id = wp_insert_post(
282
- array(
283
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
284
- 'post_title' => $step_title,
285
- 'post_status' => 'publish',
286
- )
287
- );
288
-
289
- if ( $new_step_id ) {
290
-
291
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
292
-
293
- if ( ! is_array( $flow_steps ) ) {
294
- $flow_steps = array();
295
- }
296
-
297
- $flow_steps[] = array(
298
- 'id' => $new_step_id,
299
- 'title' => $step_title,
300
- 'type' => $step_type,
301
- );
302
-
303
- // insert post meta.
304
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
305
- update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
306
-
307
- wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
308
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
309
- }
310
-
311
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
312
-
313
- return $new_step_id;
314
- }
315
-
316
- /**
317
- * Delete step for flow
318
- *
319
- * @since 1.0.0
320
- *
321
- * @return void
322
- */
323
- public function cartflows_delete_flow_step() {
324
-
325
- check_ajax_referer( 'wcf-delete-flow-step', 'security' );
326
-
327
- $flow_id = intval( $_POST['post_id'] );
328
- $step_id = intval( $_POST['step_id'] );
329
-
330
- $result = array(
331
- 'status' => false,
332
- /* translators: %s flow id */
333
- 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
334
- );
335
-
336
- if ( ! $flow_id || ! $step_id ) {
337
- wp_send_json( $result );
338
- }
339
-
340
- wp_delete_post( $step_id, true );
341
-
342
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
343
-
344
- if ( ! is_array( $flow_steps ) ) {
345
- wp_send_json( $result );
346
- }
347
-
348
- foreach ( $flow_steps as $index => $data ) {
349
-
350
- if ( intval( $data['id'] ) === $step_id ) {
351
- unset( $flow_steps[ $index ] );
352
- break;
353
- }
354
- }
355
-
356
- /* Set index order properly */
357
- $flow_steps = array_merge( $flow_steps );
358
-
359
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
360
-
361
- $result = array(
362
- 'status' => true,
363
- /* translators: %s flow id */
364
- 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
365
- );
366
-
367
- wp_send_json( $result );
368
- }
369
-
370
- /**
371
- * Reorder step flow
372
- *
373
- * @since 1.0.0
374
- *
375
- * @return void
376
- */
377
- public function cartflows_reorder_flow_steps() {
378
-
379
- check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
380
-
381
- $flow_id = intval( $_POST['post_id'] );
382
- $step_ids = array_map( 'intval', $_POST['step_ids'] );
383
-
384
- $result = array(
385
- 'status' => false,
386
- /* translators: %s flow id */
387
- 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
388
- );
389
-
390
- if ( ! $flow_id || ! is_array( $step_ids ) ) {
391
- wp_send_json( $result );
392
- }
393
-
394
- $new_flow_steps = array();
395
-
396
- foreach ( $step_ids as $index => $step_id ) {
397
-
398
- $new_flow_steps[] = array(
399
- 'id' => intval( $step_id ),
400
- 'title' => get_the_title( $step_id ),
401
- 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
402
- );
403
- }
404
-
405
- update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
406
-
407
- $result = array(
408
- 'status' => true,
409
- /* translators: %s flow id */
410
- 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
411
- );
412
-
413
- wp_send_json( $result );
414
- }
415
-
416
-
417
- /**
418
- * Load admin scripts
419
- *
420
- * @since 1.0.0
421
- *
422
- * @return void
423
- */
424
- public function admin_scripts() {
425
-
426
- global $pagenow;
427
- global $post;
428
-
429
- $screen = get_current_screen();
430
-
431
- if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
432
-
433
- wp_enqueue_script(
434
- 'wcf-flow-meta',
435
- CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
436
- array( 'jquery', 'jquery-ui-sortable' ),
437
- CARTFLOWS_VER,
438
- true
439
- );
440
-
441
- wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
442
- wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
443
-
444
- $localize = array(
445
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
446
- );
447
-
448
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
449
- }
450
- }
451
-
452
- /**
453
- * Initialize meta box
454
- *
455
- * @since 1.0.0
456
- *
457
- * @return void
458
- */
459
- public function init_metabox() {
460
-
461
- /**
462
- * Fires after the title field.
463
- *
464
- * @param WP_Post $post Post object.
465
- */
466
- add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
467
- add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
468
- add_action( 'save_post', array( $this, 'save_meta_box' ) );
469
- }
470
-
471
- /**
472
- * Is first time import?
473
- *
474
- * @param integer $post_id post ID.
475
- * @return bool
476
- */
477
- function is_flow_imported( $post_id = 0 ) {
478
-
479
- if ( 0 === $post_id ) {
480
- $post_id = get_the_ID();
481
- }
482
-
483
- $steps = get_post_meta( $post_id, 'wcf-steps', true );
484
- $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
485
-
486
- if ( empty( $steps ) && 'import' === $choice ) {
487
- return true;
488
- }
489
-
490
- return false;
491
- }
492
-
493
- /**
494
- * Setup meta box.
495
- *
496
- * @return void
497
- */
498
- function setup_meta_box() {
499
- if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
500
- return;
501
- }
502
-
503
- /**
504
- * Adding Add new step button to the top*/
505
- echo $this->add_add_new_step_button();
506
-
507
- $this->markup_meta_box();
508
- }
509
-
510
- /**
511
- * Settings meta box.
512
- *
513
- * @return void
514
- */
515
- function settings_meta_box() {
516
-
517
- if ( CARTFLOWS_FLOW_POST_TYPE == get_post_type() ) {
518
-
519
- add_meta_box(
520
- 'wcf-sandbox-settings', // Id.
521
- __( 'Flow Settings', 'cartflows' ), // Title.
522
- array( $this, 'sandbox_meta_box' ), // Callback.
523
- CARTFLOWS_FLOW_POST_TYPE, // Post_type.
524
- 'side', // Context.
525
- 'high' // Priority.
526
- );
527
-
528
- do_action( 'cartflows_add_flow_metabox' );
529
- }
530
- }
531
-
532
- /**
533
- * Metabox Markup
534
- *
535
- * @return void
536
- */
537
- function markup_meta_box() {
538
- global $post;
539
-
540
- wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
541
-
542
- // Get defaults.
543
- $meta = self::get_current_post_meta( $post->ID );
544
-
545
- /**
546
- * Get options
547
- */
548
- $updated_data = array(
549
- 'steps' => $meta['wcf-steps']['default'],
550
- );
551
-
552
- do_action( 'wcf_flow_settings_markup_before', $meta );
553
- $this->page_header_tab( $updated_data );
554
- do_action( 'wcf_flow_settings_markup_after', $meta );
555
- }
556
-
557
- /**
558
- * Metabox Markup
559
- *
560
- * @param object $post Post object.
561
- * @return void
562
- */
563
- function sandbox_meta_box( $post ) {
564
-
565
- // Get defaults.
566
- $meta = self::get_current_post_meta( $post->ID );
567
-
568
- /**
569
- * Get options
570
- */
571
- foreach ( $meta as $key => $value ) {
572
- $updated_data[ $key ] = $meta[ $key ]['default'];
573
- }
574
-
575
- do_action( 'wcf_flow_sandbox_markup_before', $meta );
576
- $this->sandbox_markup( $updated_data );
577
- do_action( 'wcf_flow_sandbox_markup_after', $meta );
578
- }
579
-
580
- /**
581
- * Page Header Tabs
582
- *
583
- * @param array $options Post meta.
584
- * @return void
585
- */
586
- function page_header_tab( $options ) {
587
-
588
- include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
589
- }
590
-
591
- /**
592
- * Sandbox Markup
593
- *
594
- * @param array $options Post meta.
595
- * @return void
596
- */
597
- function sandbox_markup( $options ) {
598
- ?>
599
- <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
600
- <div class="wcf-flow-sandbox-table-container">
601
- <?php
602
- echo wcf()->meta->get_checkbox_field(
603
- array(
604
- 'name' => 'wcf-testing',
605
- 'value' => $options['wcf-testing'],
606
- 'after' => __( 'Enable Test Mode', 'cartflows' ),
607
- )
608
- );
609
-
610
- echo wcf()->meta->get_description_field(
611
- array(
612
- 'name' => 'wcf-testing-note',
613
- 'content' => __( 'Test mode adds random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
614
- )
615
- );
616
-
617
- ?>
618
- </div>
619
- </div>
620
- <?php
621
- }
622
-
623
- /**
624
- * Keep the menu open when editing the flows.
625
- * Highlights the wanted admin (sub-) menu items for the CPT.
626
- *
627
- * @since 1.0.0
628
- */
629
- public function menu_highlight() {
630
- global $parent_file, $submenu_file, $post_type;
631
- if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
632
- $parent_file = CARTFLOWS_SLUG;
633
- $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;
634
- endif;
635
- }
636
-
637
- /**
638
- * Get metabox options
639
- *
640
- * @param int $post_id post id.
641
- * @return array
642
- */
643
- public static function get_meta_option( $post_id ) {
644
-
645
- if ( null === self::$meta_option ) {
646
- /**
647
- * Set metabox options
648
- */
649
- self::$meta_option = wcf()->options->get_flow_fields( $post_id );
650
- }
651
-
652
- return self::$meta_option;
653
- }
654
-
655
- /**
656
- * Get metabox options
657
- *
658
- * @param int $post_id post ID.
659
- * @return array
660
- */
661
- public static function get_current_post_meta( $post_id ) {
662
-
663
- $stored = get_post_meta( $post_id );
664
-
665
- $default_meta = self::get_meta_option( $post_id );
666
-
667
- // Set stored and override defaults.
668
- foreach ( $stored as $key => $value ) {
669
- if ( array_key_exists( $key, $default_meta ) ) {
670
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
671
- } else {
672
- self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
673
- }
674
- }
675
-
676
- return self::get_meta_option( $post_id );
677
- }
678
-
679
- /**
680
- * Metabox Save
681
- *
682
- * @param number $post_id Post ID.
683
- * @return void
684
- */
685
- function save_meta_box( $post_id ) {
686
-
687
- // Checks save status.
688
- $is_autosave = wp_is_post_autosave( $post_id );
689
- $is_revision = wp_is_post_revision( $post_id );
690
-
691
- $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( $_POST['nonce-flow-meta'], 'save-nonce-flow-meta' ) ) ? true : false;
692
-
693
- // Exits script depending on save status.
694
- if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
695
- return;
696
- }
697
-
698
- wcf()->options->save_flow_fields( $post_id );
699
- }
700
-
701
- /**
702
- * Localize variables in admin
703
- *
704
- * @param array $vars variables.
705
- */
706
- function localize_vars( $vars ) {
707
-
708
- $ajax_actions = array(
709
- 'wcf_setup_default_steps',
710
- 'wcf_add_flow_step',
711
- 'wcf_delete_flow_step',
712
- 'wcf_reorder_flow_steps',
713
- );
714
-
715
- foreach ( $ajax_actions as $action ) {
716
-
717
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
718
- }
719
-
720
- return $vars;
721
- }
722
-
723
- /**
724
- * Add New Step Button
725
- *
726
- * @return string
727
- */
728
- function add_add_new_step_button() {
729
- $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
730
- $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
731
- $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
732
- $add_new_btn_markup .= esc_html( 'Add New Step', 'cartflows' );
733
- $add_new_btn_markup .= '</button>';
734
- $add_new_btn_markup .= '</div>';
735
-
736
- return $add_new_btn_markup;
737
- }
738
- }
739
-
740
- /**
741
- * Kicking this off by calling 'get_instance()' method
742
- */
743
- Cartflows_Flow_Meta::get_instance();
1
+ <?php
2
+ /**
3
+ * Flow meta
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Meta Boxes setup
10
+ */
11
+ class Cartflows_Flow_Meta {
12
+
13
+
14
+ /**
15
+ * Instance
16
+ *
17
+ * @var $instance
18
+ */
19
+ private static $instance;
20
+
21
+ /**
22
+ * Meta Option
23
+ *
24
+ * @var $meta_option
25
+ */
26
+ private static $meta_option;
27
+
28
+ /**
29
+ * Initiator
30
+ */
31
+ public static function get_instance() {
32
+ if ( ! isset( self::$instance ) ) {
33
+ self::$instance = new self;
34
+ }
35
+
36
+ return self::$instance;
37
+ }
38
+
39
+ /**
40
+ * Constructor
41
+ */
42
+ public function __construct() {
43
+
44
+ add_action( 'admin_head', array( $this, 'menu_highlight' ) );
45
+
46
+ add_action( 'admin_init', array( $this, 'admin_init_actions' ) );
47
+
48
+ /* Init Metabox */
49
+ add_action( 'load-post.php', array( $this, 'init_metabox' ) );
50
+ add_action( 'load-post-new.php', array( $this, 'init_metabox' ) );
51
+
52
+ /* Add Scripts */
53
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ), 20 );
54
+
55
+ add_action( 'wp_ajax_cartflows_setup_default_steps', array( $this, 'cartflows_setup_default_steps' ) );
56
+ add_action( 'wp_ajax_cartflows_delete_flow_step', array( $this, 'cartflows_delete_flow_step' ) );
57
+
58
+ add_action( 'wp_ajax_cartflows_reorder_flow_steps', array( $this, 'cartflows_reorder_flow_steps' ) );
59
+
60
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
61
+
62
+ add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
63
+ }
64
+
65
+ /**
66
+ * Display admin notices.
67
+ *
68
+ * @since 1.0.0
69
+ *
70
+ * @return void
71
+ */
72
+ function admin_notices() {
73
+
74
+ if ( CARTFLOWS_STEP_POST_TYPE !== get_post_type() ) {
75
+ return;
76
+ }
77
+
78
+ $flow_id = get_post_meta( get_the_id(), 'wcf-flow-id', true );
79
+ if ( $flow_id ) { ?>
80
+ <div class="wcf-notice-back-edit-flow">
81
+ <p>
82
+ <a href="<?php echo esc_url( get_edit_post_link( $flow_id ) ); ?>" class="button button-primary button-hero" style="text-decoration: none;">
83
+ <i class="dashicons dashicons-arrow-left-alt"></i>
84
+ <?php _e( 'Back to edit Flow', 'cartflows' ); ?>
85
+ </a>
86
+ </p>
87
+ </div>
88
+ <?php
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Initialize admin actions.
94
+ *
95
+ * @since 1.0.0
96
+ *
97
+ * @return void
98
+ */
99
+ function admin_init_actions() {
100
+ add_action( 'before_delete_post', array( $this, 'step_post_sync' ) );
101
+ add_action( 'wp_trash_post', array( $this, 'step_post_trash_sync' ) );
102
+ add_action( 'untrashed_post', array( $this, 'step_post_untrash_sync' ) );
103
+ }
104
+
105
+ /**
106
+ * Delete term data and steps data after deleting flow.
107
+ *
108
+ * @since 1.0.0
109
+ * @param int $pid post id.
110
+ *
111
+ * @return void
112
+ */
113
+ function step_post_sync( $pid ) {
114
+
115
+ global $post_type;
116
+
117
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
118
+
119
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
120
+
121
+ if ( $steps && is_array( $steps ) ) {
122
+ foreach ( $steps as $i => $step ) {
123
+ wp_delete_post( $step['id'], true );
124
+ }
125
+ }
126
+
127
+ $term_data = term_exists( 'flow-' . $pid, CARTFLOWS_TAXONOMY_STEP_FLOW );
128
+
129
+ if ( is_array( $term_data ) ) {
130
+ wp_delete_term( $term_data['term_id'], CARTFLOWS_TAXONOMY_STEP_FLOW );
131
+ }
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Trash steps data after trashing flow.
137
+ *
138
+ * @since 1.0.0
139
+ * @param int $pid post id.
140
+ *
141
+ * @return void
142
+ */
143
+ function step_post_trash_sync( $pid ) {
144
+
145
+ global $post_type;
146
+
147
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
148
+
149
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
150
+
151
+ if ( $steps && is_array( $steps ) ) {
152
+ foreach ( $steps as $i => $step ) {
153
+ wp_trash_post( $step['id'] );
154
+ }
155
+ }
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Untrash steps data after restoring flow.
161
+ *
162
+ * @since 1.0.0
163
+ * @param int $pid post id.
164
+ *
165
+ * @return void
166
+ */
167
+ function step_post_untrash_sync( $pid ) {
168
+
169
+ global $post_type;
170
+
171
+ if ( CARTFLOWS_FLOW_POST_TYPE === $post_type ) {
172
+
173
+ $steps = get_post_meta( $pid, 'wcf-steps', true );
174
+
175
+ if ( $steps && is_array( $steps ) ) {
176
+ foreach ( $steps as $i => $step ) {
177
+ wp_untrash_post( $step['id'] );
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Setup default steps for flow
185
+ *
186
+ * @since 1.0.0
187
+ *
188
+ * @return void
189
+ */
190
+ public function cartflows_setup_default_steps() {
191
+
192
+ check_ajax_referer( 'wcf-setup-default-steps', 'security' );
193
+
194
+ $flow_id = intval( $_POST['post_id'] );
195
+
196
+ $result = array(
197
+ 'status' => false,
198
+ /* translators: %s flow id */
199
+ 'text' => sprintf( __( 'Steps not created for flow - %s', 'cartflows' ), $flow_id ),
200
+ );
201
+
202
+ if ( ! $flow_id ) {
203
+ wp_send_json( $result );
204
+ }
205
+
206
+ $is_step_exists = get_post_meta( $flow_id, 'wcf-steps', true );
207
+
208
+ if ( $is_step_exists ) {
209
+
210
+ $result = array(
211
+ 'status' => false,
212
+ /* translators: %s flow id */
213
+ 'text' => sprintf( __( 'Steps already exists. Flow - %s', 'cartflows' ), $flow_id ),
214
+ );
215
+
216
+ wp_send_json( $result );
217
+ }
218
+
219
+ /* Start Creating */
220
+
221
+ $flow_steps = array();
222
+
223
+ $steps_data = array(
224
+ 'landing' => __( 'Landing Page', 'cartflows' ),
225
+ 'checkout' => __( 'Checkout Page', 'cartflows' ),
226
+ 'thankyou' => __( 'Thank You Page', 'cartflows' ),
227
+ );
228
+
229
+ foreach ( $steps_data as $slug => $title ) {
230
+
231
+ $step_id = wp_insert_post(
232
+ array(
233
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
234
+ 'post_title' => $title,
235
+ 'post_content' => '[cartflows_navigation]',
236
+ 'post_status' => 'publish',
237
+ )
238
+ );
239
+
240
+ if ( $step_id ) {
241
+
242
+ $flow_steps[] = array(
243
+ 'id' => $step_id,
244
+ 'title' => $title,
245
+ 'type' => $slug,
246
+ );
247
+
248
+ // insert post meta.
249
+ update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
250
+ update_post_meta( $step_id, 'wcf-step-type', $slug );
251
+
252
+ wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
253
+ wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
254
+ }
255
+ }
256
+
257
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
258
+
259
+ $result = array(
260
+ 'status' => true,
261
+ /* translators: %s flow id */
262
+ 'text' => sprintf( __( 'Steps created for flow - %s', 'cartflows' ), $flow_id ),
263
+ 'redirect' => get_edit_post_link( $flow_id ),
264
+ );
265
+
266
+ wp_send_json( $result );
267
+ }
268
+
269
+ /**
270
+ * Create step for given flow.
271
+ *
272
+ * @param int $flow_id flow ID.
273
+ * @param int $step_type step type.
274
+ * @param int $step_title step title.
275
+ * @since 1.0.0
276
+ *
277
+ * @return int
278
+ */
279
+ public function create_step( $flow_id, $step_type, $step_title ) {
280
+
281
+ $new_step_id = wp_insert_post(
282
+ array(
283
+ 'post_type' => CARTFLOWS_STEP_POST_TYPE,
284
+ 'post_title' => $step_title,
285
+ 'post_status' => 'publish',
286
+ )
287
+ );
288
+
289
+ if ( $new_step_id ) {
290
+
291
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
292
+
293
+ if ( ! is_array( $flow_steps ) ) {
294
+ $flow_steps = array();
295
+ }
296
+
297
+ $flow_steps[] = array(
298
+ 'id' => $new_step_id,
299
+ 'title' => $step_title,
300
+ 'type' => $step_type,
301
+ );
302
+
303
+ // insert post meta.
304
+ update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
305
+ update_post_meta( $new_step_id, 'wcf-step-type', $step_type );
306
+
307
+ wp_set_object_terms( $new_step_id, $step_type, CARTFLOWS_TAXONOMY_STEP_TYPE );
308
+ wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
309
+ }
310
+
311
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
312
+
313
+ return $new_step_id;
314
+ }
315
+
316
+ /**
317
+ * Delete step for flow
318
+ *
319
+ * @since 1.0.0
320
+ *
321
+ * @return void
322
+ */
323
+ public function cartflows_delete_flow_step() {
324
+
325
+ check_ajax_referer( 'wcf-delete-flow-step', 'security' );
326
+
327
+ $flow_id = intval( $_POST['post_id'] );
328
+ $step_id = intval( $_POST['step_id'] );
329
+
330
+ $result = array(
331
+ 'status' => false,
332
+ /* translators: %s flow id */
333
+ 'text' => sprintf( __( 'Step not deleted for flow - %s', 'cartflows' ), $flow_id ),
334
+ );
335
+
336
+ if ( ! $flow_id || ! $step_id ) {
337
+ wp_send_json( $result );
338
+ }
339
+
340
+ wp_delete_post( $step_id, true );
341
+
342
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
343
+
344
+ if ( ! is_array( $flow_steps ) ) {
345
+ wp_send_json( $result );
346
+ }
347
+
348
+ foreach ( $flow_steps as $index => $data ) {
349
+
350
+ if ( intval( $data['id'] ) === $step_id ) {
351
+ unset( $flow_steps[ $index ] );
352
+ break;
353
+ }
354
+ }
355
+
356
+ /* Set index order properly */
357
+ $flow_steps = array_merge( $flow_steps );
358
+
359
+ update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
360
+
361
+ $result = array(
362
+ 'status' => true,
363
+ /* translators: %s flow id */
364
+ 'text' => sprintf( __( 'Step deleted for flow - %s', 'cartflows' ), $flow_id ),
365
+ );
366
+
367
+ wp_send_json( $result );
368
+ }
369
+
370
+ /**
371
+ * Reorder step flow
372
+ *
373
+ * @since 1.0.0
374
+ *
375
+ * @return void
376
+ */
377
+ public function cartflows_reorder_flow_steps() {
378
+
379
+ check_ajax_referer( 'wcf-reorder-flow-steps', 'security' );
380
+
381
+ $flow_id = intval( $_POST['post_id'] );
382
+ $step_ids = array_map( 'intval', $_POST['step_ids'] );
383
+
384
+ $result = array(
385
+ 'status' => false,
386
+ /* translators: %s flow id */
387
+ 'text' => sprintf( __( 'Steps not sorted for flow - %s', 'cartflows' ), $flow_id ),
388
+ );
389
+
390
+ if ( ! $flow_id || ! is_array( $step_ids ) ) {
391
+ wp_send_json( $result );
392
+ }
393
+
394
+ $new_flow_steps = array();
395
+
396
+ foreach ( $step_ids as $index => $step_id ) {
397
+
398
+ $new_flow_steps[] = array(
399
+ 'id' => intval( $step_id ),
400
+ 'title' => get_the_title( $step_id ),
401
+ 'type' => get_post_meta( $step_id, 'wcf-step-type', true ),
402
+ );
403
+ }
404
+
405
+ update_post_meta( $flow_id, 'wcf-steps', $new_flow_steps );
406
+
407
+ $result = array(
408
+ 'status' => true,
409
+ /* translators: %s flow id */
410
+ 'text' => sprintf( __( 'Steps sorted for flow - %s', 'cartflows' ), $flow_id ),
411
+ );
412
+
413
+ wp_send_json( $result );
414
+ }
415
+
416
+
417
+ /**
418
+ * Load admin scripts
419
+ *
420
+ * @since 1.0.0
421
+ *
422
+ * @return void
423
+ */
424
+ public function admin_scripts() {
425
+
426
+ global $pagenow;
427
+ global $post;
428
+
429
+ $screen = get_current_screen();
430
+
431
+ if ( ( 'post-new.php' == $pagenow || 'post.php' == $pagenow ) && CARTFLOWS_FLOW_POST_TYPE == $screen->post_type ) {
432
+
433
+ wp_enqueue_script(
434
+ 'wcf-flow-meta',
435
+ CARTFLOWS_URL . 'admin/assets/js/flow-admin-edit.js',
436
+ array( 'jquery', 'jquery-ui-sortable' ),
437
+ CARTFLOWS_VER,
438
+ true
439
+ );
440
+
441
+ wp_enqueue_style( 'wcf-flow-meta', CARTFLOWS_URL . 'admin/assets/css/flow-admin-edit.css', '', CARTFLOWS_VER );
442
+ wp_style_add_data( 'wcf-flow-meta', 'rtl', 'replace' );
443
+
444
+ $localize = array(
445
+ 'ajax_url' => admin_url( 'admin-ajax.php' ),
446
+ );
447
+
448
+ wp_localize_script( 'jquery', 'cartflows', apply_filters( 'wcf_js_localize', $localize ) );
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Initialize meta box
454
+ *
455
+ * @since 1.0.0
456
+ *
457
+ * @return void
458
+ */
459
+ public function init_metabox() {
460
+
461
+ /**
462
+ * Fires after the title field.
463
+ *
464
+ * @param WP_Post $post Post object.
465
+ */
466
+ add_action( 'add_meta_boxes', array( $this, 'settings_meta_box' ) );
467
+ add_action( 'edit_form_after_title', array( $this, 'setup_meta_box' ) );
468
+ add_action( 'save_post', array( $this, 'save_meta_box' ) );
469
+ }
470
+
471
+ /**
472
+ * Is first time import?
473
+ *
474
+ * @param integer $post_id post ID.
475
+ * @return bool
476
+ */
477
+ function is_flow_imported( $post_id = 0 ) {
478
+
479
+ if ( 0 === $post_id ) {
480
+ $post_id = get_the_ID();
481
+ }
482
+
483
+ $steps = get_post_meta( $post_id, 'wcf-steps', true );
484
+ $choice = get_post_meta( $post_id, 'wcf-flow-choise', true );
485
+
486
+ if ( empty( $steps ) && 'import' === $choice ) {
487
+ return true;
488
+ }
489
+
490
+ return false;
491
+ }
492
+
493
+ /**
494
+ * Setup meta box.
495
+ *
496
+ * @return void
497
+ */
498
+ function setup_meta_box() {
499
+ if ( ! Cartflows_Admin::is_flow_edit_admin() ) {
500
+ return;
501
+ }
502
+
503
+ /**
504
+ * Adding Add new step button to the top*/
505
+ echo $this->add_add_new_step_button();
506
+
507
+ $this->markup_meta_box();
508
+ }
509
+
510
+ /**
511
+ * Settings meta box.
512
+ *
513
+ * @return void
514
+ */
515
+ function settings_meta_box() {
516
+
517
+ if ( CARTFLOWS_FLOW_POST_TYPE == get_post_type() ) {
518
+
519
+ add_meta_box(
520
+ 'wcf-sandbox-settings', // Id.
521
+ __( 'Flow Settings', 'cartflows' ), // Title.
522
+ array( $this, 'sandbox_meta_box' ), // Callback.
523
+ CARTFLOWS_FLOW_POST_TYPE, // Post_type.
524
+ 'side', // Context.
525
+ 'high' // Priority.
526
+ );
527
+
528
+ do_action( 'cartflows_add_flow_metabox' );
529
+ }
530
+ }
531
+
532
+ /**
533
+ * Metabox Markup
534
+ *
535
+ * @return void
536
+ */
537
+ function markup_meta_box() {
538
+ global $post;
539
+
540
+ wp_nonce_field( 'save-nonce-flow-meta', 'nonce-flow-meta' );
541
+
542
+ // Get defaults.
543
+ $meta = self::get_current_post_meta( $post->ID );
544
+
545
+ /**
546
+ * Get options
547
+ */
548
+ $updated_data = array(
549
+ 'steps' => $meta['wcf-steps']['default'],
550
+ );
551
+
552
+ do_action( 'wcf_flow_settings_markup_before', $meta );
553
+ $this->page_header_tab( $updated_data );
554
+ do_action( 'wcf_flow_settings_markup_after', $meta );
555
+ }
556
+
557
+ /**
558
+ * Metabox Markup
559
+ *
560
+ * @param object $post Post object.
561
+ * @return void
562
+ */
563
+ function sandbox_meta_box( $post ) {
564
+
565
+ // Get defaults.
566
+ $meta = self::get_current_post_meta( $post->ID );
567
+
568
+ /**
569
+ * Get options
570
+ */
571
+ foreach ( $meta as $key => $value ) {
572
+ $updated_data[ $key ] = $meta[ $key ]['default'];
573
+ }
574
+
575
+ do_action( 'wcf_flow_sandbox_markup_before', $meta );
576
+ $this->sandbox_markup( $updated_data );
577
+ do_action( 'wcf_flow_sandbox_markup_after', $meta );
578
+ }
579
+
580
+ /**
581
+ * Page Header Tabs
582
+ *
583
+ * @param array $options Post meta.
584
+ * @return void
585
+ */
586
+ function page_header_tab( $options ) {
587
+
588
+ include_once CARTFLOWS_FLOW_DIR . 'view/meta-flow-steps.php';
589
+ }
590
+
591
+ /**
592
+ * Sandbox Markup
593
+ *
594
+ * @param array $options Post meta.
595
+ * @return void
596
+ */
597
+ function sandbox_markup( $options ) {
598
+ ?>
599
+ <div class="wcf-flow-sandbox-table wcf-general-metabox-wrap widefat">
600
+ <div class="wcf-flow-sandbox-table-container">
601
+ <?php
602
+ echo wcf()->meta->get_checkbox_field(
603
+ array(
604
+ 'name' => 'wcf-testing',
605
+ 'value' => $options['wcf-testing'],
606
+ 'after' => __( 'Enable Test Mode', 'cartflows' ),
607
+ )
608
+ );
609
+
610
+ echo wcf()->meta->get_description_field(
611
+ array(
612
+ 'name' => 'wcf-testing-note',
613
+ 'content' => __( 'Test mode adds random products in your flow, so you can preview it easily while testing.', 'cartflows' ),
614
+ )
615
+ );
616
+
617
+ ?>
618
+ </div>
619
+ </div>
620
+ <?php
621
+ }
622
+
623
+ /**
624
+ * Keep the menu open when editing the flows.
625
+ * Highlights the wanted admin (sub-) menu items for the CPT.
626
+ *
627
+ * @since 1.0.0
628
+ */
629
+ public function menu_highlight() {
630
+ global $parent_file, $submenu_file, $post_type;
631
+ if ( CARTFLOWS_FLOW_POST_TYPE == $post_type ) :
632
+ $parent_file = CARTFLOWS_SLUG;
633
+ $submenu_file = 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE;
634
+ endif;
635
+ }
636
+
637
+ /**
638
+ * Get metabox options
639
+ *
640
+ * @param int $post_id post id.
641
+ * @return array
642
+ */
643
+ public static function get_meta_option( $post_id ) {
644
+
645
+ if ( null === self::$meta_option ) {
646
+ /**
647
+ * Set metabox options
648
+ */
649
+ self::$meta_option = wcf()->options->get_flow_fields( $post_id );
650
+ }
651
+
652
+ return self::$meta_option;
653
+ }
654
+
655
+ /**
656
+ * Get metabox options
657
+ *
658
+ * @param int $post_id post ID.
659
+ * @return array
660
+ */
661
+ public static function get_current_post_meta( $post_id ) {
662
+
663
+ $stored = get_post_meta( $post_id );
664
+
665
+ $default_meta = self::get_meta_option( $post_id );
666
+
667
+ // Set stored and override defaults.
668
+ foreach ( $stored as $key => $value ) {
669
+ if ( array_key_exists( $key, $default_meta ) ) {
670
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? maybe_unserialize( $stored[ $key ][0] ) : '';
671
+ } else {
672
+ self::$meta_option[ $key ]['default'] = ( isset( $stored[ $key ][0] ) ) ? $stored[ $key ][0] : '';
673
+ }
674
+ }
675
+
676
+ return self::get_meta_option( $post_id );
677
+ }
678
+
679
+ /**
680
+ * Metabox Save
681
+ *
682
+ * @param number $post_id Post ID.
683
+ * @return void
684
+ */
685
+ function save_meta_box( $post_id ) {
686
+
687
+ // Checks save status.
688
+ $is_autosave = wp_is_post_autosave( $post_id );
689
+ $is_revision = wp_is_post_revision( $post_id );
690
+
691
+ $is_valid_nonce = ( isset( $_POST['nonce-flow-meta'] ) && wp_verify_nonce( $_POST['nonce-flow-meta'], 'save-nonce-flow-meta' ) ) ? true : false;
692
+
693
+ // Exits script depending on save status.
694
+ if ( $is_autosave || $is_revision || ! $is_valid_nonce ) {
695
+ return;
696
+ }
697
+
698
+ wcf()->options->save_flow_fields( $post_id );
699
+ }
700
+
701
+ /**
702
+ * Localize variables in admin
703
+ *
704
+ * @param array $vars variables.
705
+ */
706
+ function localize_vars( $vars ) {
707
+
708
+ $ajax_actions = array(
709
+ 'wcf_setup_default_steps',
710
+ 'wcf_add_flow_step',
711
+ 'wcf_delete_flow_step',
712
+ 'wcf_reorder_flow_steps',
713
+ );
714
+
715
+ foreach ( $ajax_actions as $action ) {
716
+
717
+ $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
718
+ }
719
+
720
+ return $vars;
721
+ }
722
+
723
+ /**
724
+ * Add New Step Button
725
+ *
726
+ * @return string
727
+ */
728
+ function add_add_new_step_button() {
729
+ $add_new_btn_markup = '<style>.wrap{ position:relative;}</style>';
730
+ $add_new_btn_markup .= "<div class='wcf-button-wrap'>";
731
+ $add_new_btn_markup .= "<button class='wcf-trigger-popup page-title-action'>";
732
+ $add_new_btn_markup .= esc_html( 'Add New Step', 'cartflows' );
733
+ $add_new_btn_markup .= '</button>';
734
+ $add_new_btn_markup .= '</div>';
735
+
736
+ return $add_new_btn_markup;
737
+ }
738
+ }
739
+
740
+ /**
741
+ * Kicking this off by calling 'get_instance()' method
742
+ */
743
+ Cartflows_Flow_Meta::get_instance();
modules/flow/classes/class-cartflows-flow-post-type.php CHANGED
@@ -76,7 +76,7 @@ class Cartflows_Flow_Post_Type {
76
  'exclude_from_search' => true,
77
  'has_archive' => false, // it shouldn't have archive page.
78
  'rewrite' => false, // it shouldn't have rewrite rules.
79
- 'supports' => array( 'title' ),
80
  'capability_type' => 'post',
81
  );
82
 
76
  'exclude_from_search' => true,
77
  'has_archive' => false, // it shouldn't have archive page.
78
  'rewrite' => false, // it shouldn't have rewrite rules.
79
+ 'supports' => array( 'title', 'thumbnail' ),
80
  'capability_type' => 'post',
81
  );
82
 
modules/flow/classes/class-cartflows-step-post-type.php CHANGED
@@ -1,450 +1,450 @@
1
- <?php
2
- /**
3
- * Step post type.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Initialization
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Step_Post_Type {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Member Variable
25
- *
26
- * @var body_classes
27
- */
28
- private $body_classes = array();
29
-
30
- /**
31
- * Initiator
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self;
36
- }
37
- return self::$instance;
38
- }
39
-
40
- /**
41
- * Constructor
42
- */
43
- public function __construct() {
44
-
45
- add_action( 'init', array( $this, 'step_post_type' ) );
46
- add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
- add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
- add_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
49
- add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
- add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ) );
51
-
52
- add_filter( 'template_include', array( $this, 'load_page_template' ), 99 );
53
- }
54
-
55
-
56
- /**
57
- * Trys to load page.php for a header, footer or part theme layout.
58
- *
59
- * @since 1.0.0
60
- * @param string $template The current template to be loaded.
61
- * @return string
62
- */
63
- function load_page_template( $template ) {
64
-
65
- global $post;
66
-
67
- if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
68
-
69
- /**
70
- * Remove Next/Prev Navigation
71
- * add_filter('next_post_link', '__return_empty_string');
72
- * add_filter('previous_post_link', '__return_empty_string');
73
- *
74
- * $page = locate_template( array( 'page.php' ) );
75
- *
76
- * if ( ! empty( $page ) ) {
77
- * return $page;
78
- * }
79
- */
80
-
81
- $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
82
-
83
- $page_template = apply_filters( 'cartflows_page_template', $page_template );
84
-
85
- $file = '';
86
-
87
- switch ( $page_template ) {
88
-
89
- case 'cartflows-default':
90
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
91
- $this->body_classes[] = $page_template;
92
- break;
93
- case 'cartflows-canvas':
94
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
95
- $this->body_classes[] = $page_template;
96
- break;
97
- default:
98
- $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
99
- $this->body_classes[] = 'cartflows-default';
100
- break;
101
- }
102
-
103
- // Just to be safe, we check if the file exist first.
104
- if ( file_exists( $file ) ) {
105
-
106
- /* Add Body Class */
107
- add_filter( 'body_class', [ $this, 'body_class' ] );
108
-
109
- return $file;
110
- } else {
111
- echo $file;
112
- }
113
- }
114
-
115
- return $template;
116
- }
117
-
118
- /**
119
- * Body classes.
120
- *
121
- * @since 1.0.0
122
- * @param array $classes Body classes.
123
- * @return array
124
- */
125
- function body_class( $classes = [] ) {
126
-
127
- $classes = array_merge( $classes, $this->body_classes );
128
-
129
- return $classes;
130
- }
131
-
132
- /**
133
- * Create custom post type
134
- */
135
- function step_post_type() {
136
-
137
- $labels = array(
138
- 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
139
- 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
140
- 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
141
- 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
142
- 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
143
- 'view_item' => esc_html__( 'View Step', 'cartflows' ),
144
- 'add_new' => esc_html__( 'Add New', 'cartflows' ),
145
- 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
146
- 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
147
- 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
148
- );
149
-
150
- $args = array(
151
- 'labels' => $labels,
152
- 'public' => true,
153
- 'query_var' => true,
154
- 'can_export' => true,
155
- 'exclude_from_search' => true,
156
- 'show_ui' => true,
157
- 'show_in_menu' => false,
158
- 'show_in_admin_bar' => true,
159
- 'supports' => array( 'title', 'editor', 'elementor' ),
160
- 'capability_type' => 'post',
161
- 'capabilities' => array(
162
- 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
163
- ),
164
- 'map_meta_cap' => true,
165
- );
166
-
167
- register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
168
-
169
- $args = array(
170
- 'label' => __( 'Step Type', 'cartflows' ),
171
- 'public' => false,
172
- 'rewrite' => false,
173
- 'hierarchical' => false,
174
- );
175
-
176
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
177
-
178
- $args = array(
179
- 'label' => __( 'Step Flow', 'cartflows' ),
180
- 'public' => false,
181
- 'rewrite' => false,
182
- 'hierarchical' => false,
183
- );
184
-
185
- register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
186
-
187
- /**
188
- * Register 'Elementor' & 'Beaver Builder' site types.
189
- *
190
- * @see self::add_terms();
191
- */
192
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
193
-
194
- $terms = array(
195
- array(
196
- 'name' => __( 'Landing', 'cartflows' ),
197
- 'args' => array(
198
- 'slug' => 'landing',
199
- ),
200
- ),
201
- array(
202
- 'name' => __( 'Checkout', 'cartflows' ),
203
- 'args' => array(
204
- 'slug' => 'checkout',
205
- ),
206
- ),
207
- array(
208
- 'name' => __( 'Thank You', 'cartflows' ),
209
- 'args' => array(
210
- 'slug' => 'thankyou',
211
- ),
212
- ),
213
- array(
214
- 'name' => __( 'Upsell', 'cartflows' ),
215
- 'args' => array(
216
- 'slug' => 'upsell',
217
- ),
218
- ),
219
- array(
220
- 'name' => __( 'Downsell', 'cartflows' ),
221
- 'args' => array(
222
- 'slug' => 'downsell',
223
- ),
224
- ),
225
- );
226
-
227
- $this->add_terms( $taxonomy, $terms );
228
- }
229
-
230
- /**
231
- * Add WordPress templates.
232
- *
233
- * Adds Cartflows templates to steps
234
- *
235
- * @since 1.0.0
236
- * @access public
237
- */
238
- function add_wp_templates_support() {
239
- add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
240
- }
241
-
242
- /**
243
- * Add page templates.
244
- *
245
- * @since 1.0.0
246
- * @access public
247
- *
248
- * @param array $page_templates Array of page templates.
249
- *
250
- * @param object $wp_theme wp theme.
251
- * @param object $post post.
252
- *
253
- * @return array Page templates.
254
- */
255
- function add_page_templates( $page_templates, $wp_theme, $post ) {
256
-
257
- $page_templates = array(
258
- 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
259
- );
260
-
261
- return $page_templates;
262
- }
263
-
264
- /**
265
- * Have WordPress match postname to any of our public post types.
266
- * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
267
- * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
268
- *
269
- * @param string $query query statement.
270
- */
271
- function add_cpt_post_names_to_main_query( $query ) {
272
-
273
- // Bail if this is not the main query.
274
- if ( ! $query->is_main_query() ) {
275
- return;
276
- }
277
- // Bail if this query doesn't match our very specific rewrite rule.
278
- if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
279
- return;
280
- }
281
- // Bail if we're not querying based on the post name.
282
- if ( empty( $query->query['name'] ) ) {
283
- return;
284
- }
285
- // Add CPT to the list of post types WP will include when it queries based on the post name.
286
- $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
287
- }
288
-
289
- /**
290
- * Modify permalink
291
- *
292
- * @param string $post_link post link.
293
- * @param array $post post data.
294
- * @param string $leavename leave name.
295
- * @return string
296
- */
297
- function post_type_permalinks( $post_link, $post, $leavename ) {
298
-
299
- // If elementor page preview, return post link as it is.
300
- if ( isset( $_REQUEST['elementor-preview'] ) ) {
301
- return $post_link;
302
- }
303
-
304
- $structure = get_option( 'permalink_structure' );
305
-
306
- if ( '/%postname%/' === $structure ) {
307
-
308
- if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
309
-
310
- $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
311
- }
312
- }
313
-
314
- return $post_link;
315
- }
316
-
317
- /**
318
- * Prevent slug duplicated
319
- *
320
- * @param string $slug post slug.
321
- * @param int $post_ID post id.
322
- * @param string $post_status post status.
323
- * @param string $post_type post type.
324
- * @param int $post_parent post parent id.
325
- * @param string $original_slug original slug.
326
- * @return string
327
- */
328
- function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
329
-
330
- $check_post_types = array(
331
- 'post',
332
- 'page',
333
- CARTFLOWS_STEP_POST_TYPE,
334
- );
335
-
336
- if ( ! in_array( $post_type, $check_post_types ) ) {
337
- return $slug;
338
- }
339
-
340
- if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
341
- // Saving a post, check for duplicates in POST or PAGE post types.
342
- $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
343
- $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
344
-
345
- if ( $post_match || $page_match ) {
346
- $slug .= '-2';
347
- }
348
- } else {
349
-
350
- // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
351
- $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
352
-
353
- if ( $custom_post_type_match ) {
354
- $slug .= '-2';
355
- }
356
- }
357
-
358
- return $slug;
359
- }
360
-
361
- /**
362
- * Add Update messages for any custom post type
363
- *
364
- * @param array $messages Array of default messages.
365
- */
366
- function post_update_messages( $messages ) {
367
-
368
- $custom_post_type = get_post_type( get_the_ID() );
369
-
370
- if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
371
-
372
- $obj = get_post_type_object( $custom_post_type );
373
- $singular_name = $obj->labels->singular_name;
374
- $messages[ $custom_post_type ] = array(
375
- 0 => '', // Unused. Messages start at index 1.
376
- /* translators: %s: singular custom post type name */
377
- 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
378
- /* translators: %s: singular custom post type name */
379
- 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
380
- /* translators: %s: singular custom post type name */
381
- 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
382
- /* translators: %s: singular custom post type name */
383
- 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
384
- /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
385
- 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
386
- /* translators: %s: singular custom post type name */
387
- 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
388
- /* translators: %s: singular custom post type name */
389
- 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
390
- /* translators: %s: singular custom post type name */
391
- 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
392
- /* translators: %s: singular custom post type name */
393
- 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
394
- /* translators: %s: singular custom post type name */
395
- 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
396
- );
397
- }
398
-
399
- return $messages;
400
- }
401
-
402
- /**
403
- * Add Terms for Taxonomy.
404
- *
405
- * => Example.
406
- *
407
- * $taxonomy = '{taxonomy}';
408
- * $terms = array(
409
- * array(
410
- * 'name' => 'Free',
411
- * ),
412
- * array(
413
- * 'name' => 'Premium',
414
- * ),
415
- * );
416
- *
417
- * self::add_terms( $taxonomy, $terms );
418
- *
419
- * @since 1.0.0
420
- * @param string $taxonomy Taxonomy Name.
421
- * @param array $terms Terms list.
422
- * @return void
423
- */
424
- function add_terms( $taxonomy = '', $terms = array() ) {
425
-
426
- foreach ( $terms as $key => $term ) {
427
-
428
- $term_exist = term_exists( $term['name'], $taxonomy );
429
-
430
- if ( empty( $term_exist ) ) {
431
-
432
- /**
433
- * Add additional args if passed from request.
434
- *
435
- * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
436
- */
437
- if ( array_key_exists( 'args', $term ) ) {
438
- wp_insert_term( $term['name'], $taxonomy, $term['args'] );
439
- } else {
440
- wp_insert_term( $term['name'], $taxonomy );
441
- }
442
- }
443
- }
444
- }
445
- }
446
-
447
- /**
448
- * Kicking this off by calling 'get_instance()' method
449
- */
450
- Cartflows_Step_Post_Type::get_instance();
1
+ <?php
2
+ /**
3
+ * Step post type.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Initialization
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Step_Post_Type {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Member Variable
25
+ *
26
+ * @var body_classes
27
+ */
28
+ private $body_classes = array();
29
+
30
+ /**
31
+ * Initiator
32
+ */
33
+ public static function get_instance() {
34
+ if ( ! isset( self::$instance ) ) {
35
+ self::$instance = new self;
36
+ }
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+
45
+ add_action( 'init', array( $this, 'step_post_type' ) );
46
+ add_action( 'init', array( $this, 'add_wp_templates_support' ) );
47
+ add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );
48
+ add_filter( 'post_type_link', array( $this, 'post_type_permalinks' ), 10, 3 );
49
+ add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );
50
+ add_action( 'pre_get_posts', array( $this, 'add_cpt_post_names_to_main_query' ) );
51
+
52
+ add_filter( 'template_include', array( $this, 'load_page_template' ), 99 );
53
+ }
54
+
55
+
56
+ /**
57
+ * Trys to load page.php for a header, footer or part theme layout.
58
+ *
59
+ * @since 1.0.0
60
+ * @param string $template The current template to be loaded.
61
+ * @return string
62
+ */
63
+ function load_page_template( $template ) {
64
+
65
+ global $post;
66
+
67
+ if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {
68
+
69
+ /**
70
+ * Remove Next/Prev Navigation
71
+ * add_filter('next_post_link', '__return_empty_string');
72
+ * add_filter('previous_post_link', '__return_empty_string');
73
+ *
74
+ * $page = locate_template( array( 'page.php' ) );
75
+ *
76
+ * if ( ! empty( $page ) ) {
77
+ * return $page;
78
+ * }
79
+ */
80
+
81
+ $page_template = get_post_meta( _get_wcf_step_id(), '_wp_page_template', true );
82
+
83
+ $page_template = apply_filters( 'cartflows_page_template', $page_template );
84
+
85
+ $file = '';
86
+
87
+ switch ( $page_template ) {
88
+
89
+ case 'cartflows-default':
90
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
91
+ $this->body_classes[] = $page_template;
92
+ break;
93
+ case 'cartflows-canvas':
94
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
95
+ $this->body_classes[] = $page_template;
96
+ break;
97
+ default:
98
+ $file = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
99
+ $this->body_classes[] = 'cartflows-default';
100
+ break;
101
+ }
102
+
103
+ // Just to be safe, we check if the file exist first.
104
+ if ( file_exists( $file ) ) {
105
+
106
+ /* Add Body Class */
107
+ add_filter( 'body_class', [ $this, 'body_class' ] );
108
+
109
+ return $file;
110
+ } else {
111
+ echo $file;
112
+ }
113
+ }
114
+
115
+ return $template;
116
+ }
117
+
118
+ /**
119
+ * Body classes.
120
+ *
121
+ * @since 1.0.0
122
+ * @param array $classes Body classes.
123
+ * @return array
124
+ */
125
+ function body_class( $classes = [] ) {
126
+
127
+ $classes = array_merge( $classes, $this->body_classes );
128
+
129
+ return $classes;
130
+ }
131
+
132
+ /**
133
+ * Create custom post type
134
+ */
135
+ function step_post_type() {
136
+
137
+ $labels = array(
138
+ 'name' => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
139
+ 'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
140
+ 'search_items' => esc_html__( 'Search Steps', 'cartflows' ),
141
+ 'all_items' => esc_html__( 'All Steps', 'cartflows' ),
142
+ 'edit_item' => esc_html__( 'Edit Step', 'cartflows' ),
143
+ 'view_item' => esc_html__( 'View Step', 'cartflows' ),
144
+ 'add_new' => esc_html__( 'Add New', 'cartflows' ),
145
+ 'update_item' => esc_html__( 'Update Step', 'cartflows' ),
146
+ 'add_new_item' => esc_html__( 'Add New', 'cartflows' ),
147
+ 'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
148
+ );
149
+
150
+ $args = array(
151
+ 'labels' => $labels,
152
+ 'public' => true,
153
+ 'query_var' => true,
154
+ 'can_export' => true,
155
+ 'exclude_from_search' => true,
156
+ 'show_ui' => true,
157
+ 'show_in_menu' => false,
158
+ 'show_in_admin_bar' => true,
159
+ 'supports' => array( 'title', 'editor', 'elementor' ),
160
+ 'capability_type' => 'post',
161
+ 'capabilities' => array(
162
+ 'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
163
+ ),
164
+ 'map_meta_cap' => true,
165
+ );
166
+
167
+ register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );
168
+
169
+ $args = array(
170
+ 'label' => __( 'Step Type', 'cartflows' ),
171
+ 'public' => false,
172
+ 'rewrite' => false,
173
+ 'hierarchical' => false,
174
+ );
175
+
176
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );
177
+
178
+ $args = array(
179
+ 'label' => __( 'Step Flow', 'cartflows' ),
180
+ 'public' => false,
181
+ 'rewrite' => false,
182
+ 'hierarchical' => false,
183
+ );
184
+
185
+ register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );
186
+
187
+ /**
188
+ * Register 'Elementor' & 'Beaver Builder' site types.
189
+ *
190
+ * @see self::add_terms();
191
+ */
192
+ $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
193
+
194
+ $terms = array(
195
+ array(
196
+ 'name' => __( 'Landing', 'cartflows' ),
197
+ 'args' => array(
198
+ 'slug' => 'landing',
199
+ ),
200
+ ),
201
+ array(
202
+ 'name' => __( 'Checkout', 'cartflows' ),
203
+ 'args' => array(
204
+ 'slug' => 'checkout',
205
+ ),
206
+ ),
207
+ array(
208
+ 'name' => __( 'Thank You', 'cartflows' ),
209
+ 'args' => array(
210
+ 'slug' => 'thankyou',
211
+ ),
212
+ ),
213
+ array(
214
+ 'name' => __( 'Upsell', 'cartflows' ),
215
+ 'args' => array(
216
+ 'slug' => 'upsell',
217
+ ),
218
+ ),
219
+ array(
220
+ 'name' => __( 'Downsell', 'cartflows' ),
221
+ 'args' => array(
222
+ 'slug' => 'downsell',
223
+ ),
224
+ ),
225
+ );
226
+
227
+ $this->add_terms( $taxonomy, $terms );
228
+ }
229
+
230
+ /**
231
+ * Add WordPress templates.
232
+ *
233
+ * Adds Cartflows templates to steps
234
+ *
235
+ * @since 1.0.0
236
+ * @access public
237
+ */
238
+ function add_wp_templates_support() {
239
+ add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
240
+ }
241
+
242
+ /**
243
+ * Add page templates.
244
+ *
245
+ * @since 1.0.0
246
+ * @access public
247
+ *
248
+ * @param array $page_templates Array of page templates.
249
+ *
250
+ * @param object $wp_theme wp theme.
251
+ * @param object $post post.
252
+ *
253
+ * @return array Page templates.
254
+ */
255
+ function add_page_templates( $page_templates, $wp_theme, $post ) {
256
+
257
+ $page_templates = array(
258
+ 'cartflows-canvas' => _x( 'Template for Page Builders', 'cartflows' ),
259
+ );
260
+
261
+ return $page_templates;
262
+ }
263
+
264
+ /**
265
+ * Have WordPress match postname to any of our public post types.
266
+ * All of our public post types can have /post-name/ as the slug, so they need to be unique across all posts.
267
+ * By default, WordPress only accounts for posts and pages where the slug is /post-name/.
268
+ *
269
+ * @param string $query query statement.
270
+ */
271
+ function add_cpt_post_names_to_main_query( $query ) {
272
+
273
+ // Bail if this is not the main query.
274
+ if ( ! $query->is_main_query() ) {
275
+ return;
276
+ }
277
+ // Bail if this query doesn't match our very specific rewrite rule.
278
+ if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
279
+ return;
280
+ }
281
+ // Bail if we're not querying based on the post name.
282
+ if ( empty( $query->query['name'] ) ) {
283
+ return;
284
+ }
285
+ // Add CPT to the list of post types WP will include when it queries based on the post name.
286
+ $query->set( 'post_type', array( 'post', 'page', CARTFLOWS_STEP_POST_TYPE ) );
287
+ }
288
+
289
+ /**
290
+ * Modify permalink
291
+ *
292
+ * @param string $post_link post link.
293
+ * @param array $post post data.
294
+ * @param string $leavename leave name.
295
+ * @return string
296
+ */
297
+ function post_type_permalinks( $post_link, $post, $leavename ) {
298
+
299
+ // If elementor page preview, return post link as it is.
300
+ if ( isset( $_REQUEST['elementor-preview'] ) ) {
301
+ return $post_link;
302
+ }
303
+
304
+ $structure = get_option( 'permalink_structure' );
305
+
306
+ if ( '/%postname%/' === $structure ) {
307
+
308
+ if ( isset( $post->post_type ) && CARTFLOWS_STEP_POST_TYPE == $post->post_type ) {
309
+
310
+ $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
311
+ }
312
+ }
313
+
314
+ return $post_link;
315
+ }
316
+
317
+ /**
318
+ * Prevent slug duplicated
319
+ *
320
+ * @param string $slug post slug.
321
+ * @param int $post_ID post id.
322
+ * @param string $post_status post status.
323
+ * @param string $post_type post type.
324
+ * @param int $post_parent post parent id.
325
+ * @param string $original_slug original slug.
326
+ * @return string
327
+ */
328
+ function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
329
+
330
+ $check_post_types = array(
331
+ 'post',
332
+ 'page',
333
+ CARTFLOWS_STEP_POST_TYPE,
334
+ );
335
+
336
+ if ( ! in_array( $post_type, $check_post_types ) ) {
337
+ return $slug;
338
+ }
339
+
340
+ if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
341
+ // Saving a post, check for duplicates in POST or PAGE post types.
342
+ $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
343
+ $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );
344
+
345
+ if ( $post_match || $page_match ) {
346
+ $slug .= '-2';
347
+ }
348
+ } else {
349
+
350
+ // Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
351
+ $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );
352
+
353
+ if ( $custom_post_type_match ) {
354
+ $slug .= '-2';
355
+ }
356
+ }
357
+
358
+ return $slug;
359
+ }
360
+
361
+ /**
362
+ * Add Update messages for any custom post type
363
+ *
364
+ * @param array $messages Array of default messages.
365
+ */
366
+ function post_update_messages( $messages ) {
367
+
368
+ $custom_post_type = get_post_type( get_the_ID() );
369
+
370
+ if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {
371
+
372
+ $obj = get_post_type_object( $custom_post_type );
373
+ $singular_name = $obj->labels->singular_name;
374
+ $messages[ $custom_post_type ] = array(
375
+ 0 => '', // Unused. Messages start at index 1.
376
+ /* translators: %s: singular custom post type name */
377
+ 1 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
378
+ /* translators: %s: singular custom post type name */
379
+ 2 => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
380
+ /* translators: %s: singular custom post type name */
381
+ 3 => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
382
+ /* translators: %s: singular custom post type name */
383
+ 4 => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
384
+ /* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
385
+ 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
386
+ /* translators: %s: singular custom post type name */
387
+ 6 => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
388
+ /* translators: %s: singular custom post type name */
389
+ 7 => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
390
+ /* translators: %s: singular custom post type name */
391
+ 8 => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
392
+ /* translators: %s: singular custom post type name */
393
+ 9 => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
394
+ /* translators: %s: singular custom post type name */
395
+ 10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
396
+ );
397
+ }
398
+
399
+ return $messages;
400
+ }
401
+
402
+ /**
403
+ * Add Terms for Taxonomy.
404
+ *
405
+ * => Example.
406
+ *
407
+ * $taxonomy = '{taxonomy}';
408
+ * $terms = array(
409
+ * array(
410
+ * 'name' => 'Free',
411
+ * ),
412
+ * array(
413
+ * 'name' => 'Premium',
414
+ * ),
415
+ * );
416
+ *
417
+ * self::add_terms( $taxonomy, $terms );
418
+ *
419
+ * @since 1.0.0
420
+ * @param string $taxonomy Taxonomy Name.
421
+ * @param array $terms Terms list.
422
+ * @return void
423
+ */
424
+ function add_terms( $taxonomy = '', $terms = array() ) {
425
+
426
+ foreach ( $terms as $key => $term ) {
427
+
428
+ $term_exist = term_exists( $term['name'], $taxonomy );
429
+
430
+ if ( empty( $term_exist ) ) {
431
+
432
+ /**
433
+ * Add additional args if passed from request.
434
+ *
435
+ * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
436
+ */
437
+ if ( array_key_exists( 'args', $term ) ) {
438
+ wp_insert_term( $term['name'], $taxonomy, $term['args'] );
439
+ } else {
440
+ wp_insert_term( $term['name'], $taxonomy );
441
+ }
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Kicking this off by calling 'get_instance()' method
449
+ */
450
+ Cartflows_Step_Post_Type::get_instance();
modules/flow/templates/template-canvas.php CHANGED
@@ -36,7 +36,12 @@
36
  do_action( 'cartflows_container_bottom' );
37
  ?>
38
  </div>
39
- <?php wp_footer(); ?>
 
 
 
 
 
40
 
41
  </body>
42
 
36
  do_action( 'cartflows_container_bottom' );
37
  ?>
38
  </div>
39
+
40
+ <?php do_action( 'cartflows_wp_footer' ); ?>
41
+
42
+ <div class="cartflows-def-footer-wrap">
43
+ <?php wp_footer(); ?>
44
+ </div>
45
 
46
  </body>
47
 
modules/flow/templates/template-default.php CHANGED
@@ -40,7 +40,12 @@
40
  do_action( 'cartflows_container_bottom' );
41
  ?>
42
  </div>
43
- <?php wp_footer(); ?>
 
 
 
 
 
44
 
45
  </body>
46
 
40
  do_action( 'cartflows_container_bottom' );
41
  ?>
42
  </div>
43
+
44
+ <?php do_action( 'cartflows_wp_footer' ); ?>
45
+
46
+ <div class="cartflows-def-footer-wrap">
47
+ <?php wp_footer(); ?>
48
+ </div>
49
 
50
  </body>
51
 
modules/flow/view/meta-flow-steps.php CHANGED
@@ -1,183 +1,183 @@
1
- <?php
2
- /**
3
- * View Flow steps
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- $get_steps = array(
9
- 'landing' => __( 'Landing', 'cartflows' ),
10
- 'checkout' => __( 'Checkout', 'cartflows' ),
11
- 'thankyou' => __( 'Thank You', 'cartflows' ),
12
- 'upsell' => __( 'Upsell', 'cartflows' ),
13
- 'downsell' => __( 'Downsell', 'cartflows' ),
14
-
15
- );
16
-
17
- ?>
18
- <div class="wcf-flow-steps-meta-box">
19
- <div class="wcf-flow-settings">
20
- <?php do_action( 'cartflows_above_flow_steps' ); ?>
21
- <div class="wcf-flow-steps-wrap">
22
- <div class="wcf-flow-steps-container">
23
- <?php if ( is_array( $options['steps'] ) ) { ?>
24
- <?php foreach ( $options['steps'] as $index => $data ) { ?>
25
- <?php
26
- $term_slug = '';
27
- $term_name = '';
28
- $step_wrap_class = '';
29
- $has_product_assigned = true;
30
- $is_global_checkout = '';
31
- $common = '';
32
-
33
- if ( isset( $data['type'] ) ) {
34
- $term_slug = $data['type'];
35
- $term_name = $get_steps[ $data['type'] ];
36
- }
37
-
38
- if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
39
- $step_wrap_class .= ' invalid-step';
40
- }
41
-
42
- if ( isset( $_GET['highlight-step-id'] ) && $_GET['highlight-step-id'] == $data['id'] ) {
43
- $step_wrap_class .= ' wcf-new-step-highlight';
44
- }
45
-
46
- if ( 'checkout' === $term_slug ) {
47
-
48
- $common = Cartflows_Helper::get_common_settings();
49
-
50
- $is_global_checkout = (int) $common['global_checkout'];
51
-
52
- if ( $data['id'] === $is_global_checkout ) {
53
- $step_wrap_class .= ' wcf-global-checkout';
54
- }
55
- }
56
-
57
- if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
58
-
59
- $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
60
-
61
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
62
- $step_wrap_class .= ' wcf-no-product-step';
63
- }
64
- }
65
-
66
- ?>
67
- <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 ); ?>">
68
- <div class="wcf-step">
69
- <div class="wcf-step-left-content">
70
- <span class="dashicons dashicons-menu"></span>
71
- <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
72
- <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
73
-
74
- <?php
75
- if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
76
- ?>
77
- <span class="wcf-no-product-badge"><?php _e( 'No Product Assigned', 'cartflows' ); ?></span>
78
- <?php
79
- } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
80
- ?>
81
- <span class="wcf-global-checkout-badge"><?php _e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
82
- <?php
83
- } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
84
- ?>
85
- <span class="wcf-global-checkout-badge"><?php _e( 'Global Checkout', 'cartflows' ); ?></span>
86
- <?php
87
- }
88
- ?>
89
-
90
- <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
91
- </div>
92
- <div class="wcf-steps-action-buttons">
93
- <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'View Step', 'cartflows' ); ?>" >
94
- <span class="dashicons dashicons-visibility"></span>
95
- <span class="wcf-step-act-btn-text">View</span>
96
- </a>
97
- <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'Edit Step', 'cartflows' ); ?>" >
98
- <span class="dashicons dashicons-edit"></span>
99
- <span class="wcf-step-act-btn-text">Edit</span>
100
- </a>
101
- <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 __( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
102
- <span class="dashicons dashicons-admin-page"></span>
103
- <span class="wcf-step-act-btn-text">Clone</span>
104
- </a>
105
- <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
106
- <span class="dashicons dashicons-trash"></span>
107
- <span class="wcf-step-act-btn-text">Delete</span>
108
- </a>
109
- </div>
110
- </div>
111
- </div><!-- .wcf-step-wrap -->
112
- <?php } ?>
113
- <?php } ?>
114
- </div><!-- .wcf-flow-steps-container -->
115
- </div> <!-- .wcf-flow-steps-wrap -->
116
- <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
117
- <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
118
- <div class='wcf-add-new-step-btn-wrap'>
119
- <button class='wcf-trigger-popup button button-primary'>
120
- <?php echo __( 'Add New Step', 'cartflows' ); ?>
121
- </button>
122
- </div>
123
- </div><!-- .wcf-flow-buttons-wrap -->
124
- </div><!-- .wcf-flow-settings -->
125
-
126
- <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
127
- <div class="wcf-templates-popup-content">
128
- <div class="spinner"></div>
129
- <div class="wcf-templates-wrap wcf-templates-wrap-flows">
130
-
131
- <div id="wcf-remote-step-actions" class="wcf-template-header">
132
- <div class="wcf-template-logo-wrap">
133
- <span class="wcf-cartflows-logo-img">
134
- <span class="cartflows-icon"></span>
135
- </span>
136
- <span class="wcf-cartflows-title"><?php _e( 'Steps Library', 'cartflows' ); ?></span>
137
- </div>
138
- <div class="wcf-tab-wrapper">
139
- <div id="wcf-get-started-steps">
140
- <ul class="filter-links ">
141
- <li>
142
- <a href="#" class="current" data-slug="ready-templates" data-title="<?php _e( 'Ready Templates', 'cartflows' ); ?>"><?php _e( 'Ready Templates', 'cartflows' ); ?></a>
143
- </li>
144
- <li>
145
- <a href="#" data-slug="canvas" data-title="<?php _e( 'Create Your Own', 'cartflows' ); ?>"><?php _e( 'Create Your Own', 'cartflows' ); ?></a>
146
- </li>
147
- </ul>
148
- </div>
149
- </div>
150
- <div class="wcf-popup-close-wrap">
151
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
152
- </div>
153
- </div>
154
-
155
- <!--<div class="wcf-search-form">
156
- <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
157
- <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
158
- </div>-->
159
- <?php if ( ! _is_cartflows_pro() ) { ?>
160
- <div class="wcf-template-notice"><p><?php echo __( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
161
- <?php } ?>
162
- <div id="wcf-remote-content">
163
- <div id="wcf-ready-templates">
164
- <div id="wcf-remote-filters">
165
- <div id="wcf-page-builders"></div>
166
- <div id="wcf-categories"></div>
167
- </div>
168
- <div class="wcf-page-builder-notice"></div>
169
- <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"></div>
170
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
171
- </div>
172
- <div id="wcf-start-from-scratch" style="display: none;">
173
- <div class="inner">
174
- <div id="wcf-scratch-steps-categories"></div>
175
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create Step', 'cartflows' ); ?></a>
176
- </div>
177
- </div>
178
- </div>
179
- </div>
180
- </div>
181
- </div><!-- .wcf-templates-popup-overlay -->
182
- </div>
183
- <?php
1
+ <?php
2
+ /**
3
+ * View Flow steps
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ $get_steps = array(
9
+ 'landing' => __( 'Landing', 'cartflows' ),
10
+ 'checkout' => __( 'Checkout', 'cartflows' ),
11
+ 'thankyou' => __( 'Thank You', 'cartflows' ),
12
+ 'upsell' => __( 'Upsell', 'cartflows' ),
13
+ 'downsell' => __( 'Downsell', 'cartflows' ),
14
+
15
+ );
16
+
17
+ ?>
18
+ <div class="wcf-flow-steps-meta-box">
19
+ <div class="wcf-flow-settings">
20
+ <?php do_action( 'cartflows_above_flow_steps' ); ?>
21
+ <div class="wcf-flow-steps-wrap">
22
+ <div class="wcf-flow-steps-container">
23
+ <?php if ( is_array( $options['steps'] ) ) { ?>
24
+ <?php foreach ( $options['steps'] as $index => $data ) { ?>
25
+ <?php
26
+ $term_slug = '';
27
+ $term_name = '';
28
+ $step_wrap_class = '';
29
+ $has_product_assigned = true;
30
+ $is_global_checkout = '';
31
+ $common = '';
32
+
33
+ if ( isset( $data['type'] ) ) {
34
+ $term_slug = $data['type'];
35
+ $term_name = $get_steps[ $data['type'] ];
36
+ }
37
+
38
+ if ( ! _is_cartflows_pro() && ( 'upsell' === $term_slug || 'downsell' === $term_slug ) ) {
39
+ $step_wrap_class .= ' invalid-step';
40
+ }
41
+
42
+ if ( isset( $_GET['highlight-step-id'] ) && $_GET['highlight-step-id'] == $data['id'] ) {
43
+ $step_wrap_class .= ' wcf-new-step-highlight';
44
+ }
45
+
46
+ if ( 'checkout' === $term_slug ) {
47
+
48
+ $common = Cartflows_Helper::get_common_settings();
49
+
50
+ $is_global_checkout = (int) $common['global_checkout'];
51
+
52
+ if ( $data['id'] === $is_global_checkout ) {
53
+ $step_wrap_class .= ' wcf-global-checkout';
54
+ }
55
+ }
56
+
57
+ if ( 'upsell' === $term_slug || 'downsell' === $term_slug || 'checkout' === $term_slug ) {
58
+
59
+ $has_product_assigned = Cartflows_Helper::has_product_assigned( $data['id'] );
60
+
61
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
62
+ $step_wrap_class .= ' wcf-no-product-step';
63
+ }
64
+ }
65
+
66
+ ?>
67
+ <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 ); ?>">
68
+ <div class="wcf-step">
69
+ <div class="wcf-step-left-content">
70
+ <span class="dashicons dashicons-menu"></span>
71
+ <span><?php echo wp_trim_words( get_the_title( $data['id'] ), 3 ); ?></span>
72
+ <span class="wcf-flow-badge"><?php echo esc_attr( $term_name ); ?></span>
73
+
74
+ <?php
75
+ if ( ( ! $has_product_assigned ) && ( $data['id'] != $is_global_checkout ) ) {
76
+ ?>
77
+ <span class="wcf-no-product-badge"><?php _e( 'No Product Assigned', 'cartflows' ); ?></span>
78
+ <?php
79
+ } elseif ( ( $has_product_assigned ) && ( $data['id'] === $is_global_checkout ) ) {
80
+ ?>
81
+ <span class="wcf-global-checkout-badge"><?php _e( 'Global Checkout - Remove selected checkout product', 'cartflows' ); ?></span>
82
+ <?php
83
+ } elseif ( ( ! $has_product_assigned ) && $data['id'] === $is_global_checkout ) {
84
+ ?>
85
+ <span class="wcf-global-checkout-badge"><?php _e( 'Global Checkout', 'cartflows' ); ?></span>
86
+ <?php
87
+ }
88
+ ?>
89
+
90
+ <input type="hidden" class="wcf-steps-hidden" name="wcf-steps[]" value="<?php echo $data['id']; ?>">
91
+ </div>
92
+ <div class="wcf-steps-action-buttons">
93
+ <a href="<?php echo get_permalink( $data['id'] ); ?>" target="_blank" class="wcf-step-view wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'View Step', 'cartflows' ); ?>" >
94
+ <span class="dashicons dashicons-visibility"></span>
95
+ <span class="wcf-step-act-btn-text">View</span>
96
+ </a>
97
+ <a href="<?php echo get_edit_post_link( $data['id'] ); ?>" class="wcf-step-edit wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'Edit Step', 'cartflows' ); ?>" >
98
+ <span class="dashicons dashicons-edit"></span>
99
+ <span class="wcf-step-act-btn-text">Edit</span>
100
+ </a>
101
+ <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 __( 'Clone Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
102
+ <span class="dashicons dashicons-admin-page"></span>
103
+ <span class="wcf-step-act-btn-text">Clone</span>
104
+ </a>
105
+ <a href="#" class="wcf-step-delete wcf-action-button wp-ui-text-highlight" title="<?php echo __( 'Delete Step', 'cartflows' ); ?>" data-id="<?php echo $data['id']; ?>">
106
+ <span class="dashicons dashicons-trash"></span>
107
+ <span class="wcf-step-act-btn-text">Delete</span>
108
+ </a>
109
+ </div>
110
+ </div>
111
+ </div><!-- .wcf-step-wrap -->
112
+ <?php } ?>
113
+ <?php } ?>
114
+ </div><!-- .wcf-flow-steps-container -->
115
+ </div> <!-- .wcf-flow-steps-wrap -->
116
+ <div class="wcf-flow-buttons-wrap"> <!-- .wcf-flow-buttons-wrap -->
117
+ <?php do_action( 'cartflows_bellow_flow_steps' ); ?>
118
+ <div class='wcf-add-new-step-btn-wrap'>
119
+ <button class='wcf-trigger-popup button button-primary'>
120
+ <?php echo __( 'Add New Step', 'cartflows' ); ?>
121
+ </button>
122
+ </div>
123
+ </div><!-- .wcf-flow-buttons-wrap -->
124
+ </div><!-- .wcf-flow-settings -->
125
+
126
+ <div id="wcf-remote-step-importer" class="wcf-templates-popup-overlay">
127
+ <div class="wcf-templates-popup-content">
128
+ <div class="spinner"></div>
129
+ <div class="wcf-templates-wrap wcf-templates-wrap-flows">
130
+
131
+ <div id="wcf-remote-step-actions" class="wcf-template-header">
132
+ <div class="wcf-template-logo-wrap">
133
+ <span class="wcf-cartflows-logo-img">
134
+ <span class="cartflows-icon"></span>
135
+ </span>
136
+ <span class="wcf-cartflows-title"><?php _e( 'Steps Library', 'cartflows' ); ?></span>
137
+ </div>
138
+ <div class="wcf-tab-wrapper">
139
+ <div id="wcf-get-started-steps">
140
+ <ul class="filter-links ">
141
+ <li>
142
+ <a href="#" class="current" data-slug="ready-templates" data-title="<?php _e( 'Ready Templates', 'cartflows' ); ?>"><?php _e( 'Ready Templates', 'cartflows' ); ?></a>
143
+ </li>
144
+ <li>
145
+ <a href="#" data-slug="canvas" data-title="<?php _e( 'Create Your Own', 'cartflows' ); ?>"><?php _e( 'Create Your Own', 'cartflows' ); ?></a>
146
+ </li>
147
+ </ul>
148
+ </div>
149
+ </div>
150
+ <div class="wcf-popup-close-wrap">
151
+ <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
152
+ </div>
153
+ </div>
154
+
155
+ <!--<div class="wcf-search-form">
156
+ <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
157
+ <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
158
+ </div>-->
159
+ <?php if ( ! _is_cartflows_pro() ) { ?>
160
+ <div class="wcf-template-notice"><p><?php echo __( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
161
+ <?php } ?>
162
+ <div id="wcf-remote-content">
163
+ <div id="wcf-ready-templates">
164
+ <div id="wcf-remote-filters">
165
+ <div id="wcf-page-builders"></div>
166
+ <div id="wcf-categories"></div>
167
+ </div>
168
+ <div class="wcf-page-builder-notice"></div>
169
+ <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"></div>
170
+ <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
171
+ </div>
172
+ <div id="wcf-start-from-scratch" style="display: none;">
173
+ <div class="inner">
174
+ <div id="wcf-scratch-steps-categories"></div>
175
+ <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create Step', 'cartflows' ); ?></a>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </div><!-- .wcf-templates-popup-overlay -->
182
+ </div>
183
+ <?php
modules/thankyou/classes/class-cartflows-thankyou-markup.php CHANGED
@@ -1,264 +1,272 @@
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
- * 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
- /* Downsell Shortcode */
38
- add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
39
-
40
- add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
41
-
42
- add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
43
-
44
- }
45
-
46
- /**
47
- * Order shortcode markup
48
- *
49
- * @param array $atts attributes.
50
- * @since 1.0.0
51
- */
52
- function cartflows_order_details_shortcode_markup( $atts ) {
53
-
54
- $output = '';
55
-
56
- if ( _is_wcf_thankyou_type() ) {
57
-
58
- /* Remove order item link */
59
- add_filter( 'woocommerce_order_item_permalink', '__return_false' );
60
-
61
- if ( ! function_exists( 'wc_print_notices' ) ) {
62
- return '<p class="woocommerce-notice">' . __( 'WooCommerce functions not exists. If you are in iframe, please reload the iframe', 'cartflows' ) . '</p>';
63
- }
64
-
65
- if ( null !== WC()->session ) {
66
- wc_print_notices();
67
- }
68
-
69
- $order = false;
70
-
71
- if ( ! isset( $_GET['wcf-order'] ) && wcf()->flow->is_flow_testmode() ) {
72
-
73
- $args = array(
74
- 'limit' => 1,
75
- 'order' => 'DESC',
76
- 'status' => array( 'completed', 'processing' ),
77
- );
78
-
79
- $latest_order = wc_get_orders( $args );
80
-
81
- $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
82
-
83
- if ( $order_id > 0 ) {
84
-
85
- $order = wc_get_order( $order_id );
86
-
87
- if ( ! $order ) {
88
- $order = false;
89
- }
90
- }
91
- } else {
92
- if ( ! isset( $_GET['wcf-order'] ) ) {
93
- return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
94
- }
95
-
96
- // Get the order.
97
- $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['wcf-order'] ) ? 0 : intval( $_GET['wcf-order'] ) );
98
- $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['wcf-key'] ) ? '' : wc_clean( wp_unslash( $_GET['wcf-key'] ) ) ); // WPCS: input var ok, CSRF ok.
99
-
100
- if ( $order_id > 0 ) {
101
-
102
- $order = wc_get_order( $order_id );
103
-
104
- if ( ! $order || $order->get_order_key() !== $order_key ) {
105
- $order = false;
106
- }
107
- }
108
- }
109
-
110
- // Empty awaiting payment session.
111
- unset( WC()->session->order_awaiting_payment );
112
-
113
- if ( null !== WC()->session ) {
114
- // Empty current cart.
115
- wc_empty_cart();
116
- }
117
-
118
- ob_start();
119
- echo "<div class='wcf-thankyou-wrap'>";
120
- wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
121
- echo '</div>';
122
- $output = ob_get_clean();
123
- }
124
-
125
- return $output;
126
- }
127
-
128
- /**
129
- * Load Thank You scripts.
130
- *
131
- * @return void
132
- */
133
- function thank_you_scripts() {
134
-
135
- if ( _is_wcf_thankyou_type() ) {
136
-
137
- do_action( 'cartflows_thank_you_scripts' );
138
-
139
- $style = $this->generate_thank_you_style();
140
-
141
- wp_add_inline_style( 'wcf-frontend-global', $style );
142
- }
143
- }
144
-
145
- /**
146
- * Set thank you as a order received page.
147
- *
148
- * @param boolean $is_order_page order page.
149
- * @return boolean
150
- */
151
- function set_order_received_page( $is_order_page ) {
152
-
153
- if ( _is_wcf_thankyou_type() ) {
154
-
155
- $is_order_page = true;
156
- }
157
-
158
- return $is_order_page;
159
- }
160
-
161
- /**
162
- * Generate Thank You Styles.
163
- *
164
- * @return string
165
- */
166
- function generate_thank_you_style() {
167
-
168
- global $post;
169
-
170
- if ( _is_wcf_thankyou_type() ) {
171
- $thank_you_id = $post->ID;
172
- } else {
173
- $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
174
- }
175
-
176
- CartFlows_Font_Families::render_fonts( $thank_you_id );
177
-
178
- $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
179
- $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
180
- $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
181
- $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
182
- $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
183
- $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
184
- $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
185
-
186
- $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
187
-
188
- $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
189
-
190
- $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
191
-
192
- $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
193
-
194
- $output = "
195
- .wcf-thankyou-wrap{
196
- color: {$text_color};
197
- font-family: {$text_font_family};
198
- max-width:{$container_width}px;
199
- }
200
-
201
- .woocommerce-order h2.woocommerce-column__title,
202
- .woocommerce-order h2.woocommerce-order-details__title,
203
- .woocommerce-order .woocommerce-thankyou-order-received,
204
- .woocommerce-order-details h2 {
205
- color: {$heading_text_color};
206
- font-family: {$heading_font_family};
207
- font-weight: {$heading_font_weight};
208
- }
209
-
210
- .woocommerce-order ul.order_details,
211
- .woocommerce-order .woocommerce-order-details,
212
- .woocommerce-order .woocommerce-customer-details{
213
- background-color: {$section_bg_color}
214
- }
215
- ";
216
-
217
- if ( 'no' == $show_order_review ) {
218
- $output .= '
219
- .woocommerce-order ul.order_details{
220
- display: none;
221
- }
222
- ';
223
- }
224
-
225
- if ( 'no' == $show_order_details ) {
226
- $output .= '
227
- .woocommerce-order .woocommerce-order-details{
228
- display: none;
229
- }
230
- ';
231
- }
232
-
233
- if ( 'no' == $show_billing_details ) {
234
- $output .= '
235
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
236
- display: none;
237
- }
238
- ';
239
- }
240
-
241
- if ( 'no' == $show_shipping_details ) {
242
- $output .= '
243
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
244
- display: none;
245
- }
246
- ';
247
- }
248
-
249
- if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
250
- $output .= '
251
- .woocommerce-order .woocommerce-customer-details{
252
- display: none;
253
- }
254
- ';
255
- }
256
-
257
- return $output;
258
- }
259
- }
260
-
261
- /**
262
- * Kicking this off by calling 'get_instance()' method
263
- */
264
- 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
+ * 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
+ /* Downsell Shortcode */
38
+ add_shortcode( 'cartflows_order_details', array( $this, 'cartflows_order_details_shortcode_markup' ) );
39
+
40
+ add_action( 'wp_enqueue_scripts', array( $this, 'thank_you_scripts' ), 21 );
41
+
42
+ add_action( 'woocommerce_is_order_received_page', array( $this, 'set_order_received_page' ) );
43
+
44
+ }
45
+
46
+ /**
47
+ * Order shortcode markup
48
+ *
49
+ * @param array $atts attributes.
50
+ * @since 1.0.0
51
+ */
52
+ function cartflows_order_details_shortcode_markup( $atts ) {
53
+
54
+ $output = '';
55
+
56
+ if ( _is_wcf_thankyou_type() ) {
57
+
58
+ /* Remove order item link */
59
+ add_filter( 'woocommerce_order_item_permalink', '__return_false' );
60
+
61
+ if ( ! function_exists( 'wc_print_notices' ) ) {
62
+ return '<p class="woocommerce-notice">' . __( 'WooCommerce functions not exists. If you are in iframe, please reload the iframe', 'cartflows' ) . '</p>';
63
+ }
64
+
65
+ $order = false;
66
+
67
+ if ( ! isset( $_GET['wcf-order'] ) && wcf()->flow->is_flow_testmode() ) {
68
+
69
+ $args = array(
70
+ 'limit' => 1,
71
+ 'order' => 'DESC',
72
+ 'status' => array( 'completed', 'processing' ),
73
+ );
74
+
75
+ $latest_order = wc_get_orders( $args );
76
+
77
+ $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
78
+
79
+ if ( $order_id > 0 ) {
80
+
81
+ $order = wc_get_order( $order_id );
82
+
83
+ if ( ! $order ) {
84
+ $order = false;
85
+ }
86
+ }
87
+ } else {
88
+ if ( ! isset( $_GET['wcf-order'] ) ) {
89
+ return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
90
+ }
91
+
92
+ // Get the order.
93
+ $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['wcf-order'] ) ? 0 : intval( $_GET['wcf-order'] ) );
94
+ $order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['wcf-key'] ) ? '' : wc_clean( wp_unslash( $_GET['wcf-key'] ) ) ); // WPCS: input var ok, CSRF ok.
95
+
96
+ if ( $order_id > 0 ) {
97
+
98
+ $order = wc_get_order( $order_id );
99
+
100
+ if ( ! $order || $order->get_order_key() !== $order_key ) {
101
+ $order = false;
102
+ }
103
+ }
104
+ }
105
+
106
+ // Empty awaiting payment session.
107
+ unset( WC()->session->order_awaiting_payment );
108
+
109
+ if ( null !== WC()->session ) {
110
+
111
+ if ( ! isset( WC()->cart ) || '' === WC()->cart ) {
112
+ WC()->cart = new WC_Cart();
113
+ }
114
+
115
+ if ( ! WC()->cart->is_empty() ) {
116
+ // wc_empty_cart();
117
+ // Empty current cart.
118
+ WC()->cart->empty_cart( true );
119
+
120
+ wc_clear_notices();
121
+ }
122
+
123
+ wc_print_notices();
124
+ }
125
+
126
+ ob_start();
127
+ echo "<div class='wcf-thankyou-wrap'>";
128
+ wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
129
+ echo '</div>';
130
+ $output = ob_get_clean();
131
+ }
132
+
133
+ return $output;
134
+ }
135
+
136
+ /**
137
+ * Load Thank You scripts.
138
+ *
139
+ * @return void
140
+ */
141
+ function thank_you_scripts() {
142
+
143
+ if ( _is_wcf_thankyou_type() ) {
144
+
145
+ do_action( 'cartflows_thank_you_scripts' );
146
+
147
+ $style = $this->generate_thank_you_style();
148
+
149
+ wp_add_inline_style( 'wcf-frontend-global', $style );
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Set thank you as a order received page.
155
+ *
156
+ * @param boolean $is_order_page order page.
157
+ * @return boolean
158
+ */
159
+ function set_order_received_page( $is_order_page ) {
160
+
161
+ if ( _is_wcf_thankyou_type() ) {
162
+
163
+ $is_order_page = true;
164
+ }
165
+
166
+ return $is_order_page;
167
+ }
168
+
169
+ /**
170
+ * Generate Thank You Styles.
171
+ *
172
+ * @return string
173
+ */
174
+ function generate_thank_you_style() {
175
+
176
+ global $post;
177
+
178
+ if ( _is_wcf_thankyou_type() ) {
179
+ $thank_you_id = $post->ID;
180
+ } else {
181
+ $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
182
+ }
183
+
184
+ CartFlows_Font_Families::render_fonts( $thank_you_id );
185
+
186
+ $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
187
+ $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
188
+ $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
189
+ $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
190
+ $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
191
+ $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
192
+ $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
193
+
194
+ $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
195
+
196
+ $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
197
+
198
+ $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
199
+
200
+ $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
201
+
202
+ $output = "
203
+ .wcf-thankyou-wrap{
204
+ color: {$text_color};
205
+ font-family: {$text_font_family};
206
+ max-width:{$container_width}px;
207
+ }
208
+
209
+ .woocommerce-order h2.woocommerce-column__title,
210
+ .woocommerce-order h2.woocommerce-order-details__title,
211
+ .woocommerce-order .woocommerce-thankyou-order-received,
212
+ .woocommerce-order-details h2 {
213
+ color: {$heading_text_color};
214
+ font-family: {$heading_font_family};
215
+ font-weight: {$heading_font_weight};
216
+ }
217
+
218
+ .woocommerce-order ul.order_details,
219
+ .woocommerce-order .woocommerce-order-details,
220
+ .woocommerce-order .woocommerce-customer-details{
221
+ background-color: {$section_bg_color}
222
+ }
223
+ ";
224
+
225
+ if ( 'no' == $show_order_review ) {
226
+ $output .= '
227
+ .woocommerce-order ul.order_details{
228
+ display: none;
229
+ }
230
+ ';
231
+ }
232
+
233
+ if ( 'no' == $show_order_details ) {
234
+ $output .= '
235
+ .woocommerce-order .woocommerce-order-details{
236
+ display: none;
237
+ }
238
+ ';
239
+ }
240
+
241
+ if ( 'no' == $show_billing_details ) {
242
+ $output .= '
243
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
244
+ display: none;
245
+ }
246
+ ';
247
+ }
248
+
249
+ if ( 'no' == $show_shipping_details ) {
250
+ $output .= '
251
+ .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
252
+ display: none;
253
+ }
254
+ ';
255
+ }
256
+
257
+ if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
258
+ $output .= '
259
+ .woocommerce-order .woocommerce-customer-details{
260
+ display: none;
261
+ }
262
+ ';
263
+ }
264
+
265
+ return $output;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Kicking this off by calling 'get_instance()' method
271
+ */
272
+ Cartflows_Thankyou_Markup::get_instance();
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: woocommerce, cart
5
  Requires at least: 4.4
6
  Requires PHP: 5.6
7
  Tested up to: 5.0.2
8
- Stable tag: 1.1.2
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -93,6 +93,13 @@ Say goodby to using the same ridgid checkout page that everyone else is using. C
93
  2. Activate the plugin through the 'Plugins' menu in WordPress
94
 
95
  == Changelog ==
 
 
 
 
 
 
 
96
  Version 1.1.2 - Friday, 4th January 2019
97
  * Fix: Import Cloud Template option not visible in thrive visual editor.
98
  * Fix: Oceanwp css conflict with checkout layout.
5
  Requires at least: 4.4
6
  Requires PHP: 5.6
7
  Tested up to: 5.0.2
8
+ Stable tag: 1.1.3
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
93
  2. Activate the plugin through the 'Plugins' menu in WordPress
94
 
95
  == Changelog ==
96
+ Version 1.1.3 - Tuesday, 15th January 2019
97
+ * New: Import / Export the flows
98
+ * Improvement: Pixel Caffeine plugin pixel compatibility added.
99
+ * Improvement: Filter introduced to change the coupon field placeholder & button text.
100
+ * Fix: Clone option conflict with Duplicate post and Duplicate page plugin.
101
+ * Fix: Cart is not empty after purchase.
102
+
103
  Version 1.1.2 - Friday, 4th January 2019
104
  * Fix: Import Cloud Template option not visible in thrive visual editor.
105
  * Fix: Oceanwp css conflict with checkout layout.