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

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

Code changes from version 1.1.0.1 to 1.1.1

Files changed (41) hide show
  1. admin/assets/css/flow-admin-edit-rtl.css +1 -1
  2. admin/assets/css/flow-admin-edit.css +1 -1
  3. admin/assets/css/global-admin-rtl.css +13 -0
  4. admin/assets/css/global-admin.css +13 -0
  5. admin/assets/js/admin-menu-settings.js +0 -4
  6. assets/css/checkout-template-rtl.css +21 -5
  7. assets/css/checkout-template.css +21 -5
  8. assets/css/frontend-rtl.css +1 -1
  9. assets/css/frontend.css +1 -1
  10. assets/css/import-rtl.css +142 -29
  11. assets/css/import.css +142 -29
  12. assets/js/checkout-template.js +14 -2
  13. assets/js/frontend.js +11 -1
  14. assets/js/import.js +274 -126
  15. assets/js/rest-api.js +1 -1
  16. cartflows.php +24 -24
  17. changelog.txt +8 -0
  18. classes/batch-process/class-cartflows-batch-process.php +156 -125
  19. classes/batch-process/class-cartflows-importer-beaver-builder-batch.php +63 -0
  20. classes/batch-process/class-cartflows-importer-beaver-builder.php +228 -0
  21. classes/batch-process/{class-cartflows-batch-process-elementor.php → class-cartflows-importer-elementor-batch.php} +66 -64
  22. classes/batch-process/class-cartflows-importer-elementor.php +70 -70
  23. classes/batch-process/helpers/class-cartflows-importer-image.php +263 -0
  24. classes/class-cartflows-admin.php +410 -398
  25. classes/class-cartflows-compatibility.php +331 -224
  26. classes/class-cartflows-divi-compatibility.php +55 -0
  27. classes/class-cartflows-flow-frontend.php +199 -199
  28. classes/class-cartflows-frontend.php +328 -322
  29. classes/class-cartflows-helper.php +301 -273
  30. classes/class-cartflows-importer.php +1134 -1038
  31. classes/class-cartflows-loader.php +419 -416
  32. classes/class-cartflows-meta-fields.php +993 -962
  33. languages/cartflows.pot +83 -92
  34. modules/checkout/classes/class-cartflows-checkout-markup.php +983 -942
  35. modules/checkout/templates/embed/checkout-template-simple.php +33 -30
  36. modules/flow/classes/class-cartflows-flow-meta.php +743 -743
  37. modules/flow/templates/template-canvas.php +45 -39
  38. modules/flow/templates/template-default.php +49 -44
  39. modules/flow/view/meta-flow-steps.php +183 -168
  40. modules/thankyou/classes/class-cartflows-thankyou-markup.php +264 -260
  41. readme.txt +11 -75
admin/assets/css/flow-admin-edit-rtl.css CHANGED
@@ -1,4 +1,4 @@
1
- .post-type-cartflows_flow.post-php .page-title-action {
2
  display: none;
3
  }
4
 
1
+ .post-type-cartflows_flow.post-php a.page-title-action {
2
  display: none;
3
  }
4
 
admin/assets/css/flow-admin-edit.css CHANGED
@@ -1,4 +1,4 @@
1
- .post-type-cartflows_flow.post-php .page-title-action {
2
  display: none;
3
  }
4
 
1
+ .post-type-cartflows_flow.post-php a.page-title-action {
2
  display: none;
3
  }
4
 
admin/assets/css/global-admin-rtl.css CHANGED
@@ -768,6 +768,19 @@
768
  margin-top: 15px;
769
  }
770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
  /**
772
  * ******************************
773
  * Field - Post Meta Typography
768
  margin-top: 15px;
769
  }
770
 
771
+ .wcf-table-container .wcf-column-right .field-wcf-hr-line {
772
+ padding-right: 0;
773
+ padding-left: 0;
774
+ }
775
+
776
+ .wcf-table-container .wcf-column-right .field-wcf-hr-line .wcf-field-row-content {
777
+ width: 100%;
778
+ }
779
+
780
+ .wcf-table-container .wcf-radio-option {
781
+ margin-bottom: 10px;
782
+ }
783
+
784
  /**
785
  * ******************************
786
  * Field - Post Meta Typography
admin/assets/css/global-admin.css CHANGED
@@ -768,6 +768,19 @@
768
  margin-top: 15px;
769
  }
770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
771
  /**
772
  * ******************************
773
  * Field - Post Meta Typography
768
  margin-top: 15px;
769
  }
770
 
771
+ .wcf-table-container .wcf-column-right .field-wcf-hr-line {
772
+ padding-left: 0;
773
+ padding-right: 0;
774
+ }
775
+
776
+ .wcf-table-container .wcf-column-right .field-wcf-hr-line .wcf-field-row-content {
777
+ width: 100%;
778
+ }
779
+
780
+ .wcf-table-container .wcf-radio-option {
781
+ margin-bottom: 10px;
782
+ }
783
+
784
  /**
785
  * ******************************
786
  * Field - Post Meta Typography
admin/assets/js/admin-menu-settings.js CHANGED
@@ -123,8 +123,6 @@
123
  data: data,
124
  success: function(data){
125
 
126
- console.log( data );
127
-
128
  // Bulk add or remove classes to all modules.
129
  $('.uael-widget-list').children( "li" ).addClass( 'activate' ).removeClass( 'deactivate' );
130
  $('.uael-widget-list').children( "li" ).find('.uael-activate-widget')
@@ -158,8 +156,6 @@
158
  type: 'POST',
159
  data: data,
160
  success: function(data){
161
-
162
- console.log( data );
163
  // Bulk add or remove classes to all modules.
164
  $('.uael-widget-list').children( "li" ).addClass( 'deactivate' ).removeClass( 'activate' );
165
  $('.uael-widget-list').children( "li" ).find('.uael-deactivate-widget')
123
  data: data,
124
  success: function(data){
125
 
 
 
126
  // Bulk add or remove classes to all modules.
127
  $('.uael-widget-list').children( "li" ).addClass( 'activate' ).removeClass( 'deactivate' );
128
  $('.uael-widget-list').children( "li" ).find('.uael-activate-widget')
156
  type: 'POST',
157
  data: data,
158
  success: function(data){
 
 
159
  // Bulk add or remove classes to all modules.
160
  $('.uael-widget-list').children( "li" ).addClass( 'deactivate' ).removeClass( 'activate' );
161
  $('.uael-widget-list').children( "li" ).find('.uael-deactivate-widget')
assets/css/checkout-template-rtl.css CHANGED
@@ -478,7 +478,8 @@
478
  padding-left: 40px;
479
  margin:20px 0 0;
480
  }
481
- .wcf-embed-checkout-form .woocommerce-checkout #order_review{
 
482
  display: inline-block;
483
  float: none;
484
  width: 45%;
@@ -488,13 +489,23 @@
488
  border-radius: 3px;
489
  }
490
 
 
 
 
 
 
 
 
 
 
 
491
  .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
492
  display: inline-block;
493
  font-family: inherit;
494
  font-weight: 600;
495
- width: 45%;
496
  margin:20px 0 0;
497
- padding: 0px 10px 20px;
498
  border: none;
499
  border-bottom: none;
500
  }
@@ -561,8 +572,9 @@
561
  .wcf-embed-checkout-form table.shop_table tbody th,
562
  .wcf-embed-checkout-form table.shop_table tfoot td,
563
  .wcf-embed-checkout-form table.shop_table tfoot th {
564
- font-weight: normal;
565
  border: none;
 
 
566
  }
567
  .wcf-embed-checkout-form table.shop_table tbody {
568
  border-top: 1px dashed #cccccc;
@@ -620,7 +632,8 @@
620
  }
621
 
622
  .wcf-embed-checkout-form .woocommerce .woocommerce-info,
623
- .wcf-embed-checkout-form .woocommerce .woocommerce-notices-wrapper .woocommerce-message{
 
624
  padding: 1em 2.0em 0.4em 2em;
625
  border-top:none;
626
  background-color: inherit;
@@ -697,6 +710,9 @@
697
  .wcf-embed-checkout-form .woocommerce-checkout #order_review{
698
  width: 100%;
699
  }
 
 
 
700
  .wcf-embed-checkout-form .woocommerce-checkout{
701
  display: block;
702
  }
478
  padding-left: 40px;
479
  margin:20px 0 0;
480
  }
481
+
482
+ .wcf-embed-checkout-form-two-column .woocommerce-checkout .wcf-order-wrap{
483
  display: inline-block;
484
  float: none;
485
  width: 45%;
489
  border-radius: 3px;
490
  }
491
 
492
+ /*.wcf-embed-checkout-form .woocommerce-checkout #order_review{
493
+ display: inline-block;
494
+ float: none;
495
+ width: 45%;
496
+ border: none;
497
+ background-color: inherit/*#F6F6F6*;
498
+ padding: 0 10px;
499
+ border-radius: 3px;
500
+ }*/
501
+
502
  .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
503
  display: inline-block;
504
  font-family: inherit;
505
  font-weight: 600;
506
+ width: 100%;
507
  margin:20px 0 0;
508
+ padding: 0px 0px 20px;
509
  border: none;
510
  border-bottom: none;
511
  }
572
  .wcf-embed-checkout-form table.shop_table tbody th,
573
  .wcf-embed-checkout-form table.shop_table tfoot td,
574
  .wcf-embed-checkout-form table.shop_table tfoot th {
 
575
  border: none;
576
+ font-weight: normal;
577
+ width: 50%;
578
  }
579
  .wcf-embed-checkout-form table.shop_table tbody {
580
  border-top: 1px dashed #cccccc;
632
  }
633
 
634
  .wcf-embed-checkout-form .woocommerce .woocommerce-info,
635
+ .wcf-embed-checkout-form .woocommerce .woocommerce-notices-wrapper .woocommerce-message,
636
+ .wcf-embed-checkout-form .woocommerce .woocommerce-NoticeGroup .woocommerce-message{
637
  padding: 1em 2.0em 0.4em 2em;
638
  border-top:none;
639
  background-color: inherit;
710
  .wcf-embed-checkout-form .woocommerce-checkout #order_review{
711
  width: 100%;
712
  }
713
+ .wcf-embed-checkout-form .woocommerce-checkout .wcf-order-wrap{
714
+ width: 100%;
715
+ }
716
  .wcf-embed-checkout-form .woocommerce-checkout{
717
  display: block;
718
  }
assets/css/checkout-template.css CHANGED
@@ -478,7 +478,8 @@
478
  padding-right: 40px;
479
  margin:20px 0 0;
480
  }
481
- .wcf-embed-checkout-form .woocommerce-checkout #order_review{
 
482
  display: inline-block;
483
  float: none;
484
  width: 45%;
@@ -488,13 +489,23 @@
488
  border-radius: 3px;
489
  }
490
 
 
 
 
 
 
 
 
 
 
 
491
  .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
492
  display: inline-block;
493
  font-family: inherit;
494
  font-weight: 600;
495
- width: 45%;
496
  margin:20px 0 0;
497
- padding: 0px 10px 20px;
498
  border: none;
499
  border-bottom: none;
500
  }
@@ -561,8 +572,9 @@
561
  .wcf-embed-checkout-form table.shop_table tbody th,
562
  .wcf-embed-checkout-form table.shop_table tfoot td,
563
  .wcf-embed-checkout-form table.shop_table tfoot th {
564
- font-weight: normal;
565
  border: none;
 
 
566
  }
567
  .wcf-embed-checkout-form table.shop_table tbody {
568
  border-top: 1px dashed #cccccc;
@@ -620,7 +632,8 @@
620
  }
621
 
622
  .wcf-embed-checkout-form .woocommerce .woocommerce-info,
623
- .wcf-embed-checkout-form .woocommerce .woocommerce-notices-wrapper .woocommerce-message{
 
624
  padding: 1em 2em 0.4em 2.0em;
625
  border-top:none;
626
  background-color: inherit;
@@ -697,6 +710,9 @@
697
  .wcf-embed-checkout-form .woocommerce-checkout #order_review{
698
  width: 100%;
699
  }
 
 
 
700
  .wcf-embed-checkout-form .woocommerce-checkout{
701
  display: block;
702
  }
478
  padding-right: 40px;
479
  margin:20px 0 0;
480
  }
481
+
482
+ .wcf-embed-checkout-form-two-column .woocommerce-checkout .wcf-order-wrap{
483
  display: inline-block;
484
  float: none;
485
  width: 45%;
489
  border-radius: 3px;
490
  }
491
 
492
+ /*.wcf-embed-checkout-form .woocommerce-checkout #order_review{
493
+ display: inline-block;
494
+ float: none;
495
+ width: 45%;
496
+ border: none;
497
+ background-color: inherit/*#F6F6F6*;
498
+ padding: 0 10px;
499
+ border-radius: 3px;
500
+ }*/
501
+
502
  .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
503
  display: inline-block;
504
  font-family: inherit;
505
  font-weight: 600;
506
+ width: 100%;
507
  margin:20px 0 0;
508
+ padding: 0px 0px 20px;
509
  border: none;
510
  border-bottom: none;
511
  }
572
  .wcf-embed-checkout-form table.shop_table tbody th,
573
  .wcf-embed-checkout-form table.shop_table tfoot td,
574
  .wcf-embed-checkout-form table.shop_table tfoot th {
 
575
  border: none;
576
+ font-weight: normal;
577
+ width: 50%;
578
  }
579
  .wcf-embed-checkout-form table.shop_table tbody {
580
  border-top: 1px dashed #cccccc;
632
  }
633
 
634
  .wcf-embed-checkout-form .woocommerce .woocommerce-info,
635
+ .wcf-embed-checkout-form .woocommerce .woocommerce-notices-wrapper .woocommerce-message,
636
+ .wcf-embed-checkout-form .woocommerce .woocommerce-NoticeGroup .woocommerce-message{
637
  padding: 1em 2em 0.4em 2.0em;
638
  border-top:none;
639
  background-color: inherit;
710
  .wcf-embed-checkout-form .woocommerce-checkout #order_review{
711
  width: 100%;
712
  }
713
+ .wcf-embed-checkout-form .woocommerce-checkout .wcf-order-wrap{
714
+ width: 100%;
715
+ }
716
  .wcf-embed-checkout-form .woocommerce-checkout{
717
  display: block;
718
  }
assets/css/frontend-rtl.css CHANGED
@@ -736,7 +736,7 @@ body.cartflows-default {
736
  # Preview Mode
737
  ---------------------------------------------------------------*/
738
  .wcf-preview-mode {
739
- background: rgba(60, 60, 60, 0.9);
740
  position: fixed;
741
  bottom: 0;
742
  right: 0;
736
  # Preview Mode
737
  ---------------------------------------------------------------*/
738
  .wcf-preview-mode {
739
+ background: #f16334;
740
  position: fixed;
741
  bottom: 0;
742
  right: 0;
assets/css/frontend.css CHANGED
@@ -736,7 +736,7 @@ body.cartflows-default {
736
  # Preview Mode
737
  ---------------------------------------------------------------*/
738
  .wcf-preview-mode {
739
- background: rgba(60, 60, 60, 0.9);
740
  position: fixed;
741
  bottom: 0;
742
  left: 0;
736
  # Preview Mode
737
  ---------------------------------------------------------------*/
738
  .wcf-preview-mode {
739
+ background: #f16334;
740
  position: fixed;
741
  bottom: 0;
742
  left: 0;
assets/css/import-rtl.css CHANGED
@@ -1,3 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
  .site-preview {
3
  background: #c5c5c5;
@@ -127,10 +139,10 @@
127
  }
128
 
129
  .wcf-remote-list .template {
130
- margin: 15px;
131
  position: relative;
132
  overflow: hidden;
133
- box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
134
  }
135
 
136
  .wcf-remote-list h3 {
@@ -192,6 +204,10 @@
192
  width: 100% !important;
193
  }
194
 
 
 
 
 
195
  .template-message-block .spinner {
196
  float: none;
197
  margin: 0;
@@ -440,10 +456,16 @@ div#TB_window {
440
  }
441
  #wcf-page-builders,
442
  #wcf-remote-flow-filters > div,
443
- #wcf-remote-step-filters > div ,
444
  #wcf-remote-step-filters > div {
445
  display: inline-block;
446
  }
 
 
 
 
 
 
 
447
  .wcf-template-header .filter-links {
448
  margin: 0;
449
  padding: 0;
@@ -462,7 +484,7 @@ div#TB_window {
462
  }
463
  .wcf-template-header .filter-links li .current {
464
  color: #000;
465
- border-bottom: 3px solid #f16334;
466
  font-weight: 600;
467
  }
468
 
@@ -487,7 +509,39 @@ div#TB_window {
487
  padding: 10px 20px 0 0;
488
  text-align: center;
489
  }
 
 
 
490
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  #wcf-remote-step-importer .wcf-search-form {
492
  display: none;
493
  }
@@ -511,16 +565,21 @@ div#TB_window {
511
  margin: 0px 1em;
512
  position: relative;
513
  }
514
- #poststuff .cartflows-step-loading h2,
515
- #poststuff .template-message-block h2 {
 
 
 
516
  font-size: 1.5em;
517
  margin: 0 0 0.5em 0;
 
 
518
  }
519
- #poststuff .template-message-block p,
520
- #poststuff .cartflows-step-loading p {
521
  font-size: 1.2em;
522
  }
523
- #poststuff .cartflows-step-loading .spinner {
524
  vertical-align: initial;
525
  }
526
 
@@ -570,15 +629,36 @@ div#TB_window {
570
  }
571
 
572
  .wcf-templates-popup-content .inner{
 
573
  position: relative;
 
574
  display: block;
575
  float: right;
576
- margin: 0;
577
  text-align: center;
 
578
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  @media only screen and (min-width: 768px) {
580
  .wcf-templates-popup-content .inner{
581
- width: 25%;
582
  }
583
  }
584
 
@@ -593,21 +673,26 @@ html.wcf-popup-open{
593
  right: 110px;
594
  }
595
 
596
- #wcf-remote-step-importer #wcf-remote-content {
597
- padding-top: 10px;
598
- }
599
-
600
  .wcf-steps-loading #wcf-remote-step-list {
601
- display: none;
602
  }
603
 
604
  #wcf-remote-content {
 
605
  overflow-y: auto;
606
  min-height: 450px;
607
  max-height: 450px;
608
  padding: 20px 20px 20px 20px;
609
  clear: both;
610
  }
 
 
 
 
 
 
 
611
 
612
  .wcf-template-list-wrap .template-name {
613
  margin: 0;
@@ -621,10 +706,10 @@ html.wcf-popup-open{
621
  }
622
 
623
  .wcf-templates-popup-content .template{
624
- margin: 15px;
625
  position: relative;
626
  overflow: hidden;
627
- box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
628
  }
629
 
630
  .wcf-tab.nav-tabs{
@@ -635,7 +720,7 @@ html.wcf-popup-open{
635
  .wcf-template-header {
636
  align-items: center;
637
  background: #fff;
638
- box-shadow: 0 0 8px rgba(0,0,0,.1);
639
  display: flex;
640
  -webkit-box-align: center;
641
  -webkit-align-items: center;
@@ -795,28 +880,56 @@ html.wcf-popup-open{
795
  margin: 4em 0 0 0;
796
  text-align: center;
797
  }
798
- #wcf-remote-step-filters {
 
 
 
 
 
 
 
 
 
 
799
  padding: 0 15px;
800
  }
801
- #wcf-remote-step-filters a {
802
  text-decoration: none;
803
  }
804
- #wcf-remote-step-filters a:focus,
805
- #wcf-remote-step-filters .filter-links li:focus {
806
  outline: none;
807
  box-shadow: none;
808
  }
809
- #wcf-remote-step-filters .filter-links li a {
810
  border-bottom: none;
811
  }
812
- #wcf-remote-step-filters .filter-links li:first-child a {
813
  margin-right: 0;
814
  }
815
- #wcf-remote-step-filters .filter-links li:last-child a {
816
  margin-left: 0;
817
  }
818
- #wcf-remote-step-filters .filter-links li a:focus,
819
- #wcf-remote-step-filters .filter-links li a:hover,
820
- #wcf-remote-step-filters .filter-links li .current {
821
  color: #f16334;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
  }
1
+ .no-elementor-notice{
2
+ border-right: none;
3
+ background: transparent;
4
+ border: none;
5
+ box-shadow: none;
6
+ padding-right: 0;
7
+ }
8
+ .no-elementor-notice span{
9
+ color: #f16334;
10
+ font-size: 18px;
11
+ vertical-align: middle;
12
+ }
13
 
14
  .site-preview {
15
  background: #c5c5c5;
139
  }
140
 
141
  .wcf-remote-list .template {
142
+ /*margin: 15px;*/
143
  position: relative;
144
  overflow: hidden;
145
+ /*box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);*/
146
  }
147
 
148
  .wcf-remote-list h3 {
204
  width: 100% !important;
205
  }
206
 
207
+ .template-message-block .description {
208
+ font-style: normal;
209
+ }
210
+
211
  .template-message-block .spinner {
212
  float: none;
213
  margin: 0;
456
  }
457
  #wcf-page-builders,
458
  #wcf-remote-flow-filters > div,
 
459
  #wcf-remote-step-filters > div {
460
  display: inline-block;
461
  }
462
+ #wcf-categories .step-type-filter-links{
463
+ background: transparent;
464
+ box-shadow: none;
465
+ border:1px solid;
466
+ border-color: #9e9e9e;
467
+ vertical-align: unset;
468
+ }
469
  .wcf-template-header .filter-links {
470
  margin: 0;
471
  padding: 0;
484
  }
485
  .wcf-template-header .filter-links li .current {
486
  color: #000;
487
+ border-bottom: 2px solid #f16334;
488
  font-weight: 600;
489
  }
490
 
509
  padding: 10px 20px 0 0;
510
  text-align: center;
511
  }
512
+ #wcf-start-from-scratch {
513
+ text-align: center;
514
+ }
515
 
516
+ #wcf-start-from-scratch .inner {
517
+ background: transparent;
518
+ box-shadow: none;
519
+ width: 94%;
520
+ margin: 0 auto;
521
+ float: none;
522
+ position: absolute;
523
+ top: 40%;
524
+ /*left: 50%;
525
+ transform: translate(-50%,-40%);*/
526
+ }
527
+ #wcf-scratch-steps-categories {
528
+ display: inline-block;
529
+ }
530
+
531
+ #wcf-scratch-steps-categories select{
532
+ border-radius: 0;
533
+ height: 29px;
534
+ border: 1px solid;
535
+ border-color: #9e9e9e;
536
+ border-width: 1px;
537
+ box-shadow: none;
538
+ padding: 2px;
539
+ line-height: 29px;
540
+ }
541
+
542
+ #wcf-start-from-scratch .description {
543
+ margin-bottom: 2em;
544
+ }
545
  #wcf-remote-step-importer .wcf-search-form {
546
  display: none;
547
  }
565
  margin: 0px 1em;
566
  position: relative;
567
  }
568
+ .cartflows-flow-import-blank.updating-message:before {
569
+ vertical-align: text-bottom;
570
+ }
571
+ #wpwrap .cartflows-step-loading h2,
572
+ #wpwrap .template-message-block h2 {
573
  font-size: 1.5em;
574
  margin: 0 0 0.5em 0;
575
+ padding: 8px 12px;
576
+ line-height: 1.4;
577
  }
578
+ #wpwrap .template-message-block p,
579
+ #wpwrap .cartflows-step-loading p {
580
  font-size: 1.2em;
581
  }
582
+ #wpwrap .cartflows-step-loading .spinner {
583
  vertical-align: initial;
584
  }
585
 
629
  }
630
 
631
  .wcf-templates-popup-content .inner{
632
+ background: #fff;
633
  position: relative;
634
+ padding:8px 8px 0 8px;
635
  display: block;
636
  float: right;
637
+ margin: 15px;
638
  text-align: center;
639
+ box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
640
  }
641
+
642
+ @media only screen and (max-width: 480px) {
643
+ .wcf-templates-popup-content{
644
+ width: 90%;
645
+ }
646
+
647
+ .wcf-template-header{
648
+ display: block !important;
649
+ padding: 15px 15px 0 15px !important;
650
+ }
651
+
652
+ .wcf-popup-close-wrap{
653
+ position: absolute;
654
+ top: 10px;
655
+ left: 5px;
656
+ }
657
+ }
658
+
659
  @media only screen and (min-width: 768px) {
660
  .wcf-templates-popup-content .inner{
661
+ width: calc(25% - 30px);
662
  }
663
  }
664
 
673
  right: 110px;
674
  }
675
 
676
+ .wcf-steps-loading #wcf-start-from-scratch,
 
 
 
677
  .wcf-steps-loading #wcf-remote-step-list {
678
+ display: none !important;
679
  }
680
 
681
  #wcf-remote-content {
682
+ background-color: #f5f5f5;
683
  overflow-y: auto;
684
  min-height: 450px;
685
  max-height: 450px;
686
  padding: 20px 20px 20px 20px;
687
  clear: both;
688
  }
689
+ #wcf-remote-content #wcf-start-from-scratch h1{
690
+ font-size: 23px;
691
+ font-weight: 400;
692
+ margin: 0 0 1em 0;
693
+ padding: 9px 0 4px;
694
+ line-height: 29px;
695
+ }
696
 
697
  .wcf-template-list-wrap .template-name {
698
  margin: 0;
706
  }
707
 
708
  .wcf-templates-popup-content .template{
709
+ margin: 0px;
710
  position: relative;
711
  overflow: hidden;
712
+ /*box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);*/
713
  }
714
 
715
  .wcf-tab.nav-tabs{
720
  .wcf-template-header {
721
  align-items: center;
722
  background: #fff;
723
+ box-shadow: 0 0 8px rgba(0,0,0,.2);
724
  display: flex;
725
  -webkit-box-align: center;
726
  -webkit-align-items: center;
880
  margin: 4em 0 0 0;
881
  text-align: center;
882
  }
883
+ #wcf-categories {
884
+ border-right: 1px #ddd dashed;
885
+ display: inline-block;
886
+ margin-right: 1em;
887
+ padding-right: 1em;
888
+ vertical-align: baseline;
889
+ }
890
+ .flow-type-filter-links {
891
+ display: none;
892
+ }
893
+ #wcf-remote-filters {
894
  padding: 0 15px;
895
  }
896
+ #wcf-remote-filters a {
897
  text-decoration: none;
898
  }
899
+ #wcf-remote-filters a:focus,
900
+ #wcf-remote-filters .filter-links li:focus {
901
  outline: none;
902
  box-shadow: none;
903
  }
904
+ #wcf-remote-filters .filter-links li a {
905
  border-bottom: none;
906
  }
907
+ #wcf-remote-filters .filter-links li:first-child a {
908
  margin-right: 0;
909
  }
910
+ #wcf-remote-filters .filter-links li:last-child a {
911
  margin-left: 0;
912
  }
913
+ #wcf-remote-filters .filter-links li a:focus,
914
+ #wcf-remote-filters .filter-links li a:hover,
915
+ #wcf-remote-filters .filter-links li .current {
916
  color: #f16334;
917
+ }
918
+
919
+ .wrap .wcf-page-builder-notice .notice {
920
+ margin: 5px 15px;
921
+ }
922
+
923
+ #wcf-api-notice-block {
924
+ text-align: center;
925
+ margin-top: 5em;
926
+ }
927
+
928
+ .wcf-templates-popup-overlay a {
929
+ transition: none;
930
+ }
931
+
932
+ .wcf-notice-wrap .notice {
933
+ display: inline-block;
934
+ margin: 1.5em 0 0 0;
935
  }
assets/css/import.css CHANGED
@@ -1,3 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
  .site-preview {
3
  background: #c5c5c5;
@@ -127,10 +139,10 @@
127
  }
128
 
129
  .wcf-remote-list .template {
130
- margin: 15px;
131
  position: relative;
132
  overflow: hidden;
133
- box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
134
  }
135
 
136
  .wcf-remote-list h3 {
@@ -192,6 +204,10 @@
192
  width: 100% !important;
193
  }
194
 
 
 
 
 
195
  .template-message-block .spinner {
196
  float: none;
197
  margin: 0;
@@ -440,10 +456,16 @@ div#TB_window {
440
  }
441
  #wcf-page-builders,
442
  #wcf-remote-flow-filters > div,
443
- #wcf-remote-step-filters > div ,
444
  #wcf-remote-step-filters > div {
445
  display: inline-block;
446
  }
 
 
 
 
 
 
 
447
  .wcf-template-header .filter-links {
448
  margin: 0;
449
  padding: 0;
@@ -462,7 +484,7 @@ div#TB_window {
462
  }
463
  .wcf-template-header .filter-links li .current {
464
  color: #000;
465
- border-bottom: 3px solid #f16334;
466
  font-weight: 600;
467
  }
468
 
@@ -487,7 +509,39 @@ div#TB_window {
487
  padding: 10px 0 0 20px;
488
  text-align: center;
489
  }
 
 
 
490
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  #wcf-remote-step-importer .wcf-search-form {
492
  display: none;
493
  }
@@ -511,16 +565,21 @@ div#TB_window {
511
  margin: 0px 1em;
512
  position: relative;
513
  }
514
- #poststuff .cartflows-step-loading h2,
515
- #poststuff .template-message-block h2 {
 
 
 
516
  font-size: 1.5em;
517
  margin: 0 0 0.5em 0;
 
 
518
  }
519
- #poststuff .template-message-block p,
520
- #poststuff .cartflows-step-loading p {
521
  font-size: 1.2em;
522
  }
523
- #poststuff .cartflows-step-loading .spinner {
524
  vertical-align: initial;
525
  }
526
 
@@ -570,15 +629,36 @@ div#TB_window {
570
  }
571
 
572
  .wcf-templates-popup-content .inner{
 
573
  position: relative;
 
574
  display: block;
575
  float: left;
576
- margin: 0;
577
  text-align: center;
 
578
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  @media only screen and (min-width: 768px) {
580
  .wcf-templates-popup-content .inner{
581
- width: 25%;
582
  }
583
  }
584
 
@@ -593,21 +673,26 @@ html.wcf-popup-open{
593
  left: 110px;
594
  }
595
 
596
- #wcf-remote-step-importer #wcf-remote-content {
597
- padding-top: 10px;
598
- }
599
-
600
  .wcf-steps-loading #wcf-remote-step-list {
601
- display: none;
602
  }
603
 
604
  #wcf-remote-content {
 
605
  overflow-y: auto;
606
  min-height: 450px;
607
  max-height: 450px;
608
  padding: 20px 20px 20px 20px;
609
  clear: both;
610
  }
 
 
 
 
 
 
 
611
 
612
  .wcf-template-list-wrap .template-name {
613
  margin: 0;
@@ -621,10 +706,10 @@ html.wcf-popup-open{
621
  }
622
 
623
  .wcf-templates-popup-content .template{
624
- margin: 15px;
625
  position: relative;
626
  overflow: hidden;
627
- box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
628
  }
629
 
630
  .wcf-tab.nav-tabs{
@@ -635,7 +720,7 @@ html.wcf-popup-open{
635
  .wcf-template-header {
636
  align-items: center;
637
  background: #fff;
638
- box-shadow: 0 0 8px rgba(0,0,0,.1);
639
  display: flex;
640
  -webkit-box-align: center;
641
  -webkit-align-items: center;
@@ -795,28 +880,56 @@ html.wcf-popup-open{
795
  margin: 4em 0 0 0;
796
  text-align: center;
797
  }
798
- #wcf-remote-step-filters {
 
 
 
 
 
 
 
 
 
 
799
  padding: 0 15px;
800
  }
801
- #wcf-remote-step-filters a {
802
  text-decoration: none;
803
  }
804
- #wcf-remote-step-filters a:focus,
805
- #wcf-remote-step-filters .filter-links li:focus {
806
  outline: none;
807
  box-shadow: none;
808
  }
809
- #wcf-remote-step-filters .filter-links li a {
810
  border-bottom: none;
811
  }
812
- #wcf-remote-step-filters .filter-links li:first-child a {
813
  margin-left: 0;
814
  }
815
- #wcf-remote-step-filters .filter-links li:last-child a {
816
  margin-right: 0;
817
  }
818
- #wcf-remote-step-filters .filter-links li a:focus,
819
- #wcf-remote-step-filters .filter-links li a:hover,
820
- #wcf-remote-step-filters .filter-links li .current {
821
  color: #f16334;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
822
  }
1
+ .no-elementor-notice{
2
+ border-left: none;
3
+ background: transparent;
4
+ border: none;
5
+ box-shadow: none;
6
+ padding-left: 0;
7
+ }
8
+ .no-elementor-notice span{
9
+ color: #f16334;
10
+ font-size: 18px;
11
+ vertical-align: middle;
12
+ }
13
 
14
  .site-preview {
15
  background: #c5c5c5;
139
  }
140
 
141
  .wcf-remote-list .template {
142
+ /*margin: 15px;*/
143
  position: relative;
144
  overflow: hidden;
145
+ /*box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);*/
146
  }
147
 
148
  .wcf-remote-list h3 {
204
  width: 100% !important;
205
  }
206
 
207
+ .template-message-block .description {
208
+ font-style: normal;
209
+ }
210
+
211
  .template-message-block .spinner {
212
  float: none;
213
  margin: 0;
456
  }
457
  #wcf-page-builders,
458
  #wcf-remote-flow-filters > div,
 
459
  #wcf-remote-step-filters > div {
460
  display: inline-block;
461
  }
462
+ #wcf-categories .step-type-filter-links{
463
+ background: transparent;
464
+ box-shadow: none;
465
+ border:1px solid;
466
+ border-color: #9e9e9e;
467
+ vertical-align: unset;
468
+ }
469
  .wcf-template-header .filter-links {
470
  margin: 0;
471
  padding: 0;
484
  }
485
  .wcf-template-header .filter-links li .current {
486
  color: #000;
487
+ border-bottom: 2px solid #f16334;
488
  font-weight: 600;
489
  }
490
 
509
  padding: 10px 0 0 20px;
510
  text-align: center;
511
  }
512
+ #wcf-start-from-scratch {
513
+ text-align: center;
514
+ }
515
 
516
+ #wcf-start-from-scratch .inner {
517
+ background: transparent;
518
+ box-shadow: none;
519
+ width: 94%;
520
+ margin: 0 auto;
521
+ float: none;
522
+ position: absolute;
523
+ top: 40%;
524
+ /*left: 50%;
525
+ transform: translate(-50%,-40%);*/
526
+ }
527
+ #wcf-scratch-steps-categories {
528
+ display: inline-block;
529
+ }
530
+
531
+ #wcf-scratch-steps-categories select{
532
+ border-radius: 0;
533
+ height: 29px;
534
+ border: 1px solid;
535
+ border-color: #9e9e9e;
536
+ border-width: 1px;
537
+ box-shadow: none;
538
+ padding: 2px;
539
+ line-height: 29px;
540
+ }
541
+
542
+ #wcf-start-from-scratch .description {
543
+ margin-bottom: 2em;
544
+ }
545
  #wcf-remote-step-importer .wcf-search-form {
546
  display: none;
547
  }
565
  margin: 0px 1em;
566
  position: relative;
567
  }
568
+ .cartflows-flow-import-blank.updating-message:before {
569
+ vertical-align: text-bottom;
570
+ }
571
+ #wpwrap .cartflows-step-loading h2,
572
+ #wpwrap .template-message-block h2 {
573
  font-size: 1.5em;
574
  margin: 0 0 0.5em 0;
575
+ padding: 8px 12px;
576
+ line-height: 1.4;
577
  }
578
+ #wpwrap .template-message-block p,
579
+ #wpwrap .cartflows-step-loading p {
580
  font-size: 1.2em;
581
  }
582
+ #wpwrap .cartflows-step-loading .spinner {
583
  vertical-align: initial;
584
  }
585
 
629
  }
630
 
631
  .wcf-templates-popup-content .inner{
632
+ background: #fff;
633
  position: relative;
634
+ padding:8px 8px 0 8px;
635
  display: block;
636
  float: left;
637
+ margin: 15px;
638
  text-align: center;
639
+ box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);
640
  }
641
+
642
+ @media only screen and (max-width: 480px) {
643
+ .wcf-templates-popup-content{
644
+ width: 90%;
645
+ }
646
+
647
+ .wcf-template-header{
648
+ display: block !important;
649
+ padding: 15px 15px 0 15px !important;
650
+ }
651
+
652
+ .wcf-popup-close-wrap{
653
+ position: absolute;
654
+ top: 10px;
655
+ right: 5px;
656
+ }
657
+ }
658
+
659
  @media only screen and (min-width: 768px) {
660
  .wcf-templates-popup-content .inner{
661
+ width: calc(25% - 30px);
662
  }
663
  }
664
 
673
  left: 110px;
674
  }
675
 
676
+ .wcf-steps-loading #wcf-start-from-scratch,
 
 
 
677
  .wcf-steps-loading #wcf-remote-step-list {
678
+ display: none !important;
679
  }
680
 
681
  #wcf-remote-content {
682
+ background-color: #f5f5f5;
683
  overflow-y: auto;
684
  min-height: 450px;
685
  max-height: 450px;
686
  padding: 20px 20px 20px 20px;
687
  clear: both;
688
  }
689
+ #wcf-remote-content #wcf-start-from-scratch h1{
690
+ font-size: 23px;
691
+ font-weight: 400;
692
+ margin: 0 0 1em 0;
693
+ padding: 9px 0 4px;
694
+ line-height: 29px;
695
+ }
696
 
697
  .wcf-template-list-wrap .template-name {
698
  margin: 0;
706
  }
707
 
708
  .wcf-templates-popup-content .template{
709
+ margin: 0px;
710
  position: relative;
711
  overflow: hidden;
712
+ /*box-shadow: 0 0 5px 1px rgba(204, 204, 204, 0.3);*/
713
  }
714
 
715
  .wcf-tab.nav-tabs{
720
  .wcf-template-header {
721
  align-items: center;
722
  background: #fff;
723
+ box-shadow: 0 0 8px rgba(0,0,0,.2);
724
  display: flex;
725
  -webkit-box-align: center;
726
  -webkit-align-items: center;
880
  margin: 4em 0 0 0;
881
  text-align: center;
882
  }
883
+ #wcf-categories {
884
+ border-left: 1px #ddd dashed;
885
+ display: inline-block;
886
+ margin-left: 1em;
887
+ padding-left: 1em;
888
+ vertical-align: baseline;
889
+ }
890
+ .flow-type-filter-links {
891
+ display: none;
892
+ }
893
+ #wcf-remote-filters {
894
  padding: 0 15px;
895
  }
896
+ #wcf-remote-filters a {
897
  text-decoration: none;
898
  }
899
+ #wcf-remote-filters a:focus,
900
+ #wcf-remote-filters .filter-links li:focus {
901
  outline: none;
902
  box-shadow: none;
903
  }
904
+ #wcf-remote-filters .filter-links li a {
905
  border-bottom: none;
906
  }
907
+ #wcf-remote-filters .filter-links li:first-child a {
908
  margin-left: 0;
909
  }
910
+ #wcf-remote-filters .filter-links li:last-child a {
911
  margin-right: 0;
912
  }
913
+ #wcf-remote-filters .filter-links li a:focus,
914
+ #wcf-remote-filters .filter-links li a:hover,
915
+ #wcf-remote-filters .filter-links li .current {
916
  color: #f16334;
917
+ }
918
+
919
+ .wrap .wcf-page-builder-notice .notice {
920
+ margin: 5px 15px;
921
+ }
922
+
923
+ #wcf-api-notice-block {
924
+ text-align: center;
925
+ margin-top: 5em;
926
+ }
927
+
928
+ .wcf-templates-popup-overlay a {
929
+ transition: none;
930
+ }
931
+
932
+ .wcf-notice-wrap .notice {
933
+ display: inline-block;
934
+ margin: 1.5em 0 0 0;
935
  }
assets/js/checkout-template.js CHANGED
@@ -83,7 +83,13 @@
83
  if( $get_bill_addr_field_two.hasClass('form-row-wide') ){
84
  $get_bill_addr_field_two.removeClass('form-row-wide');
85
  $get_bill_addr_field_two.addClass('form-row-last');
86
- $get_bill_addr_field_two.addClass('mt20');
 
 
 
 
 
 
87
  }
88
 
89
  // For Shipping address fields.
@@ -97,7 +103,13 @@
97
  if( $get_ship_addr_field_two.hasClass('form-row-wide') ){
98
  $get_ship_addr_field_two.removeClass('form-row-wide');
99
  $get_ship_addr_field_two.addClass('form-row-last');
100
- $get_ship_addr_field_two.addClass('mt20');
 
 
 
 
 
 
101
  }
102
 
103
  function address_fields_management( type ) {
83
  if( $get_bill_addr_field_two.hasClass('form-row-wide') ){
84
  $get_bill_addr_field_two.removeClass('form-row-wide');
85
  $get_bill_addr_field_two.addClass('form-row-last');
86
+
87
+ if( $get_bill_addr_field_two.find('label').hasClass('screen-reader-text') ){
88
+
89
+ $get_bill_addr_field_two.addClass('mt20');
90
+ }else{
91
+ $get_bill_addr_field_two.removeClass('mt20');
92
+ }
93
  }
94
 
95
  // For Shipping address fields.
103
  if( $get_ship_addr_field_two.hasClass('form-row-wide') ){
104
  $get_ship_addr_field_two.removeClass('form-row-wide');
105
  $get_ship_addr_field_two.addClass('form-row-last');
106
+
107
+ if( $get_ship_addr_field_two.find('label').hasClass('screen-reader-text') ){
108
+
109
+ $get_ship_addr_field_two.addClass('mt20');
110
+ }else{
111
+ $get_ship_addr_field_two.removeClass('mt20');
112
+ }
113
  }
114
 
115
  function address_fields_management( type ) {
assets/js/frontend.js CHANGED
@@ -1,7 +1,17 @@
1
  (function($){
2
 
3
- $(document).ready(function($) {
 
 
 
 
 
 
4
 
 
 
 
 
5
  $(document).on( 'click', 'a[href*="wcf-next-step"]', function(e) {
6
 
7
  e.preventDefault();
1
  (function($){
2
 
3
+ // Remove css when oceanwp theme is enabled.
4
+ var remove_oceanwp_custom_style = function(){
5
+ if( 'OceanWP' == cartflows.current_theme ){
6
+ var style = document.getElementById("oceanwp-style-css");
7
+ style.remove();
8
+ }
9
+ }
10
 
11
+ $(document).ready(function($) {
12
+
13
+ remove_oceanwp_custom_style();
14
+
15
  $(document).on( 'click', 'a[href*="wcf-next-step"]', function(e) {
16
 
17
  e.preventDefault();
assets/js/import.js CHANGED
@@ -111,7 +111,6 @@ var CartFlowsAjaxQueue = (function() {
111
  if( $('.post-type-cartflows_flow').hasClass('post-php') ) {
112
  this._cache_remote_steps();
113
  }
114
-
115
  if( $('.post-type-cartflows_flow').hasClass('edit-php') && null !== this._getParamFromURL('add-new-flow') ) {
116
  this._render_remote_flows();
117
  }
@@ -152,7 +151,8 @@ var CartFlowsAjaxQueue = (function() {
152
  };
153
 
154
  var api_post = {
155
- slug : CartFlowsImportVars.step_type + '?' + decodeURIComponent( $.param( api_params ) ),
 
156
  };
157
 
158
  CartFlowsAPI._api_request( api_post, function( data ) {
@@ -169,11 +169,13 @@ var CartFlowsAjaxQueue = (function() {
169
  {
170
  var self = CartFlowsImport;
171
 
 
 
172
  self.doc.on('click', '.cartflows-flow-import-blank', self._create_default_flow);
173
- self.doc.on('click', '#wcf-remote-flow-importer .wcf-page-builder-links a', self._show_page_bulider_for_flow);
174
- // self.doc.on('click', '#wcf-remote-flow-importer .filter-links a', self._filterFlowClick );
175
- self.doc.on('click', '#wcf-remote-step-importer .wcf-page-builder-links a', self._show_page_bulider_for_step);
176
- self.doc.on('click', '#wcf-remote-step-importer .step-type-filter-links a', self._filterStepClick );
177
 
178
  self.doc.on('click' , '.cartflows-step-import-blank:not(.get-pro)', self._create_blank_step);
179
  self.doc.on('click' , '#wcf-remote-step-importer .cartflows-step-import', self._import_step);
@@ -183,12 +185,9 @@ var CartFlowsAjaxQueue = (function() {
183
 
184
  self.doc.on( 'add_template_to_page-fail', self._add_template_to_page_fail);
185
 
186
- // self.doc.on( 'trigger-on-templates-load', self._on_templates_load );
187
-
188
  $( 'body' ).on('thickbox:iframe:loaded', self._previewLoaded );
189
 
190
  // Event's for API request.
191
- // $( document ).on('keyup input', '#wcf-remote-flow-importer .wcf-flow-search-input', self._remote_flow_search );
192
  $( document ).on('keyup input', '#wcf-remote-step-importer .wcf-flow-search-input', self._remote_step_search );
193
 
194
  $( document ).on('click', '.actions a', self._previewResponsive );
@@ -202,6 +201,35 @@ var CartFlowsAjaxQueue = (function() {
202
  // $( document ).on( 'click', '.wcf-tab > li > a', self._switch_step_tab );
203
  },
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  _switch_step_tab: function( event ) {
206
 
207
  event.preventDefault();//stop browser to take action for clicked anchor
@@ -240,8 +268,8 @@ var CartFlowsAjaxQueue = (function() {
240
  event.preventDefault();//stop browser to take action for clicked anchor
241
 
242
  // Remove all filter classes.
243
- $('.step-type-filter-links').find('a').removeClass('current');
244
- $('.step-type-filter-links').find('li:first-child a').addClass('current');
245
 
246
  window.clearTimeout(CartFlowsImport._ref);
247
  CartFlowsImport._ref = window.setTimeout(function () {
@@ -276,37 +304,62 @@ var CartFlowsAjaxQueue = (function() {
276
  /**
277
  * On Filter Clicked
278
  */
279
- _filterStepClick: function( event ) {
280
-
281
  event.preventDefault();
282
 
283
- $(this).parents('.step-type-filter-links').find('a').removeClass('current');
284
  $(this).addClass('current');
285
 
286
- $step_type = $(this).data('slug');
287
 
288
- if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
289
  $( '.wcf-template-notice' ).show();
290
 
291
  }else{
292
  $( '.wcf-template-notice' ).hide();
293
  }
294
 
 
 
 
 
295
  CartFlowsImport._showSteps();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
  if( '' == CartFlowsImportVars._is_pro_active && ( 'upsell' == $step_type || 'downsell' == $step_type ) ) {
298
- console.log( 'here' );
299
  $('.cartflows-step-import-blank').text( 'Get Pro' );
300
  $('.cartflows-step-import-blank').attr( 'href', CartFlowsImportVars.domain_url );
301
  $('.cartflows-step-import-blank').attr( 'target', '_blank' );
302
  $('.cartflows-step-import-blank').addClass('get-pro');
303
  // // $('#wcf-remote-step-list').find('.cartflows-step-import-blank').attr( 'class', 'button button-primary' );
304
  } else {
305
- $('.cartflows-step-import-blank').text( 'Create' );
306
  $('.cartflows-step-import-blank').removeClass( 'get-pro' );
307
  $('.cartflows-step-import-blank').removeAttr( 'target' );
308
  }
309
 
 
 
310
  },
311
 
312
  _showSteps: function() {
@@ -318,16 +371,26 @@ var CartFlowsAjaxQueue = (function() {
318
  _fields : CartFlowsImportVars.step_fields.toString(),
319
  };
320
 
321
- // Type.
322
- var type = $('#wcf-remote-step-filters .step-type-filter-links').find('.current').data('group') || '';
323
- var step_type = $('#wcf-remote-step-filters .step-type-filter-links').find('.current').data('slug') || '';
324
  if( '' !== type && 'all' !== type ) {
325
  api_params[ CartFlowsImportVars.step_type ] = type;
326
  }
327
 
 
 
 
 
 
 
 
 
 
328
  // API Request.
329
  var api_post = {
330
- slug : CartFlowsImportVars.step + '?' + decodeURIComponent( $.param( api_params ) ),
 
331
  };
332
 
333
  CartFlowsAPI._api_request( api_post, function( data ) {
@@ -335,12 +398,14 @@ var CartFlowsAjaxQueue = (function() {
335
  data.current_step_type = step_type;
336
 
337
  var template = wp.template('cartflows-steps-list');
338
- // if( parseInt( data.items_count ) ) {
339
  $('#wcf-remote-step-list').html( template( data ) );
340
- $('#wcf-remote-step-list').prepend( wp.template('cartflows-create-blank-step') );
341
- // } else {
342
- // $('#wcf-remote-step-list').html( wp.template('cartflows-no-steps') );
343
- // }
 
 
344
  } );
345
  },
346
 
@@ -388,48 +453,49 @@ var CartFlowsAjaxQueue = (function() {
388
  // Add Params for API request.
389
  var api_params = {
390
  licence_args : CartFlowsImportVars.licence_args,
391
- hide_empty : true,
392
- _fields : CartFlowsImportVars.flow_type_fields.toString(),
393
  };
394
 
395
  // API Request.
396
  var api_post = {
397
- slug : CartFlowsImportVars.flow_type + '?'+decodeURIComponent( $.param( api_params ) ),
398
- wrapper_class : 'flow-type-filter-links filter-links',
 
399
  show_all : false,
400
  };
401
 
402
  CartFlowsAPI._api_request( api_post, function( data ) {
403
  var template = wp.template('cartflows-term-filters');
404
- $('#cartflows-flow-funnel-type').html(template( data ));
405
- $('#cartflows-flow-funnel-type').find('li:first a').addClass('current');
406
- } );
407
-
408
- // Add Params for API request.
409
- var api_params = {
410
- licence_args : CartFlowsImportVars.licence_args,
411
- _fields : CartFlowsImportVars.flow_fields.toString(),
412
- };
413
-
414
- // API Request.
415
- var api_post = {
416
- slug : CartFlowsImportVars.flow + '?' + decodeURIComponent( $.param( api_params ) ),
417
- };
418
 
419
- CartFlowsAPI._api_request( api_post, function( data ) {
420
- var template = wp.template('cartflows-flows-list');
421
- // if( parseInt( data.items_count ) ) {
422
- $('#wcf-remote-flow-list').html( template( data ) );
 
 
 
423
 
424
- $('#wcf-remote-flow-list').prepend( wp.template('cartflows-create-blank-flow') );
425
-
 
 
426
 
 
 
427
 
428
- // } else {
429
- // $('#wcf-remote-flow-list').html( wp.template('cartflows-no-flows') );
430
- // }
431
  } );
432
-
433
  },
434
 
435
  _render_remote_flows: function( event ) {
@@ -450,6 +516,27 @@ var CartFlowsAjaxQueue = (function() {
450
  // Disable the button until caching the data.
451
  $( 'html' ).addClass('wcf-steps-loading');
452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  // Add Params for API request.
454
  var api_params = {
455
  licence_args : CartFlowsImportVars.licence_args,
@@ -458,6 +545,7 @@ var CartFlowsAjaxQueue = (function() {
458
 
459
  // API Request.
460
  var api_post = {
 
461
  slug : CartFlowsImportVars.step_type + '?'+decodeURIComponent( $.param( api_params ) ),
462
  wrapper_class : 'step-type-filter-links filter-links',
463
  show_all : false,
@@ -481,16 +569,21 @@ var CartFlowsAjaxQueue = (function() {
481
 
482
  api_params[ CartFlowsImportVars.step_type ] = data.items[ key ].id;
483
 
 
 
 
 
 
484
  // API Request.
485
  var api_post = {
486
- slug : CartFlowsImportVars.step + '?' + decodeURIComponent( $.param( api_params ) ),
 
487
  };
488
 
489
  CartFlowsAPI._api_request( api_post, function( data ) {
490
  var template = wp.template('cartflows-steps-list');
491
  if( parseInt( data.items_count ) ) {
492
  $('#wcf-remote-step-list').html( template( data ) );
493
- $('#wcf-remote-step-list').prepend( wp.template('cartflows-create-blank-step') );
494
  } else {
495
  $('#wcf-remote-step-list').html( wp.template('cartflows-no-steps') );
496
  }
@@ -500,8 +593,10 @@ var CartFlowsAjaxQueue = (function() {
500
  if( 0 == step_types_count ) {
501
 
502
  var template = wp.template('cartflows-term-filters');
503
- $('#wcf-remote-step-filters').html(template( step_type_response_data ));
504
- $('#wcf-remote-step-filters').find('li:first a').addClass('current');
 
 
505
 
506
  $('#wcf-remote-content').find( '.spinner' ).remove();
507
 
@@ -689,40 +784,70 @@ var CartFlowsAjaxQueue = (function() {
689
  $('#TB_window').removeClass('cartflows-thickbox-loading');
690
  },
691
 
692
- _show_page_bulider_for_step: function( event ) {
693
  event.preventDefault();
694
- var id = $(this).data( 'id' ) || '';
695
- var title = $(this).text() || '';
696
 
697
- $(this).parents('.wcf-page-builder-links').find('a').removeClass('current');
698
  $(this).addClass('current');
699
 
700
- if( 'elementor' == id ) {
701
- $('#wcf-upcoming-page-builders').hide().html('');
702
- $('#wcf-remote-step-list').show();
703
- } else {
704
- $('#wcf-upcoming-page-builders').show().html('<p class="description">Templates for '+title+' are coming soon.</p>');
705
- $('#wcf-upcoming-page-builders').show().prepend( wp.template('cartflows-create-blank-step') );
706
- $('#wcf-remote-step-list').hide();
707
- }
708
  },
709
 
710
- _show_page_bulider_for_flow: function( event ) {
711
- event.preventDefault();
712
- var id = $(this).data( 'id' ) || '';
713
- var title = $(this).text() || '';
714
 
715
- $(this).parents('.wcf-page-builder-links').find('a').removeClass('current');
716
- $(this).addClass('current');
717
 
718
- if( 'elementor' == id ) {
719
- $('#wcf-upcoming-page-builders').hide().html('');
720
- $('#wcf-remote-flow-list').show();
721
- } else {
722
- $('#wcf-upcoming-page-builders').show().html('<p class="description">Templates for '+title+' are coming soon.</p>');
723
- $('#wcf-upcoming-page-builders').show().prepend( wp.template('cartflows-create-blank-flow') );
724
- $('#wcf-remote-flow-list').hide();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
725
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
726
  },
727
 
728
  _create_default_flow: function( event )
@@ -778,7 +903,6 @@ var CartFlowsAjaxQueue = (function() {
778
 
779
  _process_import_flow: function( response )
780
  {
781
-
782
  var self = CartFlowsImport;
783
  var btn = $( '#wcf-remote-flow-importer .cartflows-step-import.updating-message' );
784
 
@@ -789,6 +913,9 @@ var CartFlowsAjaxQueue = (function() {
789
  case 'elementor':
790
  plugin_slug = 'elementor/elementor.php';
791
  break;
 
 
 
792
  }
793
 
794
  self._activate_plugin( plugin_slug );
@@ -903,7 +1030,14 @@ var CartFlowsAjaxQueue = (function() {
903
  _import_flow: function()
904
  {
905
  var btn = $( this );
906
- var plugins = btn.data('required');
 
 
 
 
 
 
 
907
 
908
  if( btn.hasClass('updating-message') ) {
909
  return;
@@ -920,25 +1054,25 @@ var CartFlowsAjaxQueue = (function() {
920
  wp.updates.requestFilesystemCredentials( event );
921
  }
922
 
923
- $.each( plugins, function( plugin_slug, plugin ) {
924
 
925
- var is_installed = plugin.install;
926
- var is_active = plugin.active;
 
 
927
 
928
- if( 'no' == is_installed ) {
929
 
930
- btn.text( 'Installing ' + plugin_slug + '...' );
931
-
932
  wp.updates.installPlugin({
933
- slug: plugin_slug,
934
- success: CartFlowsImport._process_import_flow,
935
- error: CartFlowsImport._handle_error
936
  });
937
 
938
  } else {
939
 
940
- if( 'no' == is_active ) {
941
- btn.text( 'Activating ' + plugin_slug + '...' );
942
  }
943
 
944
  var data = {
@@ -965,17 +1099,24 @@ var CartFlowsAjaxQueue = (function() {
965
  var btn = $(this),
966
  self = CartFlowsImport,
967
  flow_id = $("#post_ID").val(),
968
- step_slug = $('.step-type-filter-links .current').data('slug') || '',
969
- step_title = $('.step-type-filter-links .current').data('title') || '',
970
  step_type = step_slug,
971
  step_count = $('.wcf-step-wrap[data-term-slug="'+step_slug+'"]').length || 1;
972
  step_custom_title = `${step_title} ${step_count+1}`;
973
 
 
 
 
 
 
 
974
 
975
  if ( ! CartFlowsImportVars._is_pro_active && ( 'upsell' === step_type || 'downsell' === step_type )) {
976
  return;
977
  }
978
 
 
979
  btn.parents('.template').addClass('importing');
980
 
981
  if ( ! CartFlowsImportVars._is_pro_active ) {
@@ -990,11 +1131,8 @@ var CartFlowsAjaxQueue = (function() {
990
  btn.removeClass('importing updating-message')
991
  .text('Import Failed!');
992
 
993
- var notice_wrap = parent_template.find('#wcf_create_notice').show();
994
 
995
- notice_wrap.find('a')
996
- .addClass('notice notice-warning ')
997
- .text ( 'Upgrade to Pro for adding more than one Checkout step' );
998
  return;
999
  }
1000
  }
@@ -1004,7 +1142,6 @@ var CartFlowsAjaxQueue = (function() {
1004
 
1005
  $('.cartflows-step-import').addClass('disabled');
1006
  btn.addClass('importing updating-message').text('Creating..');
1007
-
1008
 
1009
  // Process Import Page.
1010
  if( $( 'body' ).hasClass( 'post-type-cartflows_flow' ) ) {
@@ -1016,8 +1153,6 @@ var CartFlowsAjaxQueue = (function() {
1016
  security : cartflows_admin.cf_step_create_blank_nonce
1017
  };
1018
 
1019
-
1020
-
1021
  // Import Template AJAX.
1022
  self._ajax( data, function( data ) {
1023
 
@@ -1031,9 +1166,12 @@ var CartFlowsAjaxQueue = (function() {
1031
  }, 3000);
1032
 
1033
  } else {
 
1034
  btn.removeClass('importing updating-message')
1035
  .text('Creating Failed!');
1036
 
 
 
1037
  template.find('.cartflows-step-preview').append( "<div class='preview'></div>" );
1038
 
1039
  template.find('.preview')
@@ -1047,17 +1185,17 @@ var CartFlowsAjaxQueue = (function() {
1047
 
1048
  _process_import_step: function( response ) {
1049
 
1050
- var step_slug = $('.step-type-filter-links .current').data('slug') || '',
1051
- step_title = $('.step-type-filter-links .current').data('title') || '',
1052
  step_count = $('.wcf-step-wrap[data-term-slug="'+step_slug+'"]').length || 1;
 
1053
  step_custom_title = `${step_title} ${step_count+1}`,
1054
- btn = $('#wcf-remote-step-importer .cartflows-step-import.updating-message'),
1055
  self = CartFlowsImport;
1056
 
1057
  if ( ! CartFlowsImportVars._is_pro_active ) {
1058
 
1059
- if ( 'checkout' === step_slug ) {
1060
-
1061
  var checkout_steps = $( '.wcf-step-wrap[data-term-slug="checkout"]');
1062
 
1063
  if ( 0 < checkout_steps.length ) {
@@ -1088,6 +1226,9 @@ var CartFlowsAjaxQueue = (function() {
1088
  case 'elementor':
1089
  plugin_slug = 'elementor/elementor.php';
1090
  break;
 
 
 
1091
  }
1092
 
1093
  self._activate_plugin( plugin_slug );
@@ -1145,13 +1286,22 @@ var CartFlowsAjaxQueue = (function() {
1145
  _import_step: function( event )
1146
  {
1147
  event.preventDefault();
1148
- var btn = $(this);
1149
- var plugins = btn.data('required');
 
 
 
 
 
 
 
 
1150
 
1151
  if( btn.hasClass('updating-message') ) {
1152
  return;
1153
  }
1154
 
 
1155
  btn.addClass('updating-message');
1156
 
1157
  if( ! $.isEmptyObject( plugins ) ) {
@@ -1162,27 +1312,25 @@ var CartFlowsAjaxQueue = (function() {
1162
 
1163
  $('#wcf-remote-step-importer').addClass('request-process');
1164
 
1165
- $.each( plugins, function( plugin_slug, plugin ) {
1166
-
1167
- var is_installed = plugin.install;
1168
- var is_active = plugin.active;
1169
 
1170
- btn.parents('.template').addClass('importing');
 
 
 
1171
 
1172
- if( 'no' == is_installed ) {
1173
 
1174
- btn.addClass('updating-message').text( 'Installing ' + plugin_slug + '...' );
1175
-
1176
  wp.updates.installPlugin({
1177
- slug: plugin_slug,
1178
- success: CartFlowsImport._process_import_step,
1179
- error: CartFlowsImport._handle_error
1180
  });
1181
 
1182
  } else {
1183
 
1184
- if( 'no' == is_active ) {
1185
- btn.addClass('updating-message').text( 'Activating ' + plugin_slug + '...' );
1186
  }
1187
 
1188
  var data = {
111
  if( $('.post-type-cartflows_flow').hasClass('post-php') ) {
112
  this._cache_remote_steps();
113
  }
 
114
  if( $('.post-type-cartflows_flow').hasClass('edit-php') && null !== this._getParamFromURL('add-new-flow') ) {
115
  this._render_remote_flows();
116
  }
151
  };
152
 
153
  var api_post = {
154
+ remote_slug : CartFlowsImportVars.step_type,
155
+ slug : CartFlowsImportVars.step_type + '?' + decodeURIComponent( $.param( api_params ) ),
156
  };
157
 
158
  CartFlowsAPI._api_request( api_post, function( data ) {
169
  {
170
  var self = CartFlowsImport;
171
 
172
+ self.doc.on( 'cartflows-api-request-fail', self._api_request_failed );
173
+ self.doc.on('click', '#wcf-get-started-steps a, .wcf-create-from-scratch-link', self._toggle_ready_templates);
174
  self.doc.on('click', '.cartflows-flow-import-blank', self._create_default_flow);
175
+ self.doc.on('click', '#wcf-remote-flow-importer .wcf-page-builder-links a', self._filterFlowPageBuilderClick);
176
+ self.doc.on('change', '#wcf-remote-step-importer #wcf-categories .step-type-filter-links', self._filterBlankStepCategoryChange );
177
+ self.doc.on('change', '#wcf-remote-step-importer #wcf-scratch-steps-categories .step-type-filter-links', self._filterBlankStepCategoryChange );
178
+ self.doc.on('click', '#wcf-remote-step-importer .wcf-page-builder-links a', self._filterStepPageBuilderClick );
179
 
180
  self.doc.on('click' , '.cartflows-step-import-blank:not(.get-pro)', self._create_blank_step);
181
  self.doc.on('click' , '#wcf-remote-step-importer .cartflows-step-import', self._import_step);
185
 
186
  self.doc.on( 'add_template_to_page-fail', self._add_template_to_page_fail);
187
 
 
 
188
  $( 'body' ).on('thickbox:iframe:loaded', self._previewLoaded );
189
 
190
  // Event's for API request.
 
191
  $( document ).on('keyup input', '#wcf-remote-step-importer .wcf-flow-search-input', self._remote_step_search );
192
 
193
  $( document ).on('click', '.actions a', self._previewResponsive );
201
  // $( document ).on( 'click', '.wcf-tab > li > a', self._switch_step_tab );
202
  },
203
 
204
+ _api_request_failed: function( event, data, jqXHR, textStatus ) {
205
+ if( 'error' == textStatus && jqXHR.responseJSON ) {
206
+ if( ! $('#wcf-api-notice-block').length ) {
207
+ $('#wcf-ready-templates').prepend( '<div id="wcf-api-notice-block"><h2>API Connection Error!</h2><p class="description">'+jqXHR.responseJSON.message+'</p></div>' );
208
+ }
209
+ }
210
+ },
211
+
212
+ _toggle_ready_templates: function( event ) {
213
+ event.preventDefault();
214
+
215
+ var slug = $(this).data('slug') || '';
216
+
217
+ $('#wcf-get-started-steps').find('a').removeClass('current');
218
+ $('#wcf-get-started-steps').find('a[data-slug="'+slug+'"]').addClass('current');
219
+
220
+ if( 'canvas' == slug ) {
221
+ $('#wcf-ready-templates').hide();
222
+ $('#wcf-start-from-scratch').show();
223
+ } else {
224
+ $('#wcf-ready-templates').show();
225
+ $('#wcf-start-from-scratch').hide();
226
+ }
227
+
228
+ if( $('#wcf-remote-step-importer').length ) {
229
+ CartFlowsImport._showSteps();
230
+ }
231
+ },
232
+
233
  _switch_step_tab: function( event ) {
234
 
235
  event.preventDefault();//stop browser to take action for clicked anchor
268
  event.preventDefault();//stop browser to take action for clicked anchor
269
 
270
  // Remove all filter classes.
271
+ $('.step-type-filter-links').find('option').removeClass('current');
272
+ $('.step-type-filter-links').find('option:first-child').addClass('current');
273
 
274
  window.clearTimeout(CartFlowsImport._ref);
275
  CartFlowsImport._ref = window.setTimeout(function () {
304
  /**
305
  * On Filter Clicked
306
  */
307
+ _filterStepPageBuilderClick: function( event ) {
 
308
  event.preventDefault();
309
 
310
+ $(this).parents('ul').find('a').removeClass('current');
311
  $(this).addClass('current');
312
 
313
+ var step_type = $('.step-type-filter-links .current').data('slug') || '';
314
 
315
+ if ( 'upsell' === step_type || 'downsell' === step_type ) {
316
  $( '.wcf-template-notice' ).show();
317
 
318
  }else{
319
  $( '.wcf-template-notice' ).hide();
320
  }
321
 
322
+ $('.wcf-page-builder-notice').html( '' );
323
+
324
+ $('#wcf-remote-step-list').html( '<span class="spinner is-active"></span>' );
325
+
326
  CartFlowsImport._showSteps();
327
+ },
328
+
329
+ _filterBlankStepCategoryChange: function( event ) {
330
+ event.preventDefault();
331
+
332
+ var val = $(this).find('option:selected').val() || '';
333
+ if( val ) {
334
+ $('.step-type-filter-links').val( val );
335
+ }
336
+
337
+ $('.step-type-filter-links').find('option').removeClass('current');
338
+ $('.step-type-filter-links').find('option:selected').addClass('current');
339
+
340
+ $step_type = $(this).find('option:selected').data('slug');
341
+
342
+ if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
343
+ $( '.wcf-template-notice' ).show();
344
+
345
+ }else{
346
+ $( '.wcf-template-notice' ).hide();
347
+ }
348
 
349
  if( '' == CartFlowsImportVars._is_pro_active && ( 'upsell' == $step_type || 'downsell' == $step_type ) ) {
 
350
  $('.cartflows-step-import-blank').text( 'Get Pro' );
351
  $('.cartflows-step-import-blank').attr( 'href', CartFlowsImportVars.domain_url );
352
  $('.cartflows-step-import-blank').attr( 'target', '_blank' );
353
  $('.cartflows-step-import-blank').addClass('get-pro');
354
  // // $('#wcf-remote-step-list').find('.cartflows-step-import-blank').attr( 'class', 'button button-primary' );
355
  } else {
356
+ $('.cartflows-step-import-blank').text( 'Create Step' );
357
  $('.cartflows-step-import-blank').removeClass( 'get-pro' );
358
  $('.cartflows-step-import-blank').removeAttr( 'target' );
359
  }
360
 
361
+ $('#wcf-remote-step-list').html( '<span class="spinner is-active"></span>' );
362
+ CartFlowsImport._showSteps();
363
  },
364
 
365
  _showSteps: function() {
371
  _fields : CartFlowsImportVars.step_fields.toString(),
372
  };
373
 
374
+ var type = $('#wcf-categories .step-type-filter-links').find('.current').data('group') || '';
375
+ var step_type = $('#wcf-categories .step-type-filter-links').find('.current').data('slug') || '';
376
+
377
  if( '' !== type && 'all' !== type ) {
378
  api_params[ CartFlowsImportVars.step_type ] = type;
379
  }
380
 
381
+ // Page Builder.
382
+ var type = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('group') || '';
383
+ var step_type = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('slug') || '';
384
+ var title = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('title') || 'Page Builder';
385
+
386
+ if( '' !== type && 'all' !== type ) {
387
+ api_params[ CartFlowsImportVars.step_page_builder ] = type;
388
+ }
389
+
390
  // API Request.
391
  var api_post = {
392
+ remote_slug : CartFlowsImportVars.step,
393
+ slug : CartFlowsImportVars.step + '?' + decodeURIComponent( $.param( api_params ) ),
394
  };
395
 
396
  CartFlowsAPI._api_request( api_post, function( data ) {
398
  data.current_step_type = step_type;
399
 
400
  var template = wp.template('cartflows-steps-list');
401
+ if( parseInt( data.items_count ) ) {
402
  $('#wcf-remote-step-list').html( template( data ) );
403
+ } else {
404
+ $('#wcf-remote-step-list').html( wp.template('cartflows-no-steps') );
405
+ $('.cartflows-no-steps').find( '.description' ).html( 'We are working on ready templates designed with '+title+'.<br/>Meanwhile you can <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own designs</a> easily.' );
406
+ }
407
+
408
+ CartFlowsImport._showPageBuilderNotice();
409
  } );
410
  },
411
 
453
  // Add Params for API request.
454
  var api_params = {
455
  licence_args : CartFlowsImportVars.licence_args,
456
+ hide_empty : false,
457
+ _fields : CartFlowsImportVars.flow_page_builder_fields.toString(),
458
  };
459
 
460
  // API Request.
461
  var api_post = {
462
+ remote_slug : CartFlowsImportVars.flow_page_builder,
463
+ slug : CartFlowsImportVars.flow_page_builder + '?'+decodeURIComponent( $.param( api_params ) ),
464
+ wrapper_class : 'wcf-page-builder-links filter-links',
465
  show_all : false,
466
  };
467
 
468
  CartFlowsAPI._api_request( api_post, function( data ) {
469
  var template = wp.template('cartflows-term-filters');
470
+ $('#wcf-page-builders').html(template( data ));
471
+ $('#wcf-page-builders').find('li:first a').addClass('current');
472
+
473
+ // Step 2: Categories.
474
+ // Add Params for API request.
475
+ var api_params = {
476
+ licence_args : CartFlowsImportVars.licence_args,
477
+ hide_empty : true,
478
+ _fields : CartFlowsImportVars.flow_type_fields.toString(),
479
+ };
 
 
 
 
480
 
481
+ // API Request.
482
+ var api_post = {
483
+ remote_slug : CartFlowsImportVars.flow_type,
484
+ slug : CartFlowsImportVars.flow_type + '?'+decodeURIComponent( $.param( api_params ) ),
485
+ wrapper_class : 'flow-type-filter-links filter-links',
486
+ show_all : false,
487
+ };
488
 
489
+ CartFlowsAPI._api_request( api_post, function( data ) {
490
+ var template = wp.template('cartflows-term-filters');
491
+ $('#wcf-categories').html(template( data ));
492
+ $('#wcf-categories').find('li:first a').addClass('current');
493
 
494
+ // Step 3: Flows.
495
+ CartFlowsImport._showFlows();
496
 
497
+ } );
 
 
498
  } );
 
499
  },
500
 
501
  _render_remote_flows: function( event ) {
516
  // Disable the button until caching the data.
517
  $( 'html' ).addClass('wcf-steps-loading');
518
 
519
+ // Add Params for API request.
520
+ var api_params = {
521
+ licence_args : CartFlowsImportVars.licence_args,
522
+ hide_empty : false,
523
+ _fields : CartFlowsImportVars.step_page_builder_fields.toString(),
524
+ };
525
+
526
+ // API Request.
527
+ var api_post = {
528
+ remote_slug : CartFlowsImportVars.step_page_builder,
529
+ slug : CartFlowsImportVars.step_page_builder + '?'+decodeURIComponent( $.param( api_params ) ),
530
+ wrapper_class : 'wcf-page-builder-links filter-links',
531
+ show_all : false,
532
+ };
533
+
534
+ CartFlowsAPI._api_request( api_post, function( data ) {
535
+ var template = wp.template('cartflows-term-filters');
536
+ $('#wcf-page-builders').html(template( data ));
537
+ $('#wcf-page-builders').find('li:first a').addClass('current');
538
+ } );
539
+
540
  // Add Params for API request.
541
  var api_params = {
542
  licence_args : CartFlowsImportVars.licence_args,
545
 
546
  // API Request.
547
  var api_post = {
548
+ remote_slug : CartFlowsImportVars.step_type,
549
  slug : CartFlowsImportVars.step_type + '?'+decodeURIComponent( $.param( api_params ) ),
550
  wrapper_class : 'step-type-filter-links filter-links',
551
  show_all : false,
569
 
570
  api_params[ CartFlowsImportVars.step_type ] = data.items[ key ].id;
571
 
572
+ var page_builder = $('.wcf-page-builder-links').find('.current').data('group') || '';
573
+ if( page_builder ) {
574
+ api_params[ CartFlowsImportVars.flow_page_builder ] = page_builder;
575
+ }
576
+
577
  // API Request.
578
  var api_post = {
579
+ remote_slug : CartFlowsImportVars.step,
580
+ slug : CartFlowsImportVars.step + '?' + decodeURIComponent( $.param( api_params ) ),
581
  };
582
 
583
  CartFlowsAPI._api_request( api_post, function( data ) {
584
  var template = wp.template('cartflows-steps-list');
585
  if( parseInt( data.items_count ) ) {
586
  $('#wcf-remote-step-list').html( template( data ) );
 
587
  } else {
588
  $('#wcf-remote-step-list').html( wp.template('cartflows-no-steps') );
589
  }
593
  if( 0 == step_types_count ) {
594
 
595
  var template = wp.template('cartflows-term-filters');
596
+ $('#wcf-categories').html(template( step_type_response_data ));
597
+ $('#wcf-scratch-steps-categories').html(template( step_type_response_data ));
598
+ $('#wcf-categories, #wcf-scratch-steps-categories').find('option:first').addClass('current');
599
+ $('#wcf-categories').find('li:first a').addClass('current');
600
 
601
  $('#wcf-remote-content').find( '.spinner' ).remove();
602
 
784
  $('#TB_window').removeClass('cartflows-thickbox-loading');
785
  },
786
 
787
+ _filterFlowPageBuilderClick: function( event ) {
788
  event.preventDefault();
 
 
789
 
790
+ $(this).parents('ul').find('a').removeClass('current');
791
  $(this).addClass('current');
792
 
793
+ $('.wcf-page-builder-notice').html( '' );
794
+
795
+ $('#wcf-remote-flow-list').html( '<span class="spinner is-active"></span>' );
796
+
797
+ CartFlowsImport._showFlows();
 
 
 
798
  },
799
 
800
+ _showPageBuilderNotice: function() {
 
 
 
801
 
802
+ var status = '';
 
803
 
804
+ var slug = $( '#wcf-page-builders' ).find('.current').data('slug') || '';
805
+ var title = $( '#wcf-page-builders' ).find('.current').data('title') || '';
806
+
807
+ if( slug && CartFlowsImportVars.required_plugins[slug] && CartFlowsImportVars.required_plugins[slug].status ) {
808
+ status = CartFlowsImportVars.required_plugins[slug].status;
809
+ }
810
+
811
+ if( title && status ) {
812
+ if( 'install' === status || 'activate' === status ) {
813
+ $('.wcf-page-builder-notice').html( '<div class="notice notice-info no-elementor-notice"><p><span class="dashicons dashicons-warning"></span> '+title+' is not available on this website. Importing a template will install and activate it automatically.</p></div>' );
814
+ }
815
+ }
816
+ },
817
+
818
+ _showFlows: function() {
819
+ // Add Params for API request.
820
+ var api_params = {
821
+ licence_args : CartFlowsImportVars.licence_args,
822
+ _fields : CartFlowsImportVars.flow_fields.toString(),
823
+ };
824
+
825
+ // Page Builder.
826
+ var type = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('group') || '';
827
+ var step_type = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('slug') || '';
828
+ var title = $('#wcf-page-builders .wcf-page-builder-links').find('.current').data('title') || 'Page Builder';
829
+ if( '' !== type && 'all' !== type ) {
830
+ api_params[ CartFlowsImportVars.flow_page_builder ] = type;
831
  }
832
+
833
+ // API Request.
834
+ var api_post = {
835
+ remote_slug : CartFlowsImportVars.flow,
836
+ slug : CartFlowsImportVars.flow + '?' + decodeURIComponent( $.param( api_params ) ),
837
+ };
838
+
839
+ CartFlowsAPI._api_request( api_post, function( data ) {
840
+
841
+ var template = wp.template('cartflows-flows-list');
842
+ if( parseInt( data.items_count ) ) {
843
+ $('#wcf-remote-flow-list').html( template( data ) );
844
+ } else {
845
+ $('#wcf-remote-flow-list').html( wp.template('cartflows-no-flows') );
846
+ $('.cartflows-no-flows').find( '.description' ).html( 'We are working on ready templates designed with '+title+'.<br/>Meanwhile you can <a href="#" data-slug="canvas" class="wcf-create-from-scratch-link">create your own designs</a> easily.' );
847
+ }
848
+
849
+ CartFlowsImport._showPageBuilderNotice();
850
+ } );
851
  },
852
 
853
  _create_default_flow: function( event )
903
 
904
  _process_import_flow: function( response )
905
  {
 
906
  var self = CartFlowsImport;
907
  var btn = $( '#wcf-remote-flow-importer .cartflows-step-import.updating-message' );
908
 
913
  case 'elementor':
914
  plugin_slug = 'elementor/elementor.php';
915
  break;
916
+ case 'beaver-builder-lite-version':
917
+ plugin_slug = 'beaver-builder-lite-version/fl-builder.php';
918
+ break;
919
  }
920
 
921
  self._activate_plugin( plugin_slug );
1030
  _import_flow: function()
1031
  {
1032
  var btn = $( this );
1033
+ var plugins_group = btn.data('required-plugin-group');
1034
+
1035
+ if( ! CartFlowsImportVars.required_plugins[plugins_group] ) {
1036
+ btn.text( 'Invalid plugin ' + plugins_group + '!' );
1037
+ return;
1038
+ }
1039
+
1040
+ var plugins = CartFlowsImportVars.required_plugins[plugins_group]['plugins'];
1041
 
1042
  if( btn.hasClass('updating-message') ) {
1043
  return;
1054
  wp.updates.requestFilesystemCredentials( event );
1055
  }
1056
 
1057
+ $.each( plugins, function( index, plugin ) {
1058
 
1059
+ var plugin_slug = plugin.slug;
1060
+ var plugin_status = plugin.status;
1061
+
1062
+ if( 'install' == plugin_status ) {
1063
 
1064
+ btn.text( 'Installing..' );
1065
 
 
 
1066
  wp.updates.installPlugin({
1067
+ slug : plugin_slug,
1068
+ success : CartFlowsImport._process_import_flow,
1069
+ error : CartFlowsImport._handle_error
1070
  });
1071
 
1072
  } else {
1073
 
1074
+ if( 'activate' == plugin_status ) {
1075
+ btn.text( 'Activating..' );
1076
  }
1077
 
1078
  var data = {
1099
  var btn = $(this),
1100
  self = CartFlowsImport,
1101
  flow_id = $("#post_ID").val(),
1102
+ step_slug = $('#wcf-scratch-steps-categories .step-type-filter-links .current').data('slug') || '',
1103
+ step_title = $('#wcf-scratch-steps-categories .step-type-filter-links .current').data('title') || '',
1104
  step_type = step_slug,
1105
  step_count = $('.wcf-step-wrap[data-term-slug="'+step_slug+'"]').length || 1;
1106
  step_custom_title = `${step_title} ${step_count+1}`;
1107
 
1108
+ $('#wcf-start-from-scratch .wcf-notice-wrap').remove();
1109
+
1110
+ if( '' === step_type ) {
1111
+ $('#wcf-start-from-scratch .inner').append( '<div class="wcf-notice-wrap"><div class="notice notice-info"><p>Please select the step type.</p></div></div>' );
1112
+ return;
1113
+ }
1114
 
1115
  if ( ! CartFlowsImportVars._is_pro_active && ( 'upsell' === step_type || 'downsell' === step_type )) {
1116
  return;
1117
  }
1118
 
1119
+
1120
  btn.parents('.template').addClass('importing');
1121
 
1122
  if ( ! CartFlowsImportVars._is_pro_active ) {
1131
  btn.removeClass('importing updating-message')
1132
  .text('Import Failed!');
1133
 
1134
+ $('#wcf-start-from-scratch .inner').append( '<div class="wcf-notice-wrap"><div class="notice notice-warning"><p>Upgrade to Pro for adding more than one Checkout step.</p></div></div>' );
1135
 
 
 
 
1136
  return;
1137
  }
1138
  }
1142
 
1143
  $('.cartflows-step-import').addClass('disabled');
1144
  btn.addClass('importing updating-message').text('Creating..');
 
1145
 
1146
  // Process Import Page.
1147
  if( $( 'body' ).hasClass( 'post-type-cartflows_flow' ) ) {
1153
  security : cartflows_admin.cf_step_create_blank_nonce
1154
  };
1155
 
 
 
1156
  // Import Template AJAX.
1157
  self._ajax( data, function( data ) {
1158
 
1166
  }, 3000);
1167
 
1168
  } else {
1169
+
1170
  btn.removeClass('importing updating-message')
1171
  .text('Creating Failed!');
1172
 
1173
+ $('#wcf-remote-step-importer').removeClass('request-process');
1174
+
1175
  template.find('.cartflows-step-preview').append( "<div class='preview'></div>" );
1176
 
1177
  template.find('.preview')
1185
 
1186
  _process_import_step: function( response ) {
1187
 
1188
+ var btn = $('#wcf-remote-step-importer .cartflows-step-import.updating-message'),
1189
+ step_slug = btn.data('slug') || '',
1190
  step_count = $('.wcf-step-wrap[data-term-slug="'+step_slug+'"]').length || 1;
1191
+ step_title = btn.data('title') || '',
1192
  step_custom_title = `${step_title} ${step_count+1}`,
 
1193
  self = CartFlowsImport;
1194
 
1195
  if ( ! CartFlowsImportVars._is_pro_active ) {
1196
 
1197
+ if ( 'checkout' === step_slug ) {
1198
+
1199
  var checkout_steps = $( '.wcf-step-wrap[data-term-slug="checkout"]');
1200
 
1201
  if ( 0 < checkout_steps.length ) {
1226
  case 'elementor':
1227
  plugin_slug = 'elementor/elementor.php';
1228
  break;
1229
+ case 'beaver-builder-lite-version':
1230
+ plugin_slug = 'beaver-builder-lite-version/fl-builder.php';
1231
+ break;
1232
  }
1233
 
1234
  self._activate_plugin( plugin_slug );
1286
  _import_step: function( event )
1287
  {
1288
  event.preventDefault();
1289
+
1290
+ var btn = $( this );
1291
+ var plugins_group = btn.data('required-plugin-group');
1292
+
1293
+ if( ! CartFlowsImportVars.required_plugins[plugins_group] ) {
1294
+ btn.text( 'Invalid plugin ' + plugins_group + '!' );
1295
+ return;
1296
+ }
1297
+
1298
+ var plugins = CartFlowsImportVars.required_plugins[plugins_group]['plugins'];
1299
 
1300
  if( btn.hasClass('updating-message') ) {
1301
  return;
1302
  }
1303
 
1304
+ btn.parents('.template').addClass('importing');
1305
  btn.addClass('updating-message');
1306
 
1307
  if( ! $.isEmptyObject( plugins ) ) {
1312
 
1313
  $('#wcf-remote-step-importer').addClass('request-process');
1314
 
1315
+ $.each( plugins, function( index, plugin ) {
 
 
 
1316
 
1317
+ var plugin_slug = plugin.slug;
1318
+ var plugin_status = plugin.status;
1319
+
1320
+ if( 'install' == plugin_status ) {
1321
 
1322
+ btn.text( 'Installing..' );
1323
 
 
 
1324
  wp.updates.installPlugin({
1325
+ slug : plugin_slug,
1326
+ success : CartFlowsImport._process_import_step,
1327
+ error : CartFlowsImport._handle_error
1328
  });
1329
 
1330
  } else {
1331
 
1332
+ if( 'activate' == plugin_status ) {
1333
+ btn.text( 'Activating..' );
1334
  }
1335
 
1336
  var data = {
assets/js/rest-api.js CHANGED
@@ -193,7 +193,7 @@
193
  })
194
  .fail(function( jqXHR, textStatus ) {
195
 
196
- $(document).trigger( 'cartflows-api-request-fail' );
197
 
198
  })
199
  .always(function() {
193
  })
194
  .fail(function( jqXHR, textStatus ) {
195
 
196
+ $(document).trigger( 'cartflows-api-request-fail', [data, jqXHR, textStatus] );
197
 
198
  })
199
  .always(function() {
cartflows.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
- /**
3
- * Plugin Name: CartFlows
4
- * Plugin URI: https://cartflows.com/
5
- * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
- * Version: 1.1.0.1
7
- * Author: CartFlows Inc
8
- * Author URI: https://cartflows.com/
9
- * Text Domain: cartflows
10
- * WC requires at least: 3.0
11
- * WC tested up to: 3.5.1
12
- *
13
- * @package CartFlows
14
- */
15
-
16
- /**
17
- * Set constants.
18
- */
19
- define( 'CARTFLOWS_FILE', __FILE__ );
20
-
21
- /**
22
- * Extensions
23
- */
24
- require_once 'classes/class-cartflows-loader.php';
1
+ <?php
2
+ /**
3
+ * Plugin Name: CartFlows
4
+ * Plugin URI: https://cartflows.com/
5
+ * Description: Create beautiful checkout pages & sales flows for WooCommerce.
6
+ * Version: 1.1.1
7
+ * Author: CartFlows Inc
8
+ * Author URI: https://cartflows.com/
9
+ * Text Domain: cartflows
10
+ * WC requires at least: 3.0
11
+ * WC tested up to: 3.5.1
12
+ *
13
+ * @package CartFlows
14
+ */
15
+
16
+ /**
17
+ * Set constants.
18
+ */
19
+ define( 'CARTFLOWS_FILE', __FILE__ );
20
+
21
+ /**
22
+ * Extensions
23
+ */
24
+ require_once 'classes/class-cartflows-loader.php';
changelog.txt CHANGED
@@ -1,3 +1,11 @@
 
 
 
 
 
 
 
 
1
  Version 1.1.0.1 - Friday, 7th December 2018
2
  - Fix: Checkout breaking issue.
3
 
1
+ Version 1.1.1 - Wednesday, 2nd January 2019
2
+ - Improvement: Added compatibility for a future release of CartFlows Pro.
3
+ - Improvement: Minor CSS and HTML changes.
4
+ - Fix: Flatsome UX builder compatibility added.
5
+ - Fix: OceanWP CSS overwrite issue.
6
+ - Fix: Divi CSS issue.
7
+ - Fix: Other minor bugs.
8
+
9
  Version 1.1.0.1 - Friday, 7th December 2018
10
  - Fix: Checkout breaking issue.
11
 
classes/batch-process/class-cartflows-batch-process.php CHANGED
@@ -1,125 +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
- * Process All
29
- *
30
- * @since 1.0.0
31
- * @var object Class object.
32
- * @access public
33
- */
34
- public static $process_all;
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
- return self::$instance;
47
- }
48
-
49
- /**
50
- * Constructor
51
- *
52
- * @since 1.0.0
53
- */
54
- public function __construct() {
55
-
56
- // If plugin - 'Elementor' not exist then return.
57
- if ( class_exists( '\Elementor\Plugin' ) ) {
58
-
59
- // Core Helpers - Image.
60
- // @todo This file is required for Elementor.
61
- // Once we implement our logic for updating elementor data then we'll delete this file.
62
- require_once ABSPATH . 'wp-admin/includes/image.php';
63
-
64
- // Core Helpers - Batch Processing.
65
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-async-request.php';
66
- require_once CARTFLOWS_DIR . 'classes/batch-process/helpers/class-wp-background-process.php';
67
-
68
- // Page Builder.
69
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-batch-process-elementor.php';
70
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
71
-
72
- self::$process_all = new CartFlows_Batch_Process_Elementor();
73
-
74
- // Start image importing after site import complete.
75
- add_action( 'cartflows_after_template_import', array( $this, 'start_batch_process' ) );
76
- add_action( 'cartflows_import_complete', array( $this, 'complete_batch_import' ) );
77
- }
78
- }
79
-
80
- /**
81
- * Batch Process Complete.
82
- *
83
- * @return void
84
- */
85
- public function complete_batch_import() {
86
- wcf()->logger->import_log( '(✓) BATCH Process Complete!' );
87
- }
88
-
89
- /**
90
- * Start Image Import
91
- *
92
- * @param integer $post_id Post Id.
93
- *
94
- * @return void
95
- */
96
- public function start_batch_process( $post_id = '' ) {
97
-
98
- wcf()->logger->import_log( '(✓) BATCH Started!' );
99
- wcf()->logger->import_log( '(✓) Step ID ' . $post_id );
100
-
101
- // Add "elementor" in import [queue].
102
- // @todo Remove required `allow_url_fopen` support.
103
- if ( ini_get( 'allow_url_fopen' ) ) {
104
- if ( is_plugin_active( 'elementor/elementor.php' ) ) {
105
-
106
- self::$process_all->push_to_queue( $post_id );
107
-
108
- // Dispatch Queue.
109
- self::$process_all->save()->dispatch();
110
-
111
- wcf()->logger->import_log( '(✓) Dispatch Request..' );
112
- }
113
- } else {
114
- wcf()->logger->import_log( '(✕) Couldn\'t not import image due to allow_url_fopen() is disabled!' );
115
- }
116
- }
117
-
118
- }
119
-
120
- /**
121
- * Kicking this off by calling 'get_instance()' method
122
- */
123
- CartFlows_Batch_Process::get_instance();
124
-
125
- 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 ADDED
@@ -0,0 +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;
classes/batch-process/class-cartflows-importer-beaver-builder.php ADDED
@@ -0,0 +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;
classes/batch-process/{class-cartflows-batch-process-elementor.php → class-cartflows-importer-elementor-batch.php} RENAMED
@@ -1,64 +1,66 @@
1
- <?php
2
- /**
3
- * Image Background Process
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( class_exists( 'WP_Background_Process' ) ) :
10
-
11
- /**
12
- * Image Background Process
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Batch_Process_Elementor extends WP_Background_Process {
17
-
18
- /**
19
- * Image Process
20
- *
21
- * @var string
22
- */
23
- protected $action = 'cartflows_elementor_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.0.0
34
- *
35
- * @param integer $post_id Post Id.
36
- * @return mixed
37
- */
38
- protected function task( $post_id ) {
39
-
40
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
41
- $obj->import_single_template( $post_id );
42
-
43
- return false;
44
- }
45
-
46
- /**
47
- * Complete
48
- *
49
- * Override if applicable, but ensure that the below actions are
50
- * performed, or, call parent::complete().
51
- *
52
- * @since 1.0.0
53
- */
54
- protected function complete() {
55
-
56
- parent::complete();
57
-
58
- do_action( 'cartflows_import_complete' );
59
-
60
- }
61
-
62
- }
63
-
64
- 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/batch-process/helpers/class-cartflows-importer-image.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Image Importer
4
+ *
5
+ * => How to use?
6
+ *
7
+ * $image = array(
8
+ * 'url' => '<image-url>',
9
+ * 'id' => '<image-id>',
10
+ * );
11
+ *
12
+ * $downloaded_image = CartFlows_Import_Image::get_instance()->import( $image );
13
+ *
14
+ * @package CartFlows
15
+ *
16
+ * @since 1.1.1
17
+ */
18
+
19
+ if ( ! class_exists( 'CartFlows_Import_Image' ) ) :
20
+
21
+ /**
22
+ * CartFlows Importer
23
+ *
24
+ * @since 1.1.1
25
+ */
26
+ class CartFlows_Import_Image {
27
+
28
+ /**
29
+ * Instance
30
+ *
31
+ * @since 1.1.1
32
+ * @var object Class object.
33
+ * @access private
34
+ */
35
+ private static $instance;
36
+
37
+ /**
38
+ * Images IDs
39
+ *
40
+ * @var array The Array of already image IDs.
41
+ * @since 1.1.1
42
+ */
43
+ private $already_imported_ids = array();
44
+
45
+ /**
46
+ * Initiator
47
+ *
48
+ * @since 1.1.1
49
+ * @return object initialized object of class.
50
+ */
51
+ public static function get_instance() {
52
+ if ( ! isset( self::$instance ) ) {
53
+ self::$instance = new self;
54
+ }
55
+ return self::$instance;
56
+ }
57
+
58
+ /**
59
+ * Constructor
60
+ *
61
+ * @since 1.1.1
62
+ */
63
+ public function __construct() {
64
+
65
+ if ( ! function_exists( 'WP_Filesystem' ) ) {
66
+ require_once ABSPATH . 'wp-admin/includes/file.php';
67
+ }
68
+
69
+ WP_Filesystem();
70
+ }
71
+
72
+ /**
73
+ * Process Image Download
74
+ *
75
+ * @since 1.1.1
76
+ * @param array $attachments Attachment array.
77
+ * @return array Attachment array.
78
+ */
79
+ public function process( $attachments ) {
80
+
81
+ $downloaded_images = array();
82
+
83
+ foreach ( $attachments as $key => $attachment ) {
84
+ $downloaded_images[] = $this->import( $attachment );
85
+ }
86
+
87
+ return $downloaded_images;
88
+ }
89
+
90
+ /**
91
+ * Get Hash Image.
92
+ *
93
+ * @since 1.1.1
94
+ * @param string $attachment_url Attachment URL.
95
+ * @return string Hash string.
96
+ */
97
+ private function get_hash_image( $attachment_url ) {
98
+ return sha1( $attachment_url );
99
+ }
100
+
101
+ /**
102
+ * Get Saved Image.
103
+ *
104
+ * @since 1.1.1
105
+ * @param string $attachment Attachment Data.
106
+ * @return string Hash string.
107
+ */
108
+ private function get_saved_image( $attachment ) {
109
+ if ( apply_filters( 'cartflows_image_importer_skip_image', false, $attachment ) ) {
110
+
111
+ CartFlows_Import_Image::log( 'Download (✕) Replace (✕) - ' . $attachment['url'] );
112
+
113
+ return $attachment;
114
+ }
115
+
116
+ global $wpdb;
117
+
118
+ // Already imported? Then return!
119
+ if ( isset( $this->already_imported_ids[ $attachment['id'] ] ) ) {
120
+
121
+ CartFlows_Import_Image::log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
122
+
123
+ return $this->already_imported_ids[ $attachment['id'] ];
124
+ }
125
+
126
+ // 1. Is already imported in Batch Import Process?
127
+ $post_id = $wpdb->get_var(
128
+ $wpdb->prepare(
129
+ 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
130
+ WHERE `meta_key` = \'_cartflows_image_hash\'
131
+ AND `meta_value` = %s
132
+ ;',
133
+ $this->get_hash_image( $attachment['url'] )
134
+ )
135
+ );
136
+
137
+ // 2. Is image already imported though XML?
138
+ if ( empty( $post_id ) ) {
139
+
140
+ // Get file name without extension.
141
+ // To check it exist in attachment.
142
+ $filename = preg_replace( '/\\.[^.\\s]{3,4}$/', '', basename( $attachment['url'] ) );
143
+
144
+ $post_id = $wpdb->get_var(
145
+ $wpdb->prepare(
146
+ 'SELECT `post_id` FROM `' . $wpdb->postmeta . '`
147
+ WHERE `meta_key` = \'_wp_attached_file\'
148
+ AND `meta_value` LIKE %s
149
+ ;',
150
+ '%' . $filename . '%'
151
+ )
152
+ );
153
+
154
+ CartFlows_Import_Image::log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
155
+ }
156
+
157
+ if ( $post_id ) {
158
+ $new_attachment = array(
159
+ 'id' => $post_id,
160
+ 'url' => wp_get_attachment_url( $post_id ),
161
+ );
162
+ $this->already_imported_ids[ $attachment['id'] ] = $new_attachment;
163
+
164
+ return $new_attachment;
165
+ }
166
+
167
+ return false;
168
+ }
169
+
170
+ /**
171
+ * Import Image
172
+ *
173
+ * @since 1.1.1
174
+ * @param array $attachment Attachment array.
175
+ * @return array Attachment array.
176
+ */
177
+ public function import( $attachment ) {
178
+
179
+ $saved_image = $this->get_saved_image( $attachment );
180
+ if ( $saved_image ) {
181
+ return $saved_image;
182
+ }
183
+
184
+ $file_content = wp_remote_retrieve_body( wp_safe_remote_get( $attachment['url'] ) );
185
+
186
+ // Empty file content?
187
+ if ( empty( $file_content ) ) {
188
+
189
+ CartFlows_Import_Image::log( 'Download (✕) Replace (✕) - ' . $attachment['url'] );
190
+ CartFlows_Import_Image::log( 'Error: Failed wp_remote_retrieve_body().' );
191
+
192
+ return $attachment;
193
+ }
194
+
195
+ // Extract the file name and extension from the URL.
196
+ $filename = basename( $attachment['url'] );
197
+
198
+ $upload = wp_upload_bits(
199
+ $filename,
200
+ null,
201
+ $file_content
202
+ );
203
+
204
+ $post = array(
205
+ 'post_title' => $filename,
206
+ 'guid' => $upload['url'],
207
+ );
208
+
209
+ $info = wp_check_filetype( $upload['file'] );
210
+ if ( $info ) {
211
+ $post['post_mime_type'] = $info['type'];
212
+ } else {
213
+ // For now just return the origin attachment.
214
+ return $attachment;
215
+ }
216
+
217
+ $post_id = wp_insert_attachment( $post, $upload['file'] );
218
+ wp_update_attachment_metadata(
219
+ $post_id,
220
+ wp_generate_attachment_metadata( $post_id, $upload['file'] )
221
+ );
222
+ update_post_meta( $post_id, '_cartflows_image_hash', $this->get_hash_image( $attachment['url'] ) );
223
+
224
+ $new_attachment = array(
225
+ 'id' => $post_id,
226
+ 'url' => $upload['url'],
227
+ );
228
+
229
+ CartFlows_Import_Image::log( 'Download (✓) Replace (✓) - ' . $attachment['url'] );
230
+
231
+ $this->already_imported_ids[ $attachment['id'] ] = $new_attachment;
232
+
233
+ return $new_attachment;
234
+ }
235
+
236
+ /**
237
+ * Debugging Log.
238
+ *
239
+ * @since 1.1.1
240
+ * @param mixed $log Log data.
241
+ * @return void
242
+ */
243
+ public static function log( $log ) {
244
+
245
+ if ( ! WP_DEBUG_LOG ) {
246
+ return;
247
+ }
248
+
249
+ if ( is_array( $log ) || is_object( $log ) ) {
250
+ error_log( print_r( $log, true ) );
251
+ } else {
252
+ error_log( $log );
253
+ }
254
+ }
255
+
256
+ }
257
+
258
+ /**
259
+ * Initialize class object with 'get_instance()' method
260
+ */
261
+ CartFlows_Import_Image::get_instance();
262
+
263
+ endif;
classes/class-cartflows-admin.php CHANGED
@@ -1,398 +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 ( CARTFLOWS_FLOW_POST_TYPE !== $current_screen->post_type ) {
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-page-builders">
305
- <ul class="wcf-page-builder-links filter-links">
306
- <li><a href="#" class="current" data-id="elementor"><?php _e( 'Elementor', 'cartflows' ); ?></a></li>
307
- <li><a href="#" data-id="divi"><?php _e( 'Divi', 'cartflows' ); ?></a></li>
308
- <li><a href="#" data-id="bb"><?php _e( 'Beaver Builder', 'cartflows' ); ?></a></li>
309
- </ul>
310
- </div>
311
- <!-- <div id="wcf-remote-flow-filters">
312
- <div id="cartflows-flow-funnel-type"></div>
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-remote-flow-list" class="wcf-remote-list wcf-template-list-wrap"></div>
326
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
327
- </div>
328
- </div>
329
- </div>
330
- </div>
331
-
332
- <?php
333
- }
334
-
335
- /**
336
- * Enqueues the needed CSS/JS for the builder's admin settings page.
337
- *
338
- * @since 1.0.0
339
- */
340
- static public function styles_scripts() {
341
-
342
- // Styles.
343
- wp_enqueue_style( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/css/admin-menu-settings.css', array(), CARTFLOWS_VER );
344
- wp_style_add_data( 'cartflows-admin-settings', 'rtl', 'replace' );
345
-
346
- // Script.
347
- wp_enqueue_script( 'cartflows-admin-settings', CARTFLOWS_URL . 'admin/assets/js/admin-menu-settings.js', array( 'jquery', 'wp-util', 'updates' ), CARTFLOWS_VER );
348
-
349
- $localize = array(
350
- 'ajax_nonce' => wp_create_nonce( 'cartflows-widget-nonce' ),
351
- );
352
-
353
- wp_localize_script( 'cartflows-admin-settings', 'cartflows', apply_filters( 'cartflows_js_localize', $localize ) );
354
- }
355
-
356
- /**
357
- * Save All admin settings here
358
- */
359
- static public function save_settings() {
360
-
361
- // Only admins can save settings.
362
- if ( ! current_user_can( 'manage_options' ) ) {
363
- return;
364
- }
365
-
366
- self::save_common_settings();
367
-
368
- // Let extensions hook into saving.
369
- do_action( 'cartflows_admin_settings_save' );
370
- }
371
-
372
- /**
373
- * Get and return page URL
374
- *
375
- * @param string $menu_slug Menu name.
376
- * @since 1.0.0
377
- * @return string page url
378
- */
379
- static public function get_page_url( $menu_slug ) {
380
-
381
- $parent_page = self::$default_menu_position;
382
-
383
- if ( strpos( $parent_page, '?' ) !== false ) {
384
- $query_var = '&page=' . self::$plugin_slug;
385
- } else {
386
- $query_var = '?page=' . self::$plugin_slug;
387
- }
388
-
389
- $parent_page_url = admin_url( $parent_page . $query_var );
390
-
391
- $url = $parent_page_url . '&action=' . $menu_slug;
392
-
393
- return esc_url( $url );
394
- }
395
-
396
- }
397
-
398
- 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-compatibility.php CHANGED
@@ -1,224 +1,331 @@
1
- <?php
2
- /**
3
- * Page builder compatibility
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- if ( ! class_exists( 'Cartflows_Compatibility' ) ) {
9
-
10
- /**
11
- * Class for page builder compatibility
12
- */
13
- class Cartflows_Compatibility {
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
- $this->load_files();
38
-
39
- // Override post meta.
40
- add_action( 'wp', array( $this, 'override_meta' ), 0 );
41
- }
42
-
43
- /**
44
- * Load page builder compatibility files
45
- */
46
- public function load_files() {
47
- if ( class_exists( '\Elementor\Plugin' ) ) {
48
- require_once CARTFLOWS_DIR . 'classes/class-cartflows-elementor-compatibility.php';
49
- }
50
- }
51
-
52
- /**
53
- * Check if elementor preview mode is on.
54
- */
55
- public function is_elementor_preview_mode() {
56
-
57
- if ( class_exists( '\Elementor\Plugin' ) ) {
58
-
59
- if ( \Elementor\Plugin::$instance->preview->is_preview_mode() ) {
60
- return true;
61
- }
62
- }
63
-
64
- return false;
65
- }
66
-
67
- /**
68
- * Check if it is beaver builder preview mode
69
- */
70
- public function is_bb_preview_mode() {
71
-
72
- if ( class_exists( 'FLBuilderModel' ) ) {
73
- if ( FLBuilderModel::is_builder_active() ) {
74
- return true;
75
- } else {
76
- return false;
77
- }
78
- }
79
-
80
- return false;
81
- }
82
-
83
- /**
84
- * Check for page builder preview mode.
85
- */
86
- public function is_page_builder_preview() {
87
-
88
- if ( $this->is_elementor_preview_mode() || $this->is_bb_preview_mode() ) {
89
- return true;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Check if divi builder enabled for post id.
97
- *
98
- * @param int $post_id post id.
99
- */
100
- public function is_divi_builder_enabled( $post_id ) {
101
-
102
- if ( function_exists( 'et_pb_is_pagebuilder_used' ) && et_pb_is_pagebuilder_used( $post_id ) ) {
103
- return true;
104
- }
105
-
106
- return false;
107
- }
108
-
109
- /**
110
- * Check if divi builder enabled for post id.
111
- */
112
- function is_divi_enabled() {
113
- $theme = wp_get_theme();
114
-
115
- if ( 'Divi' == $theme->name || 'Divi' == $theme->parent_theme ) {
116
- return true;
117
- }
118
-
119
- return false;
120
- }
121
-
122
- /**
123
- * Check for thrive architect edit page.
124
- *
125
- * @param int $post_id post id.
126
- */
127
- public function is_thrive_edit_page( $post_id ) {
128
-
129
- if ( true === $this->is_thrive_builder_page( $post_id ) ) {
130
- return true;
131
- } else {
132
- return false;
133
- }
134
- }
135
-
136
- /**
137
- * Check if the page being rendered is the main ID on the editor page.
138
- *
139
- * @since 1.0.0
140
- * @param String $post_id Post ID which is to be rendered.
141
- * @return boolean True if current if is being rendered is not being edited.
142
- */
143
- private function is_thrive_builder_page( $post_id ) {
144
- $tve = ( isset( $_GET['tve'] ) && 'true' == $_GET['tve'] ) ? true : false;
145
- $post = isset( $_GET['post'] ) ? sanitize_text_field( $_GET['post'] ) : false;
146
-
147
- return ( true == $tve && $post_id !== $post );
148
- }
149
-
150
- /**
151
- * Overwrite meta for page
152
- */
153
- public function override_meta() {
154
-
155
- // don't override meta for `elementor_library` post type.
156
- if ( 'elementor_library' == get_post_type() ) {
157
- return;
158
- }
159
-
160
- if ( ! is_singular() ) {
161
- return;
162
- }
163
-
164
- global $post;
165
- $post_id = $post->ID;
166
- $post_type = get_post_type();
167
-
168
- if ( 'cartflows_step' == $post_type && ( $this->is_elementor_preview_mode()
169
- || $this->is_bb_preview_mode() || $this->is_thrive_edit_page( $post_id )
170
- || $this->is_divi_builder_enabled( $post_id ) ) ) {
171
-
172
- if ( '' == $post->post_content ) {
173
-
174
- $this->overwrite_template( $post_id );
175
- }
176
- }
177
- }
178
-
179
- /**
180
- * Assign cartflow canvas template to page.
181
- *
182
- * @param int $post_id post ID.
183
- */
184
- public function overwrite_template( $post_id ) {
185
-
186
- $template = 'cartflows-canvas';
187
- $key = '_wp_page_template';
188
-
189
- $record_exists = get_post_meta( $post_id, $key, true );
190
-
191
- if ( 'cartflows-canvas' == $record_exists ) {
192
- return;
193
- }
194
-
195
- // As elementor doesn't allow update post meta using update_post_meta, run wpdb query to update post meta.
196
- if ( class_exists( '\Elementor\Plugin' ) ) {
197
-
198
- global $wpdb;
199
-
200
- if ( '' == $record_exists || ! $record_exists ) {
201
-
202
- $wpdb->insert(
203
- $wpdb->prefix . 'postmeta',
204
- array(
205
- 'post_id' => $post_id,
206
- 'meta_key' => $key,
207
- 'meta_value' => $template, // ... and so on
208
- )
209
- );
210
- } else {
211
-
212
- $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND post_id = %s;", $template, $key, $post_id ) );
213
- }
214
- } else {
215
-
216
- update_post_meta( $post_id, $key, $template );
217
- }
218
- }
219
-
220
- }
221
- }
222
-
223
- Cartflows_Compatibility::get_instance();
224
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Page builder compatibility
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ if ( ! class_exists( 'Cartflows_Compatibility' ) ) {
9
+
10
+ /**
11
+ * Class for page builder compatibility
12
+ */
13
+ class Cartflows_Compatibility {
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
+ $this->load_files();
38
+
39
+ // Override post meta.
40
+ add_action( 'wp', array( $this, 'override_meta' ), 0 );
41
+
42
+ add_action( 'wp_enqueue_scripts', array( $this, 'load_fontawesome' ), 10000 );
43
+ }
44
+
45
+ /**
46
+ * Load page builder compatibility files
47
+ */
48
+ public function load_files() {
49
+ if ( class_exists( '\Elementor\Plugin' ) ) {
50
+ require_once CARTFLOWS_DIR . 'classes/class-cartflows-elementor-compatibility.php';
51
+ }
52
+
53
+ if ( $this->is_divi_enabled() ) {
54
+ require_once CARTFLOWS_DIR . 'classes/class-cartflows-divi-compatibility.php';
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Check if elementor preview mode is on.
60
+ */
61
+ public function is_elementor_preview_mode() {
62
+
63
+ if ( class_exists( '\Elementor\Plugin' ) ) {
64
+
65
+ if ( \Elementor\Plugin::$instance->preview->is_preview_mode() ) {
66
+ return true;
67
+ }
68
+ }
69
+
70
+ return false;
71
+ }
72
+
73
+ /**
74
+ * Get Current Theme.
75
+ */
76
+ public function get_current_theme() {
77
+
78
+ $theme_name = '';
79
+ $theme = wp_get_theme();
80
+
81
+ if ( isset( $theme->parent_theme ) && '' != $theme->parent_theme || null != $theme->parent_theme ) {
82
+ $theme_name = $theme->parent_theme;
83
+ } else {
84
+ $theme_name = $theme->name;
85
+ }
86
+
87
+ return $theme_name;
88
+ }
89
+
90
+ /**
91
+ * Check if it is beaver builder preview mode
92
+ */
93
+ public function is_bb_preview_mode() {
94
+
95
+ if ( class_exists( 'FLBuilderModel' ) ) {
96
+ if ( FLBuilderModel::is_builder_active() ) {
97
+ return true;
98
+ } else {
99
+ return false;
100
+ }
101
+ }
102
+
103
+ return false;
104
+ }
105
+
106
+ /**
107
+ * Check for page builder preview mode.
108
+ */
109
+ public function is_page_builder_preview() {
110
+
111
+ if ( $this->is_elementor_preview_mode() || $this->is_bb_preview_mode() ) {
112
+ return true;
113
+ }
114
+
115
+ return false;
116
+ }
117
+
118
+ /**
119
+ * Check if divi builder enabled for post id.
120
+ *
121
+ * @param int $post_id post id.
122
+ */
123
+ public function is_divi_builder_enabled( $post_id ) {
124
+
125
+ if ( function_exists( 'et_pb_is_pagebuilder_used' ) && et_pb_is_pagebuilder_used( $post_id ) ) {
126
+ return true;
127
+ }
128
+
129
+ return false;
130
+ }
131
+
132
+ /**
133
+ * Check if compatibility theme enabled.
134
+ */
135
+ function is_compatibility_theme_enabled() {
136
+
137
+ $theme = wp_get_theme();
138
+
139
+ if ( $this->is_divi_enabled( $theme ) || $this->is_flatsome_enabled( $theme ) || $this->is_oceanwp_enabled( $theme ) ) {
140
+
141
+ return true;
142
+ }
143
+
144
+ return false;
145
+ }
146
+
147
+ /**
148
+ * Check if divi builder enabled for post id.
149
+ *
150
+ * @param object $theme theme data.
151
+ * @return boolean
152
+ */
153
+ function is_divi_enabled( $theme = false ) {
154
+
155
+ if ( ! $theme ) {
156
+ $theme = wp_get_theme();
157
+ }
158
+
159
+ if ( 'Divi' == $theme->name || 'Divi' == $theme->parent_theme ) {
160
+ return true;
161
+ }
162
+
163
+ return false;
164
+ }
165
+
166
+ /**
167
+ * Check if Flatsome enabled for post id.
168
+ *
169
+ * @param object $theme theme data.
170
+ * @return boolean
171
+ */
172
+ function is_flatsome_enabled( $theme = false ) {
173
+
174
+ if ( ! $theme ) {
175
+ $theme = wp_get_theme();
176
+ }
177
+
178
+ if ( 'Flatsome' == $theme->name || 'Flatsome' == $theme->parent_theme ) {
179
+ return true;
180
+ }
181
+
182
+ return false;
183
+ }
184
+
185
+ /**
186
+ * Check if OceanWp enabled for post id.
187
+ *
188
+ * @param object $theme theme data.
189
+ * @return boolean
190
+ */
191
+ function is_oceanwp_enabled( $theme = false ) {
192
+
193
+ if ( ! $theme ) {
194
+ $theme = wp_get_theme();
195
+ }
196
+
197
+ if ( 'OceanWP' == $theme->name || 'OceanWP' == $theme->parent_theme ) {
198
+ return true;
199
+ }
200
+
201
+ return false;
202
+ }
203
+
204
+ /**
205
+ * Check for thrive architect edit page.
206
+ *
207
+ * @param int $post_id post id.
208
+ */
209
+ public function is_thrive_edit_page( $post_id ) {
210
+
211
+ if ( true === $this->is_thrive_builder_page( $post_id ) ) {
212
+ return true;
213
+ } else {
214
+ return false;
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Check if the page being rendered is the main ID on the editor page.
220
+ *
221
+ * @since 1.0.0
222
+ * @param String $post_id Post ID which is to be rendered.
223
+ * @return boolean True if current if is being rendered is not being edited.
224
+ */
225
+ private function is_thrive_builder_page( $post_id ) {
226
+ $tve = ( isset( $_GET['tve'] ) && 'true' == $_GET['tve'] ) ? true : false;
227
+ $post = isset( $_GET['post'] ) ? sanitize_text_field( $_GET['post'] ) : false;
228
+
229
+ return ( true == $tve && $post_id !== $post );
230
+ }
231
+
232
+ /**
233
+ * Overwrite meta for page
234
+ */
235
+ public function override_meta() {
236
+
237
+ // don't override meta for `elementor_library` post type.
238
+ if ( 'elementor_library' == get_post_type() ) {
239
+ return;
240
+ }
241
+
242
+ if ( ! is_singular() ) {
243
+ return;
244
+ }
245
+
246
+ global $post;
247
+ $post_id = $post->ID;
248
+ $post_type = get_post_type();
249
+
250
+ if ( 'cartflows_step' == $post_type && ( $this->is_elementor_preview_mode()
251
+ || $this->is_bb_preview_mode() || $this->is_thrive_edit_page( $post_id )
252
+ || $this->is_divi_builder_enabled( $post_id ) ) ) {
253
+
254
+ if ( '' == $post->post_content ) {
255
+
256
+ $this->overwrite_template( $post_id );
257
+ }
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Assign cartflow canvas template to page.
263
+ *
264
+ * @param int $post_id post ID.
265
+ */
266
+ public function overwrite_template( $post_id ) {
267
+
268
+ $template = 'cartflows-canvas';
269
+ $key = '_wp_page_template';
270
+
271
+ $record_exists = get_post_meta( $post_id, $key, true );
272
+
273
+ if ( 'cartflows-canvas' == $record_exists ) {
274
+ return;
275
+ }
276
+
277
+ // As elementor doesn't allow update post meta using update_post_meta, run wpdb query to update post meta.
278
+ if ( class_exists( '\Elementor\Plugin' ) ) {
279
+
280
+ global $wpdb;
281
+
282
+ if ( '' == $record_exists || ! $record_exists ) {
283
+
284
+ $wpdb->insert(
285
+ $wpdb->prefix . 'postmeta',
286
+ array(
287
+ 'post_id' => $post_id,
288
+ 'meta_key' => $key,
289
+ 'meta_value' => $template, // ... and so on
290
+ )
291
+ );
292
+ } else {
293
+
294
+ $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND post_id = %s;", $template, $key, $post_id ) );
295
+ }
296
+ } else {
297
+
298
+ update_post_meta( $post_id, $key, $template );
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Load font awesome style from oceanwp on checkout page.
304
+ */
305
+ public function load_fontawesome() {
306
+
307
+ $theme = get_template();
308
+
309
+ if ( 'oceanwp' == strtolower( $theme ) && wcf()->utils->is_step_post_type() ) {
310
+
311
+ $load_fa = apply_filters( 'cartflows_maybe_load_font_awesome', true );
312
+
313
+ if ( $load_fa ) {
314
+
315
+ wp_enqueue_style( 'font-awesome', OCEANWP_CSS_DIR_URI . 'third/font-awesome.min.css', false );
316
+ }
317
+
318
+ $custom_css = '
319
+ #oceanwp-cart-sidebar-wrap,
320
+ #owp-qv-wrap{
321
+ display: none;
322
+ }';
323
+
324
+ wp_add_inline_style( 'wcf-frontend-global', $custom_css );
325
+ }
326
+ }
327
+ }
328
+ }
329
+
330
+ Cartflows_Compatibility::get_instance();
331
+
classes/class-cartflows-divi-compatibility.php ADDED
@@ -0,0 +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();
classes/class-cartflows-flow-frontend.php CHANGED
@@ -1,199 +1,199 @@
1
- <?php
2
- /**
3
- * Frontend & Markup
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- /**
9
- * Flow Markup
10
- *
11
- * @since 1.0.0
12
- */
13
- class Cartflows_Flow_Frontend {
14
-
15
-
16
- /**
17
- * Member Variable
18
- *
19
- * @var object instance
20
- */
21
- private static $instance;
22
-
23
- /**
24
- * Initiator
25
- */
26
- public static function get_instance() {
27
- if ( ! isset( self::$instance ) ) {
28
- self::$instance = new self;
29
- }
30
- return self::$instance;
31
- }
32
-
33
- /**
34
- * Constructor
35
- */
36
- public function __construct() {
37
-
38
- /* Analytics */
39
- add_action( 'wp_footer', array( $this, 'footer_markup' ) );
40
- }
41
-
42
- /**
43
- * Footer markup
44
- */
45
- function footer_markup() {
46
-
47
- if ( wcf()->utils->is_step_post_type() ) {
48
- // @codingStandardsIgnoreStart
49
- ?>
50
- <?php if( $this->is_flow_testmode() ) { ?>
51
- <div class="wcf-preview-mode">
52
- <span><?php _e( 'NOTE: Test mode is active — which may display any random products for the sake of preview.', 'cartflows' ); ?></span>
53
- </div>
54
- <?php } ?>
55
- <?php
56
- // @codingStandardsIgnoreEnd
57
- }
58
- }
59
-
60
- /**
61
- * Check if flow test mode is enable.
62
- *
63
- * @since 1.0.0
64
- * @param int $flow_id flow ID.
65
- *
66
- * @return boolean
67
- */
68
- function is_flow_testmode( $flow_id = '' ) {
69
-
70
- if ( ! $flow_id ) {
71
- $flow_id = wcf()->utils->get_flow_id();
72
- }
73
-
74
- $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
75
-
76
- if ( 'no' === $test_mode ) {
77
- return false;
78
- }
79
-
80
- return true;
81
- }
82
-
83
- /**
84
- * Get steps data.
85
- *
86
- * @since 1.0.0
87
- * @param int $flow_id flow ID.
88
- *
89
- * @return array
90
- */
91
- function get_steps( $flow_id ) {
92
-
93
- $steps = get_post_meta( $flow_id, 'wcf-steps', true );
94
-
95
- if ( ! is_array( $steps ) ) {
96
-
97
- $steps = array();
98
- }
99
-
100
- return $steps;
101
- }
102
-
103
- /**
104
- * Check thank you page exists.
105
- *
106
- * @since 1.0.0
107
- * @param array $order order data.
108
- *
109
- * @return bool
110
- */
111
- function is_thankyou_page_exists( $order ) {
112
-
113
- $thankyou_step_exist = false;
114
-
115
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
116
-
117
- if ( $flow_id ) {
118
-
119
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
120
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
121
-
122
- if ( is_array( $flow_steps ) ) {
123
-
124
- $current_step_found = false;
125
-
126
- foreach ( $flow_steps as $index => $data ) {
127
-
128
- if ( $current_step_found ) {
129
-
130
- if ( 'thankyou' === $data['type'] ) {
131
-
132
- $thankyou_step_exist = true;
133
- break;
134
- }
135
- } else {
136
-
137
- if ( intval( $data['id'] ) === $step_id ) {
138
-
139
- $current_step_found = true;
140
- }
141
- }
142
- }
143
- }
144
- }
145
-
146
- return $thankyou_step_exist;
147
- }
148
-
149
- /**
150
- * Check thank you page exists.
151
- *
152
- * @since 1.0.0
153
- * @param array $order order data.
154
- *
155
- * @return bool
156
- */
157
- function get_thankyou_page_id( $order ) {
158
-
159
- $thankyou_step_id = false;
160
-
161
- $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
162
-
163
- if ( $flow_id ) {
164
-
165
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
166
- $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
167
-
168
- if ( is_array( $flow_steps ) ) {
169
-
170
- $current_step_found = false;
171
-
172
- foreach ( $flow_steps as $index => $data ) {
173
-
174
- if ( $current_step_found ) {
175
-
176
- if ( 'thankyou' === $data['type'] ) {
177
-
178
- $thankyou_step_id = intval( $data['id'] );
179
- break;
180
- }
181
- } else {
182
-
183
- if ( intval( $data['id'] ) === $step_id ) {
184
-
185
- $current_step_found = true;
186
- }
187
- }
188
- }
189
- }
190
- }
191
-
192
- return $thankyou_step_id;
193
- }
194
- }
195
-
196
- /**
197
- * Kicking this off by calling 'get_instance()' method
198
- */
199
- Cartflows_Flow_Frontend::get_instance();
1
+ <?php
2
+ /**
3
+ * Frontend & Markup
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ /**
9
+ * Flow Markup
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ class Cartflows_Flow_Frontend {
14
+
15
+
16
+ /**
17
+ * Member Variable
18
+ *
19
+ * @var object instance
20
+ */
21
+ private static $instance;
22
+
23
+ /**
24
+ * Initiator
25
+ */
26
+ public static function get_instance() {
27
+ if ( ! isset( self::$instance ) ) {
28
+ self::$instance = new self;
29
+ }
30
+ return self::$instance;
31
+ }
32
+
33
+ /**
34
+ * Constructor
35
+ */
36
+ public function __construct() {
37
+
38
+ /* Analytics */
39
+ add_action( 'wp_footer', array( $this, 'footer_markup' ) );
40
+ }
41
+
42
+ /**
43
+ * Footer markup
44
+ */
45
+ function footer_markup() {
46
+
47
+ if ( wcf()->utils->is_step_post_type() ) {
48
+ // @codingStandardsIgnoreStart
49
+ ?>
50
+ <?php if( $this->is_flow_testmode() ) { ?>
51
+ <div class="wcf-preview-mode">
52
+ <span><?php _e( 'Test mode is active — which displays random products for previewing. It can be deactivated from the flow settings in the admin dashboard.', 'cartflows' ); ?></span>
53
+ </div>
54
+ <?php } ?>
55
+ <?php
56
+ // @codingStandardsIgnoreEnd
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Check if flow test mode is enable.
62
+ *
63
+ * @since 1.0.0
64
+ * @param int $flow_id flow ID.
65
+ *
66
+ * @return boolean
67
+ */
68
+ function is_flow_testmode( $flow_id = '' ) {
69
+
70
+ if ( ! $flow_id ) {
71
+ $flow_id = wcf()->utils->get_flow_id();
72
+ }
73
+
74
+ $test_mode = wcf()->options->get_flow_meta_value( $flow_id, 'wcf-testing' );
75
+
76
+ if ( 'no' === $test_mode ) {
77
+ return false;
78
+ }
79
+
80
+ return true;
81
+ }
82
+
83
+ /**
84
+ * Get steps data.
85
+ *
86
+ * @since 1.0.0
87
+ * @param int $flow_id flow ID.
88
+ *
89
+ * @return array
90
+ */
91
+ function get_steps( $flow_id ) {
92
+
93
+ $steps = get_post_meta( $flow_id, 'wcf-steps', true );
94
+
95
+ if ( ! is_array( $steps ) ) {
96
+
97
+ $steps = array();
98
+ }
99
+
100
+ return $steps;
101
+ }
102
+
103
+ /**
104
+ * Check thank you page exists.
105
+ *
106
+ * @since 1.0.0
107
+ * @param array $order order data.
108
+ *
109
+ * @return bool
110
+ */
111
+ function is_thankyou_page_exists( $order ) {
112
+
113
+ $thankyou_step_exist = false;
114
+
115
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
116
+
117
+ if ( $flow_id ) {
118
+
119
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
120
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
121
+
122
+ if ( is_array( $flow_steps ) ) {
123
+
124
+ $current_step_found = false;
125
+
126
+ foreach ( $flow_steps as $index => $data ) {
127
+
128
+ if ( $current_step_found ) {
129
+
130
+ if ( 'thankyou' === $data['type'] ) {
131
+
132
+ $thankyou_step_exist = true;
133
+ break;
134
+ }
135
+ } else {
136
+
137
+ if ( intval( $data['id'] ) === $step_id ) {
138
+
139
+ $current_step_found = true;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ return $thankyou_step_exist;
147
+ }
148
+
149
+ /**
150
+ * Check thank you page exists.
151
+ *
152
+ * @since 1.0.0
153
+ * @param array $order order data.
154
+ *
155
+ * @return bool
156
+ */
157
+ function get_thankyou_page_id( $order ) {
158
+
159
+ $thankyou_step_id = false;
160
+
161
+ $flow_id = wcf()->utils->get_flow_id_from_order( $order->get_id() );
162
+
163
+ if ( $flow_id ) {
164
+
165
+ $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
166
+ $step_id = wcf()->utils->get_checkout_id_from_order( $order->get_id() );
167
+
168
+ if ( is_array( $flow_steps ) ) {
169
+
170
+ $current_step_found = false;
171
+
172
+ foreach ( $flow_steps as $index => $data ) {
173
+
174
+ if ( $current_step_found ) {
175
+
176
+ if ( 'thankyou' === $data['type'] ) {
177
+
178
+ $thankyou_step_id = intval( $data['id'] );
179
+ break;
180
+ }
181
+ } else {
182
+
183
+ if ( intval( $data['id'] ) === $step_id ) {
184
+
185
+ $current_step_found = true;
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ return $thankyou_step_id;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Kicking this off by calling 'get_instance()' method
198
+ */
199
+ Cartflows_Flow_Frontend::get_instance();
classes/class-cartflows-frontend.php CHANGED
@@ -1,322 +1,328 @@
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_divi_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
- }
241
-
242
- /**
243
- * Add noindex, nofollow.
244
- *
245
- * @since 1.0.0
246
- */
247
- function noindex_flow() {
248
-
249
- $common = Cartflows_Helper::get_common_settings();
250
-
251
- if ( 'enable' === $common['disallow_indexing'] ) {
252
- echo '<meta name="robots" content="noindex,nofollow">';
253
- }
254
- }
255
-
256
- /**
257
- * WP Actions.
258
- *
259
- * @since 1.0.0
260
- */
261
- function wp_actions() {
262
-
263
- if ( wcf()->utils->is_step_post_type() ) {
264
-
265
- /* CSS Compatibility for All theme */
266
- add_filter( 'woocommerce_enqueue_styles', array( $this, 'woo_default_css' ), 9999 );
267
-
268
- add_action( 'wp_enqueue_scripts', array( $this, 'remove_theme_styles' ), 9999 );
269
-
270
- add_action( 'wp_enqueue_scripts', array( $this, 'global_flow_scripts' ), 20 );
271
- }
272
-
273
- }
274
-
275
- /**
276
- * Global flow scripts.
277
- *
278
- * @since 1.0.0
279
- */
280
- function global_flow_scripts() {
281
-
282
- global $post;
283
-
284
- $flow = get_post_meta( $post->ID, 'wcf-flow-id', true );
285
- $current_step = $post->ID;
286
- $next_step_link = '';
287
- $compatibility = Cartflows_Compatibility::get_instance();
288
-
289
- if ( _is_wcf_landing_type() ) {
290
-
291
- $next_step_id = wcf()->utils->get_next_step_id( $flow, $current_step );
292
- $next_step_link = get_permalink( $next_step_id );
293
- }
294
-
295
- $localize = array(
296
- 'ajax_url' => admin_url( 'admin-ajax.php' ),
297
- 'is_pb_preview' => $compatibility->is_page_builder_preview(),
298
- 'current_flow' => $flow,
299
- 'current_step' => $current_step,
300
- 'next_step' => $next_step_link,
301
- );
302
-
303
- wp_localize_script( 'jquery', 'cartflows', apply_filters( 'global_cartflows_js_localize', $localize ) );
304
-
305
- wp_enqueue_style( 'wcf-frontend-global', CARTFLOWS_URL . 'assets/css/frontend.css', array(), CARTFLOWS_VER );
306
- wp_style_add_data( 'wcf-frontend-global', 'rtl', 'replace' );
307
-
308
- wp_enqueue_script(
309
- 'wcf-frontend-global',
310
- CARTFLOWS_URL . 'assets/js/frontend.js',
311
- array( 'jquery' ),
312
- CARTFLOWS_VER,
313
- true
314
- );
315
- }
316
- }
317
-
318
- /**
319
- * Prepare if class 'Cartflows_Frontend' exist.
320
- * Kicking this off by calling 'get_instance()' method
321
- */
322
- 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
+ }
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();
classes/class-cartflows-helper.php CHANGED
@@ -1,273 +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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,1038 +1,1134 @@
1
- <?php
2
- /**
3
- * CartFlows Admin
4
- *
5
- * @package CartFlows
6
- * @since 1.0.0
7
- */
8
-
9
- if ( ! class_exists( 'CartFlows_Importer' ) ) :
10
-
11
- /**
12
- * CartFlows Import
13
- *
14
- * @since 1.0.0
15
- */
16
- class CartFlows_Importer {
17
-
18
- /**
19
- * Instance
20
- *
21
- * @since 1.0.0
22
- * @access private
23
- * @var object Class object.
24
- */
25
- private static $instance;
26
-
27
- /**
28
- * Initiator
29
- *
30
- * @since 1.0.0
31
- * @return object initialized object of class.
32
- */
33
- public static function get_instance() {
34
- if ( ! isset( self::$instance ) ) {
35
- self::$instance = new self;
36
- }
37
-
38
- return self::$instance;
39
- }
40
-
41
- /**
42
- * Constructor
43
- *
44
- * @since 1.0.0
45
- */
46
- public function __construct() {
47
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
48
- add_action( 'wp_ajax_cartflows_load_steps', array( $this, 'load_templates' ) );
49
- add_action( 'wp_ajax_cartflows_step_import', array( $this, 'import_step' ) );
50
- add_action( 'wp_ajax_cartflows_create_flow', array( $this, 'create_flow' ) );
51
- add_action( 'wp_ajax_cartflows_default_flow', array( $this, 'create_default_flow' ) );
52
- add_action( 'wp_ajax_cartflows_step_create_blank', array( $this, 'step_create_blank' ) );
53
- add_action( 'wp_ajax_cartflows_import_flow_step', array( $this, 'import_flow' ) );
54
- add_action( 'admin_footer', array( $this, 'js_templates' ) );
55
- add_action( 'cartflows_import_complete', array( $this, 'clear_cache' ) );
56
-
57
- add_filter( 'cartflows_admin_js_localize', array( $this, 'localize_vars' ) );
58
-
59
- add_action( 'wp_ajax_cartflows_activate_plugin', array( $this, 'activate_plugin' ) );
60
- }
61
-
62
- /**
63
- * Clear Cache.
64
- *
65
- * @since 1.0.0
66
- */
67
- public function clear_cache() {
68
- // Clear 'Elementor' file cache.
69
- if ( class_exists( '\Elementor\Plugin' ) ) {
70
- Elementor\Plugin::$instance->files_manager->clear_cache();
71
- }
72
- }
73
-
74
- /**
75
- * JS Templates
76
- *
77
- * @since 1.0.0
78
- *
79
- * @return void
80
- */
81
- function js_templates() {
82
-
83
- // Loading Templates.
84
- ?>
85
- <script type="text/template" id="tmpl-cartflows-step-loading">
86
- <div class="template-message-block cartflows-step-loading">
87
- <h2>
88
- <span class="spinner"></span>
89
- <?php _e( 'Loading Steps', 'cartflows' ); ?>
90
- </h2>
91
- <p class="description"><?php _e( 'Getting steps from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
92
- </div>
93
- </script>
94
-
95
- <?php
96
- // Search Templates.
97
- ?>
98
- <script type="text/template" id="tmpl-cartflows-searching-templates">
99
- <div class="template-message-block cartflows-searching-templates">
100
- <h2>
101
- <span class="spinner"></span>
102
- <?php _e( 'Searching Template..', 'cartflows' ); ?>
103
- </h2>
104
- <p class="description"><?php _e( 'Getting templates from the cloud. Please wait for the moment.', 'cartflows' ); ?></p>
105
- </div>
106
- </script>
107
-
108
- <?php
109
- // CartFlows Importing Template.
110
- ?>
111
- <script type="text/template" id="tmpl-cartflows-step-importing">
112
- <div class="template-message-block cartflows-step-importing">
113
- <h2><span class="spinner"></span> <?php _e( 'Importing..', 'cartflows' ); ?></h2>
114
- </div>
115
- </script>
116
-
117
- <?php
118
- // CartFlows Imported.
119
- ?>
120
- <script type="text/template" id="tmpl-cartflows-step-imported">
121
- <div class="template-message-block cartflows-step-imported">
122
- <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
123
- <p class="description"><?php _e( 'Thanks for patience', 'cartflows' ); ?> <span class="dashicons dashicons-smiley"></span></p></div>
124
- </script>
125
-
126
- <?php
127
- // No templates.
128
- ?>
129
- <script type="text/template" id="tmpl-cartflows-no-steps">
130
- <div class="cartflows-no-steps">
131
- <div class="template-message-block">
132
- <h2><?php _e( 'Steps not found!', 'cartflows' ); ?></h2>
133
- <p class="description"><?php _e( 'We\'ll provide the ready made steps to import.', 'cartflows' ); ?></p>
134
- </div>
135
- </div>
136
- </script>
137
-
138
- <?php
139
- // No templates.
140
- ?>
141
- <script type="text/template" id="tmpl-cartflows-no-flows">
142
- <div class="cartflows-no-flows">
143
- <div class="template-message-block">
144
- <h2><?php _e( 'Flows not found!', 'cartflows' ); ?></h2>
145
- <p class="description"><?php _e( 'We\'ll provide the ready made flows to import.', 'cartflows' ); ?></p>
146
- </div>
147
- </div>
148
- </script>
149
-
150
- <?php
151
- // Error handling.
152
- ?>
153
- <script type="text/template" id="tmpl-templator-error">
154
- <div class="notice notice-error"><p>{{ data }}</p></div>
155
- </script>
156
-
157
- <?php
158
- // Redirect to Elementor.
159
- ?>
160
- <script type="text/template" id="tmpl-templator-redirect-to-elementor">
161
- <div class="template-message-block templator-redirect-to-elementor">
162
- <h2><span class="dashicons dashicons-yes"></span> <?php _e( 'Imported', 'cartflows' ); ?></h2>
163
- <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>
164
- </script>
165
-
166
- <?php
167
- /**
168
- * Responsive Buttons
169
- */
170
- ?>
171
- <script type="text/template" id="tmpl-cartflows-responsive-view">
172
- <span class="responsive-view">
173
- <span class="actions">
174
- <a class="desktop" href="#"><span data-view="desktop " class="active dashicons dashicons-desktop"></span></a>
175
- <a class="tablet" href="#"><span data-view="tablet" class="dashicons dashicons-tablet"></span></a>
176
- <a class="mobile" href="#"><span data-view="mobile" class="dashicons dashicons-smartphone"></span></a>
177
- </span>
178
- </span>
179
- </script>
180
-
181
- <?php
182
- /** Blank flow */
183
- ?>
184
- <script type="text/template" id="tmpl-cartflows-create-blank-flow">
185
- <div class="inner">
186
- <div class="template">
187
- <span class="thumbnail site-preview">
188
- <div class="template-screenshot">
189
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
190
- </div>
191
- </span>
192
- <div class="template-id-container">
193
- <h3 class="template-name"> <?php _e( 'Canvas', 'cartflows' ); ?> </h3>
194
- <div class="template-actions">
195
- <a href="#" class="button button-primary cartflows-flow-import-blank"><?php _e( 'Create Flow', 'cartflows' ); ?></a>
196
- </div>
197
- </div>
198
- </div>
199
- </div>
200
- </script>
201
-
202
- <?php
203
- // Templates data.
204
- $installed_plugins = get_plugins();
205
-
206
- $import_btn_title = __( 'Import', 'cartflows' );
207
-
208
- $required_plugins = array(
209
- 'elementor' => array(
210
- 'active' => is_plugin_active( 'elementor/elementor.php' ) ? 'yes' : 'no',
211
- 'install' => isset( $installed_plugins['elementor/elementor.php'] ) ? 'yes' : 'no',
212
- ),
213
- );
214
-
215
- if ( 'yes' == $required_plugins['elementor']['install'] && 'no' == $required_plugins['elementor']['active'] ) {
216
- $import_btn_title = __( 'Activate Elementor & Import', 'cartflows' );
217
- } elseif ( 'no' == $required_plugins['elementor']['install'] ) {
218
- $import_btn_title = __( 'Install Elementor & Import', 'cartflows' );
219
- }
220
-
221
- ?>
222
- <script type="text/template" id="tmpl-cartflows-flows-list">
223
-
224
- <# if ( data.items.length ) { #>
225
- <# for ( key in data.items ) { #>
226
- <#
227
- var flow_steps = [];
228
- if( data.items[ key ].flow_steps ) {
229
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
230
- return value['id'];
231
- });
232
- }
233
- #>
234
- <div class="inner">
235
- <div class="template">
236
- <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 }}">
237
- <div class="template-screenshot">
238
- <# if( data.items[ key ].featured_image_url ) { #>
239
- <img src="{{ data.items[ key ].featured_image_url }}" />
240
- <# } else { #>
241
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
242
- <# } #>
243
- </div>
244
- <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>
245
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
246
- <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
247
- <# } #>
248
- </span>
249
- <div class="template-id-container">
250
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
251
- <div class="template-actions">
252
-
253
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
254
- <a data-flow-steps="{{ flow_steps }}" data-required="<?php echo htmlspecialchars( json_encode( $required_plugins ), ENT_QUOTES, 'UTF-8' ); ?>" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}"><?php echo $import_btn_title; ?></a>
255
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
256
- <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>
257
- <# } else { #>
258
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
259
- <# } #>
260
- </div>
261
- </div>
262
- </div>
263
- </div>
264
- <# } #>
265
- <# } #>
266
- </script>
267
-
268
- <?php
269
- // Empty Step.
270
- ?>
271
- <script type="text/template" id="tmpl-cartflows-create-blank-step">
272
- <div class="inner">
273
- <div class="template">
274
- <span class="thumbnail site-preview cartflows-flow-preview">
275
- <div class="template-screenshot">
276
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/start-scratch.jpg" />
277
- </div>
278
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
279
- </span>
280
- <div class="template-id-container">
281
- <h3 class="template-name"> Blank </h3>
282
- <div class="template-actions">
283
- <a href="#" class="button button-primary cartflows-step-import-blank"><?php _e( 'Create', 'cartflows' ); ?></a>
284
- </div>
285
- </div>
286
- </div>
287
- </div>
288
- </script>
289
-
290
- <?php
291
- // Templates data.
292
- ?>
293
- <script type="text/template" id="tmpl-cartflows-steps-list">
294
- <# if ( data.items.length ) { #>
295
- <# for ( key in data.items ) { #>
296
- <#
297
- var flow_steps = [];
298
- if( data.items[ key ].flow_steps ) {
299
- flow_steps = data.items[ key ].flow_steps.map(function(value,index) {
300
- return value['id'];
301
- });
302
- }
303
- #>
304
- <div class="inner">
305
- <div class="template">
306
- <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 }}">
307
- <div class="template-screenshot">
308
- <# if( data.items[ key ].featured_image_url ) { #>
309
- <img src="{{ data.items[ key ].featured_image_url }}" />
310
- <# } else { #>
311
- <img src="<?php echo esc_attr( CARTFLOWS_URL ); ?>assets/images/400x400.jpg" />
312
- <# } #>
313
- </div>
314
- <div id="wcf_create_notice" class=""><a href="https://cartflows.com/" target="_blank"></a></div>
315
- <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>
316
- <# if( data.items[ key ].flow_type && 'pro' === data.items[ key ].flow_type.slug ) { #>
317
- <span class="wcf-flow-type pro"><?php _e( 'Pro', 'cartflows' ); ?></span>
318
- <# } #>
319
- </span>
320
- <div class="template-id-container">
321
- <h3 class="template-name"> {{{ data.items[ key ].title.rendered }}} </h3>
322
- <div class="template-actions">
323
- <# if( data.items[ key ].licence_status && 'valid' === data.items[ key ].licence_status ) { #>
324
- <a data-required="<?php echo htmlspecialchars( json_encode( $required_plugins ), ENT_QUOTES, 'UTF-8' ); ?>" data-flow-steps="{{ flow_steps }}" href="#" class="button button-primary cartflows-step-import" data-template-id="{{ data.items[ key ].id }}"><?php echo $import_btn_title; ?></a>
325
- <# } else if( CartFlowsImportVars._is_pro_active ) { #>
326
- <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>
327
- <# } else { #>
328
- <a target="_blank" href="<?php echo esc_url( CARTFLOWS_DOMAIN_URL ); ?>" class="button button-primary"><?php _e( 'Get Pro', 'cartflows' ); ?></a>
329
- <# } #>
330
- </div>
331
- </div>
332
- </div>
333
- </div>
334
- <# } #>
335
- <# } #>
336
- </script>
337
-
338
- <?php
339
- /**
340
- * TMPL - Filters
341
- */
342
- ?>
343
- <script type="text/template" id="tmpl-cartflows-term-filters">
344
-
345
- <# if ( data ) { #>
346
-
347
- <ul class="{{ data.args.wrapper_class }} {{ data.args.class }}">
348
-
349
- <# console.log( data.args.show_all ) #>
350
- <# if ( data.args.show_all ) { #>
351
- <li>
352
- <a href="#" data-group="all"> All </a>
353
- </li>
354
- <# } #>
355
-
356
- <# for ( key in data.items ) { #>
357
- <li>
358
- <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>
359
- </li>
360
- <# } #>
361
-
362
- </ul>
363
- <# } #>
364
- </script>
365
-
366
- <?php
367
- // Step Type.
368
- ?>
369
- <script type="text/template" id="tmpl-cartflows-step-types">
370
- <ul class="wcf-tab nav-tabs">
371
- <# if( data.items_count ) { #>
372
- <# for( key in data.items ) { #>
373
- <# console.log( data.items[ key ].id ) #>
374
- <li data-slug="{{data.items[ key ].slug}}" data-title="{{ data.items[ key ].name }}">
375
- <a href="#{{{ data.items[ key ].slug }}}">{{{ data.items[ key ].name }}}</a>
376
- </li>
377
- <# } #>
378
- <# } #>
379
- </ul>
380
- </script>
381
-
382
- <?php
383
- // Add to library button.
384
- ?>
385
- <script type="text/template" id="tmpl-templator-add-to-library">
386
- <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>
387
- </script>
388
- <?php
389
- }
390
-
391
- /**
392
- * Enqueue scripts
393
- *
394
- * @since 1.0.0
395
- *
396
- * @hook admin_enqueue_scripts
397
- * @param string $hook Current page hook.
398
- */
399
- function scripts( $hook = '' ) {
400
-
401
- if ( ! self::is_supported_post( get_current_screen()->post_type ) ) {
402
- return;
403
- }
404
-
405
- wp_enqueue_script( 'cartflows-rest-api', CARTFLOWS_URL . 'assets/js/rest-api.js', array( 'jquery' ), CARTFLOWS_VER, true );
406
- wp_enqueue_style( 'cartflows-import', CARTFLOWS_URL . 'assets/css/import.css', null, CARTFLOWS_VER, 'all' );
407
- wp_style_add_data( 'cartflows-import', 'rtl', 'replace' );
408
- wp_enqueue_script( 'cartflows-import', CARTFLOWS_URL . 'assets/js/import.js', array( 'jquery', 'wp-util', 'cartflows-rest-api', 'updates' ), CARTFLOWS_VER, true );
409
-
410
- $localize_vars = array(
411
- '_is_pro_active' => _is_cartflows_pro(),
412
-
413
- // Flow and its rest fields.
414
- 'flow' => CARTFLOWS_FLOW_POST_TYPE,
415
- 'flow_fields' => array(
416
- 'id',
417
- 'title',
418
- 'flow_type',
419
- 'flow_steps',
420
- 'licence_status',
421
- 'featured_image_url',
422
- 'featured_media', // @required for field `featured_image_url`.
423
- ),
424
-
425
- // Flow type and rest fields.
426
- 'flow_type' => CARTFLOWS_TAXONOMY_FLOW_CATEGORY,
427
- 'flow_type_fields' => array(
428
- 'id',
429
- 'name',
430
- 'slug',
431
- ),
432
-
433
- // Step and its rest fields.
434
- 'step' => CARTFLOWS_STEP_POST_TYPE,
435
- 'step_fields' => array(
436
- 'title',
437
- 'featured_image_url',
438
- 'featured_media', // @required for field `featured_image_url`.
439
- 'id',
440
- 'flow_type',
441
- 'licence_status',
442
- ),
443
-
444
- // Step type and its rest fields.
445
- 'step_type' => CARTFLOWS_TAXONOMY_STEP_TYPE,
446
- 'step_type_fields' => array(
447
- 'id',
448
- 'name',
449
- 'slug',
450
- ),
451
-
452
- 'domain_url' => CARTFLOWS_DOMAIN_URL,
453
- 'server_url' => CARTFLOWS_TEMPLATES_URL,
454
- 'server_rest_url' => CARTFLOWS_TEMPLATES_URL . 'wp-json/wp/v2/',
455
- 'site_url' => site_url(),
456
- 'admin_url' => admin_url(),
457
- 'licence_args' => CartFlows_API::get_instance()->get_licence_args(),
458
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
459
- 'debug' => ( ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || isset( $_GET['debug'] ) ) ? true : false,
460
- );
461
-
462
- // Add thickbox.
463
- add_thickbox();
464
-
465
- wp_localize_script( 'cartflows-import', 'CartFlowsImportVars', $localize_vars );
466
- wp_localize_script( 'cartflows-rest-api', 'CartFlowsImportVars', $localize_vars );
467
- }
468
-
469
- /**
470
- * Load Template
471
- *
472
- * @since 1.0.0
473
- *
474
- * @hook cartflows_load_steps
475
- * @return void
476
- */
477
- function load_templates() {
478
-
479
- check_ajax_referer( 'cf-load-steps', 'security' );
480
-
481
- $args = ( isset( $_POST['args'] ) ) ? array_map( 'sanitize_text_field', $_POST['args'] ) : array();
482
- $templates = CartFlows_API::get_instance()->get_templates( $args );
483
-
484
- if ( $templates['templates_count'] ) {
485
- wp_send_json_success( $templates );
486
- } else {
487
- wp_send_json_error( $templates );
488
- }
489
- wp_die();
490
- }
491
-
492
- /**
493
- * Import.
494
- *
495
- * @since 1.0.0
496
- *
497
- * @hook wp_ajax_cartflows_import_flow_step
498
- * @return void
499
- */
500
- function import_flow() {
501
-
502
- check_ajax_referer( 'cf-import-flow-step', 'security' );
503
-
504
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
505
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
506
-
507
- wcf()->logger->import_log( '------------------------------------' );
508
- wcf()->logger->import_log( 'STARTED! Importing FLOW' );
509
- wcf()->logger->import_log( '------------------------------------' );
510
- wcf()->logger->import_log( '(✓) Creating new step from remote step [' . $template_id . '] for FLOW ' . get_the_title( $flow_id ) . ' [' . $flow_id . ']' );
511
-
512
- $response = CartFlows_API::get_instance()->get_template( $template_id );
513
-
514
- if ( false === $response['success'] ) {
515
- wcf()->logger->import_log( '(✕) Failed to fetch remote data.' );
516
- wp_send_json_error( $response );
517
- }
518
-
519
- wcf()->logger->import_log( '(✓) Successfully getting remote step response ' . json_encode( $response ) );
520
-
521
- $new_step_id = wp_insert_post(
522
- array(
523
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
524
- 'post_title' => $response['title'],
525
- 'post_content' => '',
526
- 'post_status' => 'publish',
527
- )
528
- );
529
-
530
- if ( is_wp_error( $new_step_id ) ) {
531
- wcf()->logger->import_log( '(✕) Failed to create new step for flow ' . $flow_id );
532
- wp_send_json_error( $new_step_id );
533
- }
534
-
535
- wcf()->logger->import_log( '(✓) Created new step ' . '"' . $response['title'] . '" id ' . $new_step_id );
536
- // insert post meta.
537
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
538
- wcf()->logger->import_log( '(✓) Added flow ID ' . $flow_id . ' in post meta key wcf-flow-id.' );
539
-
540
- /**
541
- * Import & Set type.
542
- */
543
- $term = isset( $response['data']['step_type'] ) ? $response['data']['step_type'] : '';
544
- $term_slug = '';
545
- if ( $term ) {
546
-
547
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
548
- $term_exist = term_exists( $term->name, $taxonomy );
549
-
550
- if ( empty( $term_exist ) ) {
551
- $terms = array(
552
- array(
553
- 'name' => $term->name,
554
- ),
555
- );
556
-
557
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
558
- wcf()->logger->import_log( '(✓) Created new term ' . $term->name );
559
- }
560
-
561
- $current_term = term_exists( $term->name, $taxonomy );
562
-
563
- // Set type object.
564
- $data = get_term( $current_term['term_id'], $taxonomy );
565
- $term_slug = $data->slug;
566
- $term_name = $data->name;
567
- wp_set_object_terms( $new_step_id, $term_slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
568
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $term_name . ' to the template ' . $new_step_id );
569
-
570
- // Set type.
571
- update_post_meta( $new_step_id, 'wcf-step-type', $term_slug );
572
- wcf()->logger->import_log( '(✓) Updated term ' . $term_name . ' to the post meta wcf-step-type.' );
573
- }
574
-
575
- // Set flow.
576
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
577
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
578
-
579
- /**
580
- * Update steps for the current flow.
581
- */
582
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
583
-
584
- if ( ! is_array( $flow_steps ) ) {
585
- $flow_steps = array();
586
- }
587
-
588
- $flow_steps[] = array(
589
- 'id' => $new_step_id,
590
- 'title' => $response['title'],
591
- 'type' => $term_slug,
592
- );
593
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
594
- wcf()->logger->import_log( '() Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
595
-
596
- // Import Post Meta.
597
- self::import_post_meta( $new_step_id, $response );
598
-
599
- wcf()->logger->import_log( '(✓) Importing step "' . get_the_title( $new_step_id ) . '" [' . $new_step_id . '] for FLOW "' . get_the_title( $flow_id ) . '" [' . $flow_id . ']' );
600
- wcf()->logger->import_log( '------------------------------------' );
601
- wcf()->logger->import_log( 'COMPLETE! Importing FLOW' );
602
- wcf()->logger->import_log( '------------------------------------' );
603
-
604
- do_action( 'cartflows_import_complete' );
605
- wcf()->logger->import_log( '(✓) BATCH STARTED for step ' . $new_step_id . ' for Blog name \'' . get_bloginfo( 'name' ) . '\' (' . get_current_blog_id() . ')' );
606
-
607
- // Batch Process.
608
- do_action( 'cartflows_after_template_import', $new_step_id, $response );
609
-
610
- /**
611
- * End
612
- */
613
- wp_send_json_success( $new_step_id );
614
- }
615
-
616
- /**
617
- * Import Step.
618
- *
619
- * @since 1.0.0
620
- * @hook wp_ajax_cartflows_step_import
621
- *
622
- * @return void
623
- */
624
- function create_default_flow() {
625
-
626
- check_ajax_referer( 'cf-default-flow', 'security' );
627
-
628
- // Create post object.
629
- $new_flow_post = array(
630
- 'post_content' => '',
631
- 'post_status' => 'publish',
632
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
633
- );
634
-
635
- // Insert the post into the database.
636
- $flow_id = wp_insert_post( $new_flow_post );
637
-
638
- if ( is_wp_error( $flow_id ) ) {
639
- wp_send_json_error( $flow_id->get_error_message() );
640
- }
641
-
642
- $flow_steps = array();
643
-
644
- $steps_data = array(
645
- 'landing' => __( 'Landing Page', 'cartflows' ),
646
- 'checkout' => __( 'Checkout Page', 'cartflows' ),
647
- 'thankyou' => __( 'Thank You Page', 'cartflows' ),
648
- );
649
-
650
- foreach ( $steps_data as $slug => $title ) {
651
-
652
- $post_content = '';
653
-
654
- switch ( $slug ) {
655
- case 'checkout':
656
- $post_content = '';
657
- break;
658
- case 'thankyou':
659
- $post_content = '';
660
- break;
661
- default:
662
- $post_content = '';
663
- break;
664
- }
665
-
666
- $step_id = wp_insert_post(
667
- array(
668
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
669
- 'post_title' => $title,
670
- 'post_content' => $post_content,
671
- 'post_status' => 'publish',
672
- )
673
- );
674
-
675
- if ( is_wp_error( $step_id ) ) {
676
- wp_send_json_error( $step_id->get_error_message() );
677
- }
678
-
679
- if ( $step_id ) {
680
-
681
- $flow_steps[] = array(
682
- 'id' => $step_id,
683
- 'title' => $title,
684
- 'type' => $slug,
685
- );
686
-
687
- // insert post meta.
688
- update_post_meta( $step_id, 'wcf-flow-id', $flow_id );
689
- update_post_meta( $step_id, 'wcf-step-type', $slug );
690
-
691
- wp_set_object_terms( $step_id, $slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
692
- wp_set_object_terms( $step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
693
- }
694
- }
695
-
696
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
697
-
698
- wp_send_json_success( $flow_id );
699
- }
700
-
701
- /**
702
- * Create Flow
703
- *
704
- * @return void
705
- */
706
- function create_flow() {
707
-
708
- check_ajax_referer( 'cf-create-flow', 'security' );
709
-
710
- // Create post object.
711
- $new_flow_post = array(
712
- 'post_content' => '',
713
- 'post_status' => 'publish',
714
- 'post_type' => CARTFLOWS_FLOW_POST_TYPE,
715
- );
716
-
717
- // Insert the post into the database.
718
- $flow_id = wp_insert_post( $new_flow_post );
719
-
720
- if ( is_wp_error( $flow_id ) ) {
721
- wp_send_json_error( $flow_id->get_error_message() );
722
- }
723
-
724
- wp_send_json_success( $flow_id );
725
- }
726
-
727
- /**
728
- * Create Step
729
- *
730
- * @return void
731
- */
732
- function import_step() {
733
-
734
- check_ajax_referer( 'cf-step-import', 'security' );
735
-
736
- $template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : '';
737
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
738
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
739
- $step_type = isset( $_POST['step_type'] ) ? sanitize_title( $_POST['step_type'] ) : '';
740
- $step_custom_title = isset( $_POST['step_custom_title'] ) ? sanitize_title( $_POST['step_custom_title'] ) : $step_title;
741
-
742
- $cartflow_meta = Cartflows_Flow_Meta::get_instance();
743
-
744
- $post_id = $cartflow_meta->create_step( $flow_id, $step_type, $step_custom_title );
745
-
746
- wcf()->logger->import_log( '------------------------------------' );
747
- wcf()->logger->import_log( 'STARTED! Importing STEP' );
748
- wcf()->logger->import_log( '------------------------------------' );
749
-
750
- if ( empty( $template_id ) || empty( $post_id ) ) {
751
- /* translators: %s: template ID */
752
- $data = sprintf( __( 'Invalid template id %1$s or post id %2$s.', 'cartflows' ), $template_id, $post_id );
753
- wcf()->logger->import_log( $data );
754
- wp_send_json_error( $data );
755
- }
756
-
757
- wcf()->logger->import_log( 'Remote Step ' . $template_id . ' for local flow "' . get_the_title( $post_id ) . '" [' . $post_id . ']' );
758
-
759
- $response = CartFlows_API::get_instance()->get_template( $template_id );
760
-
761
- wcf()->logger->import_log( json_encode( $response ) );
762
-
763
- // Import Post Meta.
764
- self::import_post_meta( $post_id, $response );
765
-
766
- do_action( 'cartflows_import_complete' );
767
-
768
- // Batch Process.
769
- do_action( 'cartflows_after_template_import', $post_id, $response );
770
-
771
- wcf()->logger->import_log( '------------------------------------' );
772
- wcf()->logger->import_log( 'COMPLETE! Importing Step' );
773
- wcf()->logger->import_log( '------------------------------------' );
774
-
775
- wp_send_json_success( $post_id );
776
- }
777
-
778
- /**
779
- * Import Step.
780
- *
781
- * @since 1.0.0
782
- * @hook wp_ajax_cartflows_step_create_blank
783
- *
784
- * @return void
785
- */
786
- function step_create_blank() {
787
-
788
- check_ajax_referer( 'cf-step-create-blank', 'security' );
789
-
790
- $flow_id = isset( $_POST['flow_id'] ) ? intval( $_POST['flow_id'] ) : '';
791
- $step_type = isset( $_POST['step_type'] ) ? sanitize_text_field( $_POST['step_type'] ) : '';
792
- $step_title = isset( $_POST['step_title'] ) ? sanitize_text_field( $_POST['step_title'] ) : '';
793
-
794
- if ( empty( $flow_id ) || empty( $step_type ) ) {
795
- /* translators: %s: flow ID */
796
- $data = sprintf( __( 'Invalid flow id %1$s or step type %2$s.', 'cartflows' ), $flow_id, $step_type );
797
- wcf()->logger->import_log( $data );
798
- wp_send_json_error( $data );
799
- }
800
-
801
- wcf()->logger->import_log( '------------------------------------' );
802
- wcf()->logger->import_log( 'STARTED! Creating Blank STEP for Flow ' . $flow_id );
803
-
804
- $step_type_title = str_replace( '-', ' ', $step_type );
805
- $step_type_slug = strtolower( str_replace( '-', ' ', $step_type ) );
806
-
807
- $new_step_id = wp_insert_post(
808
- array(
809
- 'post_type' => CARTFLOWS_STEP_POST_TYPE,
810
- 'post_title' => $step_title,
811
- 'post_content' => '',
812
- 'post_status' => 'publish',
813
- )
814
- );
815
-
816
- // insert post meta.
817
- update_post_meta( $new_step_id, 'wcf-flow-id', $flow_id );
818
-
819
- $taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;
820
- $term_exist = term_exists( $step_type_title, $taxonomy );
821
-
822
- if ( empty( $term_exist ) ) {
823
- $terms = array(
824
- array(
825
- 'name' => $step_type_title,
826
- ),
827
- );
828
-
829
- Cartflows_Step_Post_Type::get_instance()->add_terms( $taxonomy, $terms );
830
- wcf()->logger->import_log( '(✓) Created new term ' . $step_type_title );
831
- }
832
-
833
- $current_term = term_exists( $step_type_title, $taxonomy );
834
-
835
- // Set type object.
836
- $data = get_term( $current_term['term_id'], $taxonomy );
837
- $step_slug = $data->slug;
838
- wp_set_object_terms( $new_step_id, $data->slug, CARTFLOWS_TAXONOMY_STEP_TYPE );
839
- wcf()->logger->import_log( '(✓) Assigned existing term ' . $step_type_title . ' to the template ' . $new_step_id );
840
-
841
- // Set type.
842
- update_post_meta( $new_step_id, 'wcf-step-type', $data->slug );
843
- wcf()->logger->import_log( '(✓) Updated term ' . $data->name . ' to the post meta wcf-step-type.' );
844
-
845
- // Set flow.
846
- wp_set_object_terms( $new_step_id, 'flow-' . $flow_id, CARTFLOWS_TAXONOMY_STEP_FLOW );
847
- wcf()->logger->import_log( '(✓) Assigned flow step flow-' . $flow_id );
848
-
849
- CartFlows_Importer::get_instance()->set_step_to_flow( $flow_id, $new_step_id, $step_type_title, $step_slug );
850
-
851
- wcf()->logger->import_log( 'COMPLETE! Creating Blank STEP for Flow ' . $flow_id );
852
- wcf()->logger->import_log( '------------------------------------' );
853
-
854
- wp_send_json_success( $new_step_id );
855
- }
856
-
857
- /**
858
- * Import Post Meta
859
- *
860
- * @since 1.0.0
861
- *
862
- * @param integer $post_id Post ID.
863
- * @param array $response Post meta.
864
- * @return void
865
- */
866
- public static function import_post_meta( $post_id, $response ) {
867
-
868
- $metadata = (array) $response['post_meta'];
869
-
870
- foreach ( $metadata as $meta_key => $meta_value ) {
871
- $meta_value = isset( $meta_value[0] ) ? $meta_value[0] : '';
872
-
873
- if ( $meta_value ) {
874
-
875
- if ( is_serialized( $meta_value, true ) ) {
876
- $raw_data = maybe_unserialize( stripslashes( $meta_value ) );
877
- } elseif ( is_array( $meta_value ) ) {
878
- $raw_data = json_decode( stripslashes( $meta_value ), true );
879
- } else {
880
- $raw_data = $meta_value;
881
- }
882
-
883
- if ( '_elementor_data' === $meta_key ) {
884
-
885
- if ( is_array( $raw_data ) ) {
886
- $raw_data = wp_slash( json_encode( $raw_data ) );
887
- } else {
888
- $raw_data = wp_slash( $raw_data );
889
- }
890
- wcf()->logger->import_log( $raw_data );
891
- }
892
-
893
- if ( is_array( $raw_data ) ) {
894
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . json_encode( $raw_data ) );
895
- } else {
896
- wcf()->logger->import_log( '(✓) Added post meta ' . $meta_key . ' | ' . $raw_data );
897
- }
898
-
899
- update_post_meta( $post_id, $meta_key, $raw_data );
900
- }
901
- }
902
- }
903
-
904
- /**
905
- * Import Template for Elementor
906
- *
907
- * @since 1.0.0
908
- *
909
- * @param integer $post_id Post ID.
910
- * @param array $response Post meta.
911
- * @param array $page_build_data Page build data.
912
- * @return void
913
- */
914
- public static function import_template_elementor( $post_id, $response, $page_build_data ) {
915
- if ( ! is_plugin_active( 'elementor/elementor.php' ) ) {
916
- $data = __( 'Elementor is not activated. Please activate plugin Elementor Page Builder to import the step.', 'cartflows' );
917
- wcf()->logger->import_log( $data );
918
- wp_send_json_error( $data );
919
- }
920
-
921
- require_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-importer-elementor.php';
922
-
923
- wcf()->logger->import_log( '# Started "importing page builder data" for step ' . $post_id );
924
-
925
- $obj = new \Elementor\TemplateLibrary\CartFlows_Importer_Elementor();
926
- $obj->import_single_template( $post_id );
927
-
928
- wcf()->logger->import_log( '# Complete "importing page builder data" for step ' . $post_id );
929
- }
930
-
931
- /**
932
- * Supported post types
933
- *
934
- * @since 1.0.0
935
- *
936
- * @return array Supported post types.
937
- */
938
- public static function supported_post_types() {
939
- return apply_filters(
940
- 'cartflows_supported_post_types',
941
- array(
942
- CARTFLOWS_FLOW_POST_TYPE,
943
- )
944
- );
945
- }
946
-
947
- /**
948
- * Check supported post type
949
- *
950
- * @since 1.0.0
951
- *
952
- * @param string $post_type Post type.
953
- * @return boolean Supported post type status.
954
- */
955
- public static function is_supported_post( $post_type = '' ) {
956
- if ( in_array( $post_type, self::supported_post_types() ) ) {
957
- return true;
958
- }
959
-
960
- return false;
961
- }
962
-
963
- /**
964
- * Set steps to the flow
965
- *
966
- * @param integer $flow_id Flow ID.
967
- * @param integer $new_step_id New step ID.
968
- * @param string $step_title Flow Type.
969
- * @param string $step_slug Flow Type.
970
- */
971
- function set_step_to_flow( $flow_id, $new_step_id, $step_title, $step_slug ) {
972
- // Update steps for the current flow.
973
- $flow_steps = get_post_meta( $flow_id, 'wcf-steps', true );
974
-
975
- if ( ! is_array( $flow_steps ) ) {
976
- $flow_steps = array();
977
- }
978
-
979
- $flow_steps[] = array(
980
- 'id' => $new_step_id,
981
- 'title' => $step_title,
982
- 'type' => $step_slug,
983
- );
984
- update_post_meta( $flow_id, 'wcf-steps', $flow_steps );
985
- wcf()->logger->import_log( '(✓) Updated flow steps post meta key \'wcf-steps\' ' . json_encode( $flow_steps ) );
986
- }
987
-
988
- /**
989
- * Localize variables in admin
990
- *
991
- * @param array $vars variables.
992
- */
993
- function localize_vars( $vars ) {
994
-
995
- $ajax_actions = array(
996
- 'cf_step_import',
997
- 'cf_load_steps',
998
- 'cf_create_flow',
999
- 'cf_default_flow',
1000
- 'cf_step_create_blank',
1001
- 'cf_import_flow_step',
1002
- );
1003
-
1004
- foreach ( $ajax_actions as $action ) {
1005
-
1006
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
1007
- }
1008
-
1009
- return $vars;
1010
- }
1011
-
1012
- /**
1013
- * Ajax action to activate plugin
1014
- */
1015
- public function activate_plugin() {
1016
-
1017
- $plugin_slug = isset( $_POST['plugin_slug'] ) ? sanitize_text_field( $_POST['plugin_slug'] ) : '';
1018
-
1019
- if ( ! is_plugin_active( $plugin_slug ) ) {
1020
-
1021
- $activate = activate_plugin( $plugin_slug, '', false, true );
1022
-
1023
- if ( is_wp_error( $activate ) ) {
1024
- wp_send_json_error();
1025
- }
1026
- }
1027
-
1028
- wp_send_json_success();
1029
- }
1030
-
1031
- }
1032
-
1033
- /**
1034
- * Initialize class object with 'get_instance()' method
1035
- */
1036
- CartFlows_Importer::get_instance();
1037
-
1038
- 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
+
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;
classes/class-cartflows-loader.php CHANGED
@@ -1,416 +1,419 @@
1
- <?php
2
- /**
3
- * CartFlows Loader.
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- if ( ! class_exists( 'Cartflows_Loader' ) ) {
9
-
10
- /**
11
- * Class Cartflows_Loader.
12
- */
13
- final class Cartflows_Loader {
14
-
15
- /**
16
- * Member Variable
17
- *
18
- * @var instance
19
- */
20
- private static $instance = null;
21
-
22
- /**
23
- * Member Variable
24
- *
25
- * @var utils
26
- */
27
- public $utils = null;
28
-
29
- /**
30
- * Member Variable
31
- *
32
- * @var logger
33
- */
34
- public $logger = null;
35
-
36
- /**
37
- * Member Variable
38
- *
39
- * @var session
40
- */
41
- public $session = null;
42
-
43
-
44
- /**
45
- * Member Variable
46
- *
47
- * @var options
48
- */
49
- public $options = null;
50
-
51
- /**
52
- * Member Variable
53
- *
54
- * @var meta
55
- */
56
- public $meta = null;
57
-
58
- /**
59
- * Member Variable
60
- *
61
- * @var flow
62
- */
63
- public $flow = null;
64
-
65
- /**
66
- * Initiator
67
- */
68
- public static function get_instance() {
69
-
70
- if ( is_null( self::$instance ) ) {
71
-
72
- self::$instance = new self;
73
-
74
- /**
75
- * CartFlows loaded.
76
- *
77
- * Fires when Cartflows was fully loaded and instantiated.
78
- *
79
- * @since 1.0.0
80
- */
81
- do_action( 'cartflows_loaded' );
82
- }
83
-
84
- return self::$instance;
85
- }
86
-
87
- /**
88
- * Constructor
89
- */
90
- public function __construct() {
91
-
92
- $this->define_constants();
93
-
94
- // Activation hook.
95
- register_activation_hook( CARTFLOWS_FILE, array( $this, 'activation_reset' ) );
96
-
97
- // deActivation hook.
98
- register_deactivation_hook( CARTFLOWS_FILE, array( $this, 'deactivation_reset' ) );
99
-
100
- add_action( 'plugins_loaded', array( $this, 'load_plugin' ), 99 );
101
-
102
- add_action( 'plugins_loaded', array( $this, 'load_cf_textdomain' ) );
103
-
104
- // Update compatibility.
105
- require_once CARTFLOWS_DIR . 'classes/class-cartflows-update.php';
106
- }
107
-
108
- /**
109
- * Defines all constants
110
- *
111
- * @since 1.0.0
112
- */
113
- public function define_constants() {
114
-
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.0.1' );
119
- define( 'CARTFLOWS_SLUG', 'cartflows' );
120
- define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
121
-
122
- define( 'CARTFLOWS_FLOW_POST_TYPE', 'cartflows_flow' );
123
- define( 'CARTFLOWS_STEP_POST_TYPE', 'cartflows_step' );
124
-
125
- if ( ! defined( 'CARTFLOWS_SERVER_URL' ) ) {
126
- define( 'CARTFLOWS_SERVER_URL', 'https://my.cartflows.com/' );
127
- }
128
- define( 'CARTFLOWS_DOMAIN_URL', 'https://cartflows.com/' );
129
- define( 'CARTFLOWS_TEMPLATES_URL', 'https://templates.cartflows.com/' );
130
- define( 'CARTFLOWS_TAXONOMY_STEP_TYPE', 'cartflows_step_type' );
131
- define( 'CARTFLOWS_TAXONOMY_STEP_FLOW', 'cartflows_step_flow' );
132
-
133
- if ( ! defined( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER' ) ) {
134
- define( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER', 'cartflows_step_page_builder' );
135
- }
136
- if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY' ) ) {
137
- define( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY', 'cartflows_flow_category' );
138
- }
139
- }
140
-
141
- /**
142
- * Loads plugin files.
143
- *
144
- * @since 1.0.0
145
- *
146
- * @return void
147
- */
148
- function load_plugin() {
149
-
150
- if ( ! function_exists( 'WC' ) ) {
151
- add_action( 'admin_notices', array( $this, 'fails_to_load' ) );
152
- return;
153
- }
154
-
155
- $this->load_helper_files_components();
156
- $this->load_core_files();
157
- $this->load_core_components();
158
-
159
- /**
160
- * CartFlows Init.
161
- *
162
- * Fires when Cartflows is instantiated.
163
- *
164
- * @since 1.0.0
165
- */
166
- do_action( 'cartflows_init' );
167
- }
168
-
169
- /**
170
- * Load Helper Files and Components.
171
- *
172
- * @since 1.0.0
173
- *
174
- * @return void
175
- */
176
- function load_helper_files_components() {
177
-
178
- /* Public Utils */
179
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-utils.php';
180
-
181
- /* Public Session */
182
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-session.php';
183
-
184
- /* Public Global namespace functions */
185
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-functions.php';
186
-
187
- /* Admin Helper */
188
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-helper.php';
189
-
190
- /* Meta Default Values */
191
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-default-meta.php';
192
-
193
- $this->utils = Cartflows_Utils::get_instance();
194
- $this->session = Cartflows_Session::get_instance();
195
- $this->options = Cartflows_Default_Meta::get_instance();
196
-
197
- }
198
-
199
- /**
200
- * Load Core Files.
201
- *
202
- * @since 1.0.0
203
- *
204
- * @return void
205
- */
206
- function load_core_files() {
207
-
208
- /* Page builder compatibilty class */
209
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-compatibility.php';
210
-
211
- /* Admin Meta Fields*/
212
- include_once CARTFLOWS_DIR . 'classes/fields/typography/class-cartflows-font-families.php';
213
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta-fields.php';
214
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta.php';
215
-
216
- /* Cloning */
217
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-cloning.php';
218
-
219
- /* Admin Settings */
220
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin.php';
221
-
222
- /* Core Modules */
223
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-logger.php';
224
-
225
- /* Frontend Global */
226
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-frontend.php';
227
- require_once CARTFLOWS_DIR . 'classes/class-cartflows-flow-frontend.php';
228
-
229
- /* Modules */
230
- include_once CARTFLOWS_DIR . 'modules/flow/class-cartflows-flow.php';
231
- include_once CARTFLOWS_DIR . 'modules/landing/class-cartflows-landing.php';
232
- include_once CARTFLOWS_DIR . 'modules/checkout/class-cartflows-checkout.php';
233
- include_once CARTFLOWS_DIR . 'modules/thankyou/class-cartflows-thankyou.php';
234
-
235
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-api.php';
236
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer-core.php';
237
-
238
- include_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-batch-process.php';
239
- include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer.php';
240
- }
241
-
242
- /**
243
- * Load Core Components.
244
- *
245
- * @since 1.0.0
246
- *
247
- * @return void
248
- */
249
- function load_core_components() {
250
-
251
- $this->meta = Cartflows_Meta_Fields::get_instance();
252
- $this->logger = Cartflows_Logger::get_instance();
253
- $this->flow = Cartflows_Flow_Frontend::get_instance();
254
- }
255
-
256
- /**
257
- * Load CartFlows Pro Text Domain.
258
- * This will load the translation textdomain depending on the file priorities.
259
- * 1. Global Languages /wp-content/languages/cartflows/ folder
260
- * 2. Local dorectory /wp-content/plugins/cartflows/languages/ folder
261
- *
262
- * @since 1.0.3
263
- * @return void
264
- */
265
- public function load_cf_textdomain() {
266
-
267
- // Default languages directory for CartFlows Pro.
268
- $lang_dir = CARTFLOWS_DIR . 'languages/';
269
-
270
- /**
271
- * Filters the languages directory path to use for CartFlows Pro.
272
- *
273
- * @param string $lang_dir The languages directory path.
274
- */
275
- $lang_dir = apply_filters( 'cartflows_languages_directory', $lang_dir );
276
-
277
- // Traditional WordPress plugin locale filter.
278
- global $wp_version;
279
-
280
- $get_locale = get_locale();
281
-
282
- if ( $wp_version >= 4.7 ) {
283
- $get_locale = get_user_locale();
284
- }
285
-
286
- /**
287
- * Language Locale for CartFlows Pro
288
- *
289
- * @var $get_locale The locale to use.
290
- * Uses get_user_locale()` in WordPress 4.7 or greater,
291
- * otherwise uses `get_locale()`.
292
- */
293
- $locale = apply_filters( 'plugin_locale', $get_locale, 'cartflows' );
294
- $mofile = sprintf( '%1$s-%2$s.mo', 'cartflows', $locale );
295
-
296
- // Setup paths to current locale file.
297
- $mofile_local = $lang_dir . $mofile;
298
- $mofile_global = WP_LANG_DIR . '/plugins/' . $mofile;
299
-
300
- if ( file_exists( $mofile_global ) ) {
301
- // Look in global /wp-content/languages/cartflows/ folder.
302
- load_textdomain( 'cartflows', $mofile_global );
303
- } elseif ( file_exists( $mofile_local ) ) {
304
- // Look in local /wp-content/plugins/cartflows/languages/ folder.
305
- load_textdomain( 'cartflows', $mofile_local );
306
- } else {
307
- // Load the default language files.
308
- load_plugin_textdomain( 'cartflows', false, $lang_dir );
309
- }
310
- }
311
-
312
- /**
313
- * Fires admin notice when Elementor is not installed and activated.
314
- *
315
- * @since 1.0.0
316
- *
317
- * @return void
318
- */
319
- public function fails_to_load() {
320
-
321
- $screen = get_current_screen();
322
-
323
- if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) {
324
- return;
325
- }
326
-
327
- $class = 'notice notice-error';
328
- /* translators: %s: html tags */
329
- $message = sprintf( __( 'The %1$sCartFlows%2$s plugin requires %1$sWooCommerce%2$s plugin installed & activated.', 'cartflows' ), '<strong>', '</strong>' );
330
-
331
- $plugin = 'woocommerce/woocommerce.php';
332
-
333
- if ( _is_woo_installed() ) {
334
- if ( ! current_user_can( 'activate_plugins' ) ) {
335
- return;
336
- }
337
-
338
- $action_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin );
339
- $button_label = __( 'Activate WooCommerce', 'cartflows' );
340
-
341
- } else {
342
- if ( ! current_user_can( 'install_plugins' ) ) {
343
- return;
344
- }
345
-
346
- $action_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=woocommerce' ), 'install-plugin_woocommerce' );
347
- $button_label = __( 'Install WooCommerce', 'cartflows' );
348
- }
349
-
350
- $button = '<p><a href="' . $action_url . '" class="button-primary">' . $button_label . '</a></p><p></p>';
351
-
352
- printf( '<div class="%1$s"><p>%2$s</p>%3$s</div>', esc_attr( $class ), $message, $button );
353
- }
354
-
355
- /**
356
- * Activation Reset
357
- */
358
- function activation_reset() {
359
-
360
- include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-flow-post-type.php';
361
- include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-step-post-type.php';
362
-
363
- Cartflows_Flow_Post_Type::get_instance()->flow_post_type();
364
- Cartflows_Step_Post_Type::get_instance()->step_post_type();
365
- flush_rewrite_rules();
366
- }
367
-
368
- /**
369
- * Deactivation Reset
370
- */
371
- function deactivation_reset() {
372
- }
373
-
374
- /**
375
- * Logger Class Instance
376
- */
377
- function logger() {
378
- return Cartflows_Logger::get_instance();
379
- }
380
-
381
-
382
- }
383
-
384
- /**
385
- * Prepare if class 'Cartflows_Loader' exist.
386
- * Kicking this off by calling 'get_instance()' method
387
- */
388
- Cartflows_Loader::get_instance();
389
- }
390
-
391
- /**
392
- * Get global class.
393
- *
394
- * @return object
395
- */
396
- function wcf() {
397
- return Cartflows_Loader::get_instance();
398
- }
399
-
400
- if ( ! function_exists( '_is_woo_installed' ) ) {
401
-
402
- /**
403
- * Is woocommerce plugin installed.
404
- *
405
- * @since 1.0.0
406
- *
407
- * @access public
408
- */
409
- function _is_woo_installed() {
410
-
411
- $path = 'woocommerce/woocommerce.php';
412
- $plugins = get_plugins();
413
-
414
- return isset( $plugins[ $path ] );
415
- }
416
- }
 
 
 
1
+ <?php
2
+ /**
3
+ * CartFlows Loader.
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ if ( ! class_exists( 'Cartflows_Loader' ) ) {
9
+
10
+ /**
11
+ * Class Cartflows_Loader.
12
+ */
13
+ final class Cartflows_Loader {
14
+
15
+ /**
16
+ * Member Variable
17
+ *
18
+ * @var instance
19
+ */
20
+ private static $instance = null;
21
+
22
+ /**
23
+ * Member Variable
24
+ *
25
+ * @var utils
26
+ */
27
+ public $utils = null;
28
+
29
+ /**
30
+ * Member Variable
31
+ *
32
+ * @var logger
33
+ */
34
+ public $logger = null;
35
+
36
+ /**
37
+ * Member Variable
38
+ *
39
+ * @var session
40
+ */
41
+ public $session = null;
42
+
43
+
44
+ /**
45
+ * Member Variable
46
+ *
47
+ * @var options
48
+ */
49
+ public $options = null;
50
+
51
+ /**
52
+ * Member Variable
53
+ *
54
+ * @var meta
55
+ */
56
+ public $meta = null;
57
+
58
+ /**
59
+ * Member Variable
60
+ *
61
+ * @var flow
62
+ */
63
+ public $flow = null;
64
+
65
+ /**
66
+ * Initiator
67
+ */
68
+ public static function get_instance() {
69
+
70
+ if ( is_null( self::$instance ) ) {
71
+
72
+ self::$instance = new self;
73
+
74
+ /**
75
+ * CartFlows loaded.
76
+ *
77
+ * Fires when Cartflows was fully loaded and instantiated.
78
+ *
79
+ * @since 1.0.0
80
+ */
81
+ do_action( 'cartflows_loaded' );
82
+ }
83
+
84
+ return self::$instance;
85
+ }
86
+
87
+ /**
88
+ * Constructor
89
+ */
90
+ public function __construct() {
91
+
92
+ $this->define_constants();
93
+
94
+ // Activation hook.
95
+ register_activation_hook( CARTFLOWS_FILE, array( $this, 'activation_reset' ) );
96
+
97
+ // deActivation hook.
98
+ register_deactivation_hook( CARTFLOWS_FILE, array( $this, 'deactivation_reset' ) );
99
+
100
+ add_action( 'plugins_loaded', array( $this, 'load_plugin' ), 99 );
101
+
102
+ add_action( 'plugins_loaded', array( $this, 'load_cf_textdomain' ) );
103
+
104
+ // Update compatibility.
105
+ require_once CARTFLOWS_DIR . 'classes/class-cartflows-update.php';
106
+ }
107
+
108
+ /**
109
+ * Defines all constants
110
+ *
111
+ * @since 1.0.0
112
+ */
113
+ public function define_constants() {
114
+
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.1' );
119
+ define( 'CARTFLOWS_SLUG', 'cartflows' );
120
+ define( 'CARTFLOWS_SETTINGS', 'cartflows_settings' );
121
+
122
+ define( 'CARTFLOWS_FLOW_POST_TYPE', 'cartflows_flow' );
123
+ define( 'CARTFLOWS_STEP_POST_TYPE', 'cartflows_step' );
124
+
125
+ if ( ! defined( 'CARTFLOWS_SERVER_URL' ) ) {
126
+ define( 'CARTFLOWS_SERVER_URL', 'https://my.cartflows.com/' );
127
+ }
128
+ define( 'CARTFLOWS_DOMAIN_URL', 'https://cartflows.com/' );
129
+ define( 'CARTFLOWS_TEMPLATES_URL', 'https://templates.cartflows.com/' );
130
+ define( 'CARTFLOWS_TAXONOMY_STEP_TYPE', 'cartflows_step_type' );
131
+ define( 'CARTFLOWS_TAXONOMY_STEP_FLOW', 'cartflows_step_flow' );
132
+
133
+ if ( ! defined( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER' ) ) {
134
+ define( 'CARTFLOWS_TAXONOMY_STEP_PAGE_BUILDER', 'cartflows_step_page_builder' );
135
+ }
136
+ if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER' ) ) {
137
+ define( 'CARTFLOWS_TAXONOMY_FLOW_PAGE_BUILDER', 'cartflows_flow_page_builder' );
138
+ }
139
+ if ( ! defined( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY' ) ) {
140
+ define( 'CARTFLOWS_TAXONOMY_FLOW_CATEGORY', 'cartflows_flow_category' );
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Loads plugin files.
146
+ *
147
+ * @since 1.0.0
148
+ *
149
+ * @return void
150
+ */
151
+ function load_plugin() {
152
+
153
+ if ( ! function_exists( 'WC' ) ) {
154
+ add_action( 'admin_notices', array( $this, 'fails_to_load' ) );
155
+ return;
156
+ }
157
+
158
+ $this->load_helper_files_components();
159
+ $this->load_core_files();
160
+ $this->load_core_components();
161
+
162
+ /**
163
+ * CartFlows Init.
164
+ *
165
+ * Fires when Cartflows is instantiated.
166
+ *
167
+ * @since 1.0.0
168
+ */
169
+ do_action( 'cartflows_init' );
170
+ }
171
+
172
+ /**
173
+ * Load Helper Files and Components.
174
+ *
175
+ * @since 1.0.0
176
+ *
177
+ * @return void
178
+ */
179
+ function load_helper_files_components() {
180
+
181
+ /* Public Utils */
182
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-utils.php';
183
+
184
+ /* Public Session */
185
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-session.php';
186
+
187
+ /* Public Global namespace functions */
188
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-functions.php';
189
+
190
+ /* Admin Helper */
191
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-helper.php';
192
+
193
+ /* Meta Default Values */
194
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-default-meta.php';
195
+
196
+ $this->utils = Cartflows_Utils::get_instance();
197
+ $this->session = Cartflows_Session::get_instance();
198
+ $this->options = Cartflows_Default_Meta::get_instance();
199
+
200
+ }
201
+
202
+ /**
203
+ * Load Core Files.
204
+ *
205
+ * @since 1.0.0
206
+ *
207
+ * @return void
208
+ */
209
+ function load_core_files() {
210
+
211
+ /* Page builder compatibilty class */
212
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-compatibility.php';
213
+
214
+ /* Admin Meta Fields*/
215
+ include_once CARTFLOWS_DIR . 'classes/fields/typography/class-cartflows-font-families.php';
216
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta-fields.php';
217
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-meta.php';
218
+
219
+ /* Cloning */
220
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-cloning.php';
221
+
222
+ /* Admin Settings */
223
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-admin.php';
224
+
225
+ /* Core Modules */
226
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-logger.php';
227
+
228
+ /* Frontend Global */
229
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-frontend.php';
230
+ require_once CARTFLOWS_DIR . 'classes/class-cartflows-flow-frontend.php';
231
+
232
+ /* Modules */
233
+ include_once CARTFLOWS_DIR . 'modules/flow/class-cartflows-flow.php';
234
+ include_once CARTFLOWS_DIR . 'modules/landing/class-cartflows-landing.php';
235
+ include_once CARTFLOWS_DIR . 'modules/checkout/class-cartflows-checkout.php';
236
+ include_once CARTFLOWS_DIR . 'modules/thankyou/class-cartflows-thankyou.php';
237
+
238
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-api.php';
239
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer-core.php';
240
+
241
+ include_once CARTFLOWS_DIR . 'classes/batch-process/class-cartflows-batch-process.php';
242
+ include_once CARTFLOWS_DIR . 'classes/class-cartflows-importer.php';
243
+ }
244
+
245
+ /**
246
+ * Load Core Components.
247
+ *
248
+ * @since 1.0.0
249
+ *
250
+ * @return void
251
+ */
252
+ function load_core_components() {
253
+
254
+ $this->meta = Cartflows_Meta_Fields::get_instance();
255
+ $this->logger = Cartflows_Logger::get_instance();
256
+ $this->flow = Cartflows_Flow_Frontend::get_instance();
257
+ }
258
+
259
+ /**
260
+ * Load CartFlows Pro Text Domain.
261
+ * This will load the translation textdomain depending on the file priorities.
262
+ * 1. Global Languages /wp-content/languages/cartflows/ folder
263
+ * 2. Local dorectory /wp-content/plugins/cartflows/languages/ folder
264
+ *
265
+ * @since 1.0.3
266
+ * @return void
267
+ */
268
+ public function load_cf_textdomain() {
269
+
270
+ // Default languages directory for CartFlows Pro.
271
+ $lang_dir = CARTFLOWS_DIR . 'languages/';
272
+
273
+ /**
274
+ * Filters the languages directory path to use for CartFlows Pro.
275
+ *
276
+ * @param string $lang_dir The languages directory path.
277
+ */
278
+ $lang_dir = apply_filters( 'cartflows_languages_directory', $lang_dir );
279
+
280
+ // Traditional WordPress plugin locale filter.
281
+ global $wp_version;
282
+
283
+ $get_locale = get_locale();
284
+
285
+ if ( $wp_version >= 4.7 ) {
286
+ $get_locale = get_user_locale();
287
+ }
288
+
289
+ /**
290
+ * Language Locale for CartFlows Pro
291
+ *
292
+ * @var $get_locale The locale to use.
293
+ * Uses get_user_locale()` in WordPress 4.7 or greater,
294
+ * otherwise uses `get_locale()`.
295
+ */
296
+ $locale = apply_filters( 'plugin_locale', $get_locale, 'cartflows' );
297
+ $mofile = sprintf( '%1$s-%2$s.mo', 'cartflows', $locale );
298
+
299
+ // Setup paths to current locale file.
300
+ $mofile_local = $lang_dir . $mofile;
301
+ $mofile_global = WP_LANG_DIR . '/plugins/' . $mofile;
302
+
303
+ if ( file_exists( $mofile_global ) ) {
304
+ // Look in global /wp-content/languages/cartflows/ folder.
305
+ load_textdomain( 'cartflows', $mofile_global );
306
+ } elseif ( file_exists( $mofile_local ) ) {
307
+ // Look in local /wp-content/plugins/cartflows/languages/ folder.
308
+ load_textdomain( 'cartflows', $mofile_local );
309
+ } else {
310
+ // Load the default language files.
311
+ load_plugin_textdomain( 'cartflows', false, $lang_dir );
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Fires admin notice when Elementor is not installed and activated.
317
+ *
318
+ * @since 1.0.0
319
+ *
320
+ * @return void
321
+ */
322
+ public function fails_to_load() {
323
+
324
+ $screen = get_current_screen();
325
+
326
+ if ( isset( $screen->parent_file ) && 'plugins.php' === $screen->parent_file && 'update' === $screen->id ) {
327
+ return;
328
+ }
329
+
330
+ $class = 'notice notice-error';
331
+ /* translators: %s: html tags */
332
+ $message = sprintf( __( 'The %1$sCartFlows%2$s plugin requires %1$sWooCommerce%2$s plugin installed & activated.', 'cartflows' ), '<strong>', '</strong>' );
333
+
334
+ $plugin = 'woocommerce/woocommerce.php';
335
+
336
+ if ( _is_woo_installed() ) {
337
+ if ( ! current_user_can( 'activate_plugins' ) ) {
338
+ return;
339
+ }
340
+
341
+ $action_url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin );
342
+ $button_label = __( 'Activate WooCommerce', 'cartflows' );
343
+
344
+ } else {
345
+ if ( ! current_user_can( 'install_plugins' ) ) {
346
+ return;
347
+ }
348
+
349
+ $action_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=woocommerce' ), 'install-plugin_woocommerce' );
350
+ $button_label = __( 'Install WooCommerce', 'cartflows' );
351
+ }
352
+
353
+ $button = '<p><a href="' . $action_url . '" class="button-primary">' . $button_label . '</a></p><p></p>';
354
+
355
+ printf( '<div class="%1$s"><p>%2$s</p>%3$s</div>', esc_attr( $class ), $message, $button );
356
+ }
357
+
358
+ /**
359
+ * Activation Reset
360
+ */
361
+ function activation_reset() {
362
+
363
+ include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-flow-post-type.php';
364
+ include_once CARTFLOWS_DIR . 'modules/flow/classes/class-cartflows-step-post-type.php';
365
+
366
+ Cartflows_Flow_Post_Type::get_instance()->flow_post_type();
367
+ Cartflows_Step_Post_Type::get_instance()->step_post_type();
368
+ flush_rewrite_rules();
369
+ }
370
+
371
+ /**
372
+ * Deactivation Reset
373
+ */
374
+ function deactivation_reset() {
375
+ }
376
+
377
+ /**
378
+ * Logger Class Instance
379
+ */
380
+ function logger() {
381
+ return Cartflows_Logger::get_instance();
382
+ }
383
+
384
+
385
+ }
386
+
387
+ /**
388
+ * Prepare if class 'Cartflows_Loader' exist.
389
+ * Kicking this off by calling 'get_instance()' method
390
+ */
391
+ Cartflows_Loader::get_instance();
392
+ }
393
+
394
+ /**
395
+ * Get global class.
396
+ *
397
+ * @return object
398
+ */
399
+ function wcf() {
400
+ return Cartflows_Loader::get_instance();
401
+ }
402
+
403
+ if ( ! function_exists( '_is_woo_installed' ) ) {
404
+
405
+ /**
406
+ * Is woocommerce plugin installed.
407
+ *
408
+ * @since 1.0.0
409
+ *
410
+ * @access public
411
+ */
412
+ function _is_woo_installed() {
413
+
414
+ $path = 'woocommerce/woocommerce.php';
415
+ $plugins = get_plugins();
416
+
417
+ return isset( $plugins[ $path ] );
418
+ }
419
+ }
classes/class-cartflows-meta-fields.php CHANGED
@@ -1,962 +1,993 @@
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_number_field( $field_data ) {
428
-
429
- $value = $field_data['value'];
430
-
431
- $attr = '';
432
-
433
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
434
-
435
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
436
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
437
- }
438
- }
439
-
440
- $field_content = '<input type="number" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
441
-
442
- return $this->get_field( $field_data, $field_content );
443
- }
444
-
445
- function get_hidden_field( $field_data ) {
446
-
447
- $value = $field_data['value'];
448
-
449
- $attr = '';
450
-
451
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
452
-
453
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
454
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
455
- }
456
- }
457
-
458
- $field_content = '<input type="hidden" id="' . $field_data['name'] . '" name="' . $field_data['name'] . '" value="' . $value . '" ' . $attr . '>';
459
-
460
- return $this->get_field( $field_data, $field_content );
461
- }
462
-
463
- function get_area_field( $field_data ) {
464
-
465
- $value = $field_data['value'];
466
-
467
- $field_content = '<textarea name="' . $field_data['name'] . '" rows="10" cols="50">';
468
- $field_content .= $value;
469
- $field_content .= '</textarea>';
470
-
471
- return $this->get_field( $field_data, $field_content );
472
- }
473
-
474
- function get_checkbox_field( $field_data ) {
475
-
476
- $value = $field_data['value'];
477
-
478
- $field_content = '';
479
- if ( isset( $field_data['before'] ) ) {
480
- $field_content .= '<span>' . $field_data['before'] . '</span>';
481
- }
482
- $field_content .= '<input type="hidden" name="' . $field_data['name'] . '" value="no">';
483
- $field_content .= '<input type="checkbox" name="' . $field_data['name'] . '" value="yes" ' . checked( 'yes', $value, false ) . '>';
484
-
485
- if ( isset( $field_data['after'] ) ) {
486
- $field_content .= '<span>' . $field_data['after'] . '</span>';
487
- }
488
-
489
- return $this->get_field( $field_data, $field_content );
490
- }
491
-
492
- function get_font_family_field( $field_data ) {
493
-
494
- $value = $field_data['value'];
495
-
496
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
497
-
498
- $field_content = '<select class="wcf-field-font-family" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
499
-
500
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
501
-
502
- $field_content .= '<optgroup label="Other System Fonts">';
503
- foreach ( CartFlows_Font_Families::get_system_fonts() as $name => $variants ) {
504
- $field_content .= '<option value="' . esc_attr( $name ) . '" ' . selected( $name, $value, false ) . '>' . esc_attr( $name ) . '</option>';
505
- }
506
- $field_content .= '</optgroup>';
507
- $field_content .= '<optgroup label="Google">';
508
- foreach ( CartFlows_Font_Families::get_google_fonts() as $name => $single_font ) {
509
- $variants = wcf_get_prop( $single_font, '0' );
510
- $category = wcf_get_prop( $single_font, '1' );
511
- $font_value = '\'' . esc_attr( $name ) . '\', ' . esc_attr( $category );
512
- $field_content .= '<option value="' . esc_attr( $font_value ) . '" ' . selected( $font_value, $value, false ) . '>' . esc_attr( $name ) . '</option>';
513
- }
514
- $field_content .= '</optgroup>';
515
-
516
- $field_content .= '</select>';
517
-
518
- return $this->get_field( $field_data, $field_content );
519
- }
520
-
521
- function get_font_weight_field( $field_data ) {
522
-
523
- $value = $field_data['value'];
524
-
525
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
526
-
527
- $field_content = '<select data-selected="'.esc_attr( $value ).'" class="wcf-field-font-weight" data-for="' . $field_data['for'] . '" name="' . $field_data['name'] . '">';
528
-
529
- $field_content .= '<option value="" ' . selected( '', $value, false ) . '>Default</option>';
530
-
531
- $field_content .= '</select>';
532
-
533
- return $this->get_field( $field_data, $field_content );
534
- }
535
-
536
- function get_select_field( $field_data ) {
537
-
538
- $value = $field_data['value'];
539
- $pro_options = isset( $field_data['pro-options'] ) ? $field_data['pro-options'] : array();
540
-
541
- $field_content = '<select name="' . $field_data['name'] . '">';
542
-
543
-
544
- if ( is_array( $field_data['options'] ) && ! empty( $field_data['options'] ) ) {
545
-
546
- foreach ( $field_data['options'] as $data_key => $data_value ) {
547
-
548
- $disabled = '';
549
-
550
- if ( array_key_exists( $data_key, $pro_options ) ) {
551
- $disabled = 'disabled ';
552
- $data_value = $pro_options[ $data_key ];
553
- }
554
-
555
- $field_content .= '<option value="' . $data_key . '" ' . selected( $value, $data_key, false ) . ' ' . $disabled .'>' . $data_value . '</option>';
556
- }
557
- }
558
-
559
- $field_content .= '</select>';
560
-
561
- if ( isset( $field_data['after'] ) ) {
562
- $field_content .= '<span>' . $field_data['after'] . '</span>';
563
- }
564
-
565
- return $this->get_field( $field_data, $field_content );
566
- }
567
-
568
- function get_color_picker_field( $field_data ) {
569
-
570
- $value = $field_data['value'];
571
-
572
- $field_content = '<input class="wcf-color-picker" type="text" name="' . $field_data['name'] . '" value="' . $value . '">';
573
-
574
- return $this->get_field( $field_data, $field_content );
575
- }
576
-
577
- function get_product_selection_field( $field_data ) {
578
-
579
- $value = $field_data['value'];
580
-
581
- $multiple = '';
582
-
583
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
584
- $multiple = ' multiple="multiple"';
585
- }
586
-
587
- $allow_clear = '';
588
-
589
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
590
- $allow_clear = ' data-allow_clear="allow_clear"';
591
- }
592
-
593
- $field_content = '<select
594
- name="' . $field_data['name'] . '[]"
595
- class="wcf-product-search" ' . $multiple . $allow_clear . '
596
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
597
- data-action="woocommerce_json_search_products_and_variations">';
598
-
599
- if ( is_array( $value ) && ! empty( $value ) ) {
600
-
601
- foreach ( $value as $data_key => $product_id ) {
602
-
603
- $product = wc_get_product( $product_id );
604
-
605
- // posts.
606
- if ( ! empty( $product ) ) {
607
- $post_title = $product->get_name() . ' (#' . $product_id . ')';
608
-
609
- $field_content .= '<option value="' . $product_id . '" selected="selected" >' . $post_title . '</option>';
610
- }
611
- }
612
- }
613
- $field_content .= '</select>';
614
-
615
- return $this->get_field( $field_data, $field_content );
616
- }
617
-
618
- function get_coupon_selection_field( $field_data ) {
619
-
620
- $value = $field_data['value'];
621
-
622
- $multiple = '';
623
-
624
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
625
- $multiple = ' multiple="multiple"';
626
- }
627
-
628
- $allow_clear = '';
629
-
630
- if ( isset( $field_data['allow_clear'] ) && $field_data['allow_clear'] ) {
631
- $allow_clear = ' data-allow_clear="allow_clear"';
632
- }
633
-
634
- $field_content = '<select
635
- name="' . $field_data['name'] . '[]"
636
- class="wc-coupon-search wcf-coupon-search" ' . $multiple . $allow_clear . '
637
- data-placeholder="' . __( 'Search for a coupon&hellip;', 'cartflows' ) . '"
638
- data-action="wcf_json_search_coupons">';
639
-
640
- if ( is_array( $value ) && ! empty( $value ) ) {
641
-
642
- $all_discount_types = wc_get_coupon_types();
643
-
644
- foreach ( $value as $coupon_title ) {
645
-
646
- $coupon = new WC_Coupon( $coupon_title );
647
-
648
- $discount_type = $coupon->get_discount_type();
649
-
650
- if ( isset( $discount_type ) && $discount_type ) {
651
- $discount_type = ' ( Type: ' . $all_discount_types[ $discount_type ] . ' )';
652
- }
653
-
654
- $field_content .= '<option value="' . $coupon_title . '" selected="selected">' . $coupon_title . $discount_type . '</option>';
655
- }
656
- }
657
-
658
- $field_content .= '</select>';
659
-
660
- return $this->get_field( $field_data, $field_content );
661
- }
662
-
663
- function get_page_selection_field( $field_data ) {
664
-
665
- $value = $field_data['value'];
666
-
667
- $multiple = '';
668
-
669
- if ( isset( $field_data['multiple'] ) && $field_data['multiple'] ) {
670
- $multiple = 'multiple="multiple"';
671
- }
672
-
673
- $field_content = '<select
674
- name="' . $field_data['name'] . '[]"
675
- class="wcf-search-pages" ' . $multiple . '"
676
- data-action="wcf_json_search_pages">';
677
-
678
- if ( is_array( $value ) && ! empty( $value ) ) {
679
-
680
- foreach ( $value as $data_key => $data_value ) {
681
-
682
- $field_content .= '<option value="' . $data_value . '">' . get_the_title( $data_value ) . '</option>';
683
- }
684
- }
685
-
686
- $field_content .= '</select>';
687
-
688
- return $this->get_field( $field_data, $field_content );
689
- }
690
-
691
- function get_section( $field_data ) {
692
- $field_html = '<div class="wcf-field-row wcf-field-section">';
693
- $field_html .= '<div class="wcf-field-section-heading" colspan="2">';
694
- $field_html .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
695
-
696
- if ( isset( $field_data['help'] ) ) {
697
- $field_html .= '<i class="wcf-field-heading-help dashicons dashicons-editor-help" title="' . esc_attr( $field_data['help'] ) . '"></i>';
698
- }
699
- $field_html .= '</div>';
700
- $field_html .= '</div>';
701
- return $field_html;
702
- }
703
-
704
- function get_description_field( $field_data ) {
705
-
706
- $field_html = '<div class="wcf-field-row wcf-field-desc ' . $field_data['name'] . '">';
707
- $field_html .= '<div class="wcf-field-desc-content">';
708
- $field_html .= $field_data['content'];
709
- $field_html .= '</div>';
710
- $field_html .= '</div>';
711
-
712
- return $field_html;
713
- }
714
-
715
- function get_checkout_field_repeater( $field_data ) {
716
-
717
- $value = array();
718
-
719
- $value[0] = array(
720
- 'add_to' => '',
721
- 'type' => '',
722
- 'label' => '',
723
- 'name' => '',
724
- );
725
-
726
- $field_content = '';
727
-
728
- $field_content .= '<div class="wcf-field-row">';
729
- // $field_content .= '<div class="wcf-field-row-heading">';
730
- // $field_content .= '<label>' . esc_html( $field_data['label'] ) . '</label>';
731
- // $field_content .= '</div>';
732
- $field_content .= '<div class="wcf-field-row-content">';
733
- $field_content .= '<div class="wcf-cpf-wrap">';
734
-
735
- foreach ( $value as $p_key => $p_data ) {
736
- $field_content .= '<div class="wcf-cpf-row" data-key="' . $p_key . '">';
737
- $field_content .= '<div class="wcf-cpf-row-header">';
738
- $field_content .= '<span class="wcf-cpf-row-title">Add New Custom Field</span>';
739
- $field_content .= '</div>';
740
-
741
- $field_content .= '<div class="wcf-cpf-row-standard-fields">';
742
-
743
- /* Add To */
744
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-add_to">';
745
- $field_content .= '<span class="wcf-cpf-row-setting-label">Add to</span>';
746
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
747
- $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][add_to]" class="wcf-cpf-add_to">';
748
- $field_content .= '<option value="billing">Billing</option>';
749
- $field_content .= '<option value="shipping">Shipping</option>';
750
- $field_content .= '</select>';
751
- $field_content .= '</span>';
752
- $field_content .= '</div>';
753
-
754
- /* Type */
755
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-type">';
756
- $field_content .= '<span class="wcf-cpf-row-setting-label">Type</span>';
757
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
758
- $field_content .= '<select name="wcf-checkout-custom-fields[' . $p_key . '][type]" class="wcf-cpf-type">';
759
- $field_content .= '<option value="text">Text</option>';
760
- $field_content .= '<option value="textarea">Textarea</option>';
761
- $field_content .= '<option value="select">Select</option>';
762
- $field_content .= '<option value="checkbox">Checkbox</option>';
763
- $field_content .= '</select>';
764
- $field_content .= '</span>';
765
- $field_content .= '</div>';
766
-
767
- /* Textarea */
768
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-options">';
769
- $field_content .= '<span class="wcf-cpf-row-setting-label">Options *</span>';
770
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
771
- $field_content .= '<textarea value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-options" placeholder="Enter your options separated by comma."></textarea>';
772
- $field_content .= '</span>';
773
- $field_content .= '</div>';
774
-
775
- /* Label */
776
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-label">';
777
- $field_content .= '<span class="wcf-cpf-row-setting-label">Label *</span>';
778
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
779
- $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][label]" class="wcf-cpf-label">';
780
- $field_content .= '</span>';
781
- $field_content .= '</div>';
782
-
783
- /* Name */
784
- $field_content .= '<div class="wcf-cpf-fields wcf-cpf-name">';
785
- $field_content .= '<span class="wcf-cpf-row-setting-label">Name *</span>';
786
- $field_content .= '<span class="wcf-cpf-row-setting-field">';
787
- $field_content .= '<input type="text" value="" name="wcf-checkout-custom-fields[' . $p_key . '][name]" class="wcf-cpf-name">';
788
- $field_content .= '</span>';
789
- $field_content .= '</div>';
790
-
791
- $field_content .= '</div>';
792
- $field_content .= '</div>';
793
- }
794
-
795
- /* Add New Custom Field */
796
- $field_content .= '<div class="wcf-cpf-add-row">';
797
- $field_content .= '<div class="wcf-cpf-add-wrap">';
798
- $field_content .= '<button class="button button-secondary wcf-cpf-add" data-name="wcf-checkout-custom-fields">Add New Field</button>';
799
- $field_content .= '</div>';
800
- $field_content .= '</div>';
801
- /* End Add new custom field */
802
-
803
- $field_content .= '</div>';
804
- $field_content .= '</div>';
805
- $field_content .= '</div>';
806
-
807
- return $field_content;
808
- }
809
-
810
- function get_product_selection_repeater( $field_data ) {
811
-
812
- $value = $field_data['value'];
813
-
814
- if ( ! is_array( $value ) ) {
815
-
816
- $value[0] = array(
817
- 'product' => '',
818
- );
819
- } else {
820
-
821
- if ( ! isset( $value[0] ) ) {
822
-
823
- $value[0] = array(
824
- 'product' => '',
825
- );
826
- }
827
- }
828
-
829
- $field_html = '';
830
-
831
- $field_html .= '<script type="text/html" id="tmpl-wcf-product-repeater">';
832
- $field_html .= $this->generate_product_repeater_html( '{{id}}' );
833
- $field_html .= '</script>';
834
-
835
- $field_html .= '<div class="wcf-field-row">';
836
- $field_html .= '<div class="wcf-field-row-content">';
837
- $field_html .= '<div class="wcf-repeatables-wrap">';
838
-
839
- if ( is_array( $value ) ) {
840
-
841
- foreach ( $value as $p_key => $p_data ) {
842
-
843
- $selected_options = '';
844
-
845
- if ( isset( $p_data['product'] ) ) {
846
-
847
- $product = wc_get_product( $p_data['product'] );
848
-
849
- // posts.
850
- if ( ! empty( $product ) ) {
851
- $post_title = $product->get_name() . ' (#' . $p_data['product'] . ')';
852
-
853
- $selected_options = '<option value="' . $p_data['product'] . '" selected="selected" >' . $post_title . '</option>';
854
- }
855
- }
856
-
857
- $field_html .= $this->generate_product_repeater_html( $p_key, $selected_options );
858
- }
859
- }
860
-
861
- $field_html .= '<div class="wcf-add-repeatable-row">';
862
- $field_html .= '<div class="submit wcf-add-repeatable-wrap">';
863
- $field_html .= '<button class="button-primary wcf-add-repeatable" data-name="wcf-checkout-products">Add New Product</button>';
864
- $field_html .= '</div>';
865
- $field_html .= '</div>';
866
- $field_html .= '</div>';
867
- $field_html .= '</div>';
868
- $field_html .= '</div>';
869
-
870
- $field_html .= '<div class="wcf-field-row wcf-repeat-notice">';
871
- $field_html .= '<p><i>The selected products will be automatically added in the cart for this checkout.</i></p>';
872
- $field_html .= '</div>';
873
-
874
- return $field_html;
875
- }
876
-
877
- function generate_product_repeater_html( $id, $options = '' ) {
878
-
879
- $field_html = '<div class="wcf-repeatable-row" data-key="' . $id . '">';
880
-
881
- $field_html .= '<div class="wcf-repeatable-row-standard-fields">';
882
-
883
- /* Product Name */
884
- $field_html .= '<div class="wcf-repeatable-fields wcf-sel-product">';
885
- $field_html .= '<span class="wcf-repeatable-row-setting-field">';
886
- $field_html .= '<select
887
- name="wcf-checkout-products[' . $id . '][product]"
888
- class="wcf-product-search"
889
- data-allow_clear="allow_clear"
890
- data-placeholder="' . __( 'Search for a product&hellip;', 'cartflows' ) . '"
891
- data-action="woocommerce_json_search_products_and_variations">';
892
- $field_html .= $options;
893
- $field_html .= '</select>';
894
- $field_html .= '</span>';
895
- $field_html .= '<span class="wcf-repeatable-row-actions">';
896
- $field_html .= '<a class="wcf-remove-row wcf-repeatable-remove button" data-type="product">';
897
- $field_html .= '<span class="dashicons dashicons-trash"></span>';
898
- $field_html .= '<span class="wcf-repeatable-remove-button">'. __( 'Remove', 'cartflows' ).'</span>';
899
- $field_html .= '</a>';
900
- $field_html .= '</span>';
901
- $field_html .= '</div>';
902
- $field_html .= '</div>';
903
- $field_html .= '</div>';
904
-
905
- return $field_html;
906
- }
907
-
908
- function get_image_field( $field_data ) {
909
-
910
- $value = $field_data['value'];
911
-
912
- $attr = '';
913
-
914
- if ( isset( $field_data['attr'] ) && is_array( $field_data['attr'] ) ) {
915
-
916
- foreach ( $field_data['attr'] as $attr_key => $attr_value ) {
917
- $attr .= ' ' . $attr_key . '="' . $attr_value . '"';
918
- }
919
- }
920
-
921
- $display_preview_box = ( isset( $value ) && '' != $value ) ? 'display:block;' : 'display:none';
922
-
923
- $field_content = '<div id="wcf-image-preview" style="'.$display_preview_box.'">';
924
- if( isset( $value ) ){
925
- $field_content .= '<img src="'. $value .'" class="saved-image" name="'. $field_data['name'] .'" width="150">';
926
- }
927
- $field_content .= '</div>';
928
- // $field_content .= '<input type="hidden" id="wcf-image-id" class="wcf-image-id" name="wcf-image-id[image-id]" value="">';
929
- $field_content .= '<input type="hidden" id="wcf-image-value" class="wcf-image" name="' . $field_data['name'] . '" value="'.$value.'">';
930
-
931
- $field_content .= '<button type="button" ' . $attr . ' class="wcf-select-image button-secondary">Select Image</button>';
932
-
933
- $display_remove_button = ( isset( $value ) && '' != $value ) ? 'display:inline-block; margin-left: 5px;' : 'display:none';
934
-
935
- $field_content .= '<button type="button" class="wcf-remove-image button-secondary" style="'.$display_remove_button.'">Remove Image</button>';
936
-
937
- return $this->get_field( $field_data, $field_content );
938
- }
939
-
940
- /**
941
- * Localize variables in admin
942
- *
943
- * @param array $vars variables.
944
- */
945
- function localize_vars( $vars ) {
946
-
947
- $ajax_actions = array(
948
- 'wcf_add_checkout_custom_field',
949
- 'wcf_delete_checkout_custom_field',
950
- 'wcf_json_search_pages',
951
- 'wcf_json_search_coupons'
952
- );
953
-
954
- foreach ( $ajax_actions as $action ) {
955
-
956
- $vars[ $action . '_nonce' ] = wp_create_nonce( str_replace( '_', '-', $action ) );
957
- }
958
-
959
- return $vars;
960
- }
961
- }
962
- // @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
+ $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
languages/cartflows.pot CHANGED
@@ -1,14 +1,14 @@
1
- # Copyright (C) 2018 CartFlows Inc
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: CartFlows 1.1.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cartflows\n"
7
- "POT-Creation-Date: 2018-12-05 10:58:39+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
  "Language: en\n"
@@ -60,31 +60,30 @@ msgstr ""
60
  msgid "Flows Library"
61
  msgstr ""
62
 
63
- #: classes/class-cartflows-admin.php:306 classes/class-cartflows-wizard.php:273
64
- #: modules/flow/view/meta-flow-steps.php:141
65
- msgid "Elementor"
66
- msgstr ""
67
-
68
  #: classes/class-cartflows-admin.php:307
69
  #: modules/flow/view/meta-flow-steps.php:142
70
- msgid "Divi"
71
  msgstr ""
72
 
73
- #: classes/class-cartflows-admin.php:308
74
- #: modules/flow/view/meta-flow-steps.php:143
75
- msgid "Beaver Builder"
76
  msgstr ""
77
 
78
  #: classes/class-cartflows-admin.php:320
79
- #: modules/flow/view/meta-flow-steps.php:153
80
  msgid "Search Sites"
81
  msgstr ""
82
 
83
  #: classes/class-cartflows-admin.php:321
84
- #: modules/flow/view/meta-flow-steps.php:154
85
  msgid "Search Flow..."
86
  msgstr ""
87
 
 
 
 
 
88
  #: classes/class-cartflows-api.php:363
89
  msgid "Request successfully processed!"
90
  msgstr ""
@@ -99,146 +98,130 @@ msgstr ""
99
 
100
  #: classes/class-cartflows-flow-frontend.php:52
101
  msgid ""
102
- "NOTE: Test mode is active — which may display any random products for the "
103
- "sake of preview."
104
  msgstr ""
105
 
106
- #: classes/class-cartflows-importer.php:89
107
  msgid "Loading Steps"
108
  msgstr ""
109
 
110
- #: classes/class-cartflows-importer.php:91
111
  msgid "Getting steps from the cloud. Please wait for the moment."
112
  msgstr ""
113
 
114
- #: classes/class-cartflows-importer.php:102
115
  msgid "Searching Template.."
116
  msgstr ""
117
 
118
- #: classes/class-cartflows-importer.php:104
119
  msgid "Getting templates from the cloud. Please wait for the moment."
120
  msgstr ""
121
 
122
- #: classes/class-cartflows-importer.php:113
123
  msgid "Importing.."
124
  msgstr ""
125
 
126
- #: classes/class-cartflows-importer.php:122
127
- #: classes/class-cartflows-importer.php:162
128
  msgid "Imported"
129
  msgstr ""
130
 
131
- #: classes/class-cartflows-importer.php:123
132
- #: classes/class-cartflows-importer.php:163
133
- msgid "Thanks for patience"
134
- msgstr ""
135
-
136
  #: classes/class-cartflows-importer.php:132
137
- msgid "Steps not found!"
138
- msgstr ""
139
-
140
- #: classes/class-cartflows-importer.php:133
141
- msgid "We'll provide the ready made steps to import."
142
- msgstr ""
143
-
144
- #: classes/class-cartflows-importer.php:144
145
- msgid "Flows not found!"
146
  msgstr ""
147
 
148
- #: classes/class-cartflows-importer.php:145
149
- msgid "We'll provide the ready made flows to import."
 
150
  msgstr ""
151
 
152
- #: classes/class-cartflows-importer.php:163
153
  msgid "Redirecting to the Elementor edit window."
154
  msgstr ""
155
 
156
- #: classes/class-cartflows-importer.php:193
157
- msgid "Canvas"
158
- msgstr ""
159
-
160
- #: classes/class-cartflows-importer.php:195
161
- msgid "Create Flow"
162
- msgstr ""
163
-
164
- #: classes/class-cartflows-importer.php:206
165
- msgid "Import"
166
- msgstr ""
167
-
168
- #: classes/class-cartflows-importer.php:216
169
- msgid "Activate Elementor & Import"
170
- msgstr ""
171
-
172
  #: classes/class-cartflows-importer.php:218
173
- msgid "Install Elementor & Import"
174
- msgstr ""
175
-
176
- #: classes/class-cartflows-importer.php:246
177
- #: classes/class-cartflows-importer.php:317
178
  msgid "Pro"
179
  msgstr ""
180
 
181
- #: classes/class-cartflows-importer.php:256
182
- #: classes/class-cartflows-importer.php:326
183
  msgid "Activate License"
184
  msgstr ""
185
 
186
- #: classes/class-cartflows-importer.php:258
187
- #: classes/class-cartflows-importer.php:328
188
  msgid "Get Pro"
189
  msgstr ""
190
 
191
- #: classes/class-cartflows-importer.php:283
192
  msgid "Create"
193
  msgstr ""
194
 
195
- #: classes/class-cartflows-importer.php:386
 
 
 
 
 
 
 
 
196
  msgid "Import from Cloud"
197
  msgstr ""
198
 
199
- #: classes/class-cartflows-importer.php:645
 
 
 
 
 
 
 
200
  #: modules/flow/classes/class-cartflows-flow-meta.php:224
201
  msgid "Landing Page"
202
  msgstr ""
203
 
204
- #: classes/class-cartflows-importer.php:646
205
  #: modules/flow/classes/class-cartflows-flow-meta.php:225
206
  msgid "Checkout Page"
207
  msgstr ""
208
 
209
- #: classes/class-cartflows-importer.php:647
210
  #: modules/flow/classes/class-cartflows-flow-meta.php:226
211
  msgid "Thank You Page"
212
  msgstr ""
213
 
214
- #: classes/class-cartflows-importer.php:752
215
  #. translators: %s: template ID
216
  msgid "Invalid template id %1$s or post id %2$s."
217
  msgstr ""
218
 
219
- #: classes/class-cartflows-importer.php:796
220
  #. translators: %s: flow ID
221
- msgid "Invalid flow id %1$s or step type %2$s."
222
  msgstr ""
223
 
224
- #: classes/class-cartflows-importer.php:916
225
  msgid ""
226
  "Elementor is not activated. Please activate plugin Elementor Page Builder "
227
  "to import the step."
228
  msgstr ""
229
 
230
- #: classes/class-cartflows-loader.php:329
231
  #. translators: %s: html tags
232
  msgid ""
233
  "The %1$sCartFlows%2$s plugin requires %1$sWooCommerce%2$s plugin installed "
234
  "& activated."
235
  msgstr ""
236
 
237
- #: classes/class-cartflows-loader.php:339
238
  msgid "Activate WooCommerce"
239
  msgstr ""
240
 
241
- #: classes/class-cartflows-loader.php:347
242
  msgid "Install WooCommerce"
243
  msgstr ""
244
 
@@ -279,16 +262,16 @@ msgid "Ultra-Bold 900"
279
  msgstr ""
280
 
281
  #: classes/class-cartflows-meta-fields.php:214
282
- #: classes/class-cartflows-meta-fields.php:898
283
  msgid "Remove"
284
  msgstr ""
285
 
286
- #: classes/class-cartflows-meta-fields.php:596
287
- #: classes/class-cartflows-meta-fields.php:890
288
  msgid "Search for a product&hellip;"
289
  msgstr ""
290
 
291
- #: classes/class-cartflows-meta-fields.php:637
292
  msgid "Search for a coupon&hellip;"
293
  msgstr ""
294
 
@@ -352,6 +335,10 @@ msgstr ""
352
  msgid "Add locations for where this Schema should appear."
353
  msgstr ""
354
 
 
 
 
 
355
  #: classes/class-cartflows-wizard.php:294
356
  msgid "The above plugin will be installed and activated for you!"
357
  msgstr ""
@@ -456,23 +443,23 @@ msgstr ""
456
  msgid "Submit a Ticket »"
457
  msgstr ""
458
 
459
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:153
460
  msgid "Checkout ID not found"
461
  msgstr ""
462
 
463
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:309
464
  msgid "Variations Not set"
465
  msgstr ""
466
 
467
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:317
468
  msgid "This product can't be purcahsed"
469
  msgstr ""
470
 
471
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:858
472
  msgid "Coupon Code"
473
  msgstr ""
474
 
475
- #: modules/checkout/classes/class-cartflows-checkout-markup.php:863
476
  msgid "Apply"
477
  msgstr ""
478
 
@@ -688,7 +675,7 @@ msgstr ""
688
  msgid "Logo Width (In px)"
689
  msgstr ""
690
 
691
- #: modules/checkout/templates/embed/checkout-template-simple.php:22
692
  #: modules/checkout/templates/wcf-template.php:36
693
  msgid "Your cart is currently empty."
694
  msgstr ""
@@ -746,8 +733,8 @@ msgstr ""
746
 
747
  #: modules/flow/classes/class-cartflows-flow-meta.php:613
748
  msgid ""
749
- "Test mode enables you to preview your pages with random products for the "
750
- "sake of testing."
751
  msgstr ""
752
 
753
  #: modules/flow/classes/class-cartflows-flow-post-type.php:57
@@ -931,13 +918,17 @@ msgid "Add New Step"
931
  msgstr ""
932
 
933
  #: modules/flow/view/meta-flow-steps.php:136
934
- msgid "Templates"
935
  msgstr ""
936
 
937
- #: modules/flow/view/meta-flow-steps.php:157
938
  msgid "You need a Cartflows Pro version to import Upsell / Downsell"
939
  msgstr ""
940
 
 
 
 
 
941
  #: modules/landing/classes/class-cartflows-landing-meta.php:66
942
  msgid "Landing Page Settings"
943
  msgstr ""
1
+ # Copyright (C) 2019 CartFlows Inc
2
  # This file is distributed under the same license as the CartFlows package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: CartFlows 1.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"
11
+ "PO-Revision-Date: 2019-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
  "Language: en\n"
60
  msgid "Flows Library"
61
  msgstr ""
62
 
 
 
 
 
 
63
  #: classes/class-cartflows-admin.php:307
64
  #: modules/flow/view/meta-flow-steps.php:142
65
+ msgid "Ready Templates"
66
  msgstr ""
67
 
68
+ #: classes/class-cartflows-admin.php:310
69
+ #: modules/flow/view/meta-flow-steps.php:145
70
+ msgid "Create Your Own"
71
  msgstr ""
72
 
73
  #: classes/class-cartflows-admin.php:320
74
+ #: modules/flow/view/meta-flow-steps.php:156
75
  msgid "Search Sites"
76
  msgstr ""
77
 
78
  #: classes/class-cartflows-admin.php:321
79
+ #: modules/flow/view/meta-flow-steps.php:157
80
  msgid "Search Flow..."
81
  msgstr ""
82
 
83
+ #: classes/class-cartflows-admin.php:336
84
+ msgid "Design Your Flow"
85
+ msgstr ""
86
+
87
  #: classes/class-cartflows-api.php:363
88
  msgid "Request successfully processed!"
89
  msgstr ""
98
 
99
  #: classes/class-cartflows-flow-frontend.php:52
100
  msgid ""
101
+ "Test mode is active — which displays random products for previewing. It can "
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."
211
  msgstr ""
212
 
213
+ #: classes/class-cartflows-loader.php:332
214
  #. translators: %s: html tags
215
  msgid ""
216
  "The %1$sCartFlows%2$s plugin requires %1$sWooCommerce%2$s plugin installed "
217
  "& activated."
218
  msgstr ""
219
 
220
+ #: classes/class-cartflows-loader.php:342
221
  msgid "Activate WooCommerce"
222
  msgstr ""
223
 
224
+ #: classes/class-cartflows-loader.php:350
225
  msgid "Install WooCommerce"
226
  msgstr ""
227
 
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
 
274
+ #: classes/class-cartflows-meta-fields.php:668
275
  msgid "Search for a coupon&hellip;"
276
  msgstr ""
277
 
335
  msgid "Add locations for where this Schema should appear."
336
  msgstr ""
337
 
338
+ #: classes/class-cartflows-wizard.php:273
339
+ msgid "Elementor"
340
+ msgstr ""
341
+
342
  #: classes/class-cartflows-wizard.php:294
343
  msgid "The above plugin will be installed and activated for you!"
344
  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 ""
449
 
450
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:327
451
  msgid "Variations Not set"
452
  msgstr ""
453
 
454
+ #: modules/checkout/classes/class-cartflows-checkout-markup.php:336
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
 
675
  msgid "Logo Width (In px)"
676
  msgstr ""
677
 
678
+ #: modules/checkout/templates/embed/checkout-template-simple.php:25
679
  #: modules/checkout/templates/wcf-template.php:36
680
  msgid "Your cart is currently empty."
681
  msgstr ""
733
 
734
  #: modules/flow/classes/class-cartflows-flow-meta.php:613
735
  msgid ""
736
+ "Test mode adds random products in your flow, so you can preview it easily "
737
+ "while testing."
738
  msgstr ""
739
 
740
  #: modules/flow/classes/class-cartflows-flow-post-type.php:57
918
  msgstr ""
919
 
920
  #: modules/flow/view/meta-flow-steps.php:136
921
+ msgid "Steps Library"
922
  msgstr ""
923
 
924
+ #: modules/flow/view/meta-flow-steps.php:160
925
  msgid "You need a Cartflows Pro version to import Upsell / Downsell"
926
  msgstr ""
927
 
928
+ #: modules/flow/view/meta-flow-steps.php:175
929
+ msgid "Create Step"
930
+ msgstr ""
931
+
932
  #: modules/landing/classes/class-cartflows-landing-meta.php:66
933
  msgid "Landing Page Settings"
934
  msgstr ""
modules/checkout/classes/class-cartflows-checkout-markup.php CHANGED
@@ -1,942 +1,983 @@
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
- /* Checkout Shortcode */
43
- add_shortcode( 'cartflows_checkout', array( $this, 'checkout_shortcode_markup' ) );
44
-
45
- /* Preconfigured cart data */
46
- add_action( 'wp', array( $this, 'preconfigured_cart_data' ), 1 );
47
-
48
- /* Embed Checkout */
49
- add_action( 'wp', array( $this, 'shortcode_load_data' ), 999 );
50
-
51
- /* Ajax Endpoint */
52
- add_filter( 'woocommerce_ajax_get_endpoint', array( $this, 'get_ajax_endpoint' ) );
53
-
54
- add_filter( 'cartflows_add_before_main_section', array( $this, 'enable_logo_in_header' ) );
55
-
56
- add_filter( 'cartflows_primary_container_bottom', array( $this, 'show_cartflows_copyright_message' ) );
57
-
58
- add_filter( 'woocommerce_login_redirect', array( $this, 'after_login_redirect' ), 10, 2 );
59
-
60
- add_action( 'wp_ajax_cf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
61
- add_action( 'wp_ajax_nopriv_cf_woo_apply_coupon', array( $this, 'apply_coupon' ) );
62
-
63
- add_filter( 'global_cartflows_js_localize', array( $this, 'add_localize_vars' ) );
64
-
65
- /* Global Checkout */
66
- add_action( 'template_redirect', array( $this, 'global_checkout_template_redirect' ), 1 );
67
- }
68
-
69
- /**
70
- * Redirect from default to the global checkout page
71
- *
72
- * @since 1.0.0
73
- */
74
- function global_checkout_template_redirect() {
75
-
76
- if ( ! is_checkout() ) {
77
- return;
78
- }
79
-
80
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
81
- return;
82
- }
83
-
84
- // redirect only from any non HC checkout pages.
85
- $order_pay_endpoint = get_option( 'woocommerce_checkout_order_pay_endpoint', 'order-pay' );
86
- $order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
87
-
88
- $common = Cartflows_Helper::get_common_settings();
89
-
90
- $global_checkout = $common['global_checkout'];
91
-
92
- if (
93
- // ignore on order-pay.
94
- false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_pay_endpoint . '/' ) &&
95
- // ignore on TY page.
96
- false === mb_strpos( $_SERVER['REQUEST_URI'], '/' . $order_received_endpoint . '/' )
97
- ) {
98
-
99
- if ( '' !== $global_checkout ) {
100
-
101
- $link = get_permalink( $global_checkout );
102
-
103
- if ( ! empty( $link ) ) {
104
-
105
- wp_redirect( $link );
106
- die();
107
- }
108
- }
109
- }
110
- }
111
-
112
- /**
113
- * Check for checkout flag
114
- *
115
- * @param bool $is_checkout is checkout.
116
- *
117
- * @return bool
118
- */
119
- function woo_checkout_flag( $is_checkout ) {
120
-
121
- if ( ! is_admin() ) {
122
-
123
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
124
-
125
- $is_checkout = true;
126
- }
127
- }
128
-
129
- return $is_checkout;
130
- }
131
-
132
- /**
133
- * Render checkout shortcode markup.
134
- *
135
- * @param array $atts attributes.
136
- * @return string
137
- */
138
- function checkout_shortcode_markup( $atts ) {
139
-
140
- $atts = shortcode_atts(
141
- array(
142
- 'id' => 0,
143
- ),
144
- $atts
145
- );
146
-
147
- $checkout_id = intval( $atts['id'] );
148
-
149
- if ( empty( $checkout_id ) ) {
150
-
151
- if ( ! _is_wcf_checkout_type() ) {
152
-
153
- return '<h4>' . __( 'Checkout ID not found', 'cartflows' ) . '</h4>';
154
- }
155
-
156
- global $post;
157
-
158
- $checkout_id = intval( $post->ID );
159
- }
160
-
161
- $output = '';
162
-
163
- ob_start();
164
-
165
- do_action( 'cartflows_checkout_form_before', $checkout_id );
166
-
167
- $checkout_layout = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-layout' );
168
-
169
- $template_default = CARTFLOWS_CHECKOUT_DIR . 'templates/embed/checkout-template-simple.php';
170
-
171
- $template_layout = apply_filters( 'cartflows_checkout_layout_template', $checkout_layout );
172
-
173
- if ( file_exists( $template_layout ) ) {
174
- include $template_layout;
175
- } else {
176
- include $template_default;
177
- }
178
-
179
- $output .= ob_get_clean();
180
-
181
- return $output;
182
- }
183
-
184
- /**
185
- * Configure Cart Data.
186
- *
187
- * @since 1.0.0
188
- *
189
- * @return void
190
- */
191
- function preconfigured_cart_data() {
192
-
193
- if ( is_admin() ) {
194
- return;
195
- }
196
-
197
- global $post;
198
-
199
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
200
-
201
- if ( wp_doing_ajax() ) {
202
-
203
- return;
204
- } else {
205
-
206
- if ( _is_wcf_checkout_type() ) {
207
- $checkout_id = $post->ID;
208
- } else {
209
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
210
- }
211
-
212
- $flow_id = wcf()->utils->get_flow_id_from_step_id( $checkout_id );
213
-
214
- if ( wcf()->flow->is_flow_testmode( $flow_id ) ) {
215
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products', 'dummy' );
216
- } else {
217
- $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
218
- }
219
-
220
- if ( ! is_array( $products ) ) {
221
-
222
- if ( 'dummy' === $products ) {
223
-
224
- $args = array(
225
- 'posts_per_page' => 1,
226
- 'orderby' => 'rand',
227
- 'post_type' => 'product',
228
- 'meta_query' => array(
229
- // Exclude out of stock products.
230
- array(
231
- 'key' => '_stock_status',
232
- 'value' => 'outofstock',
233
- 'compare' => 'NOT IN',
234
- ),
235
- ),
236
- 'tax_query' => array(
237
- array(
238
- 'taxonomy' => 'product_type',
239
- 'field' => 'slug',
240
- 'terms' => 'simple',
241
- ),
242
- ),
243
- );
244
-
245
- $random_product = get_posts( $args );
246
-
247
- if ( isset( $random_product[0]->ID ) ) {
248
- $products = array(
249
- array(
250
- 'product' => $random_product[0]->ID,
251
- ),
252
- );
253
- } else {
254
- return;
255
- }
256
- } else {
257
- return;
258
- }
259
- }
260
-
261
- if ( is_array( $products ) && count( $products ) < 1 ) {
262
-
263
- return;
264
- }
265
- /* Empty the current cart */
266
- WC()->cart->empty_cart();
267
-
268
- /* Set customer session if not set */
269
- if ( ! is_user_logged_in() && WC()->cart->is_empty() ) {
270
- WC()->session->set_customer_session_cookie( true );
271
- }
272
-
273
- foreach ( $products as $index => $data ) {
274
-
275
- if ( ! isset( $data['product'] ) ) {
276
- return;
277
- }
278
-
279
- $product_id = $data['product'];
280
- $_product = wc_get_product( $product_id );
281
-
282
- if ( ! empty( $_product ) ) {
283
-
284
- $quantity = 1;
285
-
286
- if ( ! $_product->is_type( 'grouped' ) && ! $_product->is_type( 'external' ) ) {
287
-
288
- if ( $_product->is_type( 'variable' ) ) {
289
-
290
- $default_attributes = $_product->get_default_attributes();
291
-
292
- if ( ! empty( $default_attributes ) ) {
293
-
294
- foreach ( $_product->get_children() as $variation_id ) {
295
-
296
- $single_variation = new WC_Product_Variation( $variation_id );
297
-
298
- if ( $default_attributes == $single_variation->get_attributes() ) {
299
- WC()->cart->add_to_cart( $variation_id, $quantity );
300
- }
301
- }
302
- } else {
303
-
304
- $product_childrens = $_product->get_children();
305
-
306
- if ( isset( $product_childrens[0] ) ) {
307
- WC()->cart->add_to_cart( $product_childrens[0], $quantity );
308
- } else {
309
- echo '<p>' . __( 'Variations Not set', 'cartflows' ) . '</p>';
310
- }
311
- }
312
- } else {
313
- WC()->cart->add_to_cart( $product_id, $quantity );
314
- }
315
- } else {
316
-
317
- echo '<p>' . __( 'This product can\'t be purcahsed', 'cartflows' ) . '</p>';
318
- // WC()->cart->add_to_cart( $product_id, $quantity );.
319
- }
320
- }
321
- }
322
-
323
- do_action( 'cartflows_checkout_aftet_configure_cart', $checkout_id );
324
- }
325
- }
326
- }
327
-
328
- /**
329
- * Load shortcode data.
330
- *
331
- * @return void
332
- */
333
- function shortcode_load_data() {
334
-
335
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
336
-
337
- add_action( 'wp_enqueue_scripts', array( $this, 'shortcode_scripts' ), 21 );
338
-
339
- // Outputting the hidden field in checkout page.
340
- add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
341
- add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
342
-
343
- remove_all_actions( 'woocommerce_checkout_billing' );
344
- remove_all_actions( 'woocommerce_checkout_shipping' );
345
-
346
- // Hook in actions once.
347
- add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
348
- add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
349
-
350
- remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
351
-
352
- add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
353
-
354
- add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
355
-
356
- global $post;
357
-
358
- if ( _is_wcf_checkout_type() ) {
359
- $checkout_id = $post->ID;
360
- } else {
361
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
362
- }
363
-
364
- do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
365
- }
366
- }
367
-
368
- /**
369
- * Render checkout ID hidden field.
370
- *
371
- * @param array $checkout checkout session data.
372
- * @return void
373
- */
374
- function checkout_shortcode_post_id( $checkout ) {
375
-
376
- global $post;
377
-
378
- if ( _is_wcf_checkout_type() ) {
379
- $checkout_id = $post->ID;
380
- } else {
381
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
382
- }
383
-
384
- $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
385
-
386
- echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
387
- echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
388
- }
389
-
390
- /**
391
- * Load shortcode scripts.
392
- *
393
- * @return void
394
- */
395
- function shortcode_scripts() {
396
-
397
- wp_enqueue_style( 'wcf-checkout-template', CARTFLOWS_URL . 'assets/css/checkout-template.css', '', CARTFLOWS_VER );
398
- wp_style_add_data( 'wcf-checkout-template', 'rtl', 'replace' );
399
-
400
- if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
401
- wp_enqueue_style( 'wcf-checkout-template-divi', CARTFLOWS_URL . 'assets/css/checkout-template-divi.css', '', CARTFLOWS_VER );
402
- wp_style_add_data( 'wcf-checkout-template-divi', 'rtl', 'replace' );
403
- }
404
-
405
- wp_enqueue_script(
406
- 'wcf-checkout-template',
407
- CARTFLOWS_URL . 'assets/js/checkout-template.js',
408
- array( 'jquery' ),
409
- CARTFLOWS_VER,
410
- true
411
- );
412
-
413
- do_action( 'cartflows_checkout_scripts' );
414
-
415
- $style = $this->generate_style();
416
-
417
- wp_add_inline_style( 'wcf-checkout-template', $style );
418
-
419
- }
420
-
421
- /**
422
- * Generate styles.
423
- *
424
- * @return string
425
- */
426
- function generate_style() {
427
-
428
- global $post;
429
-
430
- if ( _is_wcf_checkout_type() ) {
431
- $checkout_id = $post->ID;
432
- } else {
433
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
434
- }
435
-
436
- CartFlows_Font_Families::render_fonts( $checkout_id );
437
-
438
- $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
439
-
440
- $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
441
-
442
- $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
443
-
444
- /*$base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
445
-
446
- $field_tb_padding = '';
447
- $field_lr_padding = '';
448
-
449
- $field_heading_color = '';
450
- $field_color = '';
451
- $field_bg_color = '';
452
- $field_border_color = '';
453
- $field_label_color = '';
454
- $submit_tb_padding = '';
455
- $submit_lr_padding = '';
456
- $hl_bg_color = '';
457
- $field_input_size = '';
458
- $box_border_color = '';
459
- $section_bg_color = '';
460
- $submit_button_height = '';
461
- $submit_color = '';
462
- $submit_bg_color = $primary_color;
463
- $submit_border_color = $primary_color;
464
-
465
- $submit_hover_color = '';
466
- $submit_bg_hover_color = $primary_color;
467
- $submit_border_hover_color = $primary_color;
468
-
469
- $section_heading_color = '';
470
-
471
- $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
472
-
473
- $button_font_family = '';
474
- $button_font_weight = '';
475
- $input_font_family = '';
476
- $input_font_weight = '';
477
- $heading_font_family = '';
478
- $heading_font_weight = '';
479
- $base_font_family = $base_font_family;
480
- /*$base_font_weight = $base_font_weight;*/
481
-
482
- if ( 'yes' == $is_advance_option ) {
483
-
484
- /**
485
- * Get Font Family and Font Weight weight values
486
- */
487
- $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
488
-
489
- $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
490
- $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
491
- $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
492
- $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
493
- $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
494
- $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
495
- $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
496
- $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
497
- $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
498
- $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
499
-
500
- $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
501
-
502
- $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
503
-
504
- $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
505
-
506
- $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
507
-
508
- $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
509
-
510
- $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
511
-
512
- $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
513
-
514
- $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
515
-
516
- $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
517
-
518
- $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
519
-
520
- $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
521
-
522
- $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
523
-
524
- $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
525
-
526
- $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
527
-
528
- $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
529
-
530
- $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
531
-
532
- /**
533
- * Get font values
534
- */
535
-
536
- if ( 'custom' == $submit_button_height ) {
537
- $submit_button_height = '38px';
538
- }
539
-
540
- if ( 'custom' == $field_input_size ) {
541
- $field_input_size = '38px';
542
- }
543
- }
544
-
545
- $output = "
546
- .wcf-embed-checkout-form .wcf-checkout-header-image img{
547
- width: {$header_logo_width}px;
548
- }
549
- .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:checked:after,
550
- .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:not(:checked):after,
551
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label:after,
552
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label:after {
553
- background: {$primary_color};
554
- }
555
-
556
- .wcf-embed-checkout-form .woocommerce-checkout label{
557
- color: {$field_label_color};
558
- }
559
- .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box{
560
- background-color: {$hl_bg_color};
561
- font-family: {$input_font_family};
562
- font-weight: {$input_font_weight};
563
- }
564
-
565
- .wcf-embed-checkout-form #add_payment_method #payment div.payment_box::before,
566
- .wcf-embed-checkout-form .woocommerce-cart #payment div.payment_box::before,
567
- .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box::before
568
- {
569
- border-color: {$hl_bg_color};
570
- border-right-color: transparent;
571
- border-left-color: transparent;
572
- border-top-color: transparent;
573
- position: absolute;
574
- }
575
-
576
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label,
577
- .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label{
578
- font-family: {$input_font_family};
579
- font-weight: {$input_font_weight};
580
- }
581
-
582
- .wcf-embed-checkout-form #order_review .wcf-custom-coupon-field input[type='text'],
583
- .wcf-embed-checkout-form .woocommerce form .form-row input.input-text,
584
- .wcf-embed-checkout-form .woocommerce form .form-row textarea,
585
- .wcf-embed-checkout-form .select2-container--default .select2-selection--single {
586
- color: {$field_color};
587
- background: {$field_bg_color};
588
- border-color: {$field_border_color};
589
- padding-top: {$field_tb_padding}px;
590
- padding-bottom: {$field_tb_padding}px;
591
- padding-left: {$field_lr_padding}px;
592
- padding-right: {$field_lr_padding}px;
593
- min-height: {$field_input_size};
594
- font-family: {$input_font_family};
595
- font-weight: {$input_font_weight};
596
- }
597
-
598
- .wcf-embed-checkout-form .woocommerce .col2-set .col-1,
599
- .wcf-embed-checkout-form .woocommerce .col2-set .col-2,
600
- .wcf-embed-checkout-form .woocommerce-checkout .shop_table,
601
- .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading,
602
- .wcf-embed-checkout-form .woocommerce-checkout #payment,
603
- .wcf-embed-checkout-form .woocommerce form.checkout_coupon
604
- {
605
- background-color: {$section_bg_color};
606
- border-color: {$box_border_color};
607
- font-family: {$input_font_family};
608
- font-weight: {$input_font_weight};
609
- }
610
-
611
- .woocommerce table.shop_table th{
612
- color: {$field_label_color};
613
- }
614
- .wcf-embed-checkout-form .woocommerce .woocommerce-info,
615
- .wcf-embed-checkout-form .woocommerce-message{
616
- border-top-color: {$primary_color};
617
- background-color: {$hl_bg_color};
618
- }
619
- .wcf-embed-checkout-form .woocommerce a{
620
- color: {$primary_color};
621
- }
622
- .wcf-embed-checkout-form .select2-container--default .select2-selection--single .select2-selection__rendered {
623
- color: {$field_color};
624
- }
625
- .wcf-embed-checkout-form ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
626
- color: {$field_color};
627
- }
628
- .wcf-embed-checkout-form ::-moz-placeholder { /* Firefox 19+ */
629
- color: {$field_color};
630
- }
631
- .wcf-embed-checkout-form :-ms-input-placeholder { /* IE 10+ */
632
- color: {$field_color};
633
- }
634
- .wcf-embed-checkout-form :-moz-placeholder { /* Firefox 18- */
635
- color: {$field_color};
636
- }
637
- .wcf-embed-checkout-form .woocommerce form p.form-row label {
638
- color: {$field_label_color};
639
- font-family: {$input_font_family};
640
- font-weight: {$input_font_weight};
641
- }
642
- .wcf-embed-checkout-form .woocommerce #order_review button {
643
- color: {$submit_color};
644
- background: {$submit_bg_color};
645
- padding-top: {$submit_tb_padding}px;
646
- padding-bottom: {$submit_tb_padding}px;
647
- padding-left: {$submit_lr_padding}px;
648
- padding-right: {$submit_lr_padding}px;
649
- border-color: {$submit_border_color};
650
- min-height: {$submit_button_height};
651
- font-family: {$button_font_family};
652
- font-weight: {$button_font_weight};
653
- }
654
- .wcf-embed-checkout-form .woocommerce-checkout form.woocommerce-form-login .button,
655
- .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button{
656
- background: {$submit_bg_color};
657
- border: 1px {$submit_border_color} solid;
658
- color: {$submit_color};
659
- min-height: {$submit_button_height};
660
- font-family: {$button_font_family};
661
- font-weight: {$button_font_weight};
662
- }
663
- .wcf-embed-checkout-form .woocommerce-checkout form.login .button:hover,
664
- .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button:hover,
665
- .wcf-embed-checkout-form .woocommerce #payment #place_order:hover,
666
- .wcf-embed-checkout-form .woocommerce #order_review button.wcf-btn-small:hover{
667
- color: {$submit_hover_color};
668
- background-color: {$submit_bg_hover_color};
669
- border-color: {$submit_border_hover_color};
670
- }
671
- .wcf-embed-checkout-form .woocommerce h3,
672
- .wcf-embed-checkout-form .woocommerce h3 span,
673
- .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
674
- color: {$section_heading_color};
675
- font-family: {$heading_font_family};
676
- font-weight: {$heading_font_weight};
677
- }
678
- .wcf-embed-checkout-form .woocommerce-info::before,
679
- .wcf-embed-checkout-form .woocommerce-message::before{
680
- color: {$primary_color};
681
- }
682
- .wcf-embed-checkout-form{
683
- font-family: {$base_font_family};
684
- }";
685
-
686
- return $output;
687
- }
688
-
689
- /**
690
- * Get ajax end points.
691
- *
692
- * @param string $endpoint_url end point URL.
693
- * @return string
694
- */
695
- function get_ajax_endpoint( $endpoint_url ) {
696
-
697
- global $post;
698
-
699
- if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
700
-
701
- if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
702
-
703
- if ( mb_strpos( $endpoint_url, 'checkout' ) === false ) {
704
-
705
- $query_args = array(
706
- 'wc-ajax' => '%%endpoint%%',
707
- );
708
-
709
- $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 );
710
- $uri = $uri[0];
711
-
712
- $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
713
- }
714
- }
715
- }
716
-
717
- return $endpoint_url;
718
- }
719
-
720
-
721
- /**
722
- * Save checkout fields.
723
- *
724
- * @param int $order_id order id.
725
- * @param array $posted posted data.
726
- * @return void
727
- */
728
- function save_checkout_fields( $order_id, $posted ) {
729
-
730
- if ( isset( $_POST['_wcf_checkout_id'] ) ) {
731
-
732
- $checkout_id = wc_clean( $_POST['_wcf_checkout_id'] );
733
-
734
- update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
735
-
736
- /*
737
- Custom Field To Do
738
- $custom_fields = get_post_meta( $checkout_id, 'wcf-custom-checkout-fields', true );
739
-
740
- if ( 'yes' === $custom_fields ) {
741
-
742
- $billing_fields = get_post_meta( $checkout_id, 'wcf_fields_billing', true );
743
-
744
- foreach ( $billing_fields as $field => $data ) {
745
-
746
- if ( isset( $data['custom'] ) && $data['custom'] ) {
747
-
748
- if ( isset( $_POST[ $field ] ) ) {
749
- update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
750
- }
751
- }
752
- }
753
-
754
- $shipping_fields = get_post_meta( $checkout_id, 'wcf_fields_shipping', true );
755
-
756
- foreach ( $shipping_fields as $field => $data ) {
757
-
758
- if ( isset( $data['custom'] ) && $data['custom'] ) {
759
-
760
- if ( isset( $_POST[ $field ] ) ) {
761
- update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
762
- }
763
- }
764
- }
765
- }
766
- */
767
- if ( isset( $_POST['_wcf_flow_id'] ) ) {
768
-
769
- $checkout_id = wc_clean( $_POST['_wcf_flow_id'] );
770
-
771
- update_post_meta( $order_id, '_wcf_flow_id', $checkout_id );
772
- }
773
- }
774
-
775
- }
776
-
777
- /**
778
- * Enable Logo In Header Of Checkout Page
779
- *
780
- * @return void
781
- */
782
- function enable_logo_in_header() {
783
- global $post;
784
-
785
- if ( _is_wcf_checkout_type() ) {
786
- $checkout_id = $post->ID;
787
- } else {
788
- $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
789
- }
790
-
791
- $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
792
- $add_image_markup = '';
793
-
794
- if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
795
- $add_image_markup = '<div class="wcf-checkout-header-image">';
796
- $add_image_markup .= '<img src="' . $header_logo_image . '" />';
797
- $add_image_markup .= '</div>';
798
- }
799
-
800
- echo $add_image_markup;
801
- }
802
-
803
- /**
804
- * Add text to the bootom of the checkout page.
805
- *
806
- * @return void
807
- */
808
- function show_cartflows_copyright_message() {
809
- $output_string = '';
810
-
811
- $output_string .= '<div class="wcf-footer-primary">';
812
- $output_string .= '<div class="wcf-footer-content">';
813
- $output_string .= '<p class="wcf-footer-message">';
814
- $output_string .= 'Checkout powered by CartFlows';
815
- $output_string .= '</p>';
816
- $output_string .= '</div>';
817
- $output_string .= '</div>';
818
-
819
- echo $output_string;
820
- }
821
-
822
- /**
823
- * Redirect users to our checkout if hidden param
824
- *
825
- * @param string $redirect redirect url.
826
- * @param object $user user.
827
- * @return string
828
- */
829
- function after_login_redirect( $redirect, $user ) {
830
-
831
- if ( isset( $_POST['_wcf_checkout_id'] ) ) {
832
-
833
- $checkout_id = intval( $_POST['_wcf_checkout_id'] );
834
-
835
- $redirect = get_permalink( $checkout_id );
836
- }
837
-
838
- return $redirect;
839
- }
840
-
841
- /**
842
- * Display coupon code field after review order fields.
843
- */
844
- function display_custom_coupon_field() {
845
-
846
- $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
847
-
848
- if ( ! $coupon_enabled ) {
849
- return;
850
- }
851
-
852
- ob_start();
853
-
854
- ?>
855
- <div class="wcf-custom-coupon-field">
856
- <div class="wcf-coupon-col-1">
857
- <span>
858
- <input type="text" name="coupon_code" class="input-text cf-coupon-code-input" placeholder="<?php _e( 'Coupon Code', 'cartflows' ); ?>" id="coupon_code" value="">
859
- </span>
860
- </div>
861
- <div class="wcf-coupon-col-2">
862
- <span>
863
- <button type="button" class="button cf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php _e( 'Apply', 'cartflows' ); ?></button>
864
- </span>
865
- </div>
866
- </div>
867
-
868
- <?php
869
-
870
- echo ob_get_clean();
871
- }
872
-
873
- /**
874
- * Apply coupon on submit of custom coupon form.
875
- */
876
- function apply_coupon() {
877
-
878
- check_ajax_referer( 'cf-apply-coupon', 'security' );
879
-
880
- $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
881
-
882
- echo json_encode( $result );
883
- die();
884
- }
885
-
886
- /**
887
- * Added ajax nonce to localize variable.
888
- *
889
- * @param array $vars localize variables.
890
- */
891
- function add_localize_vars( $vars ) {
892
-
893
- $vars['cf_validate_coupon_nonce'] = wp_create_nonce( 'cf-apply-coupon' );
894
-
895
- return $vars;
896
- }
897
-
898
- /**
899
- * Add custom class to the fields to change the UI to three column.
900
- *
901
- * @param array $fields fields.
902
- */
903
- function add_three_column_layout_fields( $fields ) {
904
-
905
- if ( empty( $fields['billing']['billing_address_2'] ) ) {
906
-
907
- if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
908
- $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
909
- }
910
- }
911
-
912
- if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
913
-
914
- if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
915
- $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
916
- }
917
- }
918
-
919
- if ( isset( $fields['billing']['billing_city'] ) &&
920
- isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
921
-
922
- $fields['billing']['billing_city']['class'] = array( 'wcf-form-col-3' );
923
- $fields['billing']['billing_state']['class'] = array( 'wcf-form-col-3' );
924
- $fields['billing']['billing_postcode']['class'] = array( 'wcf-form-col-3' );
925
- }
926
-
927
- if ( isset( $fields['shipping']['shipping_city'] ) &&
928
- isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
929
-
930
- $fields['shipping']['shipping_city']['class'] = array( 'wcf-form-col-3' );
931
- $fields['shipping']['shipping_state']['class'] = array( 'wcf-form-col-3' );
932
- $fields['shipping']['shipping_postcode']['class'] = array( 'wcf-form-col-3' );
933
- }
934
-
935
- return $fields;
936
- }
937
- }
938
-
939
- /**
940
- * Kicking this off by calling 'get_instance()' method
941
- */
942
- 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
+ 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
+ $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
+ // Outputting the hidden field in checkout page.
360
+ add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_shortcode_post_id' ), 99 );
361
+ add_action( 'woocommerce_login_form_end', array( $this, 'checkout_shortcode_post_id' ), 99 );
362
+
363
+ remove_all_actions( 'woocommerce_checkout_billing' );
364
+ remove_all_actions( 'woocommerce_checkout_shipping' );
365
+
366
+ // Hook in actions once.
367
+ add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
368
+ add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
369
+
370
+ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
371
+
372
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'display_custom_coupon_field' ) );
373
+
374
+ add_filter( 'woocommerce_checkout_fields', array( $this, 'add_three_column_layout_fields' ) );
375
+
376
+ global $post;
377
+
378
+ if ( _is_wcf_checkout_type() ) {
379
+ $checkout_id = $post->ID;
380
+ } else {
381
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
382
+ }
383
+
384
+ do_action( 'cartflows_checkout_before_shortcode', $checkout_id );
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Render checkout ID hidden field.
390
+ *
391
+ * @param array $checkout checkout session data.
392
+ * @return void
393
+ */
394
+ function checkout_shortcode_post_id( $checkout ) {
395
+
396
+ global $post;
397
+
398
+ if ( _is_wcf_checkout_type() ) {
399
+ $checkout_id = $post->ID;
400
+ } else {
401
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
402
+ }
403
+
404
+ $flow_id = get_post_meta( $checkout_id, 'wcf-flow-id', true );
405
+
406
+ echo '<input type="hidden" class="input-hidden _wcf_flow_id" name="_wcf_flow_id" value="' . intval( $flow_id ) . '">';
407
+ echo '<input type="hidden" class="input-hidden _wcf_checkout_id" name="_wcf_checkout_id" value="' . intval( $checkout_id ) . '">';
408
+ }
409
+
410
+ /**
411
+ * Load shortcode scripts.
412
+ *
413
+ * @return void
414
+ */
415
+ function shortcode_scripts() {
416
+
417
+ wp_enqueue_style( 'wcf-checkout-template', CARTFLOWS_URL . 'assets/css/checkout-template.css', '', CARTFLOWS_VER );
418
+ wp_style_add_data( 'wcf-checkout-template', 'rtl', 'replace' );
419
+
420
+ if ( Cartflows_Compatibility::get_instance()->is_divi_enabled() ) {
421
+ wp_enqueue_style( 'wcf-checkout-template-divi', CARTFLOWS_URL . 'assets/css/checkout-template-divi.css', '', CARTFLOWS_VER );
422
+ wp_style_add_data( 'wcf-checkout-template-divi', 'rtl', 'replace' );
423
+ }
424
+
425
+ wp_enqueue_script(
426
+ 'wcf-checkout-template',
427
+ CARTFLOWS_URL . 'assets/js/checkout-template.js',
428
+ array( 'jquery' ),
429
+ CARTFLOWS_VER,
430
+ true
431
+ );
432
+
433
+ do_action( 'cartflows_checkout_scripts' );
434
+
435
+ $style = $this->generate_style();
436
+
437
+ wp_add_inline_style( 'wcf-checkout-template', $style );
438
+
439
+ }
440
+
441
+
442
+ /**
443
+ * Generate styles.
444
+ *
445
+ * @return string
446
+ */
447
+ function generate_style() {
448
+
449
+ global $post;
450
+
451
+ if ( _is_wcf_checkout_type() ) {
452
+ $checkout_id = $post->ID;
453
+ } else {
454
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
455
+ }
456
+
457
+ CartFlows_Font_Families::render_fonts( $checkout_id );
458
+
459
+ $primary_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-primary-color' );
460
+
461
+ $base_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-family' );
462
+
463
+ $header_logo_width = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-width' );
464
+
465
+ /*$base_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-base-font-weight' );*/
466
+
467
+ $field_tb_padding = '';
468
+ $field_lr_padding = '';
469
+
470
+ $field_heading_color = '';
471
+ $field_color = '';
472
+ $field_bg_color = '';
473
+ $field_border_color = '';
474
+ $field_label_color = '';
475
+ $submit_tb_padding = '';
476
+ $submit_lr_padding = '';
477
+ $hl_bg_color = '';
478
+ $field_input_size = '';
479
+ $box_border_color = '';
480
+ $section_bg_color = '';
481
+ $submit_button_height = '';
482
+ $submit_color = '';
483
+ $submit_bg_color = $primary_color;
484
+ $submit_border_color = $primary_color;
485
+
486
+ $submit_hover_color = '';
487
+ $submit_bg_hover_color = $primary_color;
488
+ $submit_border_hover_color = $primary_color;
489
+
490
+ $section_heading_color = '';
491
+
492
+ $is_advance_option = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-advance-options-fields' );
493
+
494
+ $button_font_family = '';
495
+ $button_font_weight = '';
496
+ $input_font_family = '';
497
+ $input_font_weight = '';
498
+ $heading_font_family = '';
499
+ $heading_font_weight = '';
500
+ $base_font_family = $base_font_family;
501
+ /*$base_font_weight = $base_font_weight;*/
502
+
503
+ if ( 'yes' == $is_advance_option ) {
504
+
505
+ /**
506
+ * Get Font Family and Font Weight weight values
507
+ */
508
+ $section_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-section-bg-color' );
509
+
510
+ $heading_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-family' );
511
+ $heading_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-font-weight' );
512
+ $section_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-heading-color' );
513
+ $button_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-family' );
514
+ $button_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-button-font-weight' );
515
+ $input_font_family = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-family' );
516
+ $input_font_weight = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-font-weight' );
517
+ $field_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-tb-padding' );
518
+ $field_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-lr-padding' );
519
+ $field_input_size = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-field-size' );
520
+
521
+ $field_heading_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-heading-color' );
522
+
523
+ $field_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-color' );
524
+
525
+ $field_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-bg-color' );
526
+
527
+ $field_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-border-color' );
528
+
529
+ $field_label_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-field-label-color' );
530
+
531
+ $submit_tb_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-tb-padding' );
532
+
533
+ $submit_lr_padding = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-lr-padding' );
534
+
535
+ $submit_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-color' );
536
+
537
+ $submit_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-color', $primary_color );
538
+
539
+ $submit_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-color', $primary_color );
540
+
541
+ $submit_border_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-border-hover-color', $primary_color );
542
+
543
+ $submit_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-hover-color' );
544
+
545
+ $submit_bg_hover_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-submit-bg-hover-color', $primary_color );
546
+
547
+ $hl_bg_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-hl-bg-color' );
548
+
549
+ $box_border_color = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-box-border-color' );
550
+
551
+ $submit_button_height = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-input-button-size' );
552
+
553
+ /**
554
+ * Get font values
555
+ */
556
+
557
+ if ( 'custom' == $submit_button_height ) {
558
+ $submit_button_height = '38px';
559
+ }
560
+
561
+ if ( 'custom' == $field_input_size ) {
562
+ $field_input_size = '38px';
563
+ }
564
+ }
565
+
566
+ $output = "
567
+ .wcf-embed-checkout-form .wcf-checkout-header-image img{
568
+ width: {$header_logo_width}px;
569
+ }
570
+ .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:checked:after,
571
+ .wcf-embed-checkout-form .woocommerce .woocommerce-shipping-fields [type='checkbox']:not(:checked):after,
572
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label:after,
573
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label:after {
574
+ background: {$primary_color};
575
+ }
576
+
577
+ .wcf-embed-checkout-form .woocommerce-checkout label{
578
+ color: {$field_label_color};
579
+ }
580
+ .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box{
581
+ background-color: {$hl_bg_color};
582
+ font-family: {$input_font_family};
583
+ font-weight: {$input_font_weight};
584
+ }
585
+
586
+ .wcf-embed-checkout-form #add_payment_method #payment div.payment_box::before,
587
+ .wcf-embed-checkout-form .woocommerce-cart #payment div.payment_box::before,
588
+ .wcf-embed-checkout-form .woocommerce-checkout #payment div.payment_box::before
589
+ {
590
+ border-color: {$hl_bg_color};
591
+ border-right-color: transparent;
592
+ border-left-color: transparent;
593
+ border-top-color: transparent;
594
+ position: absolute;
595
+ }
596
+
597
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:checked + label,
598
+ .wcf-embed-checkout-form .woocommerce #payment [type='radio']:not(:checked) + label{
599
+ font-family: {$input_font_family};
600
+ font-weight: {$input_font_weight};
601
+ }
602
+
603
+ .wcf-embed-checkout-form #order_review .wcf-custom-coupon-field input[type='text'],
604
+ .wcf-embed-checkout-form .woocommerce form .form-row input.input-text,
605
+ .wcf-embed-checkout-form .woocommerce form .form-row textarea,
606
+ .wcf-embed-checkout-form .select2-container--default .select2-selection--single {
607
+ color: {$field_color};
608
+ background: {$field_bg_color};
609
+ border-color: {$field_border_color};
610
+ padding-top: {$field_tb_padding}px;
611
+ padding-bottom: {$field_tb_padding}px;
612
+ padding-left: {$field_lr_padding}px;
613
+ padding-right: {$field_lr_padding}px;
614
+ min-height: {$field_input_size};
615
+ font-family: {$input_font_family};
616
+ font-weight: {$input_font_weight};
617
+ }
618
+
619
+ .wcf-embed-checkout-form .woocommerce .col2-set .col-1,
620
+ .wcf-embed-checkout-form .woocommerce .col2-set .col-2,
621
+ .wcf-embed-checkout-form .woocommerce-checkout .shop_table,
622
+ .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading,
623
+ .wcf-embed-checkout-form .woocommerce-checkout #payment,
624
+ .wcf-embed-checkout-form .woocommerce form.checkout_coupon
625
+ {
626
+ background-color: {$section_bg_color};
627
+ border-color: {$box_border_color};
628
+ font-family: {$input_font_family};
629
+ font-weight: {$input_font_weight};
630
+ }
631
+
632
+ .woocommerce table.shop_table th{
633
+ color: {$field_label_color};
634
+ }
635
+ .wcf-embed-checkout-form .woocommerce .woocommerce-info,
636
+ .wcf-embed-checkout-form .woocommerce-message{
637
+ border-top-color: {$primary_color};
638
+ background-color: {$hl_bg_color};
639
+ }
640
+ .wcf-embed-checkout-form .woocommerce a{
641
+ color: {$primary_color};
642
+ }
643
+ .wcf-embed-checkout-form .select2-container--default .select2-selection--single .select2-selection__rendered {
644
+ color: {$field_color};
645
+ }
646
+ .wcf-embed-checkout-form ::-webkit-input-placeholder { /* Chrome/Opera/Safari */
647
+ color: {$field_color};
648
+ }
649
+ .wcf-embed-checkout-form ::-moz-placeholder { /* Firefox 19+ */
650
+ color: {$field_color};
651
+ }
652
+ .wcf-embed-checkout-form :-ms-input-placeholder { /* IE 10+ */
653
+ color: {$field_color};
654
+ }
655
+ .wcf-embed-checkout-form :-moz-placeholder { /* Firefox 18- */
656
+ color: {$field_color};
657
+ }
658
+ .wcf-embed-checkout-form .woocommerce form p.form-row label {
659
+ color: {$field_label_color};
660
+ font-family: {$input_font_family};
661
+ font-weight: {$input_font_weight};
662
+ }
663
+ .wcf-embed-checkout-form .woocommerce #order_review button {
664
+ color: {$submit_color};
665
+ background: {$submit_bg_color};
666
+ padding-top: {$submit_tb_padding}px;
667
+ padding-bottom: {$submit_tb_padding}px;
668
+ padding-left: {$submit_lr_padding}px;
669
+ padding-right: {$submit_lr_padding}px;
670
+ border-color: {$submit_border_color};
671
+ min-height: {$submit_button_height};
672
+ font-family: {$button_font_family};
673
+ font-weight: {$button_font_weight};
674
+ }
675
+ .wcf-embed-checkout-form .woocommerce-checkout form.woocommerce-form-login .button,
676
+ .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button{
677
+ background: {$submit_bg_color};
678
+ border: 1px {$submit_border_color} solid;
679
+ color: {$submit_color};
680
+ min-height: {$submit_button_height};
681
+ font-family: {$button_font_family};
682
+ font-weight: {$button_font_weight};
683
+ }
684
+ .wcf-embed-checkout-form .woocommerce-checkout form.login .button:hover,
685
+ .wcf-embed-checkout-form .woocommerce-checkout form.checkout_coupon .button:hover,
686
+ .wcf-embed-checkout-form .woocommerce #payment #place_order:hover,
687
+ .wcf-embed-checkout-form .woocommerce #order_review button.wcf-btn-small:hover{
688
+ color: {$submit_hover_color};
689
+ background-color: {$submit_bg_hover_color};
690
+ border-color: {$submit_border_hover_color};
691
+ }
692
+ .wcf-embed-checkout-form .woocommerce h3,
693
+ .wcf-embed-checkout-form .woocommerce h3 span,
694
+ .wcf-embed-checkout-form .woocommerce-checkout #order_review_heading{
695
+ color: {$section_heading_color};
696
+ font-family: {$heading_font_family};
697
+ font-weight: {$heading_font_weight};
698
+ }
699
+ .wcf-embed-checkout-form .woocommerce-info::before,
700
+ .wcf-embed-checkout-form .woocommerce-message::before{
701
+ color: {$primary_color};
702
+ }
703
+ .wcf-embed-checkout-form{
704
+ font-family: {$base_font_family};
705
+ }";
706
+
707
+ return $output;
708
+ }
709
+
710
+ /**
711
+ * Get ajax end points.
712
+ *
713
+ * @param string $endpoint_url end point URL.
714
+ * @return string
715
+ */
716
+ function get_ajax_endpoint( $endpoint_url ) {
717
+
718
+ global $post;
719
+
720
+ if ( ! empty( $post ) && ! empty( $_SERVER['REQUEST_URI'] ) ) {
721
+
722
+ if ( _is_wcf_checkout_type() || _is_wcf_checkout_shortcode() ) {
723
+
724
+ if ( mb_strpos( $endpoint_url, 'checkout' ) === false ) {
725
+
726
+ $query_args = array(
727
+ 'wc-ajax' => '%%endpoint%%',
728
+ );
729
+
730
+ $uri = explode( '?', $_SERVER['REQUEST_URI'], 2 );
731
+ $uri = $uri[0];
732
+
733
+ $endpoint_url = esc_url( add_query_arg( $query_args, $uri ) );
734
+ }
735
+ }
736
+ }
737
+
738
+ return $endpoint_url;
739
+ }
740
+
741
+
742
+ /**
743
+ * Save checkout fields.
744
+ *
745
+ * @param int $order_id order id.
746
+ * @param array $posted posted data.
747
+ * @return void
748
+ */
749
+ function save_checkout_fields( $order_id, $posted ) {
750
+
751
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) {
752
+
753
+ $checkout_id = wc_clean( $_POST['_wcf_checkout_id'] );
754
+
755
+ update_post_meta( $order_id, '_wcf_checkout_id', $checkout_id );
756
+
757
+ /*
758
+ Custom Field To Do
759
+ $custom_fields = get_post_meta( $checkout_id, 'wcf-custom-checkout-fields', true );
760
+
761
+ if ( 'yes' === $custom_fields ) {
762
+
763
+ $billing_fields = get_post_meta( $checkout_id, 'wcf_fields_billing', true );
764
+
765
+ foreach ( $billing_fields as $field => $data ) {
766
+
767
+ if ( isset( $data['custom'] ) && $data['custom'] ) {
768
+
769
+ if ( isset( $_POST[ $field ] ) ) {
770
+ update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
771
+ }
772
+ }
773
+ }
774
+
775
+ $shipping_fields = get_post_meta( $checkout_id, 'wcf_fields_shipping', true );
776
+
777
+ foreach ( $shipping_fields as $field => $data ) {
778
+
779
+ if ( isset( $data['custom'] ) && $data['custom'] ) {
780
+
781
+ if ( isset( $_POST[ $field ] ) ) {
782
+ update_post_meta( $order_id, $field, wc_clean( $_POST[ $field ] ) );
783
+ }
784
+ }
785
+ }
786
+ }
787
+ */
788
+ if ( isset( $_POST['_wcf_flow_id'] ) ) {
789
+
790
+ $checkout_id = wc_clean( $_POST['_wcf_flow_id'] );
791
+
792
+ update_post_meta( $order_id, '_wcf_flow_id', $checkout_id );
793
+ }
794
+ }
795
+
796
+ }
797
+
798
+ /**
799
+ * Enable Logo In Header Of Checkout Page
800
+ *
801
+ * @return void
802
+ */
803
+ function enable_logo_in_header() {
804
+ global $post;
805
+
806
+ if ( _is_wcf_checkout_type() ) {
807
+ $checkout_id = $post->ID;
808
+ } else {
809
+ $checkout_id = _get_wcf_checkout_id_from_shortcode( $post->post_content );
810
+ }
811
+
812
+ $header_logo_image = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-header-logo-image' );
813
+ $add_image_markup = '';
814
+
815
+ if ( isset( $header_logo_image ) && ! empty( $header_logo_image ) ) {
816
+ $add_image_markup = '<div class="wcf-checkout-header-image">';
817
+ $add_image_markup .= '<img src="' . $header_logo_image . '" />';
818
+ $add_image_markup .= '</div>';
819
+ }
820
+
821
+ echo $add_image_markup;
822
+ }
823
+
824
+ /**
825
+ * Add text to the bootom of the checkout page.
826
+ *
827
+ * @return void
828
+ */
829
+ function show_cartflows_copyright_message() {
830
+ $output_string = '';
831
+
832
+ $output_string .= '<div class="wcf-footer-primary">';
833
+ $output_string .= '<div class="wcf-footer-content">';
834
+ $output_string .= '<p class="wcf-footer-message">';
835
+ $output_string .= 'Checkout powered by CartFlows';
836
+ $output_string .= '</p>';
837
+ $output_string .= '</div>';
838
+ $output_string .= '</div>';
839
+
840
+ echo $output_string;
841
+ }
842
+
843
+ /**
844
+ * Redirect users to our checkout if hidden param
845
+ *
846
+ * @param string $redirect redirect url.
847
+ * @param object $user user.
848
+ * @return string
849
+ */
850
+ function after_login_redirect( $redirect, $user ) {
851
+
852
+ if ( isset( $_POST['_wcf_checkout_id'] ) ) {
853
+
854
+ $checkout_id = intval( $_POST['_wcf_checkout_id'] );
855
+
856
+ $redirect = get_permalink( $checkout_id );
857
+ }
858
+
859
+ return $redirect;
860
+ }
861
+
862
+ /**
863
+ * Display coupon code field after review order fields.
864
+ */
865
+ function display_custom_coupon_field() {
866
+
867
+ $coupon_enabled = apply_filters( 'woocommerce_coupons_enabled', true );
868
+
869
+ if ( ! $coupon_enabled ) {
870
+ return;
871
+ }
872
+
873
+ ob_start();
874
+
875
+ ?>
876
+ <div class="wcf-custom-coupon-field">
877
+ <div class="wcf-coupon-col-1">
878
+ <span>
879
+ <input type="text" name="coupon_code" class="input-text cf-coupon-code-input" placeholder="<?php _e( 'Coupon Code', 'cartflows' ); ?>" id="coupon_code" value="">
880
+ </span>
881
+ </div>
882
+ <div class="wcf-coupon-col-2">
883
+ <span>
884
+ <button type="button" class="button cf-submit-coupon wcf-btn-small" name="apply_coupon" value="Apply"><?php _e( 'Apply', 'cartflows' ); ?></button>
885
+ </span>
886
+ </div>
887
+ </div>
888
+
889
+ <?php
890
+
891
+ echo ob_get_clean();
892
+ }
893
+
894
+ /**
895
+ * Apply coupon on submit of custom coupon form.
896
+ */
897
+ function apply_coupon() {
898
+
899
+ check_ajax_referer( 'cf-apply-coupon', 'security' );
900
+
901
+ $result = WC()->cart->add_discount( sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) );
902
+
903
+ echo json_encode( $result );
904
+ die();
905
+ }
906
+
907
+ /**
908
+ * Added ajax nonce to localize variable.
909
+ *
910
+ * @param array $vars localize variables.
911
+ */
912
+ function add_localize_vars( $vars ) {
913
+
914
+ $vars['cf_validate_coupon_nonce'] = wp_create_nonce( 'cf-apply-coupon' );
915
+
916
+ return $vars;
917
+ }
918
+
919
+ /**
920
+ * Add custom class to the fields to change the UI to three column.
921
+ *
922
+ * @param array $fields fields.
923
+ */
924
+ function add_three_column_layout_fields( $fields ) {
925
+
926
+ if ( empty( $fields['billing']['billing_address_2'] ) ) {
927
+
928
+ if ( isset( $fields['billing']['billing_address_1'] ) && is_array( $fields['billing']['billing_address_1'] ) ) {
929
+ $fields['billing']['billing_address_1']['class'][] = 'form-row-full';
930
+ }
931
+ }
932
+
933
+ if ( empty( $fields['shipping']['shipping_address_2'] ) ) {
934
+
935
+ if ( isset( $fields['shipping']['shipping_address_1'] ) && is_array( $fields['shipping']['shipping_address_1'] ) ) {
936
+ $fields['shipping']['shipping_address_1']['class'][] = 'form-row-full';
937
+ }
938
+ }
939
+
940
+ if ( isset( $fields['billing']['billing_city'] ) &&
941
+ isset( $fields['billing']['billing_state'] ) && isset( $fields['billing']['billing_postcode'] ) ) {
942
+
943
+ $fields['billing']['billing_city']['class'] = array( 'wcf-form-col-3' );
944
+ $fields['billing']['billing_state']['class'] = array( 'wcf-form-col-3' );
945
+ $fields['billing']['billing_postcode']['class'] = array( 'wcf-form-col-3' );
946
+ }
947
+
948
+ if ( isset( $fields['shipping']['shipping_city'] ) &&
949
+ isset( $fields['shipping']['shipping_state'] ) && isset( $fields['shipping']['shipping_postcode'] ) ) {
950
+
951
+ $fields['shipping']['shipping_city']['class'] = array( 'wcf-form-col-3' );
952
+ $fields['shipping']['shipping_state']['class'] = array( 'wcf-form-col-3' );
953
+ $fields['shipping']['shipping_postcode']['class'] = array( 'wcf-form-col-3' );
954
+ }
955
+
956
+ return $fields;
957
+ }
958
+
959
+ /**
960
+ * Add opening dev
961
+ *
962
+ * @since 1.0.0
963
+ */
964
+ function order_wrap_div_start() {
965
+
966
+ echo "<div class='wcf-order-wrap'> ";
967
+ }
968
+
969
+ /**
970
+ * Add closing dev
971
+ *
972
+ * @since 1.0.0
973
+ */
974
+ function order_wrap_div_end() {
975
+
976
+ echo '</div> ';
977
+ }
978
+ }
979
+
980
+ /**
981
+ * Kicking this off by calling 'get_instance()' method
982
+ */
983
+ Cartflows_Checkout_Markup::get_instance();
modules/checkout/templates/embed/checkout-template-simple.php CHANGED
@@ -1,30 +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
- echo __( 'Your cart is currently empty.', 'cartflows' );
23
- } else {
24
- echo $checkout_html;
25
- }
26
- ?>
27
-
28
- <?php do_action( 'cartflows_add_after_main_section', $arg = '' ); ?>
29
- <!-- END CHECKOUT SHORTCODE -->
30
- </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 enables you to preview your pages with random products for the sake of 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 button button-primary'>";
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/templates/template-canvas.php CHANGED
@@ -1,39 +1,45 @@
1
- <?php
2
- /**
3
- * Template Name: No Header Footer
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- ?>
9
-
10
- <!DOCTYPE html>
11
- <html <?php language_attributes(); ?> class="no-js">
12
- <head>
13
- <meta charset="<?php bloginfo( 'charset' ); ?>">
14
- <meta name="viewport" content="width=device-width, initial-scale=1">
15
- <link rel="profile" href="http://gmpg.org/xfn/11">
16
- <?php wp_head(); ?>
17
- </head>
18
-
19
- <body <?php body_class(); ?>>
20
- <div class="cartflows-container">
21
-
22
- <?php
23
- do_action( 'cartflows_container_top' );
24
- while ( have_posts() ) :
25
-
26
- the_post();
27
- the_content();
28
-
29
- endwhile;
30
- do_action( 'cartflows_container_bottom' );
31
- ?>
32
- </div>
33
- <?php wp_footer(); ?>
34
-
35
- </body>
36
-
37
- </html>
38
-
39
- <?php
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template Name: No Header Footer
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ ?>
9
+
10
+ <!DOCTYPE html>
11
+ <html <?php language_attributes(); ?> class="no-js">
12
+ <head>
13
+ <meta charset="<?php bloginfo( 'charset' ); ?>">
14
+ <meta name="viewport" content="width=device-width, initial-scale=1">
15
+ <link rel="profile" href="http://gmpg.org/xfn/11">
16
+ <?php wp_head(); ?>
17
+ </head>
18
+
19
+ <body <?php body_class(); ?>>
20
+
21
+ <?php
22
+
23
+ $atts_string = Cartflows_Helper::get_cartflows_container_atts();
24
+
25
+ ?>
26
+ <div class="cartflows-container" <?php echo trim( $atts_string ); ?>>
27
+
28
+ <?php
29
+ do_action( 'cartflows_container_top' );
30
+ while ( have_posts() ) :
31
+
32
+ the_post();
33
+ the_content();
34
+
35
+ endwhile;
36
+ do_action( 'cartflows_container_bottom' );
37
+ ?>
38
+ </div>
39
+ <?php wp_footer(); ?>
40
+
41
+ </body>
42
+
43
+ </html>
44
+
45
+ <?php
modules/flow/templates/template-default.php CHANGED
@@ -1,44 +1,49 @@
1
- <?php
2
- /**
3
- * Template Name: No Header Footer
4
- *
5
- * @package CartFlows
6
- */
7
-
8
- ?>
9
-
10
- <!DOCTYPE html>
11
- <html <?php language_attributes(); ?> class="no-js">
12
- <head>
13
- <meta charset="<?php bloginfo( 'charset' ); ?>">
14
- <meta name="viewport" content="width=device-width, initial-scale=1">
15
- <link rel="profile" href="http://gmpg.org/xfn/11">
16
- <?php wp_head(); ?>
17
- </head>
18
-
19
- <body <?php body_class(); ?>>
20
- <div class="cartflows-container">
21
- <?php
22
- do_action( 'cartflows_container_top' );
23
- ?>
24
- <div class="cartflows-primary">
25
- <?php
26
- while ( have_posts() ) :
27
-
28
- the_post();
29
- the_content();
30
-
31
- endwhile;
32
- ?>
33
- </div>
34
- <?php
35
- do_action( 'cartflows_container_bottom' );
36
- ?>
37
- </div>
38
- <?php wp_footer(); ?>
39
-
40
- </body>
41
-
42
- </html>
43
-
44
- <?php
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template Name: No Header Footer
4
+ *
5
+ * @package CartFlows
6
+ */
7
+
8
+ ?>
9
+
10
+ <!DOCTYPE html>
11
+ <html <?php language_attributes(); ?> class="no-js">
12
+ <head>
13
+ <meta charset="<?php bloginfo( 'charset' ); ?>">
14
+ <meta name="viewport" content="width=device-width, initial-scale=1">
15
+ <link rel="profile" href="http://gmpg.org/xfn/11">
16
+ <?php wp_head(); ?>
17
+ </head>
18
+
19
+ <body <?php body_class(); ?>>
20
+ <?php
21
+
22
+ $atts_string = Cartflows_Helper::get_cartflows_container_atts();
23
+
24
+ ?>
25
+ <div class="cartflows-container" <?php echo trim( $atts_string ); ?>>
26
+ <?php
27
+ do_action( 'cartflows_container_top' );
28
+ ?>
29
+ <div class="cartflows-primary">
30
+ <?php
31
+ while ( have_posts() ) :
32
+
33
+ the_post();
34
+ the_content();
35
+
36
+ endwhile;
37
+ ?>
38
+ </div>
39
+ <?php
40
+ do_action( 'cartflows_container_bottom' );
41
+ ?>
42
+ </div>
43
+ <?php wp_footer(); ?>
44
+
45
+ </body>
46
+
47
+ </html>
48
+
49
+ <?php
modules/flow/view/meta-flow-steps.php CHANGED
@@ -1,168 +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( 'Templates', 'cartflows' ); ?></span>
137
- </div>
138
- <div class="wcf-tab-wrapper">
139
- <div id="wcf-page-builders">
140
- <ul class="wcf-page-builder-links filter-links">
141
- <li><a href="#" class="current" data-id="elementor"><?php _e( 'Elementor', 'cartflows' ); ?></a></li>
142
- <li><a href="#" data-id="divi"><?php _e( 'Divi', 'cartflows' ); ?></a></li>
143
- <li><a href="#" data-id="bb"><?php _e( 'Beaver Builder', 'cartflows' ); ?></a></li>
144
- </ul>
145
- </div>
146
- </div>
147
- <div class="wcf-popup-close-wrap">
148
- <span class="close-icon"><span class="wcf-cartflow-icons dashicons dashicons-no"></span></span>
149
- </div>
150
- </div>
151
-
152
- <!--<div class="wcf-search-form">
153
- <label class="screen-reader-text" for="wp-filter-search-input"><?php _e( 'Search Sites', 'cartflows' ); ?> </label>
154
- <input placeholder="<?php _e( 'Search Flow...', 'cartflows' ); ?>" type="text" aria-describedby="live-search-desc" class="wcf-flow-search-input">
155
- </div>-->
156
- <?php if ( ! _is_cartflows_pro() ) { ?>
157
- <div class="wcf-template-notice"><p><?php echo __( 'You need a Cartflows Pro version to import Upsell / Downsell', 'cartflows' ); ?></p></div>
158
- <?php } ?>
159
- <div id="wcf-remote-content">
160
- <div id="wcf-remote-step-filters"></div>
161
- <div id="wcf-remote-step-list" class="wcf-remote-list wcf-template-list-wrap"></div>
162
- <div id="wcf-upcoming-page-builders" style="display: none;" class="wcf-remote-list wcf-template-list-wrap"></div>
163
- </div>
164
- </div>
165
- </div>
166
- </div><!-- .wcf-templates-popup-overlay -->
167
- </div>
168
- <?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,260 +1,264 @@
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
- wc_print_notices();
66
-
67
- $order = false;
68
-
69
- if ( ! isset( $_GET['wcf-order'] ) && wcf()->flow->is_flow_testmode() ) {
70
-
71
- $args = array(
72
- 'limit' => 1,
73
- 'order' => 'DESC',
74
- 'status' => array( 'completed', 'processing' ),
75
- );
76
-
77
- $latest_order = wc_get_orders( $args );
78
-
79
- $order_id = ( ! empty( $latest_order ) ) ? current( $latest_order )->get_id() : 0;
80
-
81
- if ( $order_id > 0 ) {
82
-
83
- $order = wc_get_order( $order_id );
84
-
85
- if ( ! $order ) {
86
- $order = false;
87
- }
88
- }
89
- } else {
90
- if ( ! isset( $_GET['wcf-order'] ) ) {
91
- return '<p class="woocommerce-notice">Order not found. You cannot access this page directly.</p>';
92
- }
93
-
94
- // Get the order.
95
- $order_id = apply_filters( 'woocommerce_thankyou_order_id', empty( $_GET['wcf-order'] ) ? 0 : intval( $_GET['wcf-order'] ) );
96
- $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.
97
-
98
- if ( $order_id > 0 ) {
99
-
100
- $order = wc_get_order( $order_id );
101
-
102
- if ( ! $order || $order->get_order_key() !== $order_key ) {
103
- $order = false;
104
- }
105
- }
106
- }
107
-
108
- // Empty awaiting payment session.
109
- unset( WC()->session->order_awaiting_payment );
110
-
111
- // Empty current cart.
112
- wc_empty_cart();
113
-
114
- ob_start();
115
- echo "<div class='wcf-thankyou-wrap'>";
116
- wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
117
- echo '</div>';
118
- $output = ob_get_clean();
119
- }
120
-
121
- return $output;
122
- }
123
-
124
- /**
125
- * Load Thank You scripts.
126
- *
127
- * @return void
128
- */
129
- function thank_you_scripts() {
130
-
131
- if ( _is_wcf_thankyou_type() ) {
132
-
133
- do_action( 'cartflows_thank_you_scripts' );
134
-
135
- $style = $this->generate_thank_you_style();
136
-
137
- wp_add_inline_style( 'wcf-frontend-global', $style );
138
- }
139
- }
140
-
141
- /**
142
- * Set thank you as a order received page.
143
- *
144
- * @param boolean $is_order_page order page.
145
- * @return boolean
146
- */
147
- function set_order_received_page( $is_order_page ) {
148
-
149
- if ( _is_wcf_thankyou_type() ) {
150
-
151
- $is_order_page = true;
152
- }
153
-
154
- return $is_order_page;
155
- }
156
-
157
- /**
158
- * Generate Thank You Styles.
159
- *
160
- * @return string
161
- */
162
- function generate_thank_you_style() {
163
-
164
- global $post;
165
-
166
- if ( _is_wcf_thankyou_type() ) {
167
- $thank_you_id = $post->ID;
168
- } else {
169
- $thank_you_id = _get_wcf_thankyou_id( $post->post_content );
170
- }
171
-
172
- CartFlows_Font_Families::render_fonts( $thank_you_id );
173
-
174
- $text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-text-color' );
175
- $text_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-font-family' );
176
- $heading_text_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-color' );
177
- $heading_font_family = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-family' );
178
- $heading_font_weight = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-heading-font-wt' );
179
- $container_width = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-container-width' );
180
- $section_bg_color = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-tq-section-bg-color' );
181
-
182
- $show_order_review = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-overview-section' );
183
-
184
- $show_order_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-details-section' );
185
-
186
- $show_billing_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-billing-section' );
187
-
188
- $show_shipping_details = wcf()->options->get_thankyou_meta_value( $thank_you_id, 'wcf-show-shipping-section' );
189
-
190
- $output = "
191
- .wcf-thankyou-wrap{
192
- color: {$text_color};
193
- font-family: {$text_font_family};
194
- max-width:{$container_width}px;
195
- }
196
-
197
- .woocommerce-order h2.woocommerce-column__title,
198
- .woocommerce-order h2.woocommerce-order-details__title,
199
- .woocommerce-order .woocommerce-thankyou-order-received,
200
- .woocommerce-order-details h2 {
201
- color: {$heading_text_color};
202
- font-family: {$heading_font_family};
203
- font-weight: {$heading_font_weight};
204
- }
205
-
206
- .woocommerce-order ul.order_details,
207
- .woocommerce-order .woocommerce-order-details,
208
- .woocommerce-order .woocommerce-customer-details{
209
- background-color: {$section_bg_color}
210
- }
211
- ";
212
-
213
- if ( 'no' == $show_order_review ) {
214
- $output .= '
215
- .woocommerce-order ul.order_details{
216
- display: none;
217
- }
218
- ';
219
- }
220
-
221
- if ( 'no' == $show_order_details ) {
222
- $output .= '
223
- .woocommerce-order .woocommerce-order-details{
224
- display: none;
225
- }
226
- ';
227
- }
228
-
229
- if ( 'no' == $show_billing_details ) {
230
- $output .= '
231
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--billing-address{
232
- display: none;
233
- }
234
- ';
235
- }
236
-
237
- if ( 'no' == $show_shipping_details ) {
238
- $output .= '
239
- .woocommerce-order .woocommerce-customer-details .woocommerce-column--shipping-address{
240
- display: none;
241
- }
242
- ';
243
- }
244
-
245
- if ( 'no' == $show_billing_details && 'no' == $show_shipping_details ) {
246
- $output .= '
247
- .woocommerce-order .woocommerce-customer-details{
248
- display: none;
249
- }
250
- ';
251
- }
252
-
253
- return $output;
254
- }
255
- }
256
-
257
- /**
258
- * Kicking this off by calling 'get_instance()' method
259
- */
260
- 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
+ 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();
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: https://www.paypal.me/BrainstormForce
4
  Tags: woocommerce, cart
5
  Requires at least: 4.4
6
  Requires PHP: 5.6
7
- Tested up to: 5.0
8
- Stable tag: 1.1.0.1
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -13,79 +13,7 @@ Create beautiful checkout pages & sales flows for WooCommerce.
13
 
14
  == Description ==
15
 
16
- **#1 Funnel Builder For WordPress**
17
- ★★★★★<br>
18
-
19
- **Funnels are the most effective way to sell products & services.** We created <a href="https://cartflows.com" target="_blank">**CartFlows, a WordPress Funnel Builder**</a>, to help every website owner start using funnels to grow their business, generate more reveue, and have full control over their buyers journey.
20
- ## <center><a href="https://demos.cartflows.com/" target="_blank">Try The Demo</a></center> ##
21
-
22
- [youtube https://www.youtube.com/watch?v=SlE0moPKjMY]
23
-
24
- Turn your WooCommerce website into a selling machine using one-click sales funnels with frictionless checkout, custom thank you pages, global checkout replacement, and more…
25
-
26
- CartFlows is the best and easiest way to sell product and services on your website. With our library of done for you, one-click sales funnels, that literally sell your products and services for you.
27
-
28
- ## CARTFLOWS IS PERFECT FOR ##
29
-
30
- * **Selling Online Courses**
31
- * **Selling Event Tickets**
32
- * **Selling Services**
33
- * **Selling Info Product**
34
- * **Selling Physical Products**
35
- * **Selling Via Dropshipping**
36
- * **Selling Anything Really**
37
-
38
- CartFlows is the perfect <a href="https://cartflows.com/clickfunnels-alternative" target="_blank">ClickFunnels Alternative</a> because its built on the worlds most open platform, WordPress.
39
-
40
- ### CARTFLOWS GAME-CHANGING FEATURES ###
41
-
42
- See the features that make CartFlows the **Best Funnel Builder for WordPress**.
43
-
44
- * **Ready to Import Templates:**
45
- Choose from a wide variety of high converting templates. You can add a professionally crafted, multistep funnel, with one mouse click or you can build your own funnel and choose individual templates.
46
-
47
- * **Use Your Page Builder Or Gutenberg:**
48
- CartFlows will work with all popular page builders including Gutenberg. Initially we will offer templates for Beaver Builder, Elementor with Brizy and Divi coming soon. However you can use CartFlows with your own templates.
49
-
50
- * **Conversion Tested Checkout:**
51
- CartFlows replaces your complicated checkout process with our optimized checkout that instantly increases conversions, making you more money.
52
-
53
- * **Custom Next Step Thank You Pages:**
54
- Your buyers journey doesnt end after checkout. With CartFlows and our custom thank you page feautre, you can guild your new customer on their next steps.
55
-
56
- * **WooCommerce Checkout Page Replacement**
57
- Say goodby to using the same ridgid checkout page that everyone else is using. Create the perfect WooCommerce checkout page and assign it to be the default WooCommerce checkout template.
58
-
59
- ### Why is CartFlows such a game-changer? ###
60
-
61
- * **Sales Funnel Tools Are Expensive** — Most sales funnel tools carry a hefty monthly fee from $97 - $297 per month and they are worth every penny because funnels work. With CartFlows you can unleash the power of funnels for free.
62
-
63
- * **Sales Funnel Tools Are Complicated** — Most sales funnel tools are frustrating to use. You are stuck using their clunky page builer and have to go through an entirely new learnign curve. Who has time for that? With CartFlows you will feel right at home.
64
-
65
- * **Sales Funnel Tools Are Closed** — Perhaps the worst part of using other funnel builder tools is they are based on a closed platform which limits you in every way. CartFlows is open and sits on top of WordPress and WooCommerce.
66
-
67
- * **Sales Funnel Tools Lock You In** — We believe in using a platform where everything is on your domain and you control all your data. CartFlows puts you in control and in the drivers seat.
68
-
69
- ### Who Can Benefit From CartFlows? ###
70
-
71
- #### CartFlows Funnel Builder Plugin is perfect for: ####
72
- ✔ Bloggers
73
- ✔ Course Creators
74
- ✔ Coaches / Trainers
75
- ✔ Dropshippers
76
- ✔ eCommerce Store Owners
77
- ✔ Niche Sites
78
- ✔ Businesses
79
- ✔ Local Businesses
80
- ✔ Startups
81
- ✔ Personal Brands
82
- ✔ Real Estate Agents
83
- ✔ Artists & Photographers
84
- ✔ All WordPress Websites
85
-
86
- ## JOIN THE CARTFLOWS INNER CIRCLE ##
87
-
88
- **<a href="https://www.facebook.com/groups/cartflows/" target="_blank">JOIN OUR FACEBOOK GROUP COMMUNITY</a>**: Learn the tactics and techniques that other CartFlows users are doing to grow their businesses. Also get exciting insider information on upcoming feature releases.
89
 
90
  == Installation ==
91
 
@@ -93,6 +21,14 @@ 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.0.1 - Friday, 7th December 2018
97
  * Fix: Checkout breaking issue.
98
 
4
  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.1
9
  License: GPLv2 or later
10
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
11
 
13
 
14
  == Description ==
15
 
16
+ Create beautiful checkout pages & sales flows for WooCommerce.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  == Installation ==
19
 
21
  2. Activate the plugin through the 'Plugins' menu in WordPress
22
 
23
  == Changelog ==
24
+ Version 1.1.1 - Wednesday, 2nd January 2019
25
+ * Improvement: Added compatibility for a future release of CartFlows Pro.
26
+ * Improvement: Minor CSS and HTML changes.
27
+ * Fix: Flatsome UX builder compatibility added.
28
+ * Fix: OceanWP CSS overwrite issue.
29
+ * Fix: Divi CSS issue.
30
+ * Fix: Other minor bugs.
31
+
32
  Version 1.1.0.1 - Friday, 7th December 2018
33
  * Fix: Checkout breaking issue.
34